10#include "./type_traits.hpp"
11#include "./sstream.hpp"
12#include "./cstdint.hpp"
40 typedef std::size_t size_t;
43 using std::basic_string;
44 using std::char_traits;
51 namespace string_detail
67 using namespace std_dummy;
70 typedef char _yes_type;
76#if defined(LLONG_MIN) || defined(LLONG_MAX)
77 typedef long long _long_long_type;
78 typedef unsigned long long _unsigned_long_long_type;
80 typedef long _long_long_type;
81 typedef unsigned long _unsigned_long_long_type;
85 typedef _long_long_type(*_strtoll_type)(
const char*,
char**, int);
87 _yes_type _strtoll_tester(_strtoll_type);
88 _no_type _strtoll_tester(...);
90 typedef _long_long_type(*_wcstoll_type)(
const wchar_t*,
wchar_t**, int);
92 _yes_type _wcstoll_tester(_wcstoll_type);
93 _no_type _wcstoll_tester(...);
95 typedef _unsigned_long_long_type(*_strtoull_type)(
const char*,
char**, int);
97 _yes_type _strtoull_tester(_strtoull_type);
98 _no_type _strtoull_tester(...);
100 typedef _unsigned_long_long_type(*_wcstoull_type)(
const wchar_t*,
wchar_t**, int);
102 _yes_type _wcstoull_tester(_wcstoull_type);
103 _no_type _wcstoull_tester(...);
105 typedef long double(*_strtold_type)(
const char*,
char**);
107 _yes_type _strtold_tester(_strtold_type);
108 _no_type _strtold_tester(...);
110 typedef long double(*_wcstold_type)(
const wchar_t*,
wchar_t**);
112 _yes_type _wcstold_tester(_wcstold_type);
113 _no_type _wcstold_tester(...);
116 using std_cpp11::strtoll;
117 using std_cpp11::wcstoll;
118 using std_cpp11::strtoull;
119 using std_cpp11::wcstoull;
120 using std_cpp11::strtold;
121 using std_cpp11::wcstold;
124 struct _strtoll_present
126 static const bool value =
sizeof(_strtoll_tester(&strtoll)) ==
sizeof(_yes_type);
129 struct _wcstoll_present
131 static const bool value =
sizeof(_wcstoll_tester(&wcstoll)) ==
sizeof(_yes_type);
134 struct _strtoull_present
136 static const bool value =
sizeof(_strtoull_tester(&strtoull)) ==
sizeof(_yes_type);
139 struct _wcstoull_present
141 static const bool value =
sizeof(_wcstoull_tester(&wcstoull)) ==
sizeof(_yes_type);
144 struct _strtold_present
146 static const bool value =
sizeof(_strtold_tester(&strtold)) ==
sizeof(_yes_type);
149 struct _wcstold_present
151 static const bool value =
sizeof(_wcstold_tester(&wcstold)) ==
sizeof(_yes_type);
154 using std_cpp11::swprintf;
156 _yes_type _has_4arg_swprintf_tester(
int);
157 _no_type _has_4arg_swprintf_tester(
float);
159 struct _has_4arg_swprintf
161 static const bool value =
162 sizeof(_has_4arg_swprintf_tester(swprintf(_declptr<wchar_t>(), 42, _declptr<wchar_t>(), 0 ))) ==
sizeof(_yes_type);
165 using std_cpp11::snprintf;
167 _yes_type _has_4arg_snprintf_tester(
int);
168 _no_type _has_4arg_snprintf_tester(
float);
170 struct _has_4arg_snprintf
172 static const bool value =
173 sizeof(_has_4arg_snprintf_tester(
174 snprintf(_declptr<char>(), *_declptr<std::size_t>(), _declptr<const char>(), 0 )
175 )) ==
sizeof(_yes_type);
180 template<
bool _IsSigned>
181 struct _str_to_integral_chooser_impl
183 typedef long int type;
184 static long int call(
const char* str,
char** endptr,
int base)
192 long int value = strtol(str, endptr, base);
199 if(errno == 0 && _str_to_integral_chooser_impl::check(value))
202 endptr ? (*endptr - str) : (str - str + strlen(str));
203 string positive_str(str, str + length);
204 bool is_negative = (value == LONG_MIN);
207 positive_str.replace(positive_str.find_first_of(
'-'), 1, 1,
'+');
209 unsigned long int uvalue = strtoul(positive_str.c_str(), NULL, base);
210 unsigned long int _zero = 0;
212 if(errno == 0 && uvalue >
static_cast<unsigned long int>(is_negative ? _zero - (numeric_limits<long int>::min)() : (numeric_limits<long int>::max)() ))
216 if (errno && !value && endptr)
218 for (
const char *it = str; it != *endptr; it++)
220 if (isdigit(*it) && *it !=
'0')
230 static long int call(
const wchar_t* str,
wchar_t** endptr,
int base)
238 long int value = wcstol(str, endptr, base);
245 if(errno == 0 && _str_to_integral_chooser_impl::check(value))
248 endptr ? (*endptr - str) : (str - str + wcslen(str));
249 wstring positive_str(str, str + length);
250 bool is_negative = (value == LONG_MIN);
253 positive_str.replace(positive_str.find_first_of(L
'-'), 1, 1, L
'+');
255 unsigned long int uvalue = wcstoul(positive_str.c_str(), NULL, base);
256 unsigned long int _zero = 0;
258 if(errno == 0 && uvalue >
static_cast<unsigned long int>(is_negative ? _zero - (numeric_limits<long int>::min)() : (numeric_limits<long int>::max)() ))
262 if (errno && !value && endptr)
264 for (
const wchar_t *it = str; it != *endptr; it++)
266 if (iswdigit(*it) && *it != L
'0')
276 static bool check(
long int _value)
280 return ((_value == LONG_MAX || _value == LONG_MIN));
282 return ((_value == LONG_MAX || _value == -LONG_MAX));
286 return ((_value == -LONG_MIN || _value == LONG_MIN));
288 return ((_value == (std::numeric_limits<long int>::min)() || _value == (std::numeric_limits<long int>::max)()));
295 struct _snprintf_impl
297 template<
class _ArgT>
298 static int call(
char* buffer, std::size_t buf_size,
const char* format, _ArgT arg)
301 return snprintf(buffer, buf_size, format, arg);
306 struct _snprintf_impl<false>
308 template<
class _ArgT>
309 static int call(
char* buffer, std::size_t,
const char* format, _ArgT arg)
312 return sprintf(buffer, format, arg);
316 template<
class _ArgT>
318 void _snprintf4_std_impl(
char* buffer, std::size_t len,
const char* format, _ArgT arg)
320 _snprintf_impl<string_detail::_has_4arg_snprintf::value>::call(buffer, len, format, arg);
324 struct _str_to_integral_chooser_impl<false>
326 typedef unsigned long int type;
327 static unsigned long int call(
const char* str,
char** endptr,
int base)
335 unsigned long int value = strtoul(str, endptr, base);
346 if(errno == 0 && _str_to_integral_chooser_impl::check(value))
349 bool bug_present =
true;
351 string ulong_max_str;
354 _snprintf4_std_impl(buf,
sizeof(buf),
"%lu", ULONG_MAX);
357 ss << setbase(base) << ULONG_MAX;
358 if(std::string(str) == ss.str())
361 ulong_max_str = string(buf);
363 const char *ulong_max_cstr = ulong_max_str.c_str();
365 string overflow_str(ulong_max_str.length() + 1,
'0');
366 string::size_type of_size = overflow_str.length();
369 (ulong_max_cstr[of_size - 2] ==
'L' && ulong_max_cstr[of_size - 3] ==
'U') ||
370 (ulong_max_cstr[of_size - 3] ==
'L' && ulong_max_cstr[of_size - 2] ==
'U')
373 memcpy(&overflow_str[0], ulong_max_cstr, of_size - 3);
374 overflow_str[of_size - 2] =
'U';
375 overflow_str[of_size - 1] =
'L';
379 memcpy(&overflow_str[0], ulong_max_cstr, of_size - 1);
382 unsigned long overflow_value = strtoul(overflow_str.c_str(), NULL, 10);
384 if(overflow_value == ULONG_MAX && errno == ERANGE)
387 if(bug_present) errno = ERANGE;
394 static unsigned long int call(
const wchar_t* str,
wchar_t** endptr,
int base)
402 unsigned long int value = wcstoul(str, endptr, base);
413 if(errno == 0 && _str_to_integral_chooser_impl::check(value))
416 bool bug_present =
true;
418 wstring ulong_max_str;
421 ss << setbase(base) << ULONG_MAX;
422 string ulong_max_str_base = ss.str();
424 if(wstring(str) == wstring(ulong_max_str_base.c_str(), ulong_max_str_base.c_str() + ulong_max_str_base.length()))
428 _snprintf4_std_impl(buf,
sizeof(buf),
"%lu", ULONG_MAX);
430 wstring::size_type length = strlen(buf);
432 ulong_max_str = wstring(&buf[0], &buf[length]);
434 const wchar_t *ulong_max_cstr = ulong_max_str.c_str();
436 wstring overflow_str(ulong_max_str.length() + 1, L
'0');
437 wstring::size_type of_size = overflow_str.length();
440 (ulong_max_cstr[of_size - 2] == L
'L' && ulong_max_cstr[of_size - 3] == L
'U') ||
441 (ulong_max_cstr[of_size - 3] == L
'L' && ulong_max_cstr[of_size - 2] == L
'U')
444 memcpy(&overflow_str[0], ulong_max_cstr, (of_size - 3) *
sizeof(
wchar_t));
445 overflow_str[of_size - 2] = L
'U';
446 overflow_str[of_size - 1] = L
'L';
450 memcpy(&overflow_str[0], ulong_max_cstr, (of_size - 1) *
sizeof(
wchar_t));
453 unsigned long overflow_value = wcstoul(overflow_str.c_str(), NULL, 10);
455 if(overflow_value == ULONG_MAX && errno == ERANGE)
458 if(bug_present) errno = ERANGE;
465 static bool check(
unsigned long int _value)
468 return ((_value == ULONG_MAX));
470 return ((_value == (std::numeric_limits<unsigned long int>::max)()));
476 struct _str_to_integral_chooser
478 typedef _str_to_integral_chooser_impl<is_signed<_Tp>::value> impl;
481 template<
class _Tp,
unsigned long _N>
486 value = _type_cs_len<_Tp, _N / (
unsigned long)(10)>::value + 1
491 struct _type_cs_len<_Tp, 0>
499 template<
class _Tp,
bool _HasQuietNaN,
bool _HasSignalingNaN>
500 struct _not_a_number_impl
502 static _Tp NaN() {
return std::numeric_limits<_Tp>::quiet_NaN();}
506 struct _not_a_number_impl<_Tp, false, true>
508 static _Tp NaN() {
return std::numeric_limits<_Tp>::signaling_NaN(); }
512 struct _not_a_number_impl<_Tp, false, false>
514 static _Tp NaN() {
typedef _Tp type;
return type(); }
520 typedef _not_a_number_impl<_Tp, std::numeric_limits<_Tp>::has_quiet_NaN, std::numeric_limits<_Tp>::has_signaling_NaN> impl;
523 template<
class _Tp,
bool _HasInfinity>
524 struct _infinity_impl
526 static _Tp inf() {
return std::numeric_limits<_Tp>::infinity(); }
530 struct _infinity_impl<_Tp, false>
532 static _Tp inf() {
return (std::numeric_limits<_Tp>::max)(); }
538 typedef _infinity_impl<_Tp, std::numeric_limits<_Tp>::has_infinity> impl;
541#if defined(LLONG_MAX) || defined(LLONG_MIN)
544 struct _cs_to_signed_ll
547 string_detail::_long_long_type
548 call(
const char *nptr,
char **endptr,
int base)
551 const char *_s = nptr;
552 string_detail::_unsigned_long_long_type acc;
554 string_detail::_unsigned_long_long_type cutoff;
555 int neg = 0, any, cutlim;
564 }
while (isspace(_c));
571 if ((base == 0 || base == 16) &&
572 _c ==
'0' && (*_s ==
'x' || *_s ==
'X')) {
578 base = _c ==
'0' ? 8 : 10;
597 cutoff = neg ? LLONG_MIN : LLONG_MAX;
598 cutlim = cutoff % (string_detail::_unsigned_long_long_type) base;
599 cutoff /= (string_detail::_unsigned_long_long_type) base;
600 for (acc = 0, any = 0;; _c = *_s++) {
603 else if (isalpha(_c))
604 _c -= isupper(_c) ?
'A' - 10 :
'a' - 10;
609 if (any < 0 || acc > cutoff || (acc == cutoff && _c > cutlim))
618 acc = neg ? LLONG_MIN : LLONG_MAX;
622 acc =
static_cast<string_detail::_unsigned_long_long_type
>(
static_cast<string_detail::_unsigned_long_long_type
>(0) - acc);
624 *endptr = (
char *) (any ? _s - 1 : nptr);
630 struct _cs_to_signed_ll<true>
634 string_detail::_long_long_type
635 call(
const _Tp *nptr,
char **endptr,
int base)
640 string_detail::_long_long_type value = strtoll(nptr, endptr, base);
644 return _cs_to_signed_ll<false>::call(nptr, endptr, base);
652 struct _wcs_to_signed_ll
655 string_detail::_long_long_type
656 call(
const wchar_t *nptr,
wchar_t **endptr,
int base)
659 const wchar_t *_s = nptr;
660 string_detail::_unsigned_long_long_type acc;
662 string_detail::_unsigned_long_long_type cutoff;
663 int neg = 0, any, cutlim;
665 (void)&acc; (void)&cutoff;
676 }
while (isspace(_c));
683 if ((base == 0 || base == 16) &&
684 _c == L
'0' && (*_s == L
'x' || *_s == L
'X')) {
690 base = _c == L
'0' ? 8 : 10;
709 cutoff = neg ? LLONG_MIN : LLONG_MAX;
710 cutlim = (int)(cutoff % base);
711 cutoff /= (string_detail::_unsigned_long_long_type) base;
712 for (acc = 0, any = 0;; _c = *_s++) {
715 else if (isalpha(_c))
716 _c -= isupper(_c) ? L
'A' - 10 : L
'a' - 10;
721 if (any < 0 || acc > cutoff || (acc == cutoff && _c > cutlim))
730 acc = neg ? LLONG_MIN : LLONG_MAX;
734 acc =
static_cast<string_detail::_unsigned_long_long_type
>(
static_cast<string_detail::_unsigned_long_long_type
>(0) - acc);
736 *endptr = (
wchar_t *) (any ? _s - 1 : nptr);
742 struct _wcs_to_signed_ll<true>
746 string_detail::_long_long_type
747 call(
const _Tp *nptr,
wchar_t **endptr,
int base)
752 string_detail::_long_long_type value = wcstoll(nptr, endptr, base);
756 return _wcs_to_signed_ll<false>::call(nptr, endptr, base);
764 struct _cs_to_unsigned_ll
767 string_detail::_unsigned_long_long_type
768 call(
const char *nptr,
char **endptr,
int base)
771 const char *_s = nptr;
772 string_detail::_unsigned_long_long_type acc;
774 string_detail::_unsigned_long_long_type cutoff;
775 int neg = 0, any, cutlim;
782 }
while (isspace(_c));
789 if ((base == 0 || base == 16) &&
790 _c ==
'0' && (*_s ==
'x' || *_s ==
'X')) {
796 base = _c ==
'0' ? 8 : 10;
797 cutoff = (string_detail::_unsigned_long_long_type) ULLONG_MAX / (string_detail::_unsigned_long_long_type) base;
798 cutlim = (string_detail::_unsigned_long_long_type) ULLONG_MAX % (string_detail::_unsigned_long_long_type) base;
799 for (acc = 0, any = 0;; _c = *_s++) {
802 else if (isalpha(_c))
803 _c -= isupper(_c) ?
'A' - 10 :
'a' - 10;
808 if (any < 0 || acc > cutoff || (acc == cutoff && _c > cutlim))
821 acc =
static_cast<string_detail::_unsigned_long_long_type
>(
static_cast<string_detail::_unsigned_long_long_type
>(0) - acc);
823 *endptr = (
char *) (any ? _s - 1 : nptr);
829 struct _cs_to_unsigned_ll<true>
833 string_detail::_unsigned_long_long_type
834 call(
const _Tp *nptr,
char **endptr,
int base)
838 return strtoull(nptr, endptr, base);
843 struct _wcs_to_unsigned_ll
846 string_detail::_unsigned_long_long_type
847 call(
const wchar_t *nptr,
wchar_t **endptr,
int base)
850 const wchar_t *_s = nptr;
851 string_detail::_unsigned_long_long_type acc;
853 string_detail::_unsigned_long_long_type cutoff;
854 int neg = 0, any, cutlim;
861 }
while (isspace(_c));
868 if ((base == 0 || base == 16) &&
869 _c == L
'0' && (*_s == L
'x' || *_s == L
'X')) {
875 base = _c ==
'0' ? 8 : 10;
876 cutoff = (string_detail::_unsigned_long_long_type) ULLONG_MAX / (string_detail::_unsigned_long_long_type) base;
877 cutlim = (string_detail::_unsigned_long_long_type) ULLONG_MAX % (string_detail::_unsigned_long_long_type) base;
878 for (acc = 0, any = 0;; _c = *_s++) {
881 else if (isalpha(_c))
882 _c -= isupper(_c) ? L
'A' - 10 : L
'a' - 10;
887 if (any < 0 || acc > cutoff || (acc == cutoff && _c > cutlim))
900 acc =
static_cast<string_detail::_unsigned_long_long_type
>(
static_cast<string_detail::_unsigned_long_long_type
>(0) - acc);
902 *endptr = (
wchar_t *) (any ? _s - 1 : nptr);
909 struct _wcs_to_unsigned_ll<true>
913 string_detail::_unsigned_long_long_type
914 call(
const _Tp *nptr,
wchar_t **endptr,
int base)
918 return wcstoull(nptr, endptr, base);
923 template<
bool _IsSigned>
924 struct _str_to_integral_chooser_impl_ll
926 typedef string_detail::_long_long_type type;
927 static string_detail::_long_long_type call(
const char* _str,
char** endptr,
int base)
929 typedef _cs_to_signed_ll<string_detail::_strtoll_present::value> impl;
931 return impl::call(_str, endptr, base);
934 static string_detail::_long_long_type call(
const wchar_t* _str,
wchar_t** endptr,
int base)
936 typedef _wcs_to_signed_ll<string_detail::_wcstoll_present::value> impl;
938 return impl::call(_str, endptr, base);
941 static bool check(
const string_detail::_long_long_type &_value)
945 return ((_value == LLONG_MAX || _value == LLONG_MIN));
947 return ((_value == LLONG_MAX || _value == -LLONG_MAX));
951 return ((_value == -LLONG_MIN || _value == LLONG_MIN));
953 return ((_value == (std::numeric_limits<string_detail::_long_long_type>::min)() || _value == (std::numeric_limits<string_detail::_long_long_type>::max)()));
960 struct _str_to_integral_chooser_impl_ll<false>
962 typedef string_detail::_unsigned_long_long_type type;
963 static string_detail::_unsigned_long_long_type call(
const char* _str,
char** endptr,
int base)
965 typedef _cs_to_unsigned_ll<string_detail::_strtoull_present::value> impl;
967 return impl::call(_str, endptr, base);
970 static string_detail::_unsigned_long_long_type call(
const wchar_t* _str,
wchar_t** endptr,
int base)
972 typedef _wcs_to_unsigned_ll<string_detail::_wcstoull_present::value> impl;
974 return impl::call(_str, endptr, base);
977 static bool check(
const string_detail::_unsigned_long_long_type &_value)
980 return ((_value == ULLONG_MAX));
982 return ((_value == (std::numeric_limits<string_detail::_unsigned_long_long_type>::max)()));
988 struct _str_to_integral_chooser_ll
990 typedef _str_to_integral_chooser_impl_ll<is_signed<_Tp>::value> impl;
993 template<
class _Tp,
string_detail::_
unsigned_
long_
long_type _N>
994 struct _type_cs_len_ll
998 value = _type_cs_len_ll<_Tp, _N / (string_detail::_unsigned_long_long_type)(10)>::value + 1
1003 struct _type_cs_len_ll<_Tp, 0>
1013 template <
class _Tp>
1014 inline _Tp _cs_to_integral(
const char *_str,
const char *&num_s_end,
int base = 10)
1016 typedef typename _str_to_integral_chooser<_Tp>::impl _str_to_integral;
1018 int last_errno = errno;
1021 typedef typename _str_to_integral::type large_value_type;
1022 large_value_type _value = _str_to_integral::call(_str, &endptr, base);
1024 if (_str_to_integral::check(_value) && errno == ERANGE)
1026 else if (_value >
static_cast<large_value_type
>((std::numeric_limits<_Tp>::max)()) || _value <
static_cast<large_value_type
>((std::numeric_limits<_Tp>::min)()))
1028 _value = (std::numeric_limits<_Tp>::max)();
1034 if (errno != last_errno)
1040 template <
class _Tp>
1041 inline _Tp _cs_to_integral(
const wchar_t *_str,
const wchar_t *&num_s_end,
int base = 10)
1043 typedef typename _str_to_integral_chooser<_Tp>::impl _str_to_integral;
1045 int last_errno = errno;
1047 wchar_t *endptr = 0;
1048 typedef typename _str_to_integral::type large_value_type;
1049 large_value_type _value = _str_to_integral::call(_str, &endptr, base);
1051 if (_str_to_integral::check(_value) && errno == ERANGE)
1053 else if (_value >
static_cast<large_value_type
>((std::numeric_limits<_Tp>::max)()) || _value <
static_cast<large_value_type
>((std::numeric_limits<_Tp>::min)()))
1055 _value = (std::numeric_limits<_Tp>::max)();
1061 if (errno != last_errno)
1067#if defined(LLONG_MAX) || defined(LLONG_MIN)
1068 template <
class _Tp>
1069 inline _Tp _cs_to_integral_ll(
const char *_str,
const char *&num_s_end,
int base)
1071 typedef typename _str_to_integral_chooser_ll<_Tp>::impl _str_to_integral;
1073 int last_errno = errno;
1076 typedef typename _str_to_integral::type large_value_type;
1077 large_value_type _value = _str_to_integral::call(_str, &endptr, base);
1079 if (_str_to_integral::check(_value) && errno == ERANGE)
1081 else if (_value >
static_cast<large_value_type
>((std::numeric_limits<_Tp>::max)()) || _value <
static_cast<large_value_type
>((std::numeric_limits<_Tp>::min)()))
1083 _value = (std::numeric_limits<_Tp>::max)();
1089 if (errno != last_errno)
1095 template <
class _Tp>
1096 inline _Tp _cs_to_integral_ll(
const wchar_t *_str,
const wchar_t *&num_s_end,
int base)
1098 typedef typename _str_to_integral_chooser_ll<_Tp>::impl _str_to_integral;
1100 int last_errno = errno;
1102 wchar_t *endptr = 0;
1103 typedef typename _str_to_integral::type large_value_type;
1104 large_value_type _value = _str_to_integral::call(_str, &endptr, base);
1106 if (_str_to_integral::check(_value) && errno == ERANGE)
1108 else if (_value >
static_cast<large_value_type
>((std::numeric_limits<_Tp>::max)()) || _value <
static_cast<large_value_type
>((std::numeric_limits<_Tp>::min)()))
1110 _value = (std::numeric_limits<_Tp>::max)();
1116 if (errno != last_errno)
1123 template <
class _Tp>
1124 inline long double _cs_to_floating_point(
const char *_str,
const char *&num_s_end)
1126 using namespace std;
1128 int last_errno = errno;
1131 double _value = strtod(_str, &endptr);
1134 if ((_value == HUGE_VAL || _value == -HUGE_VAL) && errno == ERANGE)
1136 if (errno == ERANGE)
1139 else if (_value >
static_cast<double>((std::numeric_limits<_Tp>::max)()) || _value <
static_cast<double>(-(std::numeric_limits<_Tp>::max)()))
1141 _value = (std::numeric_limits<_Tp>::max)();
1147 if (errno != last_errno)
1153 template <
class _Tp>
1154 inline long double _cs_to_floating_point(
const wchar_t *_str,
const wchar_t *&num_s_end)
1156 using namespace std;
1158 int last_errno = errno;
1160 wchar_t *endptr = 0;
1161 double _value = wcstod(_str, &endptr);
1164 if ((_value == HUGE_VAL || _value == -HUGE_VAL) && errno == ERANGE)
1166 if (errno == ERANGE)
1169 else if (_value >
static_cast<double>((std::numeric_limits<_Tp>::max)()) || _value <
static_cast<double>(-(std::numeric_limits<_Tp>::max)()))
1171 _value = (std::numeric_limits<_Tp>::max)();
1177 if (errno != last_errno)
1186 struct _cs_to_floating_point_ld
1190 call(
const _Tp *_str,
const char *&num_s_end)
1192 using namespace std;
1194 int last_errno = errno;
1197 long double _value = strtold(_str, &endptr);
1200 if ((_value == HUGE_VALL || _value == -HUGE_VALL) && errno == ERANGE)
1208 if (errno != last_errno)
1216 call(
const _Tp *_str,
const wchar_t *&num_s_end)
1218 using namespace std;
1220 int last_errno = errno;
1222 wchar_t *endptr = 0;
1223 long double _value = wcstold(_str, &endptr);
1226 if ((_value == HUGE_VALL || _value == -HUGE_VALL) && errno == ERANGE)
1234 if (errno != last_errno)
1242 struct _cs_to_floating_point_ld<false>
1245 _a_to_floating_point(
const char *_str)
1247 using namespace std;
1251 if (sscanf(_str,
"%Lf", &value) == EOF)
1254 long double fp_integer_part = 0.0L, fp_fractional_part = 0.0L;
1255 cstddef::size_t _i, length = strlen(_str);
1258 while (_str[_i] !=
'.') {
1259 fp_integer_part = fp_integer_part * 10.0L + (_str[_i] -
'0');
1266 while (!isdigit(_str[_i]) && _str[_i] !=
'.')
1269 while (_str[_i] !=
'.') {
1270 fp_fractional_part = (fp_fractional_part + (_str[_i] -
'0')) / 10.0L;
1274 value = fp_integer_part + fp_fractional_part;
1277 if(value > (numeric_limits<long double>::max)() || value < (numeric_limits<long double>::min)())
1287 _a_to_floating_point(
const wchar_t *_str)
1289 using namespace std;
1293 if (swscanf(_str, L
"%Lf", &value) == EOF)
1296 long double fp_integer_part = 0.0L, fp_fractional_part = 0.0L;
1297 cstddef::size_t _i, length = wcslen(_str);
1300 while (_str[_i] != L
'.') {
1301 fp_integer_part = fp_integer_part * 10.0L + (_str[_i] - L
'0');
1308 while (!isdigit(_str[_i]) && _str[_i] != L
'.')
1311 while (_str[_i] != L
'.') {
1312 fp_fractional_part = (fp_fractional_part + (_str[_i] - L
'0')) / 10.0L;
1316 value = fp_integer_part + fp_fractional_part;
1319 if (value > (numeric_limits<long double>::max)() || value < (numeric_limits<long double>::min)())
1329 _cs_to_long_double(
const char *_str,
char const **_ptr)
1331 using namespace std;
1336 return _a_to_floating_point(_str);
1340 while (isspace(*_p))
1343 if (*_p ==
'+' || *_p ==
'-')
1346 typedef _not_a_number<long double>::impl not_a_number_impl;
1347 typedef _infinity<long double>::impl infinity_impl;
1350 if ((_p[0] ==
'i' || _p[0] ==
'I')
1351 && (_p[1] ==
'n' || _p[1] ==
'N')
1352 && (_p[2] ==
'f' || _p[2] ==
'F'))
1354 if ((_p[3] ==
'i' || _p[3] ==
'I')
1355 && (_p[4] ==
'n' || _p[4] ==
'N')
1356 && (_p[5] ==
'i' || _p[5] ==
'I')
1357 && (_p[6] ==
't' || _p[6] ==
'T')
1358 && (_p[7] ==
'y' || _p[7] ==
'Y'))
1361 return infinity_impl::inf();
1366 return infinity_impl::inf();
1371 if ((_p[0] ==
'n' || _p[0] ==
'N')
1372 && (_p[1] ==
'a' || _p[1] ==
'A')
1373 && (_p[2] ==
'n' || _p[2] ==
'N'))
1379 while (*_p !=
'\0' && *_p !=
')')
1385 return not_a_number_impl::NaN();
1389 if (isdigit(*_p) || *_p ==
'.')
1392 while (isdigit(*_p) || (!got_dot && *_p ==
'.'))
1400 if (*_p ==
'e' || *_p ==
'E')
1404 if (_p[_i] ==
'+' || _p[_i] ==
'-')
1406 if (isdigit(_p[_i]))
1408 while (isdigit(_p[_i]))
1411 if (std::numeric_limits<long double>::max_exponent10 < _i)
1414 return (std::numeric_limits<long double>::max)();
1416 return _a_to_floating_point(_str);
1420 return _a_to_floating_point(_str);
1424 return not_a_number_impl::NaN();
1428 _cs_to_long_double(
const wchar_t *_str,
wchar_t const **_ptr)
1430 using namespace std;
1435 return _a_to_floating_point(_str);
1439 while (isspace(*_p))
1442 if (*_p == L
'+' || *_p == L
'-')
1445 typedef _not_a_number<long double>::impl not_a_number_impl;
1446 typedef _infinity<long double>::impl infinity_impl;
1449 if ((_p[0] == L
'i' || _p[0] == L
'I')
1450 && (_p[1] == L
'n' || _p[1] == L
'N')
1451 && (_p[2] == L
'f' || _p[2] == L
'F'))
1453 if ((_p[3] == L
'i' || _p[3] == L
'I')
1454 && (_p[4] == L
'n' || _p[4] == L
'N')
1455 && (_p[5] == L
'i' || _p[5] == L
'I')
1456 && (_p[6] == L
't' || _p[6] == L
'T')
1457 && (_p[7] == L
'y' || _p[7] == L
'Y'))
1460 return infinity_impl::inf();
1465 return infinity_impl::inf();
1470 if ((_p[0] == L
'n' || _p[0] == L
'N')
1471 && (_p[1] == L
'a' || _p[1] == L
'A')
1472 && (_p[2] == L
'n' || _p[2] == L
'N'))
1478 while (*_p != L
'\0' && *_p != L
')')
1484 return not_a_number_impl::NaN();
1488 if (isdigit(*_p) || *_p == L
'.')
1491 while (isdigit(*_p) || (!got_dot && *_p == L
'.'))
1499 if (*_p == L
'e' || *_p == L
'E')
1503 if (_p[_i] == L
'+' || _p[_i] == L
'-')
1505 if (isdigit(_p[_i]))
1507 while (isdigit(_p[_i]))
1510 if (std::numeric_limits<long double>::max_exponent10 < _i)
1513 return (std::numeric_limits<long double>::max)();
1515 return _a_to_floating_point(_str);
1519 return _a_to_floating_point(_str);
1523 return not_a_number_impl::NaN();
1527 call(
const char *_str,
const char *&num_s_end)
1529 int last_errno = errno;
1531 long double _value = _cs_to_long_double(_str, &num_s_end);
1533 if (errno == ERANGE)
1536 if (errno != last_errno)
1543 call(
const wchar_t *_str,
const wchar_t *&num_s_end)
1545 int last_errno = errno;
1547 long double _value = _cs_to_long_double(_str, &num_s_end);
1549 if (errno == ERANGE)
1552 if (errno != last_errno)
1565 _cs_to_floating_point<long double>(
const char *_str,
const char *&num_s_end)
1567 typedef _cs_to_floating_point_ld<string_detail::_strtold_present::value> impl;
1569 return impl::call(_str, num_s_end);
1575 _cs_to_floating_point<long double>(
const wchar_t *_str,
const wchar_t *&num_s_end)
1577 typedef _cs_to_floating_point_ld<string_detail::_wcstold_present::value> impl;
1579 return impl::call(_str, num_s_end);
1582 struct _has_4arg_swprintf:
1583 public string_detail::_has_4arg_swprintf
1586 template<
bool>
struct _swprintf_impl;
1589 struct _swprintf_impl<true>
1591 template<
class _T1,
class _T2,
class _T3,
class _T4>
1592 static void call(_T1 _a1, _T2 _a2, _T3 _a3, _T4 _a4)
1594 using namespace std;
1595 swprintf(_a1, _a2, _a3, _a4);
1600 struct _swprintf_impl<false>
1602 template<
class _T1,
class _T2,
class _T3>
1603 static void call(_T1 _a1, cstddef::size_t, _T2 _a2, _T3 _a3)
1605 using namespace std;
1606 swprintf(_a1, _a2, _a3);
1610 template<
class _ArgT>
1612 void _swprintf4_std_impl(
wchar_t* ws, cstddef::size_t len,
const wchar_t* format, _ArgT arg)
1614 _swprintf_impl<_has_4arg_swprintf::value>::call(ws, len, format, arg);
1618 struct _to_string_impl
1620 static string call(
const _Tp &value)
1624 string _str(_ss.str());
1630 struct _to_string_impl<char*>
1632 static string call(
const char *value)
1639 struct _to_string_impl<char[_Size]>:
1640 _to_string_impl<char*>
1644 struct _to_wstring_impl
1646 static wstring call(
const _Tp &value)
1650 wstring _str(_ss.str());
1656 struct _to_wstring_impl<wchar_t*>
1658 static wstring call(
const wchar_t *value)
1665 struct _to_wstring_impl<wchar_t[_Size]>:
1666 _to_wstring_impl<wchar_t*>
1674 template <
class _Tp>
1675 inline _Tp stot(
const string &_str, cstddef::size_t *idx = 0,
int base = 10)
1677 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1678 _Tp _value = stot<_Tp>(_ptr, _eptr, base);
1681 throw(std::invalid_argument(
"invalid stdex::stot argument"));
1683 throw(std::out_of_range(
"stdex::stot argument out of range"));
1686 *idx = (cstddef::size_t) (_eptr - _ptr);
1691 template <
class _Tp>
1692 inline _Tp stot(
const wstring &_str, cstddef::size_t *idx = 0,
int base = 10)
1694 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1695 _Tp _value = stot<_Tp>(_ptr, _eptr, base);
1698 throw(std::invalid_argument(
"invalid wide stdex::stot argument"));
1700 throw(std::out_of_range(
"wide stdex::stot argument out of range"));
1703 *idx = (cstddef::size_t) (_eptr - _ptr);
1708 inline int stoi(
const string &_str, cstddef::size_t *idx = 0,
int base = 10)
1710 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1711 int _value = detail::_cs_to_integral<int>(_ptr, _eptr, base);
1714 throw(std::invalid_argument(
"invalid stdex::stoi argument"));
1716 throw(std::out_of_range(
"stdex::stoi argument out of range"));
1719 *idx = (cstddef::size_t) (_eptr - _ptr);
1724 inline int stoi(
const wstring &_str, cstddef::size_t *idx = 0,
int base = 10)
1726 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1727 int _value = detail::_cs_to_integral<int>(_ptr, _eptr, base);
1730 throw(std::invalid_argument(
"invalid wide stdex::stoi argument"));
1732 throw(std::out_of_range(
"wide stdex::stoi argument out of range"));
1735 *idx = (cstddef::size_t) (_eptr - _ptr);
1740 inline long stol(
const string &_str, cstddef::size_t *idx = 0,
int base = 10)
1742 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1743 long _value = detail::_cs_to_integral<long>(_ptr, _eptr, base);
1746 throw(std::invalid_argument(
"invalid stdex::stol argument"));
1748 throw(std::out_of_range(
"stdex::stol argument out of range"));
1751 *idx = (cstddef::size_t) (_eptr - _ptr);
1756 inline long stol(
const wstring &_str, cstddef::size_t *idx = 0,
int base = 10)
1758 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1759 long _value = detail::_cs_to_integral<long>(_ptr, _eptr, base);
1762 throw(std::invalid_argument(
"invalid wide stdex::stol argument"));
1764 throw(std::out_of_range(
"wide stdex::stol argument out of range"));
1767 *idx = (cstddef::size_t) (_eptr - _ptr);
1772 inline unsigned long stoul(
const string &_str, cstddef::size_t *idx = 0,
int base = 10)
1774 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1775 unsigned long _value = detail::_cs_to_integral<unsigned long>(_ptr, _eptr, base);
1778 throw(std::invalid_argument(
"invalid stdex::stoul argument"));
1780 throw(std::out_of_range(
"stdex::stoul argument out of range"));
1783 *idx = (cstddef::size_t) (_eptr - _ptr);
1788 inline unsigned long stoul(
const wstring &_str, cstddef::size_t *idx = 0,
int base = 10)
1790 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1791 unsigned long _value = detail::_cs_to_integral<unsigned long>(_ptr, _eptr, base);
1794 throw(std::invalid_argument(
"invalid wide stdex::stoul argument"));
1796 throw(std::out_of_range(
"wide stdex::stoul argument out of range"));
1799 *idx = (cstddef::size_t) (_eptr - _ptr);
1804 inline float stof(
const string &_str, cstddef::size_t *idx = 0)
1806 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1808 float _value =
static_cast<float>(detail::_cs_to_floating_point<float>(_ptr, _eptr));
1811 throw(std::invalid_argument(
"invalid stdex::stof argument"));
1813 throw(std::out_of_range(
"stdex::stof argument out of range"));
1816 *idx = (cstddef::size_t) (_eptr - _ptr);
1821 inline float stof(
const wstring &_str, cstddef::size_t *idx = 0)
1823 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1825 float _value =
static_cast<float>(detail::_cs_to_floating_point<float>(_ptr, _eptr));
1828 throw(std::invalid_argument(
"invalid wide stdex::stof argument"));
1830 throw(std::out_of_range(
"wide stdex::stof argument out of range"));
1833 *idx = (cstddef::size_t) (_eptr - _ptr);
1838 inline double stod(
const string &_str, cstddef::size_t *idx = 0)
1840 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1842 double _value =
static_cast<double>(detail::_cs_to_floating_point<double>(_ptr, _eptr));
1845 throw(std::invalid_argument(
"invalid stdex::stod argument"));
1847 throw(std::out_of_range(
"stdex::stod argument out of range"));
1850 *idx = (cstddef::size_t) (_eptr - _ptr);
1855 inline double stod(
const wstring &_str, cstddef::size_t *idx = 0)
1857 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1859 double _value =
static_cast<double>(detail::_cs_to_floating_point<double>(_ptr, _eptr));
1862 throw(std::invalid_argument(
"invalid wide stdex::stod argument"));
1864 throw(std::out_of_range(
"wide stdex::stod argument out of range"));
1867 *idx = (cstddef::size_t) (_eptr - _ptr);
1872 inline long double stold(
const string &_str, cstddef::size_t *idx = 0)
1874 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1876 typedef conditional<
sizeof(
long double) ==
sizeof(
double), double,
long double>::type type;
1878 long double _value = detail::_cs_to_floating_point<type>(_ptr, _eptr);
1881 throw(std::invalid_argument(
"invalid stdex::stold argument"));
1883 throw(std::out_of_range(
"stdex::stold argument out of range"));
1886 *idx = (cstddef::size_t) (_eptr - _ptr);
1891 inline long double stold(
const wstring &_str, cstddef::size_t *idx = 0)
1893 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1895 typedef conditional<
sizeof(
long double) ==
sizeof(
double), double,
long double>::type type;
1897 long double _value = detail::_cs_to_floating_point<type>(_ptr, _eptr);
1900 throw(std::invalid_argument(
"invalid wide stdex::stold argument"));
1902 throw(std::out_of_range(
"wide stdex::stold argument out of range"));
1905 *idx = (cstddef::size_t) (_eptr - _ptr);
1910#if defined(LLONG_MAX) || defined(LLONG_MIN)
1911 inline long long stoll(
const string &_str, cstddef::size_t *idx = 0,
int base = 10)
1913 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1915 long long _value = detail::_cs_to_integral_ll<long long>(_ptr, _eptr, base);
1918 throw(std::invalid_argument(
"invalid stdex::stoll argument"));
1920 throw(std::out_of_range(
"stdex::stoll argument out of range"));
1923 *idx = (cstddef::size_t) (_eptr - _ptr);
1928 inline long long stoll(
const wstring &_str, cstddef::size_t *idx = 0,
int base = 10)
1930 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1932 long long _value = detail::_cs_to_integral_ll<long long>(_ptr, _eptr, base);
1935 throw(std::invalid_argument(
"invalid wide stdex::stoll argument"));
1937 throw(std::out_of_range(
"wide stdex::stoll argument out of range"));
1940 *idx = (cstddef::size_t) (_eptr - _ptr);
1945 inline unsigned long long stoull(
const string &_str, cstddef::size_t *idx = 0,
int base = 10)
1947 const char *_eptr = _str.c_str(), *_ptr = _eptr;
1949 unsigned long long _value = detail::_cs_to_integral_ll<unsigned long long>(_ptr, _eptr, base);
1952 throw(std::invalid_argument(
"invalid stdex::stoull argument"));
1954 throw(std::out_of_range(
"stdex::stoull argument out of range"));
1957 *idx = (cstddef::size_t) (_eptr - _ptr);
1962 inline unsigned long long stoull(
const wstring &_str, cstddef::size_t *idx = 0,
int base = 10)
1964 const wchar_t *_eptr = _str.c_str(), *_ptr = _eptr;
1966 unsigned long long _value = detail::_cs_to_integral_ll<unsigned long long>(_ptr, _eptr, base);
1969 throw(std::invalid_argument(
"invalid wide stdex::stoull argument"));
1971 throw(std::out_of_range(
"wide stdex::stoull argument out of range"));
1974 *idx = (cstddef::size_t) (_eptr - _ptr);
1981 inline string to_string(
const _Tp &value)
1983 return detail::_to_string_impl<_Tp>::call(value);
1987 inline wstring to_wstring(
const _Tp &value)
1989 return detail::_to_wstring_impl<_Tp>::call(value);
1993 inline string to_string<int>(
const int &value)
1995 using namespace std;
1997 char buf[detail::_type_cs_len<int, INT_MAX>::value];
2001 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%d", value);
2007 inline wstring to_wstring<int>(
const int &value)
2009 using namespace std;
2011 wchar_t buf[detail::_type_cs_len<int, INT_MAX>::value *
sizeof(wchar_t)];
2013 wchar_t buf[32 *
sizeof(wchar_t)];
2015 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%d", value);
2017 return wstring(buf);
2021 inline string to_string<unsigned int>(
const unsigned int &value)
2023 using namespace std;
2025 char buf[detail::_type_cs_len<unsigned int, UINT_MAX>::value];
2029 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%u", value);
2035 inline wstring to_wstring<unsigned int>(
const unsigned int &value)
2037 using namespace std;
2039 wchar_t buf[detail::_type_cs_len<unsigned int, UINT_MAX>::value *
sizeof(wchar_t)];
2041 wchar_t buf[32 *
sizeof(wchar_t)];
2043 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%u", value);
2045 return wstring(buf);
2049 inline string to_string<bool>(
const bool &value)
2052 return string(
"true");
2053 return string(
"false");
2057 inline wstring to_wstring<bool>(
const bool &value)
2060 return wstring(L
"true");
2061 return wstring(L
"false");
2065 inline string to_string<float>(
const float &value)
2067 using namespace std;
2068#if defined(FLT_MANT_DIG) && defined(FLT_MIN_EXP)
2069 char buf[3 + FLT_MANT_DIG - FLT_MIN_EXP];
2073 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%f", value);
2079 inline wstring to_wstring<float>(
const float &value)
2081 using namespace std;
2082#if defined(FLT_MANT_DIG) && defined(FLT_MIN_EXP)
2083 wchar_t buf[(3 + FLT_MANT_DIG - FLT_MIN_EXP) *
sizeof(
wchar_t)];
2085 wchar_t buf[256 *
sizeof(wchar_t)];
2087 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%f", value);
2089 return wstring(buf);
2093 inline string to_string<double>(
const double &value)
2095 using namespace std;
2096#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP)
2097 char buf[3 + DBL_MANT_DIG - DBL_MIN_EXP];
2101 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%f", value);
2107 inline wstring to_wstring<double>(
const double &value)
2109 using namespace std;
2110#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP)
2111 wchar_t buf[(3 + DBL_MANT_DIG - DBL_MIN_EXP) *
sizeof(
wchar_t)];
2113 wchar_t buf[2048 *
sizeof(wchar_t)];
2115 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%f", value);
2117 return wstring(buf);
2121 inline string to_string<std::string>(
const std::string &_str)
2127 inline wstring to_wstring<std::wstring>(
const std::wstring &_str)
2134 enable_if<is_same<int, long>::value == (
false),
string>::type
2135 to_string<long>(
const long &value)
2137 using namespace std;
2139 char buf[detail::_type_cs_len<long, LONG_MAX>::value];
2142 char buf[detail::_type_cs_len<long, (ULONG_MAX / 2)>::value];
2147 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%ld", value);
2154 enable_if<is_same<int, long>::value == (
false), wstring>::type
2155 to_wstring<long>(
const long &value)
2157 using namespace std;
2159 wchar_t buf[detail::_type_cs_len<long, LONG_MAX>::value *
sizeof(wchar_t)];
2162 wchar_t buf[detail::_type_cs_len<long, (ULONG_MAX / 2)>::value *
sizeof(
wchar_t)];
2164 wchar_t buf[256 *
sizeof(wchar_t)];
2167 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%ld", value);
2169 return wstring(buf);
2174 enable_if<is_same<unsigned int, unsigned long>::value == (
false),
string>::type
2175 to_string<unsigned long>(
const unsigned long &value)
2177 using namespace std;
2179 char buf[detail::_type_cs_len<unsigned long, ULONG_MAX>::value];
2182 char buf[detail::_type_cs_len<
unsigned long, (LONG_MAX * 2 + 1)>::value];
2187 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%lu", value);
2194 enable_if<is_same<unsigned int, unsigned long>::value == (
false), wstring>::type
2195 to_wstring<unsigned long>(
const unsigned long &value)
2197 using namespace std;
2199 wchar_t buf[detail::_type_cs_len<unsigned long, ULONG_MAX>::value *
sizeof(wchar_t)];
2202 wchar_t buf[detail::_type_cs_len<
unsigned long, (LONG_MAX * 2 + 1)>::value *
sizeof(
wchar_t)];
2204 wchar_t buf[512 *
sizeof(wchar_t)];
2207 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%lu", value);
2209 return wstring(buf);
2214 enable_if<is_same<long double, double>::value == (
false),
string>::type
2215 to_string<long double>(
const long double &value)
2217 using namespace std;
2218#if defined(LDBL_MANT_DIG) && defined(LDBL_MIN_EXP)
2219 char buf[3 + LDBL_MANT_DIG - LDBL_MIN_EXP];
2223 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%Lf", value);
2230 cstddef::size_t e_pos = result.rfind(
'e');
2231 if (e_pos != string::npos)
2233#ifdef LDBL_MAX_10_EXP
2234 char str_integer_part_reverse[LDBL_MAX_10_EXP + 3];
2236 char str_integer_part_reverse[
sizeof(buf)];
2238 long double fp_integer_part, fp_fractional_part;
2239 cstddef::size_t symbols_converted_n = 0;
2240 fp_fractional_part = modfl(value, &fp_integer_part);
2241 while (fp_integer_part > 0.0L)
2243 str_integer_part_reverse[symbols_converted_n++] =
'0' + (char) fmod(fp_integer_part, 10.0L);
2244 fp_integer_part = floor(fp_integer_part / 10.0L);
2247 for (cstddef::size_t _i = 0; _i < symbols_converted_n; _i++)
2248 buf[_i] = str_integer_part_reverse[symbols_converted_n - _i - 1];
2250 buf[symbols_converted_n++] =
'.';
2252 if (fp_fractional_part > 0.0L)
2254 while (fp_fractional_part > 0.0L)
2256 fp_fractional_part *= 10.0L;
2257 fp_fractional_part = modfl(fp_fractional_part, &fp_integer_part);
2258 buf[symbols_converted_n++] =
'0' + (char) fp_integer_part;
2262 buf[symbols_converted_n++] =
'0';
2264 buf[symbols_converted_n] = 0;
2274 enable_if<is_same<long double, double>::value == (
false), wstring>::type
2275 to_wstring<long double>(
const long double &value)
2277 using namespace std;
2278#if defined(LDBL_MANT_DIG) && defined(LDBL_MIN_EXP)
2279 wchar_t buf[(3 + LDBL_MANT_DIG - LDBL_MIN_EXP) *
sizeof(
wchar_t)];
2281 wchar_t buf[4096 *
sizeof(wchar_t)];
2283 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%Lf", value);
2285 wstring result(buf);
2290 cstddef::size_t e_pos = result.rfind(L
'e');
2291 if (e_pos != string::npos)
2293#ifdef LDBL_MAX_10_EXP
2294 wchar_t str_integer_part_reverse[(LDBL_MAX_10_EXP + 3) *
sizeof(
wchar_t)];
2296 wchar_t str_integer_part_reverse[
sizeof(buf)];
2298 long double fp_integer_part, fp_fractional_part;
2299 cstddef::size_t symbols_converted_n = 0;
2300 fp_fractional_part = modfl(value, &fp_integer_part);
2301 while (fp_integer_part > 0.0L)
2303 str_integer_part_reverse[symbols_converted_n++] = L
'0' + (char) fmod(fp_integer_part, 10.0L);
2304 fp_integer_part = floor(fp_integer_part / 10.0L);
2307 for (cstddef::size_t _i = 0; _i < symbols_converted_n; _i++)
2308 buf[_i] = str_integer_part_reverse[symbols_converted_n - _i - 1];
2310 buf[symbols_converted_n++] = L
'.';
2312 if (fp_fractional_part > 0.0L)
2314 while (fp_fractional_part > 0.0L)
2316 fp_fractional_part *= 10.0L;
2317 fp_fractional_part = modfl(fp_fractional_part, &fp_integer_part);
2318 buf[symbols_converted_n++] = L
'0' + (char) fp_integer_part;
2322 buf[symbols_converted_n++] = L
'0';
2324 buf[symbols_converted_n] = 0;
2332#if defined(LLONG_MAX) || defined(LLONG_MIN)
2336 enable_if<is_same<detail::string_detail::_long_long_type, long>::value == (
false),
string>::type
2337 to_string<detail::string_detail::_long_long_type>(
const detail::string_detail::_long_long_type &value)
2339 using namespace std;
2341 char buf[detail::_type_cs_len_ll<detail::string_detail::_long_long_type, LLONG_MAX>::value];
2344 char buf[detail::_type_cs_len_ll<detail::string_detail::_long_long_type, (ULONG_MAX / 2)>::value];
2349 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%lld", value);
2356 enable_if<is_same<detail::string_detail::_long_long_type, long>::value == (
false), wstring>::type
2357 to_wstring<detail::string_detail::_long_long_type>(
const detail::string_detail::_long_long_type &value)
2359 using namespace std;
2361 wchar_t buf[detail::_type_cs_len_ll<detail::string_detail::_long_long_type, LLONG_MAX>::value *
sizeof(wchar_t)];
2364 wchar_t buf[detail::_type_cs_len_ll<detail::string_detail::_long_long_type, (ULONG_MAX / 2)>::value *
sizeof(
wchar_t)];
2366 wchar_t buf[1024 *
sizeof(wchar_t)];
2369 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%lld", value);
2371 return wstring(buf);
2376 enable_if<is_same<detail::string_detail::_unsigned_long_long_type, unsigned long>::value == (
false),
string>::type
2377 to_string<detail::string_detail::_unsigned_long_long_type>(
const detail::string_detail::_unsigned_long_long_type &value)
2379 using namespace std;
2381 char buf[detail::_type_cs_len_ll<detail::string_detail::_unsigned_long_long_type, ULLONG_MAX>::value];
2384 char buf[detail::_type_cs_len_ll<detail::string_detail::_unsigned_long_long_type, (LLONG_MAX * 2 + 1)>::value];
2389 detail::_snprintf4_std_impl(buf,
sizeof(buf),
"%llu", value);
2396 enable_if<is_same<detail::string_detail::_unsigned_long_long_type, unsigned long>::value == (
false), wstring>::type
2397 to_wstring<detail::string_detail::_unsigned_long_long_type>(
const detail::string_detail::_unsigned_long_long_type &value)
2399 using namespace std;
2401 wchar_t buf[detail::_type_cs_len_ll<detail::string_detail::_unsigned_long_long_type, ULLONG_MAX>::value *
sizeof(wchar_t)];
2404 wchar_t buf[detail::_type_cs_len_ll<detail::string_detail::_unsigned_long_long_type, (LLONG_MAX * 2 + 1)>::value *
sizeof(
wchar_t)];
2406 wchar_t buf[1024 *
sizeof(wchar_t)];
2409 detail::_swprintf4_std_impl(buf,
sizeof(buf) /
sizeof(
wchar_t), L
"%llu", value);
2411 return wstring(buf);