diff options
Diffstat (limited to 'system/lib/libcxx/string.cpp')
-rw-r--r-- | system/lib/libcxx/string.cpp | 823 |
1 files changed, 332 insertions, 491 deletions
diff --git a/system/lib/libcxx/string.cpp b/system/lib/libcxx/string.cpp index c71af4fe..5a869116 100644 --- a/system/lib/libcxx/string.cpp +++ b/system/lib/libcxx/string.cpp @@ -11,9 +11,12 @@ #include "cstdlib" #include "cwchar" #include "cerrno" -#ifdef _WIN32 +#include "limits" +#include "stdexcept" +#ifdef _LIBCPP_MSVCRT #include "support/win32/support.h" -#endif // _WIN32 +#endif // _LIBCPP_MSVCRT +#include <stdio.h> _LIBCPP_BEGIN_NAMESPACE_STD @@ -26,662 +29,500 @@ template string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); -int -stoi(const string& str, size_t* idx, int base) +namespace +{ + +template<typename T> +inline +void throw_helper( const string& msg ) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw T( msg ); +#else + printf("%s\n", msg.c_str()); + abort(); +#endif +} + +inline +void throw_from_string_out_of_range( const string& func ) +{ + throw_helper<out_of_range>(func + ": out of range"); +} + +inline +void throw_from_string_invalid_arg( const string& func ) +{ + throw_helper<invalid_argument>(func + ": no conversion"); +} + +// as_integer + +template<typename V, typename S, typename F> +inline +V +as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) { - char* ptr; - const char* const p = str.c_str(); + typename S::value_type* ptr; + const typename S::value_type* const p = str.c_str(); typename remove_reference<decltype(errno)>::type errno_save = errno; errno = 0; - long r = strtol(p, &ptr, base); + V r = f(p, &ptr, base); swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE || r < numeric_limits<int>::min() || - numeric_limits<int>::max() < r) - throw out_of_range("stoi: out of range"); + if (errno_save == ERANGE) + throw_from_string_out_of_range(func); if (ptr == p) - throw invalid_argument("stoi: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS + throw_from_string_invalid_arg(func); if (idx) *idx = static_cast<size_t>(ptr - p); + return r; +} + +template<typename V, typename S> +inline +V +as_integer(const string& func, const S& s, size_t* idx, int base); + +// string +template<> +inline +int +as_integer(const string& func, const string& s, size_t* idx, int base ) +{ + // Use long as no Stantard string to integer exists. + long r = as_integer_helper<long>( func, s, idx, base, strtol ); + if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) + throw_from_string_out_of_range(func); return static_cast<int>(r); } +template<> +inline +long +as_integer(const string& func, const string& s, size_t* idx, int base ) +{ + return as_integer_helper<long>( func, s, idx, base, strtol ); +} + +template<> +inline +unsigned long +as_integer( const string& func, const string& s, size_t* idx, int base ) +{ + return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); +} + +template<> +inline +long long +as_integer( const string& func, const string& s, size_t* idx, int base ) +{ + return as_integer_helper<long long>( func, s, idx, base, strtoll ); +} + +template<> +inline +unsigned long long +as_integer( const string& func, const string& s, size_t* idx, int base ) +{ + return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); +} + +// wstring +template<> +inline int -stoi(const wstring& str, size_t* idx, int base) +as_integer( const string& func, const wstring& s, size_t* idx, int base ) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - long r = wcstol(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE || r < numeric_limits<int>::min() || - numeric_limits<int>::max() < r) - throw out_of_range("stoi: out of range"); - if (ptr == p) - throw invalid_argument("stoi: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); + // Use long as no Stantard string to integer exists. + long r = as_integer_helper<long>( func, s, idx, base, wcstol ); + if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) + throw_from_string_out_of_range(func); return static_cast<int>(r); } +template<> +inline long -stol(const string& str, size_t* idx, int base) +as_integer( const string& func, const wstring& s, size_t* idx, int base ) +{ + return as_integer_helper<long>( func, s, idx, base, wcstol ); +} + +template<> +inline +unsigned long +as_integer( const string& func, const wstring& s, size_t* idx, int base ) +{ + return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul ); +} + +template<> +inline +long long +as_integer( const string& func, const wstring& s, size_t* idx, int base ) +{ + return as_integer_helper<long long>( func, s, idx, base, wcstoll ); +} + +template<> +inline +unsigned long long +as_integer( const string& func, const wstring& s, size_t* idx, int base ) +{ + return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull ); +} + +// as_float + +template<typename V, typename S, typename F> +inline +V +as_float_helper(const string& func, const S& str, size_t* idx, F f ) { - char* ptr; - const char* const p = str.c_str(); + typename S::value_type* ptr; + const typename S::value_type* const p = str.c_str(); typename remove_reference<decltype(errno)>::type errno_save = errno; errno = 0; - long r = strtol(p, &ptr, base); + V r = f(p, &ptr); swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS if (errno_save == ERANGE) - throw out_of_range("stol: out of range"); + throw_from_string_out_of_range(func); if (ptr == p) - throw invalid_argument("stol: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS + throw_from_string_invalid_arg(func); if (idx) *idx = static_cast<size_t>(ptr - p); return r; } +template<typename V, typename S> +inline +V as_float( const string& func, const S& s, size_t* idx = nullptr ); + +template<> +inline +float +as_float( const string& func, const string& s, size_t* idx ) +{ + return as_float_helper<float>( func, s, idx, strtof ); +} + +template<> +inline +double +as_float(const string& func, const string& s, size_t* idx ) +{ + return as_float_helper<double>( func, s, idx, strtod ); +} + +template<> +inline +long double +as_float( const string& func, const string& s, size_t* idx ) +{ + return as_float_helper<long double>( func, s, idx, strtold ); +} + +template<> +inline +float +as_float( const string& func, const wstring& s, size_t* idx ) +{ + return as_float_helper<float>( func, s, idx, wcstof ); +} + +template<> +inline +double +as_float( const string& func, const wstring& s, size_t* idx ) +{ + return as_float_helper<double>( func, s, idx, wcstod ); +} + +template<> +inline +long double +as_float( const string& func, const wstring& s, size_t* idx ) +{ + return as_float_helper<long double>( func, s, idx, wcstold ); +} + +} // unnamed namespace + +int +stoi(const string& str, size_t* idx, int base) +{ + return as_integer<int>( "stoi", str, idx, base ); +} + +int +stoi(const wstring& str, size_t* idx, int base) +{ + return as_integer<int>( "stoi", str, idx, base ); +} + +long +stol(const string& str, size_t* idx, int base) +{ + return as_integer<long>( "stol", str, idx, base ); +} + long stol(const wstring& str, size_t* idx, int base) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - long r = wcstol(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stol: out of range"); - if (ptr == p) - throw invalid_argument("stol: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<long>( "stol", str, idx, base ); } unsigned long stoul(const string& str, size_t* idx, int base) { - char* ptr; - const char* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - unsigned long r = strtoul(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stoul: out of range"); - if (ptr == p) - throw invalid_argument("stoul: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<unsigned long>( "stoul", str, idx, base ); } unsigned long stoul(const wstring& str, size_t* idx, int base) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - unsigned long r = wcstoul(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stoul: out of range"); - if (ptr == p) - throw invalid_argument("stoul: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<unsigned long>( "stoul", str, idx, base ); } long long stoll(const string& str, size_t* idx, int base) { - char* ptr; - const char* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - long long r = strtoll(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stoll: out of range"); - if (ptr == p) - throw invalid_argument("stoll: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<long long>( "stoll", str, idx, base ); } long long stoll(const wstring& str, size_t* idx, int base) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - long long r = wcstoll(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stoll: out of range"); - if (ptr == p) - throw invalid_argument("stoll: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<long long>( "stoll", str, idx, base ); } unsigned long long stoull(const string& str, size_t* idx, int base) { - char* ptr; - const char* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - unsigned long long r = strtoull(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stoull: out of range"); - if (ptr == p) - throw invalid_argument("stoull: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<unsigned long long>( "stoull", str, idx, base ); } unsigned long long stoull(const wstring& str, size_t* idx, int base) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - unsigned long long r = wcstoull(p, &ptr, base); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stoull: out of range"); - if (ptr == p) - throw invalid_argument("stoull: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_integer<unsigned long long>( "stoull", str, idx, base ); } float stof(const string& str, size_t* idx) { - char* ptr; - const char* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - float r = strtof(p, &ptr); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stof: out of range"); - if (ptr == p) - throw invalid_argument("stof: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_float<float>( "stof", str, idx ); } float stof(const wstring& str, size_t* idx) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - float r = wcstof(p, &ptr); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stof: out of range"); - if (ptr == p) - throw invalid_argument("stof: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_float<float>( "stof", str, idx ); } double stod(const string& str, size_t* idx) { - char* ptr; - const char* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - double r = strtod(p, &ptr); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stod: out of range"); - if (ptr == p) - throw invalid_argument("stod: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_float<double>( "stod", str, idx ); } double stod(const wstring& str, size_t* idx) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - double r = wcstod(p, &ptr); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stod: out of range"); - if (ptr == p) - throw invalid_argument("stod: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_float<double>( "stod", str, idx ); } long double stold(const string& str, size_t* idx) { - char* ptr; - const char* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - long double r = strtold(p, &ptr); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stold: out of range"); - if (ptr == p) - throw invalid_argument("stold: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_float<long double>( "stold", str, idx ); } long double stold(const wstring& str, size_t* idx) { - wchar_t* ptr; - const wchar_t* const p = str.c_str(); - typename remove_reference<decltype(errno)>::type errno_save = errno; - errno = 0; - long double r = wcstold(p, &ptr); - swap(errno, errno_save); -#ifndef _LIBCPP_NO_EXCEPTIONS - if (errno_save == ERANGE) - throw out_of_range("stold: out of range"); - if (ptr == p) - throw invalid_argument("stold: no conversion"); -#endif // _LIBCPP_NO_EXCEPTIONS - if (idx) - *idx = static_cast<size_t>(ptr - p); - return r; + return as_float<long double>( "stold", str, idx ); } -string to_string(int val) +// to_string + +namespace +{ + +// as_string + +template<typename S, typename P, typename V > +inline +S +as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) { - string s; - s.resize(s.capacity()); + typedef typename S::size_type size_type; + size_type available = s.size(); while (true) { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%d", val)); - if (n2 <= s.size()) + int status = sprintf_like(&s[0], available + 1, fmt, a); + if ( status >= 0 ) { - s.resize(n2); - break; + size_type used = static_cast<size_type>(status); + if ( used <= available ) + { + s.resize( used ); + break; + } + available = used; // Assume this is advice of how much space we need. } - s.resize(n2); + else + available = available * 2 + 1; + s.resize(available); } return s; } -string to_string(unsigned val) +template <class S, class V, bool = is_floating_point<V>::value> +struct initial_string; + +template <class V, bool b> +struct initial_string<string, V, b> { - string s; - s.resize(s.capacity()); - while (true) + string + operator()() const { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%u", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); + string s; + s.resize(s.capacity()); + return s; } - return s; -} +}; -string to_string(long val) +template <class V> +struct initial_string<wstring, V, false> { - string s; - s.resize(s.capacity()); - while (true) + wstring + operator()() const { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%ld", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); + const size_t n = (numeric_limits<unsigned long long>::digits / 3) + + ((numeric_limits<unsigned long long>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + return s; } - return s; -} +}; -string to_string(unsigned long val) +template <class V> +struct initial_string<wstring, V, true> { - string s; - s.resize(s.capacity()); - while (true) + wstring + operator()() const { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%lu", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); + wstring s(20, wchar_t()); + s.resize(s.capacity()); + return s; } - return s; +}; + +typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); + +inline +wide_printf +get_swprintf() +{ +#ifndef _LIBCPP_MSVCRT + return swprintf; +#else + return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf); +#endif +} + +} // unnamed namespace + +string to_string(int val) +{ + return as_string(snprintf, initial_string<string, int>()(), "%d", val); +} + +string to_string(unsigned val) +{ + return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val); +} + +string to_string(long val) +{ + return as_string(snprintf, initial_string<string, long>()(), "%ld", val); +} + +string to_string(unsigned long val) +{ + return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val); } string to_string(long long val) { - string s; - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%lld", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return s; + return as_string(snprintf, initial_string<string, long long>()(), "%lld", val); } string to_string(unsigned long long val) { - string s; - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%llu", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return s; + return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val); } string to_string(float val) { - string s; - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%f", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return s; + return as_string(snprintf, initial_string<string, float>()(), "%f", val); } string to_string(double val) { - string s; - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%f", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return s; + return as_string(snprintf, initial_string<string, double>()(), "%f", val); } string to_string(long double val) { - string s; - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%Lf", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return s; + return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val); } wstring to_wstring(int val) { - const size_t n = (numeric_limits<int>::digits / 3) - + ((numeric_limits<int>::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%d", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val); } wstring to_wstring(unsigned val) { - const size_t n = (numeric_limits<unsigned>::digits / 3) - + ((numeric_limits<unsigned>::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%u", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val); } wstring to_wstring(long val) { - const size_t n = (numeric_limits<long>::digits / 3) - + ((numeric_limits<long>::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%ld", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val); } wstring to_wstring(unsigned long val) { - const size_t n = (numeric_limits<unsigned long>::digits / 3) - + ((numeric_limits<unsigned long>::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%lu", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val); } wstring to_wstring(long long val) { - const size_t n = (numeric_limits<long long>::digits / 3) - + ((numeric_limits<long long>::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%lld", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val); } wstring to_wstring(unsigned long long val) { - const size_t n = (numeric_limits<unsigned long long>::digits / 3) - + ((numeric_limits<unsigned long long>::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%llu", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val); } wstring to_wstring(float val) { - const size_t n = 20; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%f", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val); } wstring to_wstring(double val) { - const size_t n = 20; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%f", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val); } wstring to_wstring(long double val) { - const size_t n = 20; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - while (true) - { - int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val); - if (n2 > 0) - { - s.resize(static_cast<size_t>(n2)); - break; - } - s.resize(2*s.size()); - s.resize(s.capacity()); - } - return s; + return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val); } - _LIBCPP_END_NAMESPACE_STD |