32 using locale_t = _locale_t;
34 inline locale_t create_locale(_In_
int category, _In_z_
const char* locale) {
return _create_locale(category, locale); }
35 inline locale_t create_locale(_In_
int category, _In_z_
const wchar_t* locale) {
return _wcreate_locale(category, locale); }
36 inline void free_locale(_In_opt_ locale_t locale) { _free_locale(locale); }
38 using locale_t = ::locale_t;
40 inline locale_t create_locale(_In_
int category, _In_z_
const char* locale)
44 case LC_ALL : mask = LC_ALL_MASK ;
break;
45 case LC_COLLATE : mask = LC_COLLATE_MASK ;
break;
46 case LC_CTYPE : mask = LC_CTYPE_MASK ;
break;
47 case LC_MESSAGES: mask = LC_MESSAGES_MASK;
break;
48 case LC_MONETARY: mask = LC_MONETARY_MASK;
break;
49 case LC_NUMERIC : mask = LC_NUMERIC_MASK ;
break;
50 case LC_TIME : mask = LC_TIME_MASK ;
break;
52 return newlocale(mask, locale, LC_GLOBAL_LOCALE);
55 inline void free_locale(_In_opt_ locale_t locale) { freelocale(locale); }
76 using locale = std::unique_ptr<__crt_locale_pointers, free_locale_delete>;
77#elif defined(__APPLE__)
78 using locale = std::unique_ptr<struct _xlocale, free_locale_delete>;
80 using locale = std::unique_ptr<struct __locale_struct, free_locale_delete>;
86 const locale locale_C(create_locale(LC_ALL,
"C"));
92 typedef wchar_t utf16_t;
94 typedef char16_t utf16_t;
102 inline bool is_high_surrogate(_In_ utf16_t chr)
104 return 0xd800 < chr && chr < 0xdc00;
112 inline bool is_low_surrogate(_In_ utf16_t chr)
114 return 0xdc00 < chr && chr < 0xe000;
122 inline bool is_surrogate_pair(_In_reads_(2)
const utf16_t* str)
124 return is_high_surrogate(str[0]) && is_low_surrogate(str[1]);
132 inline char32_t surrogate_pair_to_ucs4(_In_reads_(2)
const utf16_t* str)
134 _Assume_(is_surrogate_pair(str));
136 ((
char32_t)(str[0] - 0xd800) << 10) +
137 (char32_t)(str[1] - 0xdc00) +
146 inline void ucs4_to_surrogate_pair(_Out_writes_(2) utf16_t* str, _In_
char32_t chr)
148 _Assume_(chr >= 0x10000);
150 str[0] = 0xd800 + (char32_t)((chr >> 10) & 0x3ff);
151 str[1] = 0xdc00 + (char32_t)(chr & 0x3ff);
159 inline bool iscombining(_In_
char32_t chr)
162 (0x0300 <= chr && chr < 0x0370) ||
163 (0x1dc0 <= chr && chr < 0x1e00) ||
164 (0x20d0 <= chr && chr < 0x2100) ||
165 (0xfe20 <= chr && chr < 0xfe30);
174 inline size_t islbreak(_In_ T chr)
176 return chr ==
'\n' || chr ==
'\r';
186 inline size_t islbreak(_In_reads_or_z_opt_(count)
const T* chr, _In_
size_t count)
188 _Assume_(chr || !count);
189 if (count >= 2 && ((chr[0] ==
'\r' && chr[1] ==
'\n') || (chr[0] ==
'\n' && chr[1] ==
'\r')))
191 if (count > 1 && (chr[0] ==
'\n' || chr[0] ==
'\r'))
202 inline size_t glyphlen(_In_reads_or_z_opt_(count)
const wchar_t* glyph, _In_
size_t count)
204 _Assume_(glyph || !count);
207 size_t i = count < 2 || !is_surrogate_pair(glyph) ? 1 : 2;
211 for (; i < count && iscombining(glyph[i]); ++i);
225 inline size_t strlen(_In_z_
const T* str)
229 for (i = 0; str[i]; ++i);
242 inline size_t strnlen(_In_reads_or_z_opt_(count)
const T* str, _In_
size_t count)
244 _Assume_(str || !count);
246 for (i = 0; i < count && str[i]; ++i);
250 constexpr auto npos{
static_cast<size_t>(-1) };
261 inline size_t strchr(_In_z_
const T* str, _In_ T chr)
264 for (
size_t i = 0; str[i]; ++i)
265 if (str[i] == chr)
return i;
279 inline size_t strnchr(
280 _In_reads_or_z_opt_(count)
const T* str,
284 _Assume_(str || !count);
285 for (
size_t i = 0; i < count && str[i]; ++i)
286 if (str[i] == chr)
return i;
300 inline size_t strrnchr(
301 _In_reads_or_z_opt_(count)
const T* str,
305 _Assume_(str || !count);
307 for (
size_t i = 0; i < count && str[i]; ++i)
308 if (str[i] == chr) z = i;
322 inline size_t strnichr(
323 _In_reads_or_z_opt_(count)
const T* str,
326 _In_
const std::locale& locale)
328 _Assume_(str || !count);
329 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
330 chr = ctype.tolower(chr);
331 for (
size_t i = 0; i < count && str[i]; ++i)
332 if (ctype.tolower(str[i]) == chr)
return i;
346 inline size_t strrnichr(
347 _In_reads_or_z_opt_(count)
const T* str,
350 _In_
const std::locale& locale)
352 _Assume_(str || !count);
353 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
354 chr = ctype.tolower(chr);
356 for (
size_t i = 0; i < count && str[i]; ++i)
357 if (ctype.tolower(str[i]) == chr) z = i;
369 template <
class T1,
class T2>
370 inline int strcmp(
const T1* str1,
const T2* str2)
372 _Assume_(str1 && str2);
374 for (
size_t i = 0; (a = str1[i]) | (b = str2[i]); ++i) {
375 if (a > b)
return +1;
376 if (a < b)
return -1;
391 template <
class T1,
class T2>
393 _In_reads_or_z_opt_(count1)
const T1* str1, _In_
size_t count1,
394 _In_reads_or_z_opt_(count2)
const T2* str2, _In_
size_t count2)
396 _Assume_(str1 || !count1);
397 _Assume_(str2 || !count2);
398 size_t i; T1 a; T2 b;
399 for (i = 0; i < count1 && i < count2 && ((a = str1[i]) | (b = str2[i])); ++i) {
400 if (a > b)
return +1;
401 if (a < b)
return -1;
403 if (i < count1 && str1[i])
return +1;
404 if (i < count2 && str2[i])
return -1;
417 template <
class T1,
class T2>
418 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)
420 _Assume_((str1 && str2) || !count);
421 size_t i; T1 a; T2 b;
422 for (i = 0; i < count && ((a = str1[i]) | (b = str2[i])); ++i) {
423 if (a > b)
return +1;
424 if (a < b)
return -1;
426 if (i < count && str1[i])
return +1;
427 if (i < count && str2[i])
return -1;
443 _In_reads_or_z_opt_(count1)
const T* str1, _In_
size_t count1,
444 _In_reads_or_z_opt_(count2)
const T* str2, _In_
size_t count2,
445 _In_
const std::locale& locale)
447 _Assume_(str1 || !count1);
448 _Assume_(str2 || !count2);
449 auto& collate = std::use_facet<std::collate<T>>(locale);
450 return collate.compare(str1, str1 + count1, str2, str2 + count2);
461 template <
class T1,
class T2>
462 inline int stricmp(_In_z_
const T1* str1, _In_z_
const T2* str2, _In_
const std::locale& locale)
466 size_t i; T1 a; T2 b;
467 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
468 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
469 for (i = 0; (a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i])); i++) {
470 if (a > b)
return +1;
471 if (a < b)
return -1;
473 if (str1[i])
return +1;
474 if (str2[i])
return -1;
487 template <
class T1,
class T2>
488 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)
490 _Assume_(str1 || !count);
491 _Assume_(str2 || !count);
492 size_t i; T1 a; T2 b;
493 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
494 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
495 for (i = 0; i < count && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
496 if (a > b)
return +1;
497 if (a < b)
return -1;
499 if (i < count && str1[i])
return +1;
500 if (i < count && str2[i])
return -1;
514 template <
class T1,
class T2>
516 _In_reads_or_z_opt_(count1)
const T1* str1, _In_
size_t count1,
517 _In_reads_or_z_opt_(count2)
const T2* str2, _In_
size_t count2,
518 _In_
const std::locale& locale)
520 _Assume_(str1 || !count1);
521 _Assume_(str2 || !count2);
522 size_t i; T1 a; T2 b;
523 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
524 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
525 for (i = 0; i < count1 && i < count2 && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
526 if (a > b)
return +1;
527 if (a < b)
return -1;
529 if (i < count1 && str1[i])
return +1;
530 if (i < count2 && str2[i])
return -1;
542 template <
class T1,
class T2>
543 inline size_t strstr(
544 _In_z_
const T1* str,
545 _In_z_
const T2* sample)
549 for (
size_t offset = 0;; ++offset) {
550 for (
size_t i = offset, j = 0;; ++i, ++j) {
555 if (str[i] != sample[j])
570 template <
class T1,
class T2>
571 inline size_t strnstr(
572 _In_reads_or_z_opt_(count)
const T1* str,
574 _In_z_
const T2* sample)
576 _Assume_(str || !count);
578 for (
size_t offset = 0;; ++offset) {
579 for (
size_t i = offset, j = 0;; ++i, ++j) {
582 if (i >= count || !str[i])
584 if (str[i] != sample[j])
598 template <
class T1,
class T2>
599 inline size_t stristr(
600 _In_z_
const T1* str,
601 _In_z_
const T2* sample,
602 _In_
const std::locale& locale)
606 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
607 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
608 for (
size_t offset = 0;; ++offset) {
609 for (
size_t i = offset, j = 0;; ++i, ++j) {
614 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
629 template <
class T1,
class T2>
630 inline size_t strnistr(
631 _In_reads_or_z_opt_(count)
const T1* str,
633 _In_z_
const T2* sample,
634 _In_
const std::locale& locale)
636 _Assume_(str || !count);
638 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
639 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
640 for (
size_t offset = 0;; ++offset) {
641 for (
size_t i = offset, j = 0;; ++i, ++j) {
644 if (i >= count || !str[i])
646 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
660 template <
class T1,
class T2>
661 inline size_t strcpy(
662 _Out_writes_z_(_String_length_(src) + 1) T1* dst,
663 _In_z_
const T2* src)
665 _Assume_(dst && src);
666 for (
size_t i = 0; ; ++i) {
667 if ((dst[i] = src[i]) == 0)
681 template <
class T1,
class T2>
682 inline size_t strncpy(
683 _Out_writes_(count) _Post_maybez_ T1* dst,
684 _In_reads_or_z_opt_(count)
const T2* src, _In_
size_t count)
686 _Assume_(dst && src || !count);
687 for (
size_t i = 0; ; ++i) {
690 if ((dst[i] = src[i]) == 0)
705 template <
class T1,
class T2>
706 inline size_t strncpy(
707 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_
size_t count_dst,
708 _In_reads_or_z_opt_(count_src)
const T2* src, _In_
size_t count_src)
710 _Assume_(dst || !count_dst);
711 _Assume_(src || !count_src);
712 for (
size_t i = 0; ; ++i)
716 if (i >= count_src) {
720 if ((dst[i] = src[i]) == 0)
733 template <
class T1,
class T2>
734 inline size_t strcat(
735 _In_z_ _Out_writes_z_(_String_length_(dst) + _String_length_(src) + 1) T1* dst,
736 _In_z_
const T2* src)
738 _Assume_(dst && src);
739 for (
size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
740 if ((dst[j] = src[i]) == 0)
754 template <
class T1,
class T2>
755 inline size_t strncat(
756 _Out_writes_(count) _Post_maybez_ T1* dst,
757 _In_reads_or_z_opt_(count)
const T2* src, _In_
size_t count)
759 _Assume_(dst && src || !count);
760 for (
size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
763 if ((dst[j] = src[i]) == 0)
778 template <
class T1,
class T2>
779 inline size_t strncat(
780 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_
size_t count_dst,
781 _In_reads_or_z_opt_(count_src)
const T2* src, _In_
size_t count_src)
783 _Assume_(dst || !count_dst);
784 _Assume_(src || !count_src);
785 for (
size_t i = 0, j = stdex::strnlen<T1>(dst, count_dst); ; ++i, ++j)
789 if (i >= count_src) {
793 if ((dst[j] = src[i]) == 0)
809 inline _Check_return_ _Ret_maybenull_z_ T* strdup(_In_opt_z_
const T* str)
813 size_t count = strlen(str) + 1;
814 T* dst =
new T[count];
815 strncpy(dst, count, str, SIZE_MAX);
831 inline _Ret_z_ T* strndup(
832 _In_reads_or_z_opt_(count)
const T* str,
835 T* dst =
new T[count];
836 strncpy(dst, count, str, SIZE_MAX);
850 inline size_t crlf2nl(_Out_writes_z_(strlen(src)) T* dst, _In_z_
const T* src)
855 for (i = j = 0; src[j];) {
856 if (src[j] !=
'\r' || src[j + 1] !=
'\n')
873 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
874 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &dst, _In_z_
const _Elem* src)
877 _Assume_(src != dst.c_str());
879 dst.reserve(strlen(src));
880 for (
size_t j = 0; src[j];) {
881 if (src[j] !=
'\r' || src[j + 1] !=
'\n')
895 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
896 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
899 for (i = j = 0, n = str.size(); j < n;) {
900 if (str[j] !=
'\r' || str[j + 1] !=
'\n')
911 template <
class T,
class T_bin>
912 inline T_bin strtoint(
913 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
914 _Out_opt_
size_t* end,
916 _Out_ uint8_t& flags)
918 _Assume_(str || !count);
919 _Assume_(radix == 0 || 2 <= radix && radix <= 36);
922 T_bin value = 0, digit,
924 max_ui_pre1, max_ui_pre2;
930 if (i >= count || !str[i])
goto error;
931 if (!isspace(str[i]))
break;
938 if (i >= count || !str[i])
goto error;
940 else if (str[i] ==
'-') {
943 if (i >= count || !str[i])
goto error;
948 if (str[i] ==
'0' && i + 1 < count && (str[i + 1] ==
'x' || str[i + 1] ==
'X')) {
950 if (i >= count || !str[i])
goto error;
957 if (i >= count || !str[i])
goto error;
958 if (str[i] ==
'x' || str[i] ==
'X') {
961 if (i >= count || !str[i])
goto error;
971 max_ui_pre1 = max_ui / (T_bin)radix;
972 max_ui_pre2 = max_ui % (T_bin)radix;
974 if (
'0' <= str[i] && str[i] <=
'9')
975 digit = (T_bin)str[i] -
'0';
976 else if (
'A' <= str[i] && str[i] <=
'Z')
977 digit = (T_bin)str[i] -
'A' +
'\x0a';
978 else if (
'a' <= str[i] && str[i] <=
'z')
979 digit = (T_bin)str[i] -
'a' +
'\x0a';
982 if (digit >= (T_bin)radix)
985 if (value < max_ui_pre1 ||
986 (value == max_ui_pre1 && digit <= max_ui_pre2))
987 value = value * (T_bin)radix + digit;
994 if (i >= count || !str[i])
1014 template <
class T,
class T_bin>
1016 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1017 _Out_opt_
size_t* end,
1023 switch (
sizeof(T_bin)) {
1025 value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags);
1026 if ((flags & 0x01) && (value & 0x80)) {
1030 return (flags & 0x02) ?
1031 (flags & 0x01) ? (T_bin)0x80 : (T_bin)0x7f :
1032 (flags & 0x01) ? -value : value;
1035 value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags);
1036 if ((flags & 0x01) && (value & 0x8000)) {
1040 return (flags & 0x02) ?
1041 (flags & 0x01) ? (T_bin)0x8000 : (T_bin)0x7fff :
1042 (flags & 0x01) ? -value : value;
1045 value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags);
1046 if ((flags & 0x01) && (value & 0x80000000)) {
1050 return (flags & 0x02) ?
1051 (flags & 0x01) ? (T_bin)0x80000000 : (T_bin)0x7fffffff :
1052 (flags & 0x01) ? -value : value;
1055 value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags);
1056 if ((flags & 0x01) && (value & 0x8000000000000000)) {
1060 return (flags & 0x02) ?
1061 (flags & 0x01) ? (T_bin)0x8000000000000000 : (T_bin)0x7fffffffffffffff :
1062 (flags & 0x01) ? -value : value;
1065 throw std::invalid_argument(
"Unsupported bit length");
1079 template <
class T,
class T_bin>
1080 inline T_bin strtouint(
1081 _In_reads_or_z_opt_(count)
const T* str,
1083 _Out_opt_
size_t* end,
1089 switch (
sizeof(T_bin)) {
1090 case 1: value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags);
break;
1091 case 2: value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags);
break;
1092 case 4: value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags);
break;
1093 case 8: value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags);
break;
1094 default:
throw std::invalid_argument(
"Unsupported bit length");
1097 return (flags & 0x02) ?
1098 (flags & 0x01) ? (T_bin)0 : (T_bin)-1 :
1099 (flags & 0x01) ? ~value : value;
1113 inline int32_t strto32(
1114 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1115 _Out_opt_
size_t* end,
1118 return strtoint<T, int32_t>(str, count, end, radix);
1132 inline int64_t strto64(
1133 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1134 _Out_opt_
size_t* end,
1137 return strtoint<T, int64_t>(str, count, end, radix);
1152 inline intptr_t strtoi(
1153 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1154 _Out_opt_
size_t* end,
1157#if defined(_WIN64) || defined(__LP64__)
1158 return (intptr_t)strto64(str, count, end, radix);
1160 return (intptr_t)strto32(str, count, end, radix);
1175 inline uint32_t strtou32(
1176 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1177 _Out_opt_
size_t* end,
1180 return strtouint<T, uint32_t>(str, count, end, radix);
1194 inline uint64_t strtou64(
1195 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1196 _Out_opt_
size_t* end,
1199 return strtouint<T, uint64_t>(str, count, end, radix);
1214 inline size_t strtoui(
1215 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count,
1216 _Out_opt_
size_t* end,
1219#if defined(_WIN64) || defined(__LP64__)
1220 return (
size_t)strtou64(str, count, end, radix);
1222 return (
size_t)strtou32(str, count, end, radix);
1227 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)
1232#pragma warning(suppress: 4996)
1233 r = _vsnprintf_l(str, capacity, format, locale, arg);
1235 r = ::vsnprintf(str, capacity, format, arg);
1237 if (r == -1 && strnlen(str, capacity) == capacity) {
1239 capacity += std::max<size_t>(capacity / 8, 0x80);
1240 if (capacity > INT_MAX)
1241 throw std::invalid_argument(
"string too big");
1242 return (
int)capacity;
1247 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)
1252#pragma warning(suppress: 4996)
1253 r = _vsnwprintf_l(str, capacity, format, locale, arg);
1255 r = vswprintf(str, capacity, format, arg);
1257 if (r == -1 && strnlen(str, capacity) == capacity) {
1259 capacity += std::max<size_t>(capacity / 8, 0x80);
1260 if (capacity > INT_MAX)
1261 throw std::invalid_argument(
"string too big");
1262 return (
int)capacity;
1276 template<
class _Elem,
class _Traits,
class _Ax>
1277 inline void 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)
1279 _Elem buf[1024/
sizeof(_Elem)];
1282 int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg);
1285 str.append(buf, count);
1287 for (
size_t capacity = 2*1024/
sizeof(_Elem);; capacity *= 2) {
1289 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
1290 count = vsnprintf(buf_dyn.get(), capacity - 1, format, locale, arg);
1292 str.append(buf_dyn.get(), count);
1306 template<
class _Elem,
class _Traits,
class _Ax>
1307 inline void appendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2)
const _Elem *format, _In_opt_ locale_t locale, ...)
1310 va_start(arg, locale);
1311 vappendf(str, format, locale, arg);
1323 template<
class _Elem,
class _Traits,
class _Ax>
1324 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)
1327 vappendf(str, format, locale, arg);
1337 template<
class _Elem,
class _Traits,
class _Ax>
1338 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, ...)
1341 va_start(arg, locale);
1342 vsprintf(str, format, locale, arg);
1355 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1356 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)
1358 std::basic_string<_Elem, _Traits, _Ax> str;
1359 vappendf(str, format, locale, arg);
1371 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1372 inline std::basic_string<_Elem, _Traits, _Ax> sprintf(_In_z_ _Printf_format_string_params_(2)
const _Elem *format, _In_opt_ locale_t locale, ...)
1375 va_start(arg, locale);
1376 auto str = vsprintf(format, locale, arg);
1382 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)
1385 return _strftime_l(str, capacity, format, time, locale);
1387 return strftime_l(str, capacity, format, time, locale);
1391 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)
1394 return _wcsftime_l(str, capacity, format, time, locale);
1396 return wcsftime_l(str, capacity, format, time, locale);
1409 template<
class _Elem,
class _Traits,
class _Ax>
1410 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)
1412 _Elem buf[1024/
sizeof(_Elem)];
1415 size_t count = strftime(buf, _countof(buf), format, time, locale);
1418 str.append(buf, count);
1420 for (
size_t capacity = 2*1024/
sizeof(_Elem);; capacity *= 2) {
1422 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
1423 count = strftime(buf_dyn.get(), capacity, format, time, locale);
1425 str.append(buf_dyn.get(), count);
1440 template<
class _Elem,
class _Traits,
class _Ax>
1441 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)
1444 strcatftime(str, format, time, locale);
1457 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1458 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)
1460 std::basic_string<_Elem, _Traits, _Ax> str;
1461 strcatftime(str, format, time, locale);
1471 inline void uuidtostr(_Out_writes_z_(39)
char str[39], _In_
const uuid_t&
id)
1474 _snprintf_s_l(str, 39, _TRUNCATE,
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
1477 static_cast<unsigned int>(
id.Data2),
1478 static_cast<unsigned int>(
id.Data3),
1479 static_cast<unsigned int>(
id.Data4[0]),
static_cast<unsigned int>(
id.Data4[1]),
1480 static_cast<unsigned int>(
id.Data4[2]),
static_cast<unsigned int>(
id.Data4[3]),
static_cast<unsigned int>(
id.Data4[4]),
static_cast<unsigned int>(
id.Data4[5]),
static_cast<unsigned int>(
id.Data4[6]),
static_cast<unsigned int>(
id.Data4[7]));
1482 *
reinterpret_cast<const uint32_t*
>(&
id[0]),
1483 static_cast<unsigned int>(*
reinterpret_cast<const uint16_t*
>(&
id[4])),
1484 static_cast<unsigned int>(*
reinterpret_cast<const uint16_t*
>(&
id[6])),
1485 static_cast<unsigned int>(
id[8]),
static_cast<unsigned int>(
id[9]),
1486 static_cast<unsigned int>(
id[10])),
static_cast<unsigned int>(
id[11]),
static_cast<unsigned int>(
id[12]),
static_cast<unsigned int>(
id)),
static_cast<unsigned int>(
id[14]),
static_cast<unsigned int>(
id[15]));
1496 inline void uuidtostr(_Out_writes_z_(39)
wchar_t str[39], _In_
const uuid_t&
id)
1499 _snwprintf_s_l(str, 39, _TRUNCATE, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
1502 static_cast<unsigned int>(
id.Data2),
1503 static_cast<unsigned int>(
id.Data3),
1504 static_cast<unsigned int>(
id.Data4[0]),
static_cast<unsigned int>(
id.Data4[1]),
1505 static_cast<unsigned int>(
id.Data4[2]),
static_cast<unsigned int>(
id.Data4[3]),
static_cast<unsigned int>(
id.Data4[4]),
static_cast<unsigned int>(
id.Data4[5]),
static_cast<unsigned int>(
id.Data4[6]),
static_cast<unsigned int>(
id.Data4[7]));
1507 *
reinterpret_cast<const uint32_t*
>(&
id[0]),
1508 static_cast<unsigned int>(*
reinterpret_cast<const uint16_t*
>(&
id[4])),
1509 static_cast<unsigned int>(*
reinterpret_cast<const uint16_t*
>(&
id[6])),
1510 static_cast<unsigned int>(
id[8]),
static_cast<unsigned int>(
id[9]),
1511 static_cast<unsigned int>(
id[10])),
static_cast<unsigned int>(
id[11]),
static_cast<unsigned int>(
id[12]),
static_cast<unsigned int>(
id)),
static_cast<unsigned int>(
id[14]),
static_cast<unsigned int>(
id[15]));
1523 inline void strlwr(_Inout_z_ T* str, _In_
const std::locale& locale)
1526 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1527 for (
size_t i = 0; str[i]; ++i)
1528 str[i] = ctype.tolower(str[i]);
1540 inline void strlwr(_Inout_updates_z_(count) T* str, _In_
size_t count, _In_
const std::locale& locale)
1542 _Assume_(str || !count);
1543 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1544 for (
size_t i = 0; i < count && str[i]; ++i)
1545 str[i] = ctype.tolower(str[i]);
1556 inline void strupr(_Inout_z_ T* str, _In_
const std::locale& locale)
1559 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1560 for (
size_t i = 0; str[i]; ++i)
1561 str[i] = ctype.toupper(str[i]);
1573 inline void strupr(_Inout_updates_z_(count) T* str, _In_
size_t count, _In_
const std::locale& locale)
1575 _Assume_(str || !count);
1576 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1577 for (
size_t i = 0; i < count && str[i]; ++i)
1578 str[i] = ctype.toupper(str[i]);
1588 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1589 inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_
const std::locale& locale)
1591 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
1592 for (
size_t i = 0; i < str.size(); ++i)
1593 str[i] = ctype.toupper(str[i]);
1605 inline size_t ltrim(
1606 _Inout_z_count_(count) T* str, _In_
size_t count,
1607 _In_
const std::locale& locale)
1609 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1610 for (
size_t i = 0;; ++i) {
1612 if (count) str[0] = 0;
1619 if (!ctype.is(ctype.space, str[i])) {
1621 return strnlen(str, count);
1622 size_t n = count != SIZE_MAX ? strncpy(str, str + i, count - i) : strcpy(str, str + i);
1634 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1635 inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_
const std::locale& locale)
1637 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
1643 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }));
1655 inline size_t rtrim(
1656 _Inout_z_count_(count) T* str, _In_
size_t count,
1657 _In_
const std::locale& locale)
1659 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
1660 for (
size_t i = 0, j = 0;;) {
1661 if (i >= count || !str[i]) {
1662 if (j < count) str[j] = 0;
1665 if (!ctype.is(ctype.space, str[i]))
1677 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1678 static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_
const std::locale& locale)
1680 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
1685 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
1699 _Inout_z_count_(count) T* str, _In_
size_t count,
1700 _In_
const std::locale& locale)
1702 return ltrim(str, rtrim(str, count, locale), locale);
1710 template<
class _Elem,
class _Traits = std::
char_traits<_Elem>,
class _Ax = std::allocator<_Elem>>
1711 static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_
const std::locale& locale)
1713 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
1719 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }));
1724 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
Deleter for unique_ptr using free_locale.
Definition string.hpp:62
void operator()(locale_t locale) const
Delete a pointer.
Definition string.hpp:66