EHS
Loading...
Searching...
No Matches
Str.h
Go to the documentation of this file.
1#pragma once
2
3#include "Types.h"
4#include "BaseObj.h"
5#include "Util.h"
6#include "Vector.h"
7
8#include <utility>
9
10namespace ehs
11{
17
18 enum class IndexResult
19 {
22 };
23
27 template<typename T = Char_8, typename N = UInt_64>
28 class Str
29 {
30 private:
31 N size;
32 T* data;
33
34 public:
37 {
38 delete[] data;
39 }
40
43 : size(0), data(nullptr)
44 {
45 }
46
50 Str(const T* const str, const N size)
51 : size(size), data(nullptr)
52 {
53 if (!size)
54 return;
55
56 data = new T[this->size + 1];
57
58 Util::Copy(data, str, Size(true));
59
60 data[this->size] = 0;
61 }
62
65 Str(const T* const str)
66 : size(Len(str)), data(nullptr)
67 {
68 data = new T[size + 1];
69
70 Util::Copy(data, str, Size(true));
71
72 data[size] = 0;
73 }
74
77 Str(const N size)
78 : size(size), data(new T[size + 1])
79 {
80 data[size] = 0;
81 }
82
84 Str(Str&& str) noexcept
85 : size(str.size), data(str.data)
86 {
87 str.size = 0;
88 str.data = nullptr;
89 }
90
93 Str(const Str& str)
94 : size(str.size), data(new T[size + 1])
95 {
96 Util::Copy(data, str.data, Size(true));
97
98 data[size] = 0;
99 }
100
101 Str& operator=(Str&& str) noexcept
102 {
103 if (this == &str)
104 return *this;
105
106 size = str.size;
107 delete[] data;
108 data = str.data;
109
110 str.size = 0;
111 str.data = nullptr;
112
113 return *this;
114 }
115
119 Str& operator=(const Str& str)
120 {
121 if (&str == this)
122 return *this;
123
124 size = str.size;
125
126 delete[] data;
127 data = new T[size + 1];
128 Util::Copy(data, str.data, Size(true));
129 data[size] = 0;
130
131 return *this;
132 }
133
137 Str<T, N>& operator=(const T* const str)
138 {
139 size = Len(str);
140
141 delete[] data;
142
143 data = new T[size + 1];
144
145 Util::Copy(data, str, Size(true));
146
147 data[size] = 0;
148
149 return *this;
150 }
151
155 Str<T, N>& operator+=(const T* const str)
156 {
157 N inputSize = Len(str);
158
159 T* result = new T[size + inputSize + 1];
160
161 Util::Copy(result, data, Size(true));
162
163 delete[] data;
164
165 Util::Copy(&result[size], str, inputSize * sizeof(T));
166
167 result[size + inputSize] = 0;
168 size += inputSize;
169 data = result;
170
171 return *this;
172 }
173
178 {
179 T* result = new T[size + str.size + 1];
180
181 Util::Copy(result, data, Size(true));
182
183 delete[] data;
184
185 Util::Copy(&result[size], str, str.Size(true));
186
187 result[size + str.size] = 0;
188 size += str.Size();
189 data = result;
190
191 return *this;
192 }
193
197 Str<T, N>& operator+=(const SInt_64 num)
198 {
199 return operator+=(FromNum(num));
200 }
201
205 Str<T, N>& operator+=(const UInt_64 num)
206 {
207 return operator+=(FromNum(num));
208 }
209
214 {
215 return operator+=(FromNum(num));
216 }
217
222 {
223 return operator+=(FromNum(num));
224 }
225
230 {
231 return operator+=(FromNum(num));
232 }
233
238 {
239 return operator+=(FromNum(num));
240 }
241
246 {
247 return operator+=(FromNum(num));
248 }
249
254 {
255 return operator+=(FromNum(num));
256 }
257
258 #ifdef EHS_OS_WINDOWS
262 Str<T, N>& operator+=(const DWORD num)
263 {
264 return operator+=(FromNum(num));
265 }
266
270 Str<T, N>& operator+=(const HRESULT num)
271 {
272 return operator+=(FromNum(num));
273 }
274 #endif
275
279 Str<T, N>& operator+=(const float num)
280 {
281 return operator+=(FromNum(num));
282 }
283
287 Str<T, N>& operator+=(const double num)
288 {
289 return operator+=(FromNum(num));
290 }
291
295 Str<T, N>& operator+=(const long double num)
296 {
297 return operator+=(FromNum(num));
298 }
299
303 Str<T, N> operator+(const T* const str) const
304 {
305 N inSize = Len(str);
306
307 Str<T, N> result(size + inSize);
308
309 Util::Copy(result.data, data, Size(true));
310
311 Util::Copy(&result.data[size], str, inSize * sizeof(T));
312
313 result.data[size + inSize] = 0;
314
315 return result;
316 }
317
321 Str<T, N> operator+(const Str<T, N>& str) const
322 {
323 Str<T, N> result(size + str.size);
324
325 Util::Copy(result.data, data, Size(true));
326
327 Util::Copy(&result.data[size], str.data, str.Size(true));
328
329 result.data[size + str.size] = 0;
330
331 return result;
332 }
333
337 Str<T, N> operator+(const SInt_64 num) const
338 {
339 return operator+(FromNum(num));
340 }
341
345 Str<T, N> operator+(const UInt_64 num) const
346 {
347 return operator+(FromNum(num));
348 }
349
353 Str<T, N> operator+(const SInt_32 num) const
354 {
355 return operator+(FromNum(num));
356 }
357
361 Str<T, N> operator+(const UInt_32 num) const
362 {
363 return operator+(FromNum(num));
364 }
365
369 Str<T, N> operator+(const SInt_16 num) const
370 {
371 return operator+(FromNum(num));
372 }
373
377 Str<T, N> operator+(const UInt_16 num) const
378 {
379 return operator+(FromNum(num));
380 }
381
385 Str<T, N> operator+(const SInt_8 num) const
386 {
387 return operator+(FromNum(num));
388 }
389
393 Str<T, N> operator+(const UInt_8 num) const
394 {
395 return operator+(FromNum(num));
396 }
397
398 #ifdef EHS_OS_WINDOWS
402 Str<T, N> operator+(const DWORD num) const
403 {
404 return operator+(FromNum(num));
405 }
406
410 Str<T, N> operator+(const HRESULT num) const
411 {
412 return operator+(FromNum(num));
413 }
414 #endif
415
419 Str<T, N> operator+(const float num) const
420 {
421 return operator+(FromNum(num));
422 }
423
427 Str<T, N> operator+(const double num) const
428 {
429 return operator+(FromNum(num));
430 }
431
435 Str<T, N> operator+(const long double num) const
436 {
437 return operator+(FromNum(num));
438 }
439
443 bool operator==(T* str) const
444 {
445 if (size != Len(str))
446 return false;
447
448 return Util::Compare(data, str, Size(true));
449 }
450
454 bool operator==(const T* const str) const
455 {
456 if (size != Len(str))
457 return false;
458
459 return Util::Compare(data, str, Size(true));
460 }
461
465 bool operator==(const Str<T, N>& str) const
466 {
467 if (size != str.size)
468 return false;
469
470 return Util::Compare(data, str, Size(true));
471 }
472
476 bool operator!=(const T* const str) const
477 {
478 if (size != Len(str))
479 return true;
480
481 return !Util::Compare(data, str, Size(true));
482 }
483
487 bool operator!=(const Str<T, N>& str) const
488 {
489 if (size != str.size)
490 return true;
491
492 return !Util::Compare(data, str, Size(true));
493 }
494
496 operator T* () const
497 {
498 return data;
499 }
500
503 void Resize(const N newSize)
504 {
505 if (newSize == size)
506 return;
507
508 T* result = new T[newSize + 1];
509
510 if (newSize > size)
511 Util::Copy(result, data, Size(true));
512 else
513 Util::Copy(result, data, newSize * sizeof(T));
514
515 size = newSize;
516
517 delete[] data;
518
519 data = result;
520 data[size] = 0;
521 }
522
526 N Size(bool inBytes = false) const
527 {
528 if (inBytes)
529 return sizeof(T) * size;
530 else
531 return size;
532 }
533
536 {
537 size = Len(data);
538
539 T* result = new T[size + 1];
540 Util::Copy(result, data, Size(true));
541
542 delete[] data;
543
544 result[size] = 0;
545 data = result;
546 }
547
551 void Copy(const N dstOffset, const Str<T, N>& src)
552 {
553 if (dstOffset + src.size > size)
554 {
555 //Log_8 log(__FUNCSIG__, LogType::ERR, 0, "The parameters \"dstOffset\" (" + Str_8::FromNum(dstOffset) + ") + \"srcSize\" (" + Str_8::FromNum(src.Size()) + ") is greater than the referenced string object's size (" + Str_8::FromNum(size) + ").");
556 return;
557 }
558
559 Util::Copy(&data[dstOffset], src, src.Size(true));
560 }
561
565 void Copy(const N dstOffset, const T* const src)
566 {
567 N srcSize = Len(src);
568
569 if (dstOffset + srcSize > size)
570 {
571 //Log_8 log(__FUNCSIG__, LogType::ERR, 0, "The parameters \"dstOffset\" (" + Str_8::FromNum(dstOffset) + ") + \"srcSize\" (" + Str_8::FromNum(srcSize) + ") is greater than the referenced string object's size (" + Str_8::FromNum(size) + ").");
572 return;
573 }
574
575 Util::Copy(&data[dstOffset], src, srcSize * sizeof(T));
576 }
577
582 void Copy(const N dstOffset, const T* const src, const N srcSize)
583 {
584 if (dstOffset + srcSize > size)
585 {
586 //Log_8 log(__FUNCSIG__, LogType::ERR, 0, "The parameters \"dstOffset\" (" + Str_8::FromNum(dstOffset) + ") + \"srcSize\" (" + Str_8::FromNum(srcSize) + ") is greater than the referenced string object's size (" + Str_8::FromNum(size) + ").");
587 return;
588 }
589
590 Util::Copy(&data[dstOffset], src, srcSize * sizeof(T));
591 }
592
596 void Insert(const N index, const Str& value)
597 {
598 if (!value.size)
599 return;
600
601 N newSize = size + value.size;
602
603 T* result = new T[newSize + 1];
604
605 Util::Copy(result, data, index * sizeof(T));
606
607 Util::Copy(&result[index], value.data, value.Size(true));
608
609 Util::Copy(&result[index + value.size], &data[index], size - index);
610
611 result[newSize] = 0;
612
613 delete[] data;
614 data = result;
615 size = newSize;
616 }
617
621 void Insert(const N index, const T value)
622 {
623 N newSize = 0;
624 if (index > size - 1)
625 newSize = size + ((index + 1) - size);
626 else
627 newSize = size + 1;
628
629 T* result = new T[newSize + 1];
630
631 for (N i = 0; i < index; ++i)
632 result[i] = data[i];
633
634 result[index] = value;
635
636 for (N i = index; i < size; ++i)
637 result[i + 1] = data[i];
638
639 result[newSize] = 0;
640
641 delete[] data;
642 data = result;
643 size = newSize;
644 }
645
650 Str Remove(const N start, const N end)
651 {
652 if (!size || start >= size || end > size || end <= start)
653 return {};
654
655 Str popped(&data[start], end - start);
656
657 N newSize = size - popped.size;
658 T* result = new T[newSize + 1];
659
660 Util::Copy(result, data, start * sizeof(T));
661
662 Util::Copy(&result[start], &data[end], (size - end) * sizeof(T));
663
664 result[newSize] = 0;
665
666 delete[] data;
667 data = result;
668 size = newSize;
669
670 return popped;
671 }
672
676 T Remove(const N index)
677 {
678 T popped = {};
679
680 if (!size || index >= size)
681 return popped;
682
683 popped = data[index];
684
685 N newSize = size - 1;
686 T* result = new T[newSize];
687
688 for (N i = 0; i < index; ++i)
689 result[i] = data[i];
690
691 for (N i = index + 1; i < size; ++i)
692 result[i - 1] = data[i];
693
694 delete[] data;
695 data = result;
696 size = newSize;
697
698 return popped;
699 }
700
703 void Push(const Str<T, N> &value)
704 {
705 T* result = new T[size + value.size + 1];
706 Util::Copy(result, data, Size(true));
707 Util::Copy(&result[size], value, value.Size(true));
708
709 result[size + value.Size()] = 0;
710
711 delete[] data;
712
713 data = result;
714 size += value.size;
715 }
716
720 void Push(const T* const value, const N size)
721 {
722 T* result = new T[this->size + size + 1];
723 Util::Copy(result, data, Size(true));
724 Util::Copy(&result[this->size], value, size * sizeof(T));
725
726 result[this->size + size] = 0;
727
728 delete[] data;
729
730 data = result;
731 this->size += size;
732 }
733
736 void Push(const T* const value)
737 {
738 N inSize = Len(value);
739
740 T* result = new T[size + inSize + 1];
741 Util::Copy(result, data, Size(true));
742 Util::Copy(&result[size], value, inSize * sizeof(T));
743
744 result[size + inSize] = 0;
745
746 delete[] data;
747
748 data = result;
749 size += inSize;
750 }
751
754 void Push(const T value)
755 {
756 T* result = new T[size + 2];
757
758 Util::Copy(result, data, Size(true));
759
760 result[size] = value;
761 result[size + 1] = 0;
762
763 delete[] data;
764
765 data = result;
766 ++size;
767 }
768
771 T Pop()
772 {
773 T* result = new T[size--];
774
775 T value = data[size];
776
777 Util::Copy(result, data, Size(true));
778
779 result[size] = 0;
780
781 delete[] data;
782
783 data = result;
784
785 return value;
786 }
787
790 const Byte* ToBytes() const
791 {
792 return (Byte*)data;
793 }
794
798 {
799 return (Byte*)data;
800 }
801
803 void ToLower()
804 {
805 for (N i = 0; i < size; ++i)
806 if (data[i] > 64 && data[i] < 91)
807 data[i] += 32;
808 }
809
813 {
814 Str<T, N> result(size);
815
816 for (N i = 0; i < size; ++i)
817 if (data[i] > 64 && data[i] < 91)
818 result[i] = data[i] + 32;
819 else
820 result[i] = data[i];
821
822 return result;
823 }
824
826 void ToUpper()
827 {
828 for (N i = 0; i < size; ++i)
829 if (data[i] > 96 && data[i] < 123)
830 data[i] -= 32;
831 }
832
836 {
837 Str<T, N> result(size);
838
839 for (N i = 0; i < size; ++i)
840 if (data[i] > 96 && data[i] < 123)
841 result[i] = data[i] - 32;
842 else
843 result[i] = data[i];
844
845 return result;
846 }
847
849 void Reverse()
850 {
851 if (size <= 1 || !data)
852 return;
853
854 T* r = new T[size + 1];
855
856 for (N i = 0; i < size; ++i)
857 r[i] = data[size - 1 - i];
858
859 r[size] = 0;
860
861 delete[] data;
862
863 data = r;
864 }
865
869 {
870 if (size <= 1 || !data)
871 return *this;
872
873 Str<T, N> r(size);
874
875 for (N i = 0; i < size; ++i)
876 r[i] = data[size - 1 - i];
877
878 return r;
879 }
880
885 Str<T, N> Sub(const N index, const N size = 0) const
886 {
887 if (index >= this->size)
888 {
889 //Log_8 log(__FUNCSIG__, LogType::ERR, 0, "The given index parameter, \"" + Str<T, N>::FromNum(index) + "\" is greater than the string's size, \"" + Str<T, N>::FromNum(this->size) + "\".");
890
891 return Str<T, N>();
892 }
893
894 if (size)
895 {
896 if (size > this->size)
897 {
898 //Log_8 log(__FUNCSIG__, LogType::ERR, 1, "The given size parameter, \"" + Str<T, N>::FromNum(size) + "\" is greater than the string's size, \"" + Str<T, N>::FromNum(this->size) + "\", at the index, \"" + Str<T, N>::FromNum(index) + "\".");
899
900 return Str<T, N>();
901 }
902
903 Str<T, N> result(size);
904
905 Util::Copy(result, &data[index], result.Size(true));
906
907 return result;
908 }
909 else
910 {
911 Str<T, N> result(this->size - index);
912
913 Util::Copy(result, &data[index], result.Size(true));
914
915 return result;
916 }
917 }
918
923 Vector<Str<T, N>, N> Split(const Str<T, N>& delimeter, const N max = 0) const
924 {
925 Vector<Str<T, N>, N> result(0, 5);
926
927 N b = 0;
928
929 for (N i = 0, c = 0; i < size; ++i)
930 {
931 if (data[i] == delimeter[c])
932 {
933 if (++c == delimeter.Size())
934 {
935 N r = i - (c - 1) - b;
936 if (!r)
937 result.Push(Str<T, N>());
938 else
939 result.Push(Str<T, N>(&data[b], r));
940
941 b = i + 1;
942 c = 0;
943
944 if (max && result.Size() == max)
945 break;
946 }
947 }
948 else
949 {
950 c = 0;
951 }
952 }
953
954 if (b < size)
955 result.Push(Str<T, N>(&data[b], size - b));
956
957 return result;
958 }
959
963 Str<T, N> RemoveAll(const Str<T, N>& delimeter) const
964 {
965 Str<T, N> result(size);
966
967 for (N i = 0, b = 0, c = 0; i < size; ++i)
968 {
969 if (data[i] == delimeter[c])
970 {
971 if (++c == delimeter.Size())
972 c = 0;
973 }
974 else
975 {
976 if (c)
977 for (N d = c; d < 0; --d)
978 result[b++] = data[i - d];
979 else
980 result[b++] = data[i];
981
982 c = 0;
983 }
984 }
985
986 return result;
987 }
988
993 Str ReplaceAll(const Str& delimeter, const Str& replacer) const
994 {
995 Str<T, N> result;
996
997 for (N i = 0, b = 0; i < size; ++i)
998 {
999 if (data[i] == delimeter[b])
1000 {
1001 if (++b == delimeter.Size())
1002 {
1003 result.Push(replacer);
1004 b = 0;
1005 }
1006 }
1007 else
1008 {
1009 result.Push(data[i]);
1010 }
1011 }
1012
1013 return result;
1014 }
1015
1022 bool Find(const Str<T, N> &delimeter, N* const index = nullptr, const SearchPattern pattern = SearchPattern::LEFT_RIGHT, const IndexResult result = IndexResult::BEGINNING) const
1023 {
1024 if (pattern == SearchPattern::LEFT_RIGHT)
1025 {
1026 for (N i = 0, c = 0; i < size; ++i)
1027 {
1028 if (data[i] == delimeter[c])
1029 {
1030 if (++c == delimeter.Size())
1031 {
1032 if (result == IndexResult::BEGINNING)
1033 {
1034 if (index)
1035 *index = i - (c - 1);
1036
1037 return true;
1038 }
1039 else
1040 {
1041 if (index)
1042 *index = i;
1043
1044 return true;
1045 }
1046 }
1047 }
1048 }
1049 }
1050 else if (pattern == SearchPattern::RIGHT_LEFT)
1051 {
1052 for (N i = size, c = delimeter.Size(); i > 0; --i)
1053 {
1054 if (data[i - 1] == delimeter[c - 1])
1055 {
1056 if (--c == 0)
1057 {
1058 if (result == IndexResult::BEGINNING)
1059 {
1060 if (index)
1061 *index = i - (delimeter.Size() - 1);
1062
1063 return true;
1064 }
1065 else
1066 {
1067 if (index)
1068 *index = i;
1069
1070 return true;
1071 }
1072 }
1073 }
1074 }
1075 }
1076
1077 return false;
1078 }
1079
1084 bool Contains(const Str<T, N>& delimeter, const SearchPattern pattern = SearchPattern::LEFT_RIGHT) const
1085 {
1086 if (pattern == SearchPattern::LEFT_RIGHT)
1087 {
1088 for (N i = 0, c = 0; i < size; ++i)
1089 {
1090 if (data[i] == delimeter[c])
1091 {
1092 if (++c == delimeter.Size())
1093 {
1094 return true;
1095 }
1096 }
1097 }
1098 }
1099 else if (pattern == SearchPattern::RIGHT_LEFT)
1100 {
1101 for (N i = size, c = delimeter.Size(); i > 0; --i)
1102 {
1103 if (data[i - 1] == delimeter[c - 1])
1104 {
1105 if (--c == 0)
1106 {
1107 return true;
1108 }
1109 }
1110 }
1111 }
1112
1113 return false;
1114 }
1115
1117 {
1118 Vector<Str> args;
1119 T *quoteStart = nullptr;
1120 T *spaceStart = nullptr;
1121
1122 for (T *i = data; i <= data + size; ++i)
1123 {
1124 if (*i == '\"' && !spaceStart)
1125 {
1126 if (quoteStart)
1127 {
1128 args.Push(Str(quoteStart, i - quoteStart));
1129 quoteStart = nullptr;
1130 }
1131 else
1132 {
1133 if (i + 1 < &data[size - 1])
1134 quoteStart = i + 1;
1135 else
1136 args.Push({});
1137 }
1138 }
1139 else if (*i == ' ' && !quoteStart)
1140 {
1141 if (spaceStart)
1142 {
1143 args.Push(Str(spaceStart, i - spaceStart));
1144 spaceStart = i + 1;
1145 }
1146 else
1147 {
1148 if (i + 1 < &data[size - 1])
1149 spaceStart = i + 1;
1150 else
1151 args.Push({});
1152 }
1153 }
1154 }
1155
1156 if (quoteStart)
1157 args.Push(Str(quoteStart, &data[size - 1] - (quoteStart - 1)));
1158 else if (spaceStart)
1159 args.Push(Str(spaceStart, &data[size - 1] - (spaceStart - 1)));
1160
1161 return args;
1162 }
1163
1166 bool IsNum() const
1167 {
1168 if (!size)
1169 return false;
1170
1171 if ((data[0] < '0' || data[0] > '9') && data[0] != '-' && data[0] != '.')
1172 return false;
1173
1174 for (N i = 1; i < size; ++i)
1175 if ((data[i] < '0' || data[i] > '9') && data[i] != '.')
1176 return false;
1177
1178 return true;
1179 }
1180
1185 template<typename I = int>
1186 static Str NumToHex(const I num)
1187 {
1188 static const T hex[] = "0123456789ABCDEF";
1189
1190 Str result(sizeof(I) * 2);
1191
1192 for (UInt_8 i = 0; i < sizeof(I); ++i)
1193 {
1194 result[i * 2] = hex[((Byte*)&num)[i] / 16];
1195 result[i * 2 + 1] = hex[((Byte*)&num)[i] % 16];
1196 }
1197
1198 return result;
1199 }
1200
1205 template<typename I = int>
1206 static I HexToNum(const Str& in)
1207 {
1208 N offset = 0;
1209 bool neg = false;
1210
1211 if (in[offset] == 45)
1212 {
1213 neg = true;
1214 ++offset;
1215 }
1216 else if (in[offset] == 43)
1217 ++offset;
1218
1219 if (in[offset] == 48 && (in[offset + 1] == 88 || in[offset + 1] == 120))
1220 offset += 2;
1221
1222 N acc = 0;
1223
1224 for (N i = offset; i < in.Size(); ++i)
1225 {
1226 I value = 0;
1227
1228 if (in[i] > 47 && in[i] < 58)
1229 value = in[i] - 48;
1230 else if (in[i] > 64 && in[i] < 71)
1231 value = in[i] - 55;
1232 else if (in[i] > 96 && in[i] < 103)
1233 value = in[i] - 87;
1234
1235 if (value >= 16)
1236 return 0;
1237
1238 acc *= 16;
1239 acc += value;
1240 }
1241
1242 return neg ? -acc : acc;
1243 }
1244
1248 template<typename I = int>
1249 I HexToNum() const
1250 {
1251 N offset = 0;
1252 bool neg = false;
1253
1254 if (data[offset] == 45)
1255 {
1256 neg = true;
1257 ++offset;
1258 }
1259 else if (data[offset] == 43)
1260 ++offset;
1261
1262 if (data[offset] == 48 && (data[offset + 1] == 88 || data[offset + 1] == 120))
1263 offset += 2;
1264
1265 N acc = 0;
1266
1267 for (N i = offset; i < size; ++i)
1268 {
1269 I value = 0;
1270
1271 if (data[i] > 47 && data[i] < 58)
1272 value = data[i] - 48;
1273 else if (data[i] > 64 && data[i] < 71)
1274 value = data[i] - 55;
1275 else if (data[i] > 96 && data[i] < 103)
1276 value = data[i] - 87;
1277
1278 if (value >= 16)
1279 return 0;
1280
1281 acc *= 16;
1282 acc += value;
1283 }
1284
1285 return neg ? -acc : acc;
1286 }
1287
1292 template<typename I = N>
1293 I ToDecimal() const
1294 {
1295 I r = 0;
1296
1297 if (!size)
1298 return r;
1299
1300 for (N i = data[0] == '-' ? 1 : 0; i < size; ++i)
1301 r = r * 10 + data[i] - '0';
1302
1303 if (data[0] == '-')
1304 r *= -1;
1305
1306 return r;
1307 }
1308
1312 float ToFloat() const
1313 {
1314 Str<T, N> ide;
1315 ide.Push(46);
1316
1317 N decPoint = size;
1318 Find(ide, &decPoint);
1319
1320 float result = 0.0f;
1321 float fraction = 0.0f;
1322 float scale = 1.0f;
1323
1324 for (N i = 0; i < decPoint; ++i)
1325 result = result * 10.0f + data[i] - '0';
1326
1327 for (N i = decPoint + 1; i < size; ++i)
1328 {
1329 fraction = fraction * 10.0f + data[i] - '0';
1330 scale *= 10.0f;
1331 }
1332
1333 result += fraction / scale;
1334
1335 return result;
1336 }
1337
1341 double ToDouble() const
1342 {
1343 Str<T, N> ide;
1344 ide.Push(46);
1345
1346 N decPoint = size;
1347 Find(ide, &decPoint);
1348
1349 double result = 0.0f;
1350 double fraction = 0.0f;
1351 double scale = 1.0f;
1352
1353 for (N i = 0; i < decPoint; ++i)
1354 result = result * 10.0f + data[i] - '0';
1355
1356 for (N i = decPoint + 1; i < size; ++i)
1357 {
1358 fraction = fraction * 10.0f + data[i] - '0';
1359 scale *= 10.0f;
1360 }
1361
1362 result += fraction / scale;
1363
1364 return result;
1365 }
1366
1370 long double ToLDouble() const
1371 {
1372 Str<T, N> ide;
1373 ide.Push(46);
1374
1375 N decPoint = size;
1376 Find(ide, &decPoint);
1377
1378 long double result = 0.0f;
1379 long double fraction = 0.0f;
1380 long double scale = 1.0f;
1381
1382 for (N i = 0; i < decPoint; ++i)
1383 result = result * 10.0f + data[i] - '0';
1384
1385 for (N i = decPoint + 1; i < size; ++i)
1386 {
1387 fraction = fraction * 10.0f + data[i] - '0';
1388 scale *= 10.0f;
1389 }
1390
1391 result += fraction / scale;
1392
1393 return result;
1394 }
1395
1399 static Str<T, N> FromNum(const SInt_64 num)
1400 {
1401 if (num == 0)
1402 {
1403 Str<T, N> z(1);
1404 z[0] = 48;
1405 return z;
1406 }
1407
1408 Str<T, N> r(21);
1409
1410 SInt_64 nonNeg;
1411 if (num < 0)
1412 nonNeg = -num;
1413 else
1414 nonNeg = num;
1415
1416 N i = 0;
1417
1418 while (nonNeg != 0)
1419 {
1420 r[i++] = 48 + nonNeg % 10;
1421 nonNeg /= 10;
1422 }
1423
1424 if (num < 0)
1425 r[i++] = 45;
1426
1427 r.Resize(i);
1428
1429 return r.GetReverse();
1430 }
1431
1435 static Str<T, N> FromNum(const UInt_64 num)
1436 {
1437 if (num == 0)
1438 {
1439 Str<T, N> z(1);
1440 z[0] = 48;
1441 return z;
1442 }
1443
1444 Str<T, N> r(21);
1445
1446 UInt_64 nonNeg = num;
1447
1448 N i = 0;
1449
1450 while (nonNeg != 0)
1451 {
1452 r[i++] = 48 + nonNeg % 10;
1453 nonNeg /= 10;
1454 }
1455
1456 r.Resize(i);
1457
1458 return r.GetReverse();
1459 }
1460
1464 static Str<T, N> FromNum(const SInt_32 num)
1465 {
1466 if (num == 0)
1467 {
1468 Str<T, N> z(1);
1469 z[0] = 48;
1470 return z;
1471 }
1472
1473 Str<T, N> r(11);
1474
1475 SInt_32 nonNeg;
1476 if (num < 0)
1477 nonNeg = -num;
1478 else
1479 nonNeg = num;
1480
1481 N i = 0;
1482
1483 while (nonNeg != 0)
1484 {
1485 r[i++] = 48 + nonNeg % 10;
1486 nonNeg /= 10;
1487 }
1488
1489 if (num < 0)
1490 r[i++] = 45;
1491
1492 r.Resize(i);
1493
1494 return r.GetReverse();
1495 }
1496
1500 static Str<T, N> FromNum(const UInt_32 num)
1501 {
1502 if (num == 0)
1503 {
1504 Str<T, N> z(1);
1505 z[0] = 48;
1506 return z;
1507 }
1508
1509 Str<T, N> r(11);
1510
1511 UInt_32 nonNeg = num;
1512
1513 N i = 0;
1514
1515 while (nonNeg != 0)
1516 {
1517 r[i++] = 48 + nonNeg % 10;
1518 nonNeg /= 10;
1519 }
1520
1521 r.Resize(i);
1522
1523 return r.GetReverse();
1524 }
1525
1529 static Str<T, N> FromNum(const SInt_16 num)
1530 {
1531 if (num == 0)
1532 {
1533 Str<T, N> z(1);
1534 z[0] = 48;
1535 return z;
1536 }
1537
1538 Str<T, N> r(6);
1539
1540 SInt_16 nonNeg;
1541 if (num < 0)
1542 nonNeg = -num;
1543 else
1544 nonNeg = num;
1545
1546 N i = 0;
1547
1548 while (nonNeg != 0)
1549 {
1550 r[i++] = 48 + nonNeg % 10;
1551 nonNeg /= 10;
1552 }
1553
1554 if (num < 0)
1555 r[i++] = 45;
1556
1557 r.Resize(i);
1558
1559 return r.GetReverse();
1560 }
1561
1565 static Str<T, N> FromNum(const UInt_16 num)
1566 {
1567 if (num == 0)
1568 {
1569 Str<T, N> z(1);
1570 z[0] = 48;
1571 return z;
1572 }
1573
1574 Str<T, N> r(6);
1575
1576 UInt_16 nonNeg = num;
1577
1578 N i = 0;
1579
1580 while (nonNeg != 0)
1581 {
1582 r[i++] = 48 + nonNeg % 10;
1583 nonNeg /= 10;
1584 }
1585
1586 r.Resize(i);
1587
1588 return r.GetReverse();
1589 }
1590
1594 static Str<T, N> FromNum(const SInt_8 num)
1595 {
1596 if (num == 0)
1597 {
1598 Str<T, N> z(1);
1599 z[0] = 48;
1600 return z;
1601 }
1602
1603 Str<T, N> r(4);
1604
1605 SInt_8 nonNeg;
1606 if (num < 0)
1607 nonNeg = -num;
1608 else
1609 nonNeg = num;
1610
1611 N i = 0;
1612
1613 while (nonNeg != 0)
1614 {
1615 r[i++] = 48 + nonNeg % 10;
1616 nonNeg /= 10;
1617 }
1618
1619 if (num < 0)
1620 r[i++] = 45;
1621
1622 r.Resize(i);
1623
1624 return r.GetReverse();
1625 }
1626
1630 static Str<T, N> FromNum(const UInt_8 num)
1631 {
1632 if (num == 0)
1633 {
1634 Str<T, N> z(1);
1635 z[0] = 48;
1636 return z;
1637 }
1638
1639 Str<T, N> r(4);
1640
1641 UInt_8 nonNeg = num;
1642
1643 N i = 0;
1644
1645 while (nonNeg != 0)
1646 {
1647 r[i++] = 48 + nonNeg % 10;
1648 nonNeg /= 10;
1649 }
1650
1651 r.Resize(i);
1652
1653 return r.GetReverse();
1654 }
1655
1656 #ifdef EHS_OS_WINDOWS
1659 static Str<T, N> FromNum(const DWORD num)
1660 {
1661 if (num == 0)
1662 {
1663 Str<T, N> z(1);
1664 z[0] = 48;
1665 return z;
1666 }
1667
1668 Str<T, N> r(11);
1669
1670 DWORD nonNeg = num;
1671
1672 N i = 0;
1673
1674 while (nonNeg != 0)
1675 {
1676 r[i++] = 48 + nonNeg % 10;
1677 nonNeg /= 10;
1678 }
1679
1680 r.Resize(i);
1681
1682 return r.GetReverse();
1683 }
1684
1687 static Str<T, N> FromNum(const HRESULT num)
1688 {
1689 if (num == 0)
1690 {
1691 Str<T, N> z(1);
1692 z[0] = 48;
1693 return z;
1694 }
1695
1696 Str<T, N> r(11);
1697
1698 HRESULT nonNeg;
1699 if (num < 0)
1700 nonNeg = -num;
1701 else
1702 nonNeg = num;
1703
1704 N i = 0;
1705
1706 while (nonNeg != 0)
1707 {
1708 r[i++] = 48 + nonNeg % 10;
1709 nonNeg /= 10;
1710 }
1711
1712 if (num < 0)
1713 r[i++] = 45;
1714
1715 r.Resize(i);
1716
1717 return r.GetReverse();
1718 }
1719 #endif
1720
1725 static Str<T, N> FromNum(const float num, const UInt_8 maxDecimals = 5)
1726 {
1727 SInt_64 whole = (SInt_64)num;
1728
1729 Str<T, N> result;
1730 if (whole < 0)
1731 result.Push(45);
1732
1733 result += Str<T, N>::FromNum(whole);
1734
1735 UInt_64 power = 10;
1736 for (UInt_64 i = 0; i < (UInt_64)maxDecimals - 1; ++i)
1737 power *= 10;
1738
1739 SInt_64 fraction = (SInt_64)((num - (float)whole) * (float)power);
1740 if (!fraction)
1741 return result;
1742
1743 result.Push(46);
1744
1745 Str<T, N> fResult(maxDecimals);
1746 N i = 0;
1747
1748 while (fraction)
1749 {
1750 fResult[i++] = 48 + fraction % 10;
1751 fraction /= 10;
1752 }
1753
1754 while (i < maxDecimals)
1755 fResult[i++] = 48;
1756
1757 fResult.Reverse();
1758 result += fResult;
1759
1760 return result;
1761 }
1762
1767 static Str<T, N> FromNum(const double num, const UInt_8 maxDecimals = 5)
1768 {
1769 SInt_64 whole = (SInt_64)num;
1770
1771 Str<T, N> result;
1772 if (whole < 0)
1773 result.Push(45);
1774
1775 result += Str<T, N>::FromNum(whole);
1776
1777 UInt_64 power = 10;
1778 for (UInt_64 i = 0; i < (UInt_64)maxDecimals - 1; ++i)
1779 power *= 10;
1780
1781 SInt_64 fraction = (SInt_64)((num - (double)whole) * (double)power);
1782 if (!fraction)
1783 return result;
1784
1785 result.Push(46);
1786
1787 Str<T, N> fResult(maxDecimals);
1788 N i = 0;
1789
1790 while (fraction)
1791 {
1792 fResult[i++] = 48 + fraction % 10;
1793 fraction /= 10;
1794 }
1795
1796 while (i < maxDecimals)
1797 fResult[i++] = 48;
1798
1799 fResult.Reverse();
1800 result += fResult;
1801
1802 return result;
1803 }
1804
1809 static Str<T, N> FromNum(const long double num, const UInt_8 maxDecimals = 5)
1810 {
1811 SInt_64 whole = (SInt_64)num;
1812
1813 Str<T, N> result;
1814 if (whole < 0)
1815 result.Push(45);
1816
1817 result += Str<T, N>::FromNum(whole);
1818
1819 UInt_64 power = 10;
1820 for (UInt_64 i = 0; i < (UInt_64)maxDecimals - 1; ++i)
1821 power *= 10;
1822
1823 SInt_64 fraction = (SInt_64)((num - (long double)whole) * (long double)power);
1824 if (!fraction)
1825 return result;
1826
1827 result.Push(46);
1828
1829 Str<T, N> fResult(maxDecimals);
1830 N i = 0;
1831
1832 while (fraction)
1833 {
1834 fResult[i++] = 48 + fraction % 10;
1835 fraction /= 10;
1836 }
1837
1838 while (i < maxDecimals)
1839 fResult[i++] = 48;
1840
1841 fResult.Reverse();
1842 result += fResult;
1843
1844 return result;
1845 }
1846
1850 static UInt_32 Hash_32(const Str<T, N>& str)
1851 {
1852 if (!str.Size())
1853 return 0;
1854
1855 const Byte* const bytes = str.ToBytes();
1856
1857 UInt_32 hash = 2166136261ul;
1858
1859 for (N i = 0; i < str.Size(true); ++i)
1860 hash = (hash ^ bytes[i]) * 16777619;
1861
1862 return hash;
1863 }
1864
1868 {
1869 if (!size)
1870 return 0;
1871
1872 const Byte* const bytes = ToBytes();
1873
1874 UInt_32 hash = 2166136261ul;
1875
1876 for (N i = 0; i < Size(true); ++i)
1877 hash = (hash ^ bytes[i]) * 16777619;
1878
1879 return hash;
1880 }
1881
1885 static UInt_64 Hash_64(const Str<T, N>& str)
1886 {
1887 if (!str.Size())
1888 return 0;
1889
1890 const Byte* const bytes = str.ToBytes();
1891
1892 UInt_64 hash = 14695981039346656037ull;
1893
1894 for (N i = 0; i < str.Size(true); ++i)
1895 hash = (hash ^ bytes[i]) * 1099511628211;
1896
1897 return hash;
1898 }
1899
1902 UInt_64 Hash_64() const
1903 {
1904 if (!size)
1905 return 0;
1906
1907 const Byte* const bytes = ToBytes();
1908
1909 UInt_64 hash = 14695981039346656037ull;
1910
1911 for (N i = 0; i < Size(true); ++i)
1912 hash = (hash ^ bytes[i]) * 1099511628211;
1913
1914 return hash;
1915 }
1916
1920 static N Len(const T* const str)
1921 {
1922 if (!str)
1923 return 0;
1924
1925 N count = 0;
1926 while (str[count])
1927 ++count;
1928 return count;
1929 }
1930
1935 static bool Cmp(const T* const a, const T* const b)
1936 {
1937 N aSize = Len(a);
1938 N bSize = Len(b);
1939
1940 if (aSize != bSize)
1941 return false;
1942
1943 return Util::Compare(a, b, aSize);
1944 }
1945 };
1946
1947 template class EHS_LIB_IO Str<Char_32, UInt_64>;
1948 template class EHS_LIB_IO Str<Char_16, UInt_64>;
1949 template class EHS_LIB_IO Str<Char_8, UInt_64>;
1950
1954}
1955
1956template<typename T = ehs::Char_8, typename N = ehs::UInt_64>
1957bool operator==(const T* const first, const ehs::Str<T, N>& second)
1958{
1959 N inSize = ehs::Str<T, N>::Len(first);
1960 if (second.Size() != inSize)
1961 return false;
1962
1963 return ehs::Util::Compare(first, second, second.Size(true));
1964}
1965
1966template<typename T = ehs::Char_8, typename N = ehs::UInt_64>
1967bool operator!=(const T* const first, const ehs::Str<T, N>& second)
1968{
1969 N inSize = ehs::Str<T, N>::Len(first);
1970 if (second.Size() != inSize)
1971 return true;
1972
1973 return !ehs::Util::Compare(first, second, second.Size(true));
1974}
1975
1980template<typename T = ehs::Char_8, typename N = ehs::UInt_64>
1981ehs::Str<T, N> operator+(const T* const first, const ehs::Str<T, N>& second)
1982{
1983 N inSize = ehs::Str<T, N>::Len(first);
1984
1985 ehs::Str<T, N> result(inSize + second.Size());
1986
1987 ehs::Util::Copy(result, first, inSize * sizeof(T));
1988 ehs::Util::Copy(&result[inSize], &second[0], second.Size(true));
1989
1990 result[inSize + second.Size()] = 0;
1991
1992 return result;
1993}
bool operator!=(const T *const first, const ehs::Str< T, N > &second)
Definition Str.h:1967
ehs::Str< T, N > operator+(const T *const first, const ehs::Str< T, N > &second)
Definition Str.h:1981
bool operator==(const T *const first, const ehs::Str< T, N > &second)
Definition Str.h:1957
Definition Str.h:29
UInt_64 Hash_64() const
Definition Str.h:1902
bool Contains(const Str< T, N > &delimeter, const SearchPattern pattern=SearchPattern::LEFT_RIGHT) const
Definition Str.h:1084
bool operator==(const T *const str) const
Definition Str.h:454
void Copy(const N dstOffset, const Str< T, N > &src)
Definition Str.h:551
Str< T, N > operator+(const UInt_16 num) const
Definition Str.h:377
static Str< T, N > FromNum(const SInt_64 num)
Definition Str.h:1399
bool Find(const Str< T, N > &delimeter, N *const index=nullptr, const SearchPattern pattern=SearchPattern::LEFT_RIGHT, const IndexResult result=IndexResult::BEGINNING) const
Definition Str.h:1022
Str< T, N > GetUpper() const
Definition Str.h:835
static bool Cmp(const T *const a, const T *const b)
Definition Str.h:1935
bool IsNum() const
Definition Str.h:1166
Vector< Str > ParseArgs() const
Definition Str.h:1116
void ToLower()
Converts all upper-case ASCII characters to lower-case.
Definition Str.h:803
Str & operator=(const Str &str)
Definition Str.h:119
void Insert(const N index, const Str &value)
Definition Str.h:596
bool operator==(T *str) const
Definition Str.h:443
Str< T, N > operator+(const Str< T, N > &str) const
Definition Str.h:321
void Insert(const N index, const T value)
Definition Str.h:621
Str< T, N > & operator+=(const long double num)
Definition Str.h:295
void Push(const T *const value, const N size)
Definition Str.h:720
bool operator!=(const T *const str) const
Definition Str.h:476
static Str< T, N > FromNum(const UInt_64 num)
Definition Str.h:1435
Str< T, N > operator+(const float num) const
Definition Str.h:419
void Push(const T *const value)
Definition Str.h:736
Str(const Str &str)
Definition Str.h:93
Str< T, N > GetLower() const
Definition Str.h:812
static UInt_64 Hash_64(const Str< T, N > &str)
Definition Str.h:1885
Str< T, N > & operator+=(const UInt_16 num)
Definition Str.h:237
Str< T, N > Sub(const N index, const N size=0) const
Definition Str.h:885
Str< T, N > operator+(const SInt_16 num) const
Definition Str.h:369
Str()
Default members initialization.
Definition Str.h:42
Str< T, N > & operator+=(const UInt_32 num)
Definition Str.h:221
static Str< T, N > FromNum(const UInt_8 num)
Definition Str.h:1630
Str< T, N > & operator+=(const SInt_64 num)
Definition Str.h:197
long double ToLDouble() const
Definition Str.h:1370
void ToUpper()
Converts all lower-case ASCII characters to upper-case.
Definition Str.h:826
static Str< T, N > FromNum(const UInt_16 num)
Definition Str.h:1565
bool operator!=(const Str< T, N > &str) const
Definition Str.h:487
void Push(const Str< T, N > &value)
Definition Str.h:703
void Reverse()
Reverses the entire string object.
Definition Str.h:849
static Str< T, N > FromNum(const SInt_32 num)
Definition Str.h:1464
Str< T, N > RemoveAll(const Str< T, N > &delimeter) const
Definition Str.h:963
static Str< T, N > FromNum(const SInt_16 num)
Definition Str.h:1529
bool operator==(const Str< T, N > &str) const
Definition Str.h:465
static Str< T, N > FromNum(const double num, const UInt_8 maxDecimals=5)
Definition Str.h:1767
Str ReplaceAll(const Str &delimeter, const Str &replacer) const
Definition Str.h:993
Str< T, N > & operator+=(const SInt_32 num)
Definition Str.h:213
static I HexToNum(const Str &in)
Definition Str.h:1206
static UInt_64 Len(const Char_32 *const str)
Definition Str.h:1920
I ToDecimal() const
Definition Str.h:1293
Str(Str &&str) noexcept
A move constructor.
Definition Str.h:84
Str< T, N > & operator+=(const double num)
Definition Str.h:287
Str< T, N > & operator+=(const Str< T, N > &str)
Definition Str.h:177
static Str< T, N > FromNum(const SInt_8 num)
Definition Str.h:1594
Str< T, N > operator+(const UInt_8 num) const
Definition Str.h:393
void Push(const T value)
Definition Str.h:754
Str< T, N > & operator+=(const UInt_64 num)
Definition Str.h:205
N Size(bool inBytes=false) const
Definition Str.h:526
Str< T, N > operator+(const SInt_64 num) const
Definition Str.h:337
Str(const T *const str)
Definition Str.h:65
static Str< T, N > FromNum(const long double num, const UInt_8 maxDecimals=5)
Definition Str.h:1809
Str< T, N > operator+(const UInt_64 num) const
Definition Str.h:345
const Byte * ToBytes() const
Definition Str.h:790
I HexToNum() const
Definition Str.h:1249
Str< T, N > operator+(const double num) const
Definition Str.h:427
Str< T, N > operator+(const SInt_8 num) const
Definition Str.h:385
double ToDouble() const
Definition Str.h:1341
Str< T, N > operator+(const SInt_32 num) const
Definition Str.h:353
void Copy(const N dstOffset, const T *const src)
Definition Str.h:565
Str< T, N > & operator+=(const T *const str)
Definition Str.h:155
T Remove(const N index)
Definition Str.h:676
Str< T, N > & operator+=(const SInt_8 num)
Definition Str.h:245
void Resize(const N newSize)
Definition Str.h:503
Str< T, N > operator+(const UInt_32 num) const
Definition Str.h:361
Str(const N size)
Definition Str.h:77
static Str NumToHex(const I num)
Definition Str.h:1186
static UInt_32 Hash_32(const Str< T, N > &str)
Definition Str.h:1850
Str< T, N > GetReverse()
Definition Str.h:868
Str< T, N > & operator+=(const float num)
Definition Str.h:279
Vector< Str< T, N >, N > Split(const Str< T, N > &delimeter, const N max=0) const
Definition Str.h:923
Str & operator=(Str &&str) noexcept
Definition Str.h:101
void ExactSize()
Finds the null terminator in the string and makes it the exact size if greater than.
Definition Str.h:535
UInt_32 Hash_32() const
Definition Str.h:1867
T Pop()
Definition Str.h:771
static Str< T, N > FromNum(const float num, const UInt_8 maxDecimals=5)
Definition Str.h:1725
~Str()
Frees any data created on the heap.
Definition Str.h:36
static Str< T, N > FromNum(const UInt_32 num)
Definition Str.h:1500
float ToFloat() const
Definition Str.h:1312
Str< T, N > operator+(const T *const str) const
Definition Str.h:303
Str< T, N > operator+(const long double num) const
Definition Str.h:435
Str< T, N > & operator=(const T *const str)
Definition Str.h:137
Str< T, N > & operator+=(const SInt_16 num)
Definition Str.h:229
Byte * ToBytes()
Definition Str.h:797
Str Remove(const N start, const N end)
Definition Str.h:650
void Copy(const N dstOffset, const T *const src, const N srcSize)
Definition Str.h:582
Str< T, N > & operator+=(const UInt_8 num)
Definition Str.h:253
Str(const T *const str, const N size)
Definition Str.h:50
static void Copy(void *out, const void *in, UInt_64 size)
Definition Util.cpp:67
static bool Compare(const void *a, const void *b, UInt_64 size)
Definition Util.cpp:9
Definition Vector.h:18
void Push(const T *const value, const N size)
Definition Vector.h:389
N Size() const
Definition Vector.h:240
Definition Anchor.h:6
IndexResult
Definition Str.h:19
@ BEGINNING
Definition Str.h:20
@ ENDING
Definition Str.h:21
SearchPattern
Definition Str.h:13
@ RIGHT_LEFT
Definition Str.h:15
@ LEFT_RIGHT
Definition Str.h:14
signed int SInt_32
Definition Types.h:50
unsigned int UInt_32
Definition Types.h:49
Str< Char_16, UInt_64 > Str_16
Definition Str.h:1952
unsigned char UInt_8
Definition Types.h:43
Str< Char_8, UInt_64 > Str_8
Definition Str.h:1953
unsigned char Byte
Definition Types.h:39
signed char SInt_8
Definition Types.h:44
unsigned short UInt_16
Definition Types.h:46
Str< Char_32, UInt_64 > Str_32
Definition Str.h:1951
signed short SInt_16
Definition Types.h:47