30 typedef wchar_t utf16_t;
32 typedef char16_t utf16_t;
40 inline bool is_high_surrogate(_In_ utf16_t chr)
42 return 0xd800 < chr && chr < 0xdc00;
50 inline bool is_low_surrogate(_In_ utf16_t chr)
52 return 0xdc00 < chr && chr < 0xe000;
60 inline bool is_surrogate_pair(_In_reads_(2)
const utf16_t* str)
62 return is_high_surrogate(str[0]) && is_low_surrogate(str[1]);
70 inline char32_t surrogate_pair_to_ucs4(_In_reads_(2)
const utf16_t* str)
72 _Assume_(is_surrogate_pair(str));
74 ((
char32_t)(str[0] - 0xd800) << 10) +
75 (char32_t)(str[1] - 0xdc00) +
84 inline void ucs4_to_surrogate_pair(_Out_writes_(2) utf16_t* str, _In_
char32_t chr)
86 _Assume_(chr >= 0x10000);
88 str[0] = 0xd800 + (char32_t)((chr >> 10) & 0x3ff);
89 str[1] = 0xdc00 + (char32_t)(chr & 0x3ff);
97 inline bool iscombining(_In_
char32_t chr)
100 (0x0300 <= chr && chr < 0x0370) ||
101 (0x1dc0 <= chr && chr < 0x1e00) ||
102 (0x20d0 <= chr && chr < 0x2100) ||
103 (0xfe20 <= chr && chr < 0xfe30);
112 inline bool islbreak(_In_ T chr)
114 return chr ==
'\n' || chr ==
'\r';
126 inline size_t islbreak(_In_reads_or_z_opt_(count)
const T* chr, _In_
size_t count)
128 _Assume_(chr || !count);
129 if (count >= 2 && ((chr[0] ==
'\r' && chr[1] ==
'\n') || (chr[0] ==
'\n' && chr[1] ==
'\r')))
131 if (count > 1 && (chr[0] ==
'\n' || chr[0] ==
'\r'))
142 inline bool isspace(_In_ T chr)
144 return chr ==
' ' || chr ==
'\t' || chr ==
'\n' || chr ==
'\r' || chr ==
'\v' || chr ==
'\f';
153 inline bool islower(_In_ T chr)
155 return 'a' <= chr && chr <=
'z';
164 inline bool isupper(_In_ T chr)
166 return 'A' <= chr && chr <=
'Z';
175 inline bool isdigit(_In_ T chr)
177 return '0' <= chr && chr <=
'9';
186 inline bool isalpha(_In_ T chr)
188 return islower(chr) || isupper(chr);
197 inline size_t glyphlen(_In_reads_or_z_opt_(count)
const wchar_t* glyph, _In_
size_t count)
199 _Assume_(glyph || !count);
202 size_t i = count < 2 || !is_surrogate_pair(glyph) ? 1 : 2;
206 for (; i < count && iscombining(glyph[i]); ++i);
220 inline T tolower(_In_ T chr)
222 return isupper(chr) ? chr | 0x20 : chr;
233 inline T toupper(_In_ T chr)
235 return islower(chr) ? chr | ~0x20 : chr;
246 inline size_t strlen(_In_z_
const T* str)
250 for (i = 0; str[i]; ++i);
263 inline size_t strnlen(_In_reads_or_z_opt_(count)
const T* str, _In_
size_t count)
265 _Assume_(str || !count);
267 for (i = 0; i < count && str[i]; ++i);
271 constexpr auto npos{
static_cast<size_t>(-1) };
282 inline size_t strchr(_In_z_
const T* str, _In_ T chr)
285 for (
size_t i = 0; str[i]; ++i)
286 if (str[i] == chr)
return i;
300 inline size_t strnchr(
301 _In_reads_or_z_opt_(count)
const T* str,
305 _Assume_(str || !count);
306 for (
size_t i = 0; i < count && str[i]; ++i)
307 if (str[i] == chr)
return i;
321 inline size_t strrnchr(
322 _In_reads_or_z_opt_(count)
const T* str,
326 _Assume_(str || !count);
328 for (
size_t i = 0; i < count && str[i]; ++i)
329 if (str[i] == chr) z = i;
343 _In_reads_or_z_opt_(count)
const T* str,
346 _Assume_(str || !count);
347 for (
size_t i = 0; i < count && str[i]; ++i)
348 if (!isspace(str[i]))
364 _In_reads_or_z_opt_(count)
const T* str,
366 _In_
const std::locale& locale)
368 _Assume_(str || !count);
369 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
370 for (
size_t i = 0; i < count && str[i]; ++i)
371 if (!ctype.is(ctype.space, str[i]))
386 inline size_t strnichr(
387 _In_reads_or_z_opt_(count)
const T* str,
391 _Assume_(str || !count);
393 for (
size_t i = 0; i < count && str[i]; ++i)
394 if (tolower(str[i]) == chr)
return i;
409 inline size_t strnichr(
410 _In_reads_or_z_opt_(count)
const T* str,
413 _In_
const std::locale& locale)
415 _Assume_(str || !count);
416 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
417 chr = ctype.tolower(chr);
418 for (
size_t i = 0; i < count && str[i]; ++i)
419 if (ctype.tolower(str[i]) == chr)
return i;
433 inline size_t strrnichr(
434 _In_reads_or_z_opt_(count)
const T* str,
438 _Assume_(str || !count);
441 for (
size_t i = 0; i < count && str[i]; ++i)
442 if (tolower(str[i]) == chr) z = i;
457 inline size_t strrnichr(
458 _In_reads_or_z_opt_(count)
const T* str,
461 _In_
const std::locale& locale)
463 _Assume_(str || !count);
464 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
465 chr = ctype.tolower(chr);
467 for (
size_t i = 0; i < count && str[i]; ++i)
468 if (ctype.tolower(str[i]) == chr) z = i;
480 template <
class T1,
class T2>
481 inline int strcmp(
const T1* str1,
const T2* str2)
483 _Assume_(str1 && str2);
485 for (
size_t i = 0; (a = str1[i]) | (b = str2[i]); ++i) {
486 if (a > b)
return +1;
487 if (a < b)
return -1;
502 template <
class T1,
class T2>
504 _In_reads_or_z_opt_(count1)
const T1* str1, _In_
size_t count1,
505 _In_reads_or_z_opt_(count2)
const T2* str2, _In_
size_t count2)
507 _Assume_(str1 || !count1);
508 _Assume_(str2 || !count2);
509 size_t i; T1 a; T2 b;
510 for (i = 0; i < count1 && i < count2 && ((a = str1[i]) | (b = str2[i])); ++i) {
511 if (a > b)
return +1;
512 if (a < b)
return -1;
514 if (i < count1 && str1[i])
return +1;
515 if (i < count2 && str2[i])
return -1;
528 template <
class T1,
class T2>
529 inline int strncmp(_In_reads_or_z_opt_(count)
const T1* str1, _In_reads_or_z_opt_(count)
const T2* str2, _In_
size_t count)
531 _Assume_((str1 && str2) || !count);
532 size_t i; T1 a; T2 b;
533 for (i = 0; i < count && ((a = str1[i]) | (b = str2[i])); ++i) {
534 if (a > b)
return +1;
535 if (a < b)
return -1;
537 if (i < count && str1[i])
return +1;
538 if (i < count && str2[i])
return -1;
555 _In_reads_or_z_opt_(count1)
const T* str1, _In_
size_t count1,
556 _In_reads_or_z_opt_(count2)
const T* str2, _In_
size_t count2,
557 _In_
const std::locale& locale)
559 _Assume_(str1 || !count1);
560 _Assume_(str2 || !count2);
561 auto& collate = std::use_facet<std::collate<T>>(locale);
562 return collate.compare(str1, str1 + count1, str2, str2 + count2);
573 template <
class T1,
class T2>
574 inline int stricmp(_In_z_
const T1* str1, _In_z_
const T2* str2)
578 size_t i; T1 a; T2 b;
579 for (i = 0; (a = tolower(str1[i])) | (b = tolower(str2[i])); i++) {
580 if (a > b)
return +1;
581 if (a < b)
return -1;
583 if (str1[i])
return +1;
584 if (str2[i])
return -1;
597 template <
class T1,
class T2>
598 inline int stricmp(_In_z_
const T1* str1, _In_z_
const T2* str2, _In_
const std::locale& locale)
602 size_t i; T1 a; T2 b;
603 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
604 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
605 for (i = 0; (a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i])); i++) {
606 if (a > b)
return +1;
607 if (a < b)
return -1;
609 if (str1[i])
return +1;
610 if (str2[i])
return -1;
623 template <
class T1,
class T2>
624 inline int strnicmp(_In_reads_or_z_opt_(count)
const T1* str1, _In_reads_or_z_opt_(count)
const T2* str2, _In_
size_t count)
626 _Assume_(str1 || !count);
627 _Assume_(str2 || !count);
628 size_t i; T1 a; T2 b;
629 for (i = 0; i < count && ((a = tolower(str1[i])) | (b = tolower(str2[i]))); i++) {
630 if (a > b)
return +1;
631 if (a < b)
return -1;
633 if (i < count && str1[i])
return +1;
634 if (i < count && str2[i])
return -1;
648 template <
class T1,
class T2>
649 inline int strnicmp(_In_reads_or_z_opt_(count)
const T1* str1, _In_reads_or_z_opt_(count)
const T2* str2, _In_
size_t count, _In_
const std::locale& locale)
651 _Assume_(str1 || !count);
652 _Assume_(str2 || !count);
653 size_t i; T1 a; T2 b;
654 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
655 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
656 for (i = 0; i < count && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
657 if (a > b)
return +1;
658 if (a < b)
return -1;
660 if (i < count && str1[i])
return +1;
661 if (i < count && str2[i])
return -1;
675 template <
class T1,
class T2>
677 _In_reads_or_z_opt_(count1)
const T1* str1, _In_
size_t count1,
678 _In_reads_or_z_opt_(count2)
const T2* str2, _In_
size_t count2)
680 _Assume_(str1 || !count1);
681 _Assume_(str2 || !count2);
682 size_t i; T1 a; T2 b;
683 for (i = 0; i < count1 && i < count2 && ((a = tolower(str1[i])) | (b = tolower(str2[i]))); i++) {
684 if (a > b)
return +1;
685 if (a < b)
return -1;
687 if (i < count1 && str1[i])
return +1;
688 if (i < count2 && str2[i])
return -1;
703 template <
class T1,
class T2>
705 _In_reads_or_z_opt_(count1)
const T1* str1, _In_
size_t count1,
706 _In_reads_or_z_opt_(count2)
const T2* str2, _In_
size_t count2,
707 _In_
const std::locale& locale)
709 _Assume_(str1 || !count1);
710 _Assume_(str2 || !count2);
711 size_t i; T1 a; T2 b;
712 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
713 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
714 for (i = 0; i < count1 && i < count2 && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
715 if (a > b)
return +1;
716 if (a < b)
return -1;
718 if (i < count1 && str1[i])
return +1;
719 if (i < count2 && str2[i])
return -1;
731 template <
class T1,
class T2>
732 inline size_t strstr(
733 _In_z_
const T1* str,
734 _In_z_
const T2* sample)
738 for (
size_t offset = 0;; ++offset) {
739 for (
size_t i = offset, j = 0;; ++i, ++j) {
744 if (str[i] != sample[j])
759 template <
class T1,
class T2>
760 inline size_t strnstr(
761 _In_reads_or_z_opt_(count)
const T1* str,
763 _In_z_
const T2* sample)
765 _Assume_(str || !count);
767 for (
size_t offset = 0;; ++offset) {
768 for (
size_t i = offset, j = 0;; ++i, ++j) {
771 if (i >= count || !str[i])
773 if (str[i] != sample[j])
787 template <
class T1,
class T2>
788 inline size_t stristr(
789 _In_z_
const T1* str,
790 _In_z_
const T2* sample)
794 for (
size_t offset = 0;; ++offset) {
795 for (
size_t i = offset, j = 0;; ++i, ++j) {
800 if (tolower(str[i]) != tolower(sample[j]))
815 template <
class T1,
class T2>
816 inline size_t stristr(
817 _In_z_
const T1* str,
818 _In_z_
const T2* sample,
819 _In_
const std::locale& locale)
823 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
824 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
825 for (
size_t offset = 0;; ++offset) {
826 for (
size_t i = offset, j = 0;; ++i, ++j) {
831 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
846 template <
class T1,
class T2>
847 inline size_t strnistr(
848 _In_reads_or_z_opt_(count)
const T1* str,
850 _In_z_
const T2* sample)
852 _Assume_(str || !count);
854 for (
size_t offset = 0;; ++offset) {
855 for (
size_t i = offset, j = 0;; ++i, ++j) {
858 if (i >= count || !str[i])
860 if (tolower(str[i]) != tolower(sample[j]))
876 template <
class T1,
class T2>
877 inline size_t strnistr(
878 _In_reads_or_z_opt_(count)
const T1* str,
880 _In_z_
const T2* sample,
881 _In_
const std::locale& locale)
883 _Assume_(str || !count);
885 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
886 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
887 for (
size_t offset = 0;; ++offset) {
888 for (
size_t i = offset, j = 0;; ++i, ++j) {
891 if (i >= count || !str[i])
893 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
907 template <
class T1,
class T2>
908 inline size_t strcpy(
909 _Out_writes_z_(_String_length_(src) + 1) T1* dst,
910 _In_z_
const T2* src)
912 _Assume_(dst && src);
913 for (
size_t i = 0; ; ++i) {
914 if ((dst[i] = src[i]) == 0)
928 template <
class T1,
class T2>
929 inline size_t strncpy(
930 _Out_writes_(count) _Post_maybez_ T1* dst,
931 _In_reads_or_z_opt_(count)
const T2* src, _In_
size_t count)
933 _Assume_(dst && src || !count);
934 for (
size_t i = 0; ; ++i) {
937 if ((dst[i] = src[i]) == 0)
952 template <
class T1,
class T2>
953 inline size_t strncpy(
954 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_
size_t count_dst,
955 _In_reads_or_z_opt_(count_src)
const T2* src, _In_
size_t count_src)
957 _Assume_(dst || !count_dst);
958 _Assume_(src || !count_src);
959 for (
size_t i = 0; ; ++i)
963 if (i >= count_src) {
967 if ((dst[i] = src[i]) == 0)
980 template <
class T1,
class T2>
981 inline size_t strcat(
982 _In_z_ _Out_writes_z_(_String_length_(dst) + _String_length_(src) + 1) T1* dst,
983 _In_z_
const T2* src)
985 _Assume_(dst && src);
986 for (
size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
987 if ((dst[j] = src[i]) == 0)
1001 template <
class T1,
class T2>
1002 inline size_t strncat(
1004 _In_reads_or_z_opt_(count)
const T2* src, _In_
size_t count)
1006 _Assume_(dst && src || !count);
1007 for (
size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
1010 if ((dst[j] = src[i]) == 0)
1025 template <
class T1,
class T2>
1026 inline size_t strncat(
1027 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_
size_t count_dst,
1028 _In_reads_or_z_opt_(count_src)
const T2* src, _In_
size_t count_src)
1030 _Assume_(dst || !count_dst);
1031 _Assume_(src || !count_src);
1032 for (
size_t i = 0, j = stdex::strnlen<T1>(dst, count_dst); ; ++i, ++j)
1036 if (i >= count_src) {
1040 if ((dst[j] = src[i]) == 0)
1056 inline _Check_return_ _Ret_maybenull_z_ T* strdup(_In_opt_z_
const T* str)
1058 if (!str) _Unlikely_
1060 size_t count = strlen(str) + 1;
1061 T* dst =
new T[count];
1062 strncpy(dst, count, str, SIZE_MAX);
1078 inline _Ret_z_ T* strndup(
1079 _In_reads_or_z_opt_(count)
const T* str,
1082 T* dst =
new T[count];
1083 strncpy(dst, count, str, SIZE_MAX);
1097 inline size_t crlf2nl(_Out_writes_z_(strlen(src)) T* dst, _In_z_
const T* src)
1102 for (i = j = 0; src[j];) {
1103 if (src[j] !=
'\r' || src[j + 1] !=
'\n')
1104 dst[i++] = src[j++];
1120 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1121 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& dst, _In_z_
const _Elem* src)
1124 _Assume_(src != dst.c_str());
1126 dst.reserve(strlen(src));
1127 for (
size_t j = 0; src[j];) {
1128 if (src[j] !=
'\r' || src[j + 1] !=
'\n')
1142 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1143 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
1146 for (i = j = 0, n = str.size(); j < n;) {
1147 if (str[j] !=
'\r' || str[j + 1] !=
'\n')
1148 str[i++] = str[j++];
1158 template <
class T,
class T_bin>
1159 inline T_bin strtoint(
1160 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1161 _Out_opt_
size_t* end,
1163 _Out_ uint8_t& flags)
1165 _Assume_(str || !count);
1166 _Assume_(radix == 0 || 2 <= radix && radix <= 36);
1169 T_bin value = 0, digit,
1171 max_ui_pre1, max_ui_pre2;
1177 if (i >= count || !str[i])
goto error;
1178 if (!isspace(str[i]))
break;
1182 if (str[i] ==
'+') {
1185 if (i >= count || !str[i])
goto error;
1187 else if (str[i] ==
'-') {
1190 if (i >= count || !str[i])
goto error;
1195 if (str[i] ==
'0' && i + 1 < count && (str[i + 1] ==
'x' || str[i + 1] ==
'X')) {
1197 if (i >= count || !str[i])
goto error;
1202 if (str[i] ==
'0') {
1204 if (i >= count || !str[i])
goto error;
1205 if (str[i] ==
'x' || str[i] ==
'X') {
1208 if (i >= count || !str[i])
goto error;
1218 max_ui_pre1 = max_ui / (T_bin)radix;
1219 max_ui_pre2 = max_ui % (T_bin)radix;
1221 if (
'0' <= str[i] && str[i] <=
'9')
1222 digit = (T_bin)str[i] -
'0';
1223 else if (
'A' <= str[i] && str[i] <=
'Z')
1224 digit = (T_bin)str[i] -
'A' +
'\x0a';
1225 else if (
'a' <= str[i] && str[i] <=
'z')
1226 digit = (T_bin)str[i] -
'a' +
'\x0a';
1229 if (digit >= (T_bin)radix)
1232 if (value < max_ui_pre1 ||
1233 (value == max_ui_pre1 && digit <= max_ui_pre2))
1234 value = value * (T_bin)radix + digit;
1241 if (i >= count || !str[i])
1261 template <
class T,
class T_bin>
1263 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1264 _Out_opt_
size_t* end,
1270 switch (
sizeof(T_bin)) {
1272 value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags);
1273 if ((flags & 0x01) && (value & 0x80)) {
1277 return (flags & 0x02) ?
1278 (flags & 0x01) ? (T_bin)0x80 : (T_bin)0x7f :
1279 (flags & 0x01) ? -value : value;
1282 value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags);
1283 if ((flags & 0x01) && (value & 0x8000)) {
1287 return (flags & 0x02) ?
1288 (flags & 0x01) ? (T_bin)0x8000 : (T_bin)0x7fff :
1289 (flags & 0x01) ? -value : value;
1292 value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags);
1293 if ((flags & 0x01) && (value & 0x80000000)) {
1297 return (flags & 0x02) ?
1298 (flags & 0x01) ? (T_bin)0x80000000 : (T_bin)0x7fffffff :
1299 (flags & 0x01) ? -value : value;
1302 value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags);
1303 if ((flags & 0x01) && (value & 0x8000000000000000)) {
1307 return (flags & 0x02) ?
1308 (flags & 0x01) ? (T_bin)0x8000000000000000 : (T_bin)0x7fffffffffffffff :
1309 (flags & 0x01) ? -value : value;
1312 throw std::invalid_argument(
"Unsupported bit length");
1326 template <
class T,
class T_bin>
1327 inline T_bin strtouint(
1328 _In_reads_or_z_opt_(count)
const T* str,
1330 _Out_opt_
size_t* end,
1336 switch (
sizeof(T_bin)) {
1337 case 1: value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags);
break;
1338 case 2: value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags);
break;
1339 case 4: value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags);
break;
1340 case 8: value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags);
break;
1341 default:
throw std::invalid_argument(
"Unsupported bit length");
1344 return (flags & 0x02) ?
1345 (flags & 0x01) ? (T_bin)0 : (T_bin)-1 :
1346 (flags & 0x01) ? ~value : value;
1360 inline int32_t strto32(
1361 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1362 _Out_opt_
size_t* end,
1365 return strtoint<T, int32_t>(str, count, end, radix);
1379 inline int64_t strto64(
1380 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1381 _Out_opt_
size_t* end,
1384 return strtoint<T, int64_t>(str, count, end, radix);
1399 inline intptr_t strtoi(
1400 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1401 _Out_opt_
size_t* end,
1404#if defined(_WIN64) || defined(__LP64__)
1405 return (intptr_t)strto64(str, count, end, radix);
1407 return (intptr_t)strto32(str, count, end, radix);
1422 inline uint32_t strtou32(
1423 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1424 _Out_opt_
size_t* end,
1427 return strtouint<T, uint32_t>(str, count, end, radix);
1441 inline uint64_t strtou64(
1442 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1443 _Out_opt_
size_t* end,
1446 return strtouint<T, uint64_t>(str, count, end, radix);
1461 inline size_t strtoui(
1462 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1463 _Out_opt_
size_t* end,
1466#if defined(_WIN64) || defined(__LP64__)
1467 return (
size_t)strtou64(str, count, end, radix);
1469 return (
size_t)strtou32(str, count, end, radix);
1474 inline int vsnprintf(_Out_z_cap_(capacity)
char* str, _In_
size_t capacity, _In_z_ _Printf_format_string_params_(2)
const char* format, _In_opt_ locale_t locale, _In_ va_list arg)
1479#pragma warning(suppress: 4996)
1480 r = _vsnprintf_l(str, capacity, format, locale, arg);
1482 r = ::vsnprintf(str, capacity, format, arg);
1484 if (r == -1 && strnlen(str, capacity) == capacity) {
1486 capacity += std::max<size_t>(capacity / 8, 0x80);
1487 if (capacity > INT_MAX)
1488 throw std::invalid_argument(
"string too big");
1489 return (
int)capacity;
1494 inline int vsnprintf(_Out_z_cap_(capacity)
wchar_t* str, _In_
size_t capacity, _In_z_ _Printf_format_string_params_(2)
const wchar_t* format, _In_opt_ locale_t locale, _In_ va_list arg)
1499#pragma warning(suppress: 4996)
1500 r = _vsnwprintf_l(str, capacity, format, locale, arg);
1502 r = vswprintf(str, capacity, format, arg);
1504 if (r == -1 && strnlen(str, capacity) == capacity) {
1506 capacity += std::max<size_t>(capacity / 8, 0x80);
1507 if (capacity > INT_MAX)
1508 throw std::invalid_argument(
"string too big");
1509 return (
int)capacity;
1525 template<
class _Elem,
class _Traits,
class _Ax>
1526 inline size_t vappendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2)
const _Elem* format, _In_opt_ locale_t locale, _In_ va_list arg)
1528 _Elem buf[1024 /
sizeof(_Elem)];
1531 int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg);
1534 str.append(buf, count);
1537 for (
size_t capacity = 2 * 1024 /
sizeof(_Elem);; capacity *= 2) {
1539 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
1540 count = vsnprintf(buf_dyn.get(), capacity - 1, format, locale, arg);
1542 str.append(buf_dyn.get(), count);
1557 template<
class _Elem,
class _Traits,
class _Ax>
1558 inline size_t appendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2)
const _Elem* format, _In_opt_ locale_t locale, ...)
1561 va_start(arg, locale);
1562 size_t n = vappendf(str, format, locale, arg);
1575 template<
class _Elem,
class _Traits,
class _Ax>
1576 inline void vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2)
const _Elem* format, _In_opt_ locale_t locale, _In_ va_list arg)
1579 vappendf(str, format, locale, arg);
1589 template<
class _Elem,
class _Traits,
class _Ax>
1590 inline void sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2)
const _Elem* format, _In_opt_ locale_t locale, ...)
1593 va_start(arg, locale);
1594 vsprintf(str, format, locale, arg);
1607 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1608 inline std::basic_string<_Elem, _Traits, _Ax> vsprintf(_In_z_ _Printf_format_string_params_(2)
const _Elem* format, _In_opt_ locale_t locale, _In_ va_list arg)
1610 std::basic_string<_Elem, _Traits, _Ax> str;
1611 vappendf(str, format, locale, arg);
1623 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1624 inline std::basic_string<_Elem, _Traits, _Ax> sprintf(_In_z_ _Printf_format_string_params_(2)
const _Elem* format, _In_opt_ locale_t locale, ...)
1627 va_start(arg, locale);
1628 auto str = vsprintf(format, locale, arg);
1634 inline size_t strftime(_Out_z_cap_(capacity)
char* str, _In_
size_t capacity, _In_z_ _Printf_format_string_
const char* format, _In_
const struct tm* time, _In_opt_ locale_t locale)
1637 return _strftime_l(str, capacity, format, time, locale);
1639 return strftime_l(str, capacity, format, time, locale);
1643 inline size_t strftime(_Out_z_cap_(capacity)
wchar_t* str, _In_
size_t capacity, _In_z_ _Printf_format_string_
const wchar_t* format, _In_
const struct tm* time, _In_opt_ locale_t locale)
1646 return _wcsftime_l(str, capacity, format, time, locale);
1648 return wcsftime_l(str, capacity, format, time, locale);
1661 template<
class _Elem,
class _Traits,
class _Ax>
1662 inline void strcatftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_
const _Elem* format, _In_
const struct tm* time, _In_opt_ locale_t locale)
1664 _Elem buf[1024 /
sizeof(_Elem)];
1667 size_t count = strftime(buf, _countof(buf), format, time, locale);
1670 str.append(buf, count);
1673 for (
size_t capacity = 2 * 1024 /
sizeof(_Elem);; capacity *= 2) {
1675 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
1676 count = strftime(buf_dyn.get(), capacity, format, time, locale);
1678 str.append(buf_dyn.get(), count);
1693 template<
class _Elem,
class _Traits,
class _Ax>
1694 inline void strftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_
const _Elem* format, _In_
const struct tm* time, _In_opt_ locale_t locale)
1697 strcatftime(str, format, time, locale);
1710 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1711 inline std::basic_string<_Elem, _Traits, _Ax> strftime(_In_z_ _Printf_format_string_
const _Elem* format, _In_
const struct tm* time, _In_opt_ locale_t locale)
1713 std::basic_string<_Elem, _Traits, _Ax> str;
1714 strcatftime(str, format, time, locale);
1724 inline void strlwr(_Inout_z_ T* str)
1727 for (
size_t i = 0; str[i]; ++i)
1728 str[i] = tolower(str[i]);
1738 inline void strlwr(_Inout_z_ T* str, _In_
const std::locale& locale)
1741 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1742 for (
size_t i = 0; str[i]; ++i)
1743 str[i] = ctype.tolower(str[i]);
1753 inline void strlwr(_Inout_updates_z_(count) T* str, _In_
size_t count)
1755 _Assume_(str || !count);
1756 for (
size_t i = 0; i < count && str[i]; ++i)
1757 str[i] = tolower(str[i]);
1768 inline void strlwr(_Inout_updates_z_(count) T* str, _In_
size_t count, _In_
const std::locale& locale)
1770 _Assume_(str || !count);
1771 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1772 for (
size_t i = 0; i < count && str[i]; ++i)
1773 str[i] = ctype.tolower(str[i]);
1782 inline void strupr(_Inout_z_ T* str)
1785 for (
size_t i = 0; str[i]; ++i)
1786 str[i] = toupper(str[i]);
1796 inline void strupr(_Inout_z_ T* str, _In_
const std::locale& locale)
1799 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1800 for (
size_t i = 0; str[i]; ++i)
1801 str[i] = ctype.toupper(str[i]);
1811 inline void strupr(_Inout_updates_z_(count) T* str, _In_
size_t count)
1813 _Assume_(str || !count);
1814 for (
size_t i = 0; i < count && str[i]; ++i)
1815 str[i] = toupper(str[i]);
1826 inline void strupr(_Inout_updates_z_(count) T* str, _In_
size_t count, _In_
const std::locale& locale)
1828 _Assume_(str || !count);
1829 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1830 for (
size_t i = 0; i < count && str[i]; ++i)
1831 str[i] = ctype.toupper(str[i]);
1839 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1840 inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
1842 for (
size_t i = 0; i < str.size(); ++i)
1843 str[i] = toupper(str[i]);
1852 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1853 inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_
const std::locale& locale)
1855 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
1856 for (
size_t i = 0; i < str.size(); ++i)
1857 str[i] = ctype.toupper(str[i]);
1869 inline size_t ltrim(
1870 _Inout_z_count_(count) T* str, _In_
size_t count)
1872 for (
size_t i = 0;; ++i) {
1874 if (count) str[0] = 0;
1881 if (!isspace(str[i])) {
1883 return strnlen(str, count);
1884 size_t n = count != SIZE_MAX ? strncpy(str, str + i, count - i) : strcpy(str, str + i);
1901 inline size_t ltrim(
1902 _Inout_z_count_(count) T* str, _In_
size_t count,
1903 _In_
const std::locale& locale)
1905 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1906 for (
size_t i = 0;; ++i) {
1908 if (count) str[0] = 0;
1915 if (!ctype.is(ctype.space, str[i])) {
1917 return strnlen(str, count);
1918 size_t n = count != SIZE_MAX ? strncpy(str, str + i, count - i) : strcpy(str, str + i);
1930 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1931 inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s)
1938 [&](_In_ _Elem ch) { return !isspace(ch); }));
1947 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1948 inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_
const std::locale& locale)
1950 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
1956 [&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); }));
1968 inline size_t rtrim(
1969 _Inout_z_count_(count) T* str, _In_
size_t count)
1971 for (
size_t i = 0, j = 0;;) {
1972 if (i >= count || !str[i]) {
1973 if (j < count) str[j] = 0;
1976 if (!isspace(str[i]))
1993 inline size_t rtrim(
1994 _Inout_z_count_(count) T* str, _In_
size_t count,
1995 _In_
const std::locale& locale)
1997 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1998 for (
size_t i = 0, j = 0;;) {
1999 if (i >= count || !str[i]) {
2000 if (j < count) str[j] = 0;
2003 if (!ctype.is(ctype.space, str[i]))
2015 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
2016 static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s)
2022 [&](_In_ _Elem ch) { return !isspace(ch); }).base(),
2032 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
2033 static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_
const std::locale& locale)
2035 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
2040 [&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
2054 _Inout_z_count_(count) T* str, _In_
size_t count)
2056 return ltrim(str, rtrim(str, count));
2070 _Inout_z_count_(count) T* str, _In_
size_t count,
2071 _In_
const std::locale& locale)
2073 return ltrim(str, rtrim(str, count, locale), locale);
2081 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
2082 static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s)
2084 auto nonspace = [&](_In_ _Elem ch) {
return !isspace(ch); };
2105 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
2106 static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_
const std::locale& locale)
2108 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
2109 auto nonspace = [&](_In_ _Elem ch) {
return !ctype.is(ctype.space, ch); };