8 #ifndef INCL_evo_impl_str_h 9 #define INCL_evo_impl_str_h 17 #pragma warning(disable:4146) 28 static const char CHARMAP_TYPE_MASK = 0x07;
29 inline const char* CHARMAP_TYPE()
30 {
return "@@@@@@@@@AAAAA@@@@@@@@@@@@@@@@@@ABBBBBBBBBBBBBBBCCCCCCCCCCBBBBBBBDDDDDDDDDDDDDDDDDDDDDDDDDDBBBBBBEEEEEEEEEEEEEEEEEEEEEEEEEEBBBB@"; }
31 inline const char* CHARMAP_BREAK_TYPE()
32 {
return "@@@@@@@@@AAAAA@@@@@@@@@@@@@@@@@@ADB@@D@BCD@@DDDDEEEEEEEEEE@DC@DD@EEEEEEEEEEEEEEEEEEEEEEEEEEC@D@EBEEEEEEEEEEEEEEEEEEEEEEEEEEC@D@@"; }
34 static const int CHARMAP_ALPHA_LEN = 36;
36 static const int CHARMAP_UPPER_FIRST = 65;
37 static const int CHARMAP_UPPER_LAST = 90;
38 inline const char* CHARMAP_UPPER()
39 {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
41 static const int CHARMAP_LOWER_FIRST = 97;
42 static const int CHARMAP_LOWER_LAST = 122;
43 inline const char* CHARMAP_LOWER()
44 {
return "abcdefghijklmnopqrstuvwxyz"; }
79 return (
CharType)(impl::CHARMAP_TYPE()[(int)ch] & impl::CHARMAP_TYPE_MASK);
94 return (
CharBreakType)(impl::CHARMAP_BREAK_TYPE()[(int)ch] & impl::CHARMAP_TYPE_MASK);
106 if (ch < impl::CHARMAP_LOWER_FIRST || ch > impl::CHARMAP_LOWER_LAST)
108 return impl::CHARMAP_UPPER()[ch - impl::CHARMAP_LOWER_FIRST];
120 if (ch < impl::CHARMAP_UPPER_FIRST || ch > impl::CHARMAP_UPPER_LAST)
122 return impl::CHARMAP_LOWER()[ch - impl::CHARMAP_UPPER_FIRST];
161 assert( str != NULL );
162 assert( str <= end );
163 const uchar LBITS_1 = 0x80;
164 const uchar LBITS_11 = 0xC0;
165 const uchar LBITS_111 = 0xE0;
166 const uchar LBITS_1111 = 0xF0;
167 const uchar LBITS_11111 = 0xF8;
168 const uchar RBITS_111111 = 0x3F;
169 const uchar RBITS_11111 = 0x1F;
170 const uchar RBITS_1111 = 0x0F;
171 const uchar RBITS_111 = 0x07;
172 for (
const uchar* p; str < end; ) {
173 p = (
const uchar*)str;
174 if ((*p & LBITS_1) != 0) {
175 if ((*p & LBITS_111) == LBITS_11) {
177 if (str+1 < end && (p[1] & LBITS_11) == LBITS_1) {
178 code = ((uint32)(p[0] & RBITS_11111) << 6) |
179 (uint32)(p[1] & RBITS_111111);
182 }
else if ((*p & LBITS_1111) == LBITS_111) {
184 if (str+2 < end && (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1) {
185 code = ((uint32)(p[0] & RBITS_1111) << 12) |
186 ((uint32)(p[1] & RBITS_111111) << 6) |
187 (uint32)(p[2] & RBITS_111111);
190 }
else if ((*p & LBITS_11111) == LBITS_1111) {
192 if (str+3 < end && (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1 && (p[3] & LBITS_11) == LBITS_1) {
193 code = ((uint32)(p[0] & RBITS_111) << 18) |
194 ((uint32)(p[1] & RBITS_111111) << 12) |
195 ((uint32)(p[2] & RBITS_111111) << 6) |
196 (uint32)(p[3] & RBITS_111111);
235 assert( str != NULL );
236 const uchar LBITS_1 = 0x80;
237 const uchar LBITS_11 = 0xC0;
238 const uchar LBITS_111 = 0xE0;
239 const uchar LBITS_1111 = 0xF0;
240 const uchar LBITS_11111 = 0xF8;
241 const uchar RBITS_111111 = 0x3F;
242 const uchar RBITS_11111 = 0x1F;
243 const uchar RBITS_1111 = 0x0F;
244 const uchar RBITS_111 = 0x07;
245 for (
const uchar* p; *str != 0; ) {
246 p = (
const uchar*)str;
247 if ((*p & LBITS_1) != 0) {
248 if ((*p & LBITS_111) == LBITS_11) {
250 if (str[1] != 0 && (p[1] & LBITS_11) == LBITS_1) {
251 code = ((uint32)(p[0] & RBITS_11111) << 6) |
252 (uint32)(p[1] & RBITS_111111);
255 }
else if ((*p & LBITS_1111) == LBITS_111) {
257 if (str[1] != 0 && str[2] != 0 &&
258 (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1) {
259 code = ((uint32)(p[0] & RBITS_1111) << 12) |
260 ((uint32)(p[1] & RBITS_111111) << 6) |
261 (uint32)(p[2] & RBITS_111111);
264 }
else if ((*p & LBITS_11111) == LBITS_1111) {
266 if (str[1] != 0 && str[2] != 0 && str[3] != 0 &&
267 (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1 && (p[3] & LBITS_11) == LBITS_1) {
268 code = ((uint32)(p[0] & RBITS_111) << 18) |
269 ((uint32)(p[1] & RBITS_111111) << 12) |
270 ((uint32)(p[2] & RBITS_111111) << 6) |
271 (uint32)(p[3] & RBITS_111111);
305 inline int utf8_compare(
const char* str1, ulong len1,
const char* str2, ulong len2) {
309 }
else if (str2 == NULL) {
311 }
else if (str1 == str2) {
314 else if (len1 > len2)
317 const char* end1 = str1 + len1;
318 const char* end2 = str2 + len2;
324 }
else if (str2 >= end2)
326 else if (*str1 < *str2)
328 else if (*str1 > *str2)
346 inline int utf8_compare(
const char* str1, ulong len1,
const char* str2) {
350 }
else if (str2 == NULL) {
353 const char* end1 = str1 + len1;
359 }
else if (*str2 == 0)
361 else if (*str1 < *str2)
363 else if (*str1 > *str2)
384 }
else if (str2 == NULL) {
392 }
else if (*str2 == 0)
394 else if (*str1 < *str2)
396 else if (*str1 > *str2)
418 inline const char*
utf8_min(
const char* str,
const char* end,
bool strict=
false, ulong mincount=1, uint minsize=2) {
419 assert( str != NULL );
420 assert( str <= end );
421 assert( mincount > 0 );
422 assert( minsize >= 2 );
423 assert( minsize <= 4 );
424 const uchar LBITS_1 = 0x80;
425 const uchar LBITS_11 = 0xC0;
426 const uchar LBITS_111 = 0xE0;
427 const uchar LBITS_1111 = 0xF0;
428 const uchar LBITS_11111 = 0xF8;
430 for (
const uchar* p; str < end; ) {
431 p = (
const uchar*)str;
432 if ((*p & LBITS_1) != 0) {
433 if ((*p & LBITS_111) == LBITS_11) {
435 if (str+1 < end && (p[1] & LBITS_11) == LBITS_1) {
436 if (minsize <= 2 && ++count >= mincount)
441 }
else if ((*p & LBITS_1111) == LBITS_111) {
443 if (str+2 < end && (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1) {
444 if (minsize <= 3 && ++count >= mincount)
449 }
else if ((*p & LBITS_11111) == LBITS_1111) {
451 if (str+3 < end && (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1 && (p[3] & LBITS_11) == LBITS_1) {
452 if (minsize <= 4 && ++count >= mincount)
482 assert( str != NULL );
483 assert( str <= end );
484 const uchar LBITS_1 = 0x80;
485 const uchar LBITS_11 = 0xC0;
486 const uchar LBITS_111 = 0xE0;
487 const uchar LBITS_1111 = 0xF0;
488 const uchar LBITS_11111 = 0xF8;
490 for (
const uchar* p; str < end; ) {
491 p = (
const uchar*)str;
492 if ((*p & LBITS_1) != 0) {
493 if ((*p & LBITS_111) == LBITS_11) {
495 if (str+1 < end && (p[1] & LBITS_11) == LBITS_1) {
500 }
else if ((*p & LBITS_1111) == LBITS_111) {
502 if (str+2 < end && (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1) {
507 }
else if ((*p & LBITS_11111) == LBITS_1111) {
509 if (str+3 < end && (p[1] & LBITS_11) == LBITS_1 && (p[2] & LBITS_11) == LBITS_1 && (p[3] & LBITS_11) == LBITS_1) {
544 assert( str != NULL );
545 assert( str <= end );
549 if (outbuf == NULL) {
552 if ((p =
utf8_scan(code, str, end, mode)) == NULL) {
557 if (code < 0x10000) {
559 if (code >= 0xD800 && code <= 0xDFFF) {
576 if ((p =
utf8_scan(code, str, end, mode)) == NULL) {
581 if (code < 0x10000) {
583 if (code >= 0xD800 && code <= 0xDFFF) {
592 if (written >= outsize)
594 outbuf[written] = (wchar16)code;
598 if (written + 1 >= outsize)
601 outbuf[written] = (wchar16)((code >> 10) & 0x3FF) + 0xD800;
602 outbuf[written+1] = (wchar16)(code & 0x3FF) + 0xDC00;
631 assert( str != NULL );
632 assert( str <= end );
634 uint32 ch1 = (uint16)*str;
635 if (!(ch1 < 0xD800 || ch1 > 0xDFFF)) {
636 if (ch1 <= 0xDBFF && str+1 < end) {
637 uint32 ch2 = (uint16)str[1];
638 if (!(ch2 < 0xDC00 || ch2 > 0xDFFF)) {
640 ch1 = ((ch1 - 0xD800) & 0x3FF) << 10;
641 ch2 = (ch2 - 0xDC00) & 0x3FF;
642 code = (ch1 | ch2) + 0x10000;
683 assert( str != NULL );
685 uint32 ch1 = (uint16)*str;
688 if (!(ch1 < 0xD800 || ch1 > 0xDFFF)) {
689 if (ch1 <= 0xDBFF && str[1] != 0) {
690 uint32 ch2 = (uint16)str[1];
691 if (!(ch2 < 0xDC00 || ch2 > 0xDFFF)) {
693 ch1 = ((ch1 - 0xD800) & 0x3FF) << 10;
694 ch2 = (ch2 - 0xDC00) & 0x3FF;
695 code = (ch1 | ch2) + 0x10000;
729 inline int utf16_compare(
const wchar16* str1, ulong len1,
const wchar16* str2, ulong len2) {
733 }
else if (str2 == NULL) {
735 }
else if (str1 == str2) {
738 else if (len1 > len2)
741 const wchar16* end1 = str1 + len1;
742 const wchar16* end2 = str2 + len2;
743 wchar32 code1, code2;
751 }
else if (str2 == NULL)
753 else if (code1 < code2)
755 else if (code1 > code2)
771 inline int utf16_compare(
const wchar16* str1, ulong len1,
const wchar16* str2) {
775 }
else if (str2 == NULL) {
778 const wchar16* end1 = str1 + len1;
779 wchar32 code1, code2;
787 }
else if (str2 == NULL)
789 else if (code1 < code2)
791 else if (code1 > code2)
810 }
else if (str2 == NULL) {
813 wchar32 code1, code2;
821 }
else if (str2 == NULL)
823 else if (code1 < code2)
825 else if (code1 > code2)
842 inline int utf16_compare8(
const wchar16* str1, ulong len1,
const char* str2, ulong len2) {
846 }
else if (str2 == NULL) {
849 const wchar16* end1 = str1 + len1;
850 const char* end2 = str2 + len2;
851 wchar32 code1, code2;
859 }
else if (str2 == NULL)
861 else if (code1 < code2)
863 else if (code1 > code2)
883 }
else if (str2 == NULL) {
886 const wchar16* end1 = str1 + len1;
887 wchar32 code1, code2;
895 }
else if (str2 == NULL)
897 else if (code1 < code2)
899 else if (code1 > code2)
918 }
else if (str2 == NULL) {
921 wchar32 code1, code2;
929 }
else if (str2 == NULL)
931 else if (code1 < code2)
933 else if (code1 > code2)
949 const wchar16* p = str;
952 return (ulong)(p - str);
966 inline const wchar16*
utf16_min(
const wchar16* str,
const wchar16* end,
bool strict=
false, uint mincount=1) {
967 assert( str != NULL );
968 assert( str <= end );
969 assert( mincount > 0 );
972 uint32 ch1 = (uint16)*str;
973 if (!(ch1 < 0xD800 || ch1 > 0xDFFF)) {
974 if (ch1 <= 0xDBFF && str+1 < end) {
975 uint32 ch2 = (uint16)str[1];
976 if (!(ch2 < 0xDC00 || ch2 > 0xDFFF)) {
978 if (++count >= mincount)
1010 assert( str != NULL );
1011 assert( str <= end );
1014 uint32 ch1 = (uint16)*str;
1015 if (!(ch1 < 0xD800 || ch1 > 0xDFFF)) {
1016 if (ch1 <= 0xDBFF && str+1 < end) {
1017 uint32 ch2 = (uint16)str[1];
1018 if (!(ch2 < 0xDC00 || ch2 > 0xDFFF)) {
1054 assert( str != NULL );
1055 assert( str <= end );
1059 if (outbuf == NULL) {
1062 if ((p =
utf16_scan(code, str, end, mode)) == NULL) {
1068 if (code < 0x0080) {
1071 }
else if (code < 0x0800) {
1074 }
else if (code < 0x10000) {
1079 assert( code <= 0x10FFFF );
1085 const uchar LBITS_1 = 0x80;
1086 const uchar LBITS_11 = 0xC0;
1087 const uchar LBITS_111 = 0xE0;
1088 const uchar LBITS_1111 = 0xF0;
1089 const uchar RBITS_111111 = 0x3F;
1090 const uchar RBITS_11111 = 0x1F;
1091 const uchar RBITS_1111 = 0x0F;
1092 const uchar RBITS_111 = 0x07;
1093 uchar* out = (uchar*)outbuf;
1095 if ((p =
utf16_scan(code, str, end, mode)) == NULL) {
1100 if (code < 0x0080) {
1102 if (written >= outsize)
1104 out[written] = (uchar)code;
1106 }
else if (code < 0x0800) {
1108 if (written + 1 >= outsize)
1110 outbuf[written] = ((uchar)(code >> 6) & RBITS_11111) | LBITS_11;
1111 outbuf[written+1] = ((uchar)code & RBITS_111111) | LBITS_1;
1113 }
else if (code < 0x10000) {
1115 if (written + 2 >= outsize)
1117 outbuf[written] = ((uchar)(code >> 12) & RBITS_1111) | LBITS_111;
1118 outbuf[written+1] = ((uchar)(code >> 6) & RBITS_111111) | LBITS_1;
1119 outbuf[written+2] = ((uchar)code & RBITS_111111) | LBITS_1;
1123 assert( code <= 0x10FFFF );
1124 if (written + 3 >= outsize)
1126 outbuf[written] = ((uchar)(code >> 18) & RBITS_111) | LBITS_1111;
1127 outbuf[written+1] = ((uchar)(code >> 12) & RBITS_111111) | LBITS_1;
1128 outbuf[written+2] = ((uchar)(code >> 6) & RBITS_111111) | LBITS_1;
1129 outbuf[written+3] = ((uchar)code & RBITS_111111) | LBITS_1;
1151 #if !defined(EVO_NO_MEMRCHR) && defined(EVO_GLIBC_MEMRCHR) 1152 return (
char*)::memrchr(str, ch, size);
1154 for (
const char* p = str + size; p > str; )
1177 inline ulong string_search_impl_kmp(T* table,
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset=0) {
1178 assert( pattern_size > 1 );
1179 assert( data_size > pattern_size );
1183 for (uint len = 0, i = 1; i < pattern_size; ) {
1184 assert( len < pattern_size );
1185 if (pattern[i] == pattern[len]) {
1186 table[i] = (T)++len;
1188 }
else if (len != 0) {
1189 len = table[len - 1];
1197 for (ulong i = 0, j = 0; i < data_size; ) {
1198 if (data[i] == pattern[j]) {
1200 if (++j == pattern_size)
1201 return offset + (i - j);
1202 }
else if (j == 0) {
1212 inline ulong string_search_impl_kmp_reverse(T* table,
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset=0) {
1214 assert( pattern_size > 1 );
1215 assert( data_size > pattern_size );
1216 const uint pend = pattern_size - 1;
1220 for (uint len = 0, i = 1; i < pattern_size; ) {
1221 assert( len < pattern_size );
1222 if (pattern[pend - i] == pattern[pend - len]) {
1223 table[i] = (T)++len;
1225 }
else if (len != 0) {
1226 len = table[len - 1];
1234 const uint dend = data_size - 1;
1235 for (ulong i = 0, j = 0; i < data_size; ) {
1236 if (data[dend - i] == pattern[pend - j]) {
1238 if (++j == pattern_size)
1239 return offset + (data_size - (i - j) - pattern_size);
1240 }
else if (j == 0) {
1251 inline ulong string_search(
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1252 if (pattern_size > 0 && pattern_size <= data_size) {
1253 if (pattern_size == 1) {
1255 const char* ptr = (
char*)memchr(data, *pattern, data_size);
1257 return offset + (ulong)(ptr - data);
1258 }
else if (pattern_size == data_size) {
1260 if (memcmp(data, pattern, data_size) == 0)
1263 #if !defined(EVO_NO_MEMMEM) && defined(EVO_GLIBC_MEMMEM) 1265 const char* ptr = (
char*)memmem(data, data_size, pattern, pattern_size);
1267 return offset + (ulong)(ptr - data);
1270 const uint8 STACK_BUF_SIZE = 128;
1271 if (pattern_size <= STACK_BUF_SIZE) {
1273 uint8 table[STACK_BUF_SIZE];
1274 return string_search_impl_kmp<uint8>(table, pattern, pattern_size, data, data_size, offset);
1277 uint* table = (uint*)::malloc(pattern_size *
sizeof(uint));
1278 const ulong result = string_search_impl_kmp<uint>(table, pattern, pattern_size, data, data_size, offset);
1289 inline ulong string_search_kmp(
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1290 if (pattern_size > 0 && pattern_size <= data_size) {
1291 if (pattern_size == 1) {
1293 const char* ptr = (
char*)memchr(data, *pattern, data_size);
1295 return offset + (ulong)(ptr - data);
1296 }
else if (pattern_size == data_size) {
1298 if (memcmp(data, pattern, data_size) == 0)
1301 const uint8 STACK_BUF_SIZE = 128;
1302 if (pattern_size <= STACK_BUF_SIZE) {
1304 uint8 table[STACK_BUF_SIZE];
1305 return string_search_impl_kmp<uint8>(table, pattern, pattern_size, data, data_size, offset);
1308 uint* table = (uint*)::malloc(pattern_size *
sizeof(uint));
1309 const ulong result = string_search_impl_kmp<uint>(table, pattern, pattern_size, data, data_size, offset);
1319 inline ulong string_search_basic(
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1320 if (pattern_size > 0 && pattern_size <= data_size) {
1321 if (pattern_size == 1) {
1323 const char* ptr = (
char*)memchr(data, *pattern, data_size);
1325 return offset + (ulong)(ptr - data);
1326 }
else if (pattern_size == data_size) {
1328 if (memcmp(data, pattern, data_size) == 0)
1331 data_size = data_size + 1 - pattern_size;
1332 const uchar pattern_first = (uchar)*pattern;
1333 const char* start = data;
1334 const char* end = data + data_size;
1335 while (data < end) {
1336 if ((data = (
char*)memchr(data, pattern_first, data_size)) == NULL)
1338 if (memcmp(data, pattern, pattern_size) == 0)
1339 return offset + (ulong)(data - start);
1341 data_size = (ulong)(end - data);
1349 inline ulong string_search(
StringSearchAlg alg,
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1352 return string_search_kmp(pattern, pattern_size, data, data_size, offset);
1354 return string_search_basic(pattern, pattern_size, data, data_size, offset);
1356 return string_search(pattern, pattern_size, data, data_size, offset);
1363 inline ulong string_search_reverse(
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1364 if (pattern_size > 0 && pattern_size <= data_size) {
1365 if (pattern_size == 1) {
1367 #if !defined(EVO_NO_MEMRCHR) && defined(EVO_GLIBC_MEMRCHR) 1368 const char* ptr = (
char*)memrchr(data, *pattern, data_size);
1370 return offset + (ulong)(ptr - data);
1372 const uchar pattern_first = (uchar)*pattern;
1373 for (
const char* ptr = data + data_size; ptr > data; )
1374 if (*--ptr == pattern_first)
1375 return offset + (ulong)(ptr - data);
1377 }
else if (pattern_size == data_size) {
1379 if (memcmp(data, pattern, data_size) == 0)
1382 const uint8 STACK_BUF_SIZE = 128;
1383 if (pattern_size <= STACK_BUF_SIZE) {
1385 uint8 table[STACK_BUF_SIZE];
1386 return string_search_impl_kmp_reverse<uint8>(table, pattern, pattern_size, data, data_size, offset);
1389 uint* table = (uint*)::malloc(pattern_size *
sizeof(uint));
1390 const ulong result = string_search_impl_kmp_reverse<uint>(table, pattern, pattern_size, data, data_size, offset);
1400 inline ulong string_search_reverse_basic(
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1401 if (pattern_size > 0 && pattern_size <= data_size) {
1402 if (pattern_size == 1) {
1404 #if !defined(EVO_NO_MEMRCHR) && defined(EVO_GLIBC_MEMRCHR) 1405 const char* ptr = (
char*)memrchr(data, *pattern, data_size);
1407 return offset + (ulong)(ptr - data);
1409 const uchar pattern_first = (uchar)*pattern;
1410 for (
const char* ptr = data + data_size; ptr > data; )
1411 if (*--ptr == pattern_first)
1412 return offset + (ulong)(ptr - data);
1414 }
else if (pattern_size == data_size) {
1416 if (memcmp(data, pattern, data_size) == 0)
1419 data_size = data_size + 1 - pattern_size;
1420 const uchar pattern_first = (uchar)*pattern;
1422 #if !defined(EVO_NO_MEMRCHR) && defined(EVO_GLIBC_MEMRCHR) 1424 if ((ptr = (
char*)memrchr(data, pattern_first, data_size)) == NULL)
1426 data_size = (ulong)(ptr - data);
1427 if (memcmp(ptr, pattern, pattern_size) == 0)
1428 return offset + data_size;
1433 ptr = data + data_size;
1435 if (*--ptr == pattern_first && memcmp(ptr, pattern, pattern_size) == 0)
1436 return offset + (ulong)(ptr - data);
1444 inline ulong string_search_reverse(
StringSearchAlg alg,
const char* pattern, uint pattern_size,
const char* data, ulong data_size, ulong offset) {
1447 return string_search_reverse_basic(pattern, pattern_size, data, data_size, offset);
1450 return string_search_reverse(pattern, pattern_size, data, data_size, offset);
1463 T tonum(
const char* str, ulong size,
Error& error,
int base) {
1464 const char*
const end = str + size;
1470 while (str < end && ((ch=*str) ==
' ' || ch ==
'\t'))
1473 if ((ch=*str) ==
'+')
1476 { neg =
true; ++str; }
1479 { error =
EInval;
return 0; }
1493 { error =
EInval;
return 0; }
1500 { error =
EInval;
return 0; }
1507 { error =
EInval;
return 0; }
1521 { error =
EInval;
return 0; }
1527 { error =
EInval;
return 0; }
1533 { error =
EInval;
return 0; }
1545 else if (*str ==
'0' && str+1 < end && (str[1] ==
'x' || str[1] ==
'X'))
1548 { error =
EInval;
return 0; }
1554 else if (*str ==
'0' && str+1 < end && (str[1] ==
'o' || str[1] ==
'O'))
1557 { error =
EInval;
return 0; }
1563 else if (*str ==
'0' && str+1 < end && (str[1] ==
'b' || str[1] ==
'B'))
1566 { error =
EInval;
return 0; }
1576 #if defined(EVO_OLDCC) 1578 const T MAX = IntegerT<T>::MAX;
1583 for (; str < end; ++str) {
1585 if (ch >=
'0' && ch <=
'9')
1587 else if (ch >=
'A' && ch <=
'Z')
1589 else if (ch >=
'a' && ch <=
'z')
1593 if (str < end && *str ==
'.' && base == 10) {
1596 while (str < end && (ch=*str) >=
'0' && ch <=
'9')
1599 while (str < end && ((ch=*str) ==
' ' || ch ==
'\t'))
1607 { error =
EInval;
break; }
1608 assert( ch < base );
1609 if (num > limitbase || (num == limitbase && ch > (limitnum % base))) {
1611 #if defined(EVO_OLDCC) // fixes undefined reference on older compilers 1612 return (neg ? MIN : MAX);
1625 T tonumf(
const char* str, ulong size,
Error& error) {
1627 const int BASE = 10;
1628 const char* end = str + size;
1633 while ( str < end && ((ch=end[-1]) ==
' ' || ch ==
'\t') )
1637 while ( str < end && ((ch=*str) ==
' ' || ch ==
'\t') )
1641 case '+': ++str;
break;
1642 case '-': neg =
true; ++str;
break;
1654 if ( end-str >= 3 &&
1655 ((ch=str[1]) ==
'n' || ch ==
'N') &&
1656 ((ch=str[2]) ==
'f' || ch ==
'F') )
1662 ((ch=str[1]) ==
'a' || ch ==
'A') &&
1663 ((ch=str[2]) ==
'n' || ch ==
'N') )
1669 bool found_point =
false;
1679 if (ch >=
'0' && ch <=
'9')
1682 else if (ch ==
'.') {
1685 { error =
EInval;
return 0.0; }
1689 }
else if (ch ==
'e' || ch ==
'E') {
1692 { error =
EInval;
break; }
1694 bool exp_neg =
false;
1696 case '+': ++str;
break;
1697 case '-': exp_neg =
true; ++str;
break;
1699 for (; str < end; ++str) {
1700 if ((ch=*str) >=
'0' && ch <=
'9')
1711 }
else if (ch ==
'#') {
1714 if ( end-str >= 3 &&
1715 ((ch=str[0]) ==
'I' || ch ==
'i') &&
1716 ((ch=str[1]) ==
'N' || ch ==
'n') &&
1717 ((ch=str[2]) ==
'F' || ch ==
'f') )
1729 if (sig_digits != 0 || ch != 0) {
1731 if (sig_digits > MAXDIGITS) {
1741 if (digits == 0 || str != end)
1758 template<
class Size>
1759 bool tobool(
const char* str, Size size,
Error& error) {
1760 #define EVO_TMP_GET_CHAR_TOUPPER(INDEX) ch = str[INDEX]; if (ch >= 'a') ch -= 32; 1761 #define EVO_TMP_ELSE_INVALID else { error = EInval; return false; } 1762 #define EVO_TMP_TRUE_IF_CHAR(VAL) if (ch == VAL) { error = ENone; return true; } EVO_TMP_ELSE_INVALID 1765 while (size > 0 && ( (ch=*str) ==
' ' || ch ==
'\t' ))
1767 while (size > 0 && ( (ch=str[size-1]) ==
' ' || ch ==
'\t' ))
1772 EVO_TMP_GET_CHAR_TOUPPER(0);
1773 if ( ch ==
'T' || ch ==
'Y' || (ch >=
'1' && ch <=
'9') ) {
1776 }
else if ( ch ==
'F' || ch ==
'N' || ch ==
'0' )
1782 EVO_TMP_GET_CHAR_TOUPPER(0);
1784 EVO_TMP_GET_CHAR_TOUPPER(1);
1785 EVO_TMP_TRUE_IF_CHAR(
'N');
1789 EVO_TMP_GET_CHAR_TOUPPER(0);
1791 EVO_TMP_GET_CHAR_TOUPPER(1);
1793 EVO_TMP_GET_CHAR_TOUPPER(2);
1797 } EVO_TMP_ELSE_INVALID;
1798 } EVO_TMP_ELSE_INVALID;
1799 }
else if (ch ==
'Y') {
1800 EVO_TMP_GET_CHAR_TOUPPER(1);
1802 EVO_TMP_GET_CHAR_TOUPPER(2);
1803 EVO_TMP_TRUE_IF_CHAR(
'S');
1804 } EVO_TMP_ELSE_INVALID;
1808 EVO_TMP_GET_CHAR_TOUPPER(0);
1810 EVO_TMP_GET_CHAR_TOUPPER(1);
1812 EVO_TMP_GET_CHAR_TOUPPER(2);
1814 EVO_TMP_GET_CHAR_TOUPPER(3);
1815 EVO_TMP_TRUE_IF_CHAR(
'E');
1816 } EVO_TMP_ELSE_INVALID;
1817 } EVO_TMP_ELSE_INVALID;
1821 EVO_TMP_GET_CHAR_TOUPPER(0);
1823 EVO_TMP_GET_CHAR_TOUPPER(1);
1825 EVO_TMP_GET_CHAR_TOUPPER(2);
1827 EVO_TMP_GET_CHAR_TOUPPER(3);
1829 EVO_TMP_GET_CHAR_TOUPPER(4);
1833 } EVO_TMP_ELSE_INVALID;
1834 } EVO_TMP_ELSE_INVALID;
1835 } EVO_TMP_ELSE_INVALID;
1836 } EVO_TMP_ELSE_INVALID;
1842 return (tonum<ulong>(str, size, error, 0) != 0);
1844 #undef EVO_TMP_GET_CHAR_TOUPPER 1845 #undef EVO_TMP_ELSE_INVALID 1846 #undef EVO_TMP_TRUE_IF_CHAR 1851 static ulong fnum(
char* endptr, T num,
int base) {
1852 assert( endptr != NULL );
1853 assert( base >= 0 );
1857 assert( base <= 136 );
1859 digits =
"0123456789abcdefghijklmnopqrstuvwxyz";
1861 assert( base <= 36 );
1862 digits =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1870 *--ptr = digits[num % (T)base];
1876 *--ptr = digits[unum % (T)base];
1881 return (ulong)(endptr - ptr);
1886 static ulong fnumu(
char* endptr, T num,
int base) {
1887 assert( endptr != NULL );
1888 assert( base >= 0 );
1892 assert( base <= 136 );
1894 digits =
"0123456789abcdefghijklmnopqrstuvwxyz";
1896 assert( base <= 36 );
1897 digits =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1905 *--ptr = digits[num % (T)base];
1908 return (ulong)(endptr - ptr);
1913 static T fnumf_weight(T num,
int precision) {
1915 if (num != 0.0 && evo_modf(num, &dummy) != 0.0) {
1917 if (precision < 0 || precision > 6) {
1919 for (
int i=0; i<precision; ++i)
1922 const T TABLE[] = { (T)0.5, (T)0.05, (T)0.005, (T)0.0005, (T)0.00005, (T)0.000005, (T)0.0000005 };
1923 weight = TABLE[precision];
1935 template<
class T>
struct FloatNumF {
1936 static T dig_roundup() {
return 0.00001f; }
1937 static T dig_roundup_limit() {
return 0.1f; }
1939 template<>
struct FloatNumF<double> {
1940 static double dig_roundup() {
return 0.00001; }
1941 static double dig_roundup_limit() {
return 0.1; }
1943 template<>
struct FloatNumF<ldouble> {
1944 static ldouble dig_roundup() {
return 0.00001L; }
1945 static ldouble dig_roundup_limit() {
return 0.1L; }
1950 static ulong fnumf(
char* ptr, T num,
int exp,
int precision) {
1952 const char* startptr = ptr;
1974 return (ulong)(ptr - startptr);
1981 return (ulong)(ptr - startptr);
1983 while (exp < 0 && precision > 0) {
1993 T digit_roundup = FloatNumF<T>::dig_roundup();
1995 while (num > PRECISION) {
1997 if (--digit_roundup_counter == 0)
1998 digit_roundup = FloatNumF<T>::dig_roundup_limit();
2002 digit = (int)(num + digit_roundup);
2020 *ptr =
'0' + (char)digit;
2035 }
while (--exp > 0);
2037 { *ptr =
'.'; ++ptr; }
2041 while (precision > 0) {
2047 return (ulong)(ptr - startptr);
2052 static ulong fnumfe(
char* ptr, T num,
int exp,
bool cap) {
2054 const char* startptr = ptr;
2082 return (ulong)(ptr - startptr);
2087 bool on_fraction =
false;
2088 bool show_e =
false;
2089 if (exp < -2 || exp > E_THRESHOLD) {
2100 { *ptr =
'0'; ++ptr; ++exp; }
2108 T digit_roundup = FloatNumF<T>::dig_roundup();
2110 while (num > PRECISION) {
2112 if (--digit_roundup_counter == 0)
2113 digit_roundup = FloatNumF<T>::dig_roundup_limit();
2117 digit = (int)(num + digit_roundup);
2127 *ptr =
'0' + (char)digit;
2138 }
else if (--exp == 0) {
2149 else if (zero_count > 0)
2164 *ptr = (cap?
'E':
'e'); ++ptr;
2166 { *ptr =
'-'; ++ptr; exp = -exp; }
2168 { *ptr =
'+'; ++ptr; }
2170 ptr[0] =
'0' + ((exp / 100) % 10);
2171 ptr[1] =
'0' + ((exp / 10) % 10);
2172 ptr[2] =
'0' + (exp % 10);
2174 }
else if (exp >= 10) {
2175 ptr[0] =
'0' + ((exp / 10) % 10);
2176 ptr[1] =
'0' + (exp % 10);
2179 { *ptr =
'0' + (char)exp; ++ptr; }
2186 }
while (--exp > 0);
2191 return (ulong)(ptr - startptr);
2194 #if defined(EVO_FNUMF_SPRINTF) 2197 static ulong fnumf_sprintf_setup(
char*& fmt,
char* buf,
double num,
int precision) {
2198 if (precision < 0) {
2204 fmt = buf + FNUMF_SPRINTF_BUF_SIZE - 1;
2207 fmt -= fnumu(fmt, (uint)(precision < 0 ? 0 : precision), 10);
2211 int result = ::snprintf(NULL, 0, fmt, num);
2212 return (ulong)(result < 0 ? 0 : result);
2215 static ulong fnumf_sprintf_setup(
char*& fmt,
char* buf,
float num,
int precision) {
2216 return fnumf_sprintf_setup(fmt, buf, (
double)num, precision);
2219 static ulong fnumf_sprintf_setup(
char*& fmt,
char* buf, ldouble num,
int precision) {
2220 if (precision < 0) {
2227 fmt = buf + FNUMF_SPRINTF_BUF_SIZE - 1;
2231 fmt -= fnumu(fmt, (uint)(precision < 0 ? 0 : precision), 10);
2235 int result = ::snprintf(NULL, 0, fmt, num);
2236 return (ulong)(result < 0 ? 0 : result);
2241 template<
class T>
struct ToBool {
2242 template<
class Size>
static T getbool(
const char* data, Size size) {
2247 typename T::Type value = impl::tobool(data, size, error);
2254 template<
class T>
struct ToBoolPod {
2255 template<
class Size>
static T getbool(
const char* data, Size size) {
2258 T result = impl::tobool(data, size, error);
2264 template<
class T>
struct ToNum {
2265 template<
class Size>
static T getnum(
const char* data, Size size,
int base) {
2270 typename T::Type value = impl::tonum<typename T::Type>(data, size, error, base);
2277 template<
class T>
struct ToNumPod {
2278 template<
class Size>
static T getnum(
const char* data, Size size,
int base) {
2281 T result = impl::tonum<T>(data, size, error, base);
2287 template<
class T>
struct ToNumf {
2288 template<
class Size>
static T getnum(
const char* data, Size size) {
2293 typename T::Type value = impl::tonumf<typename T::Type>(data, size, error);
2300 template<
class T>
struct ToNumfPod {
2301 template<
class Size>
static T getnum(
const char* data, Size size) {
2304 T result = impl::tonumf<T>(data, size, error);
2530 if (align_padding > 0) {
2531 switch (field->
align) {
2536 align_padright = align_padding;
2539 align_padleft = (align_padding / 2);
2540 align_padright = align_padding - align_padleft;
2543 align_padleft = align_padding;
2548 align_padleft = align_padright = 0;
2639 void impl_prefix_info(
char& prefix_ch, uint& prefix_len)
const {
2683 static void impl_prefix_write(
char*& p,
char prefix_ch, uint prefix_len) {
2684 switch (prefix_len) {
2699 void impl_num_write(
char* p, T num,
int digits,
int width,
int align_padding,
const FmtSetField* field)
const {
2700 int align_padleft, align_padright;
2703 if (align_padleft > 0) {
2704 memset(p, (
int)(uchar)field->
fill, align_padleft);
2709 if (digits < width) {
2714 const uint padlen = width - digits;
2715 p += padlen + digits - 1;
2716 impl::fnum(p, num,
fDEC);
2718 const int ch = (pad_ch == 0 ?
'0' : (int)(uchar)pad_ch);
2719 memset(p0, ch, padlen);
2722 impl::fnum(p, num,
fDEC);
2725 if (digits < width) {
2726 const uint padlen = width - digits;
2727 const int ch = (pad_ch == 0 ?
'0' : (int)(uchar)pad_ch);
2728 memset(p, ch, padlen);
2732 impl::fnum(p, num,
fDEC);
2735 if (align_padright > 0)
2736 memset(p, (
int)(uchar)field->
fill, align_padright);
2787 FmtSetFloat(
int precision=
fpCURRENT,
int width=-1,
char ch=0,
char ch_sp=0) : precision(precision), pad_width(width), pad_ch(ch), pad_ch_sp(ch_sp)
2820 void impl_info(T& num,
int& exp,
int& maxlen,
int align_width)
const {
2821 if (precision < 0) {
2828 if (pad_width > maxlen)
2830 if (align_width > maxlen)
2831 maxlen = align_width;
2834 ulong impl_write(
char* buf, T num,
int exp,
int align_width,
const FmtSetField* field)
const {
2838 len = (long)impl::fnumfe(p, num, exp,
false);
2840 len = (long)impl::fnumf(p, num, exp, precision);
2842 const int width = (pad_width > len ? pad_width : len);
2843 const int align_padding = (align_width > width ? align_width - width : 0);
2845 int align_padleft, align_padright;
2848 char* p1 = p + align_padleft;
2849 if (len < pad_width) {
2850 const int padlen = pad_width - len;
2852 memmove(p1 + padlen, p, len);
2853 memset(p1, (
int)(uchar)pad_ch_sp, padlen);
2854 }
else if (num < 0.0) {
2855 memmove(p1 + 1 + padlen, p+1, len-1);
2856 memset(p1 + 1, (
int)(uchar)pad_ch, padlen);
2859 memmove(p1 + padlen, p, len);
2860 memset(p1, (
int)(uchar)pad_ch, padlen);
2862 if (align_padleft > 0)
2863 memset(p, (
int)(uchar)field->
fill, align_padleft);
2864 p = p1 + len + padlen;
2865 }
else if (align_padleft > 0) {
2866 memmove(p1, p, len);
2867 memset(p, (
int)(uchar)field->
fill, align_padleft);
2872 if (align_padright > 0) {
2873 memset(p, (
int)(uchar)field->
fill, align_padright);
2874 p += align_padright;
2877 return (ulong)(p - buf);
2893 FmtAttribs() : num_int(
fbAUTO,
fPREFIX0, 0,
'0'), num_flt(
fPREC_AUTO, 0,
'0',
' '), field(
fLEFT, 0,
' ')
2922 FmtChar(
char ch, ulong count) : ch(ch), count(count)
2970 FmtString(
const StringBase& str,
int width=-1,
char ch=0) : str(str), fmt(width, ch)
2979 FmtString(
const StringBase& str,
FmtAlign align,
int width=-1,
char ch=0) : str(str), fmt(align, width, ch)
3014 FmtStringWrap(
const StringBase& str,
int width) : str(str), width(width), indent(0)
3018 indent = new_indent;
3165 FmtFloatT(T num,
int precision=
fpCURRENT,
int width=-1,
char ch=
'0',
char ch_sp=
' ') : null(false), num(num), fmt(precision, width, ch, ch_sp)
3175 FmtFloatT(
const FloatClass& num,
int precision=
fpCURRENT,
int width=-1,
char ch=
'0',
char ch_sp=
' ') : null(num.null()), num(num.value()), fmt(precision, width, ch, ch_sp)
3184 This&
width(
int width,
char ch=0,
char ch_sp=0) {
3308 FmtDump(
const void* buf, ulong size, uint maxline=24,
bool compact=
false,
bool upper=
false) : buf(buf), size(size), maxline(maxline), compact(compact), upper(upper)
3315 #if defined(_MSC_VER) 3316 #pragma warning(pop) FmtIntT< int8 > FmtInt8
Explicitly format an integer.
Definition: str.h:3110
ListBase< char, StrSizeT > StringBase
Definition: str.h:3004
bool compact
Whether to use compact mode (no address or ASCII output)
Definition: str.h:3298
char ascii_tolower(char ch)
Convert ASCII character to lowercase.
Definition: str.h:119
ulong utf8_to16(const char *&str, const char *end, wchar16 *outbuf=NULL, ulong outsize=0, UtfMode mode=umREPLACE_INVALID)
Convert UTF-8 string to UTF-16 string.
Definition: str.h:543
CharBreakType ascii_breaktype(char ch)
Get ASCII character word-break type.
Definition: str.h:91
This & operator=(const This &src)
Definition: str.h:3233
Basic search using memchr() and memcmp()
Definition: str.h:1167
FmtSetField & reset()
Reset attributes to defaults (not unspecified).
Definition: str.h:2502
ulong size
Buffer size in bytes to dump.
Definition: str.h:3296
static T inf()
Get infinity value.
Definition: type.h:1346
This & width(int width, char ch=0)
Helper for setting padding attributes.
Definition: str.h:2996
FmtFloatT< float > FmtFloat
Explicitly format a floating pointer number.
Definition: str.h:3192
Out of bounds error.
Definition: sys.h:1129
Holds integer formatting attributes.
Definition: str.h:2589
This & width(int width, char ch=0)
Helper for setting padding attributes.
Definition: str.h:3099
1-digit floating point precision
Definition: str.h:2345
Holds a Newline value that can be null, which implicitly converts to NL_SYS (system default newline)...
Definition: sys.h:813
char pad_ch
Fill character, 0 if unspecified (use baseline or default) (default: '0')
Definition: str.h:2593
FmtFloatT(const FloatClass &num, int precision=fpCURRENT, int width=-1, char ch='0', char ch_sp=' ')
Constructor for class number type (Float, etc) with all attributes.
Definition: str.h:3175
This pairs a FmtIntT type with FmtSetField for output formatting.
Definition: str.h:3034
FmtString(const StringBase &str, int width=-1, char ch=0)
Constructor.
Definition: str.h:2970
StringBase str
Definition: str.h:3006
int utf8_compare(const char *str1, ulong len1, const char *str2, ulong len2)
Compare two non-terminated UTF-8 strings.
Definition: str.h:305
CharType ascii_type(char ch)
Get ASCII character type.
Definition: str.h:76
Invalid argument or data.
Definition: sys.h:1123
bool upper
Whether to use uppercase hex, false for lowercase.
Definition: str.h:3299
FmtDump(const void *buf, ulong size, uint maxline=24, bool compact=false, bool upper=false)
Explicitly format a hex dump of given buffer.
Definition: str.h:3308
FmtIntT< int16 > FmtInt16
Explicitly format an integer.
Definition: str.h:3111
Punctuation used after a word ends, break words after this ( )]}>!%;,./ )
Definition: str.h:64
Base 16: hexadecimal.
Definition: str.h:2324
FmtSetField field
Definition: str.h:3204
Formatting attributes (used internally).
Definition: str.h:2886
static T nan()
Get Not-A-Number (NaN) value.
Definition: type.h:1369
Single character base prefix (x for hex, o for octal, b for binary)
Definition: str.h:2334
FmtFieldFloat< T > This
Definition: str.h:3223
FmtIntT< uint > FmtUInt
Explicitly format an integer.
Definition: str.h:3116
Word character (A-Z, a-z, 0-9, _)
Definition: str.h:65
Automatic floating point precision – either normal decimal notation or E notation, whichever is shorter (default)
Definition: str.h:2343
Numeric digit character (0-9)
Definition: str.h:53
Evo implementation detail for system portability – this is included by most Evo headers, include this via: include <evo/type.h>.
FmtIntT< uint8 > FmtUInt8
Explicitly format an integer.
Definition: str.h:3119
Holds string to use when formatting null values.
Definition: str.h:2406
Whitespace character, used between words.
Definition: str.h:61
CharBreakType
Character break type returned by ascii_breaktype().
Definition: str.h:59
FloatT< T >::This FloatClass
Number class type.
Definition: str.h:3150
5-digit floating point precision
Definition: str.h:2349
char fill
Field fill character to pad up to width (default: ' ')
Definition: str.h:2484
No floating point precision (whole numbers)
Definition: str.h:2344
int pad_width
Width to fill to, 0 for none, -1 to ignore (leave current width) (default: 0)
Definition: str.h:2777
ulong utf16_strlen(const wchar16 *str)
Find terminated UTF-16 string length.
Definition: str.h:946
uint count
Character repeat count.
Definition: str.h:2916
FmtFieldNum< T > FmtFieldType
This type paired with field info.
Definition: str.h:3069
Newline
Newline type.
Definition: sys.h:748
static T eps()
Get machine epsilon.
Definition: type.h:1377
int utf16_compare(const wchar16 *str1, ulong len1, const wchar16 *str2, ulong len2)
Compare two non-terminated UTF-16 strings.
Definition: str.h:729
FmtIntT< ushort > FmtUShort
Explicitly format an integer.
Definition: str.h:3115
IntegerT< T >::This IntClass
Number class type.
Definition: str.h:3067
FmtFloatT< double > FmtFloatD
Explicitly format a floating pointer number.
Definition: str.h:3193
FmtSetFloat(int precision=fpCURRENT, int width=-1, char ch=0, char ch_sp=0)
Constructor with all attributes.
Definition: str.h:2787
Other character type.
Definition: str.h:50
const wchar16 * utf16_min(const wchar16 *str, const wchar16 *end, bool strict=false, uint mincount=1)
Scan for UTF-16 surrogate pairs, which each require a pair of wchar16 values (4 bytes).
Definition: str.h:966
FmtFieldFloat(const FmtFloatT< T > &num, FmtAlign align=fLEFT, int width=0, char fill=' ')
Definition: str.h:3227
FmtString(const StringBase &str, FmtAlign align, int width=-1, char ch=0)
Constructor.
Definition: str.h:2979
No base prefix (default)
Definition: str.h:2333
This & width(int width, char ch=0, char ch_sp=0)
Helper for setting padding attributes.
Definition: str.h:3184
Basic integer type.
Definition: type.h:980
uint maxline
Maximum bytes per line to dump, 0 for none (all 1 line)
Definition: str.h:3297
FmtSetFloat fmt
Definition: str.h:3156
int width
Definition: str.h:3007
FmtFloatT< T > num
Definition: str.h:3224
bool null
Definition: str.h:3154
Check if type is a Plan Old Data type.
Definition: meta.h:528
FmtStringWrap & set_indent(int new_indent=0)
Definition: str.h:3017
No error.
Definition: sys.h:1115
FmtFieldNum< T > This
Definition: str.h:3202
FmtIntT< int32 > FmtInt32
Explicitly format an integer.
Definition: str.h:3112
int pad_width
Width to fill to, 0 for none, -1 if unspecified (use baseline or default) (default: 0) ...
Definition: str.h:2592
Skip invalid characters.
Definition: str.h:139
FmtFieldNum & operator=(const This &src)
Definition: str.h:3212
FmtSetNull & reset()
Reset to defaults.
Definition: str.h:2436
Error
General Evo error code stored in exceptions, or used directly when exceptions are disabled...
Definition: sys.h:1113
FmtAlign
Formatting alignment.
Definition: str.h:2356
FmtSetField(int width, char fill=0)
Short constructor with default alignment.
Definition: str.h:2498
FmtIntT(const IntClass &num, int base=fbCURRENT, FmtBasePrefix prefix=fbpCURRENT, int width=-1, char ch=0)
Constructor for class number type (Int, etc) with all attributes.
Definition: str.h:3091
Punctuation or symbol character.
Definition: str.h:52
uint32 StrSizeT
Default Evo string size type.
Definition: sys.h:734
FmtIntT< long > FmtLong
Explicitly format an integer.
Definition: str.h:3108
const char * string_memrchr(const char *str, char ch, size_t size)
Evo implementation of memrchr() to search for character in reverse.
Definition: str.h:1150
Base 10: decimal (default)
Definition: str.h:2323
Include invalid characters – try to use as-is (dangerous)
Definition: str.h:137
FmtIntT< int > FmtInt
Explicitly format an integer.
Definition: str.h:3107
4-digit floating point precision
Definition: str.h:2348
const void * buf
Buffer to dump.
Definition: str.h:3295
static int maxdigits_prec(int exp, int precision)
Get max formatting digits with given exponent and precision, including sign and any additional chars ...
Definition: type.h:1306
Other charcater type.
Definition: str.h:60
Base 2: binary.
Definition: str.h:2321
ulong utf16_count(const wchar16 *str, const wchar16 *end, UtfMode mode=umREPLACE_INVALID)
Count Unicode character values in UTF-16 string.
Definition: str.h:1009
FmtIntT< short > FmtShort
Explicitly format an integer.
Definition: str.h:3106
T Type
Translated type.
Definition: meta.h:373
ulong utf8_count(const char *str, const char *end, UtfMode mode=umREPLACE_INVALID)
Count Unicode character values in UTF-8 string.
Definition: str.h:481
T IntPod
Number POD type.
Definition: str.h:3068
CharType
Character type returned by ascii_type().
Definition: str.h:49
static const EndT END
Special integer value for indicating end of items or no item.
Definition: type.h:1846
ListBase< char, StrSizeT > StringBase
StringBase type.
Definition: str.h:2933
void merge(const FmtSetInt &src)
Merge source attributes (used internally).
Definition: str.h:2626
const char * str
Pointer to string for formatting null values, ignored if size is 0.
Definition: str.h:2407
Align center by adding filler on left and right sides.
Definition: str.h:2359
Default, uses system memmem() if possible (define EVO_NO_MEMMEM to prevent this), otherwise same as s...
Definition: str.h:1165
FmtSetInt & reset()
Reset attributes to defaults (not unspecified).
Definition: str.h:2613
FmtIntT< ulongl > FmtULongL
Explicitly format an integer.
Definition: str.h:3118
void merge(const FmtSetField &src)
Merge source attributes (used internally).
Definition: str.h:2514
T Type
Translated type.
Definition: meta.h:363
Explicitly format an integer.
Definition: str.h:3065
Base 8: octal.
Definition: str.h:2322
FmtString(const FmtString &str, FmtAlign align, int width, char ch=0)
Constructor with override fields for compatibility with FmtFieldType.
Definition: str.h:2988
FmtIntT< uint32 > FmtUInt32
Explicitly format an integer.
Definition: str.h:3121
FmtSetNull(const ListBase< char, StrSizeT > &null)
Constructor.
Definition: str.h:2430
FmtStringWrap(const StringBase &str, int width)
Definition: str.h:3014
FmtString(const char *str, StrSizeT size, int width=-1, char ch=0)
Constructor.
Definition: str.h:2952
FmtString(const char *str, FmtAlign align=fLEFT)
Constructor.
Definition: str.h:2943
FmtAlign align
Field alignment type (default: fLEFT)
Definition: str.h:2482
FmtSetNull(const char *null)
Constructor.
Definition: str.h:2417
char ascii_toupper(char ch)
Convert ASCII character to uppercase.
Definition: str.h:105
FmtString FmtFieldType
This type paired with field info.
Definition: str.h:2934
FmtFieldFloat(const This &src)
Definition: str.h:3230
FmtPrecision
Formatting floating point precision type.
Definition: str.h:2341
Current prefix (i.e. unspecified/default)
Definition: str.h:2332
FmtSetInt fmt
Formatting attributes.
Definition: str.h:3266
const char * utf8_scan(wchar32 &code, const char *str, const char *end, UtfMode mode=umREPLACE_INVALID)
Scan for next Unicode character in UTF-8 string.
Definition: str.h:160
void merge(const FmtSetFloat &src)
Merge from source (used internally).
Definition: str.h:2806
static const int MAXSTRLEN
Max formatted length, including either sign or hex/octal prefix (0x/0), but not both.
Definition: type.h:987
Evo C++ Library namespace.
Definition: alg.h:11
FmtIntT< uint16 > FmtUInt16
Explicitly format an integer.
Definition: str.h:3120
StringSearchAlg
String search algorithm selection.
Definition: str.h:1164
static const EndT NONE
Special integer value for indicating no item or unknown item.
Definition: type.h:1832
static T exp10(T num, int exp)
Multiply number by 10 raised to exponent.
Definition: type.h:1407
Stop or error on invalid character.
Definition: str.h:140
FmtIntT< T > This
This type
Definition: str.h:3066
char pad_ch_sp
Padding character used with special value (inf or nan), 0 to ignore (leave current fill character) (d...
Definition: str.h:2779
Holds floating point formatting attributes.
Definition: str.h:2775
FmtSetNull()
Constructor.
Definition: str.h:2411
FmtPtr(const void *ptr, int base, FmtBasePrefix prefix=fbpCURRENT, int width=-1, char ch=0)
Constructor for formatting a pointer.
Definition: str.h:3284
Explicitly format a string.
Definition: str.h:2931
Uppercase alphabetic character (A-Z)
Definition: str.h:54
Replace invalid characters with UNICODE_REPLACEMENT_CHAR.
Definition: str.h:138
UtfMode
UTF decoding mode used to set how to handle invalid character values.
Definition: str.h:136
T num
Definition: str.h:3155
FmtSetInt fmt
Formatting attributes.
Definition: str.h:3072
int precision
Floating point precision (number of digits after decimal), fPREC_AUTO for automatic (default: fPREC_A...
Definition: str.h:2776
FmtFieldNum(const FmtIntT< T > &num, FmtAlign align=fLEFT, int width=0, char fill=' ')
Definition: str.h:3206
FmtStringWrap & set_newline(NewlineDefault nl)
Definition: str.h:3027
Check if type is a floating point type.
Definition: meta.h:277
FmtString This
This type
Definition: str.h:2932
FmtAttribs & reset()
Reset to defaults.
Definition: str.h:2899
FmtAttribs()
Constructor.
Definition: str.h:2893
static T fexp10(int &exp, T num)
Extract normalized base 10 mantissa and exponent from number.
Definition: type.h:1438
Knuth-Morris-Pratt using partial match table.
Definition: str.h:1166
FmtIntT< uint64 > FmtUInt64
Explicitly format an integer.
Definition: str.h:3122
FmtString(const char *str, StrSizeT size, FmtAlign align, int width=-1, char ch=0)
Constructor.
Definition: str.h:2962
Explicitly format a repeated character.
Definition: str.h:2914
Align left by adding filler on right side.
Definition: str.h:2358
FmtStringWrap & set_newline(Newline nl)
Definition: str.h:3022
int base
Base for formatting (default: fDEC)
Definition: str.h:2590
Default newline type, implicitly converts to NL_SYS (system default newline).
Definition: sys.h:773
Explicitly format a pointer.
Definition: str.h:3264
char pad_ch
Padding character, 0 to ignore (leave current fill character) (default: '0')
Definition: str.h:2778
FmtWidth
Formatting field width.
Definition: str.h:2367
FmtFloatT(T num, int precision=fpCURRENT, int width=-1, char ch='0', char ch_sp=' ')
Constructor for POD number type with all attributes.
Definition: str.h:3165
StrSizeT size
String (str) size for formatting null values, 0 for none/empty
Definition: str.h:2408
FmtIntT< longl > FmtLongL
Explicitly format an integer.
Definition: str.h:3109
const wchar16 * utf16_scan_term(wchar32 &code, const wchar16 *str, UtfMode mode=umREPLACE_INVALID)
Scan for next Unicode character in terminated UTF-16 string.
Definition: str.h:682
FmtSetField field
Field alignment attributes.
Definition: str.h:2890
FmtIntT< T > num
Definition: str.h:3203
Base 16: hexadecimal (lowercase)
Definition: str.h:2325
int indent
Definition: str.h:3008
Whitespace character.
Definition: str.h:51
FmtChar(char ch, ulong count)
Constructor.
Definition: str.h:2922
static const wchar16 UNICODE_REPLACEMENT_CHAR
Unicode code point for "Replacement Character" used when decoding invalid UTF bytes or values...
Definition: str.h:133
FmtBasePrefix prefix
Formatting prefix type (default: fPREFIX0)
Definition: str.h:2591
Nullable basic floating-point base type.
Definition: type.h:1291
StringBase str
Definition: str.h:2936
3-digit floating point precision
Definition: str.h:2347
T FloatPod
Number POD type.
Definition: str.h:3151
static void setup_align(int &align_padleft, int &align_padright, int align_padding, const FmtSetField *field)
Used to setup and calculate alignment padding (used internally).
Definition: str.h:2529
FmtBasePrefix
Formatting integer base prefix type.
Definition: str.h:2331
int width
Field width to align in (default: 0)
Definition: str.h:2483
FmtPtr(const void *ptr, FmtBasePrefix prefix=fbpCURRENT, int width=-1, char ch=0)
Constructor for formatting a pointer.
Definition: str.h:3274
2-digit floating point precision
Definition: str.h:2346
Lowercase alphabetic character (a-z)
Definition: str.h:55
const void * ptr
Pointer to format.
Definition: str.h:3265
FmtStringWrap(const char *str, StrSizeT size, int width, int indent=0)
Definition: str.h:3011
Punctuation used before a word begins, break words before this ( ([{< )
Definition: str.h:63
FmtIntT(T num, int base=fbCURRENT, FmtBasePrefix prefix=fbpCURRENT, int width=-1, char ch=0)
Constructor for POD number type with all attributes.
Definition: str.h:3081
Double character base prefix (0x for hex, 0o for octal, 0b for binary)
Definition: str.h:2335
FmtSetField(FmtAlign align=faCURRENT, int width=-1, char fill=0)
Main constructor.
Definition: str.h:2491
Align right by adding filler on left side.
Definition: str.h:2360
FmtSetField field
Definition: str.h:3225
FmtFloatT< T > This
This type.
Definition: str.h:3149
FmtIntT< ulong > FmtULong
Explicitly format an integer.
Definition: str.h:3117
Current floating point precision (i.e. unspecified/default)
Definition: str.h:2342
FmtFieldNum(const This &src)
Definition: str.h:3209
This pairs a FmtFloatT type with FmtSetField for output formatting.
Definition: str.h:3035
Quote character, break word before or after this depending on whether begin or end quote ('"`) ...
Definition: str.h:62
FmtSetInt num_int
Integer attributes.
Definition: str.h:2888
Check if type is an integer (whole number) type.
Definition: meta.h:248
int utf16_compare8(const wchar16 *str1, ulong len1, const char *str2, ulong len2)
Compare a non-terminated UTF-16 string to a non-terminated UTF-8 string.
Definition: str.h:842
char ch
Character to format.
Definition: str.h:2915
FmtSetField fmt
Definition: str.h:2937
FmtFloatT< ldouble > FmtFloatL
Explicitly format a floating pointer number.
Definition: str.h:3194
FmtSetInt(int base=fbCURRENT, FmtBasePrefix prefix=fbpCURRENT, int width=-1, char ch=0)
Main constructor with all attributes.
Definition: str.h:2601
Check if type is a boolean (true/false) type.
Definition: meta.h:229
const char * utf8_scan_term(wchar32 &code, const char *str, UtfMode mode=umREPLACE_INVALID)
Scan for next Unicode character in terminated UTF-8 string.
Definition: str.h:234
FmtFieldFloat< T > FmtFieldType
This type paired with field info.
Definition: str.h:3152
Explicitly format a floating pointer number.
Definition: str.h:3148
6-digit floating point precision
Definition: str.h:2350
Holds field and alignment formatting attributes.
Definition: str.h:2481
T num
Number to format.
Definition: str.h:3071
FmtSetNull(const char *null, StrSizeT size)
Constructor.
Definition: str.h:2424
NewlineValue newline
Definition: str.h:3009
static T precision()
Get best precision value.
Definition: type.h:1314
FmtSetNull null
String to use for null values from strings (like String) or primitives (like Int) ...
Definition: str.h:2887
const char * utf8_min(const char *str, const char *end, bool strict=false, ulong mincount=1, uint minsize=2)
Scan for UTF-8 multi-byte characters of at least minsize.
Definition: str.h:418
FmtSetInt(int base, int width, char ch=0)
Short constructor without prefix.
Definition: str.h:2609
Explicitly format a hex dump from buffer.
Definition: str.h:3294
Current base (i.e. unspecified/default)
Definition: str.h:2319
FmtBase
Formatting integer base.
Definition: str.h:2318
Current alignment (i.e. unspecified/default)
Definition: str.h:2357
FmtSetFloat num_flt
Floating point attributes.
Definition: str.h:2889
FmtSetFloat & reset()
Reset to defaults.
Definition: str.h:2793
ulong utf16_to8(const wchar16 *&str, const wchar16 *end, char *outbuf=NULL, ulong outsize=0, UtfMode mode=umREPLACE_INVALID)
Convert UTF-16 string to UTF-8 string.
Definition: str.h:1053
FmtIntT< int64 > FmtInt64
Explicitly format an integer.
Definition: str.h:3113
Auto base detection.
Definition: str.h:2320
const wchar16 * utf16_scan(wchar32 &code, const wchar16 *str, const wchar16 *end, UtfMode mode=umREPLACE_INVALID)
Scan for next Unicode character in UTF-16 string.
Definition: str.h:630