Index: libcxx/src/string.cpp =================================================================== --- libcxx/src/string.cpp +++ libcxx/src/string.cpp @@ -7,12 +7,14 @@ //===----------------------------------------------------------------------===// #include "string" +#include "charconv" #include "cstdlib" #include "cwchar" #include "cerrno" #include "limits" #include "stdexcept" #include +#include "__debug" _LIBCPP_BEGIN_NAMESPACE_STD @@ -375,11 +377,11 @@ return s; } -template ::value> +template struct initial_string; -template -struct initial_string +template <> +struct initial_string { string operator()() const @@ -390,23 +392,8 @@ } }; -template -struct initial_string -{ - wstring - operator()() const - { - const size_t n = (numeric_limits::digits / 3) - + ((numeric_limits::digits % 3) != 0) - + 1; - wstring s(n, wchar_t()); - s.resize(s.capacity()); - return s; - } -}; - -template -struct initial_string +template <> +struct initial_string { wstring operator()() const @@ -430,95 +417,108 @@ #endif } +template +S i_to_string(const V v) +{ + // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers. + // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented), + // so we need +1 here. + constexpr size_t bufsize = numeric_limits::digits10 + 2; // +1 for minus, +1 for digits10 + char buf[bufsize]; + const auto res = to_chars(buf, buf + bufsize, v); + _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value"); + return S(buf, res.ptr); +} + } // unnamed namespace string to_string(int val) { - return as_string(snprintf, initial_string()(), "%d", val); + return i_to_string(val); } string to_string(unsigned val) { - return as_string(snprintf, initial_string()(), "%u", val); + return i_to_string(val); } string to_string(long val) { - return as_string(snprintf, initial_string()(), "%ld", val); + return i_to_string(val); } string to_string(unsigned long val) { - return as_string(snprintf, initial_string()(), "%lu", val); + return i_to_string(val); } string to_string(long long val) { - return as_string(snprintf, initial_string()(), "%lld", val); + return i_to_string(val); } string to_string(unsigned long long val) { - return as_string(snprintf, initial_string()(), "%llu", val); + return i_to_string(val); } string to_string(float val) { - return as_string(snprintf, initial_string()(), "%f", val); + return as_string(snprintf, initial_string()(), "%f", val); } string to_string(double val) { - return as_string(snprintf, initial_string()(), "%f", val); + return as_string(snprintf, initial_string()(), "%f", val); } string to_string(long double val) { - return as_string(snprintf, initial_string()(), "%Lf", val); + return as_string(snprintf, initial_string()(), "%Lf", val); } wstring to_wstring(int val) { - return as_string(get_swprintf(), initial_string()(), L"%d", val); + return i_to_string(val); } wstring to_wstring(unsigned val) { - return as_string(get_swprintf(), initial_string()(), L"%u", val); + return i_to_string(val); } wstring to_wstring(long val) { - return as_string(get_swprintf(), initial_string()(), L"%ld", val); + return i_to_string(val); } wstring to_wstring(unsigned long val) { - return as_string(get_swprintf(), initial_string()(), L"%lu", val); + return i_to_string(val); } wstring to_wstring(long long val) { - return as_string(get_swprintf(), initial_string()(), L"%lld", val); + return i_to_string(val); } wstring to_wstring(unsigned long long val) { - return as_string(get_swprintf(), initial_string()(), L"%llu", val); + return i_to_string(val); } wstring to_wstring(float val) { - return as_string(get_swprintf(), initial_string()(), L"%f", val); + return as_string(get_swprintf(), initial_string()(), L"%f", val); } wstring to_wstring(double val) { - return as_string(get_swprintf(), initial_string()(), L"%f", val); + return as_string(get_swprintf(), initial_string()(), L"%f", val); } wstring to_wstring(long double val) { - return as_string(get_swprintf(), initial_string()(), L"%Lf", val); + return as_string(get_swprintf(), initial_string()(), L"%Lf", val); } _LIBCPP_END_NAMESPACE_STD