1349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 981ad6265SDimitry Andric #include <__assert> 1081ad6265SDimitry Andric #include <cerrno> 1181ad6265SDimitry Andric #include <charconv> 1281ad6265SDimitry Andric #include <cstdlib> 1381ad6265SDimitry Andric #include <limits> 1481ad6265SDimitry Andric #include <stdexcept> 150b57cec5SDimitry Andric #include <stdio.h> 1681ad6265SDimitry Andric #include <string> 170b57cec5SDimitry Andric 18349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1981ad6265SDimitry Andric # include <cwchar> 20349cc55cSDimitry Andric #endif 21349cc55cSDimitry Andric 220b57cec5SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 230b57cec5SDimitry Andric 241838bd0fSDimitry Andric #ifndef _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON 251838bd0fSDimitry Andric 261838bd0fSDimitry Andric template <bool> 271838bd0fSDimitry Andric struct __basic_string_common; 281838bd0fSDimitry Andric 291838bd0fSDimitry Andric // The struct isn't declared anymore in the headers. It's only here for ABI compatibility. 301838bd0fSDimitry Andric template <> 311838bd0fSDimitry Andric struct __basic_string_common<true> { 321838bd0fSDimitry Andric _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; 331838bd0fSDimitry Andric _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; 341838bd0fSDimitry Andric }; 351838bd0fSDimitry Andric 36349cc55cSDimitry Andric void __basic_string_common<true>::__throw_length_error() const { 371838bd0fSDimitry Andric std::__throw_length_error("basic_string"); 381838bd0fSDimitry Andric } 391838bd0fSDimitry Andric void __basic_string_common<true>::__throw_out_of_range() const { 401838bd0fSDimitry Andric std::__throw_out_of_range("basic_string"); 41349cc55cSDimitry Andric } 42349cc55cSDimitry Andric 431838bd0fSDimitry Andric #endif // _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON 440b57cec5SDimitry Andric 45fe6060f1SDimitry Andric #define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; 465ffd83dbSDimitry Andric #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 475ffd83dbSDimitry Andric _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char) 48349cc55cSDimitry Andric # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 495ffd83dbSDimitry Andric _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t) 50349cc55cSDimitry Andric # endif 515ffd83dbSDimitry Andric #else 525ffd83dbSDimitry Andric _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char) 53349cc55cSDimitry Andric # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 545ffd83dbSDimitry Andric _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t) 555ffd83dbSDimitry Andric # endif 56349cc55cSDimitry Andric #endif 57fe6060f1SDimitry Andric #undef _LIBCPP_EXTERN_TEMPLATE_DEFINE 580b57cec5SDimitry Andric 59fe6060f1SDimitry Andric template string operator+<char, char_traits<char>, allocator<char>>(char const*, string const&); 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric namespace 620b57cec5SDimitry Andric { 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric template<typename T> 6581ad6265SDimitry Andric inline void throw_helper(const string& msg) { 660b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 670b57cec5SDimitry Andric throw T(msg); 680b57cec5SDimitry Andric #else 690b57cec5SDimitry Andric fprintf(stderr, "%s\n", msg.c_str()); 700b57cec5SDimitry Andric _VSTD::abort(); 710b57cec5SDimitry Andric #endif 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 7481ad6265SDimitry Andric inline void throw_from_string_out_of_range(const string& func) { 750b57cec5SDimitry Andric throw_helper<out_of_range>(func + ": out of range"); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 7881ad6265SDimitry Andric inline void throw_from_string_invalid_arg(const string& func) { 790b57cec5SDimitry Andric throw_helper<invalid_argument>(func + ": no conversion"); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric // as_integer 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric template<typename V, typename S, typename F> 8581ad6265SDimitry Andric inline V as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) { 860b57cec5SDimitry Andric typename S::value_type* ptr = nullptr; 870b57cec5SDimitry Andric const typename S::value_type* const p = str.c_str(); 88*bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> errno_save = errno; 890b57cec5SDimitry Andric errno = 0; 900b57cec5SDimitry Andric V r = f(p, &ptr, base); 910b57cec5SDimitry Andric swap(errno, errno_save); 920b57cec5SDimitry Andric if (errno_save == ERANGE) 930b57cec5SDimitry Andric throw_from_string_out_of_range(func); 940b57cec5SDimitry Andric if (ptr == p) 950b57cec5SDimitry Andric throw_from_string_invalid_arg(func); 960b57cec5SDimitry Andric if (idx) 970b57cec5SDimitry Andric *idx = static_cast<size_t>(ptr - p); 980b57cec5SDimitry Andric return r; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric template<typename V, typename S> 10281ad6265SDimitry Andric inline V as_integer(const string& func, const S& s, size_t* idx, int base); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // string 1050b57cec5SDimitry Andric template<> 10681ad6265SDimitry Andric inline int as_integer(const string& func, const string& s, size_t* idx, int base) { 1070b57cec5SDimitry Andric // Use long as no Standard string to integer exists. 1080b57cec5SDimitry Andric long r = as_integer_helper<long>(func, s, idx, base, strtol); 1090b57cec5SDimitry Andric if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 1100b57cec5SDimitry Andric throw_from_string_out_of_range(func); 1110b57cec5SDimitry Andric return static_cast<int>(r); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric template<> 11581ad6265SDimitry Andric inline long as_integer(const string& func, const string& s, size_t* idx, int base) { 1160b57cec5SDimitry Andric return as_integer_helper<long>(func, s, idx, base, strtol); 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric template<> 12081ad6265SDimitry Andric inline unsigned long as_integer(const string& func, const string& s, size_t* idx, int base) { 1210b57cec5SDimitry Andric return as_integer_helper<unsigned long>(func, s, idx, base, strtoul); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric template<> 12581ad6265SDimitry Andric inline long long as_integer(const string& func, const string& s, size_t* idx, int base) { 1260b57cec5SDimitry Andric return as_integer_helper<long long>(func, s, idx, base, strtoll); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric template<> 13081ad6265SDimitry Andric inline unsigned long long as_integer(const string& func, const string& s, size_t* idx, int base) { 1310b57cec5SDimitry Andric return as_integer_helper<unsigned long long>(func, s, idx, base, strtoull); 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 134349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1350b57cec5SDimitry Andric // wstring 1360b57cec5SDimitry Andric template<> 13781ad6265SDimitry Andric inline int as_integer(const string& func, const wstring& s, size_t* idx, int base) { 1380b57cec5SDimitry Andric // Use long as no Stantard string to integer exists. 1390b57cec5SDimitry Andric long r = as_integer_helper<long>(func, s, idx, base, wcstol); 1400b57cec5SDimitry Andric if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 1410b57cec5SDimitry Andric throw_from_string_out_of_range(func); 1420b57cec5SDimitry Andric return static_cast<int>(r); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric template<> 14681ad6265SDimitry Andric inline long as_integer(const string& func, const wstring& s, size_t* idx, int base) { 1470b57cec5SDimitry Andric return as_integer_helper<long>(func, s, idx, base, wcstol); 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric template<> 1510b57cec5SDimitry Andric inline 1520b57cec5SDimitry Andric unsigned long 1530b57cec5SDimitry Andric as_integer(const string& func, const wstring& s, size_t* idx, int base) 1540b57cec5SDimitry Andric { 1550b57cec5SDimitry Andric return as_integer_helper<unsigned long>(func, s, idx, base, wcstoul); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric template<> 15981ad6265SDimitry Andric inline long long as_integer(const string& func, const wstring& s, size_t* idx, int base) { 1600b57cec5SDimitry Andric return as_integer_helper<long long>(func, s, idx, base, wcstoll); 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric template<> 16481ad6265SDimitry Andric inline unsigned long long as_integer(const string& func, const wstring& s, size_t* idx, int base) { 1650b57cec5SDimitry Andric return as_integer_helper<unsigned long long>(func, s, idx, base, wcstoull); 1660b57cec5SDimitry Andric } 167349cc55cSDimitry Andric #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric // as_float 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric template<typename V, typename S, typename F> 17281ad6265SDimitry Andric inline V as_float_helper(const string& func, const S& str, size_t* idx, F f) { 1730b57cec5SDimitry Andric typename S::value_type* ptr = nullptr; 1740b57cec5SDimitry Andric const typename S::value_type* const p = str.c_str(); 175*bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> errno_save = errno; 1760b57cec5SDimitry Andric errno = 0; 1770b57cec5SDimitry Andric V r = f(p, &ptr); 1780b57cec5SDimitry Andric swap(errno, errno_save); 1790b57cec5SDimitry Andric if (errno_save == ERANGE) 1800b57cec5SDimitry Andric throw_from_string_out_of_range(func); 1810b57cec5SDimitry Andric if (ptr == p) 1820b57cec5SDimitry Andric throw_from_string_invalid_arg(func); 1830b57cec5SDimitry Andric if (idx) 1840b57cec5SDimitry Andric *idx = static_cast<size_t>(ptr - p); 1850b57cec5SDimitry Andric return r; 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric template<typename V, typename S> 18981ad6265SDimitry Andric inline V as_float(const string& func, const S& s, size_t* idx = nullptr); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric template<> 19281ad6265SDimitry Andric inline float as_float(const string& func, const string& s, size_t* idx) { 1930b57cec5SDimitry Andric return as_float_helper<float>(func, s, idx, strtof); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric template<> 19781ad6265SDimitry Andric inline double as_float(const string& func, const string& s, size_t* idx) { 1980b57cec5SDimitry Andric return as_float_helper<double>(func, s, idx, strtod); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric template<> 20281ad6265SDimitry Andric inline long double as_float(const string& func, const string& s, size_t* idx) { 2030b57cec5SDimitry Andric return as_float_helper<long double>(func, s, idx, strtold); 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 206349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 2070b57cec5SDimitry Andric template<> 20881ad6265SDimitry Andric inline float as_float(const string& func, const wstring& s, size_t* idx) { 2090b57cec5SDimitry Andric return as_float_helper<float>(func, s, idx, wcstof); 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric template<> 21381ad6265SDimitry Andric inline double as_float(const string& func, const wstring& s, size_t* idx) { 2140b57cec5SDimitry Andric return as_float_helper<double>(func, s, idx, wcstod); 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric template<> 21881ad6265SDimitry Andric inline long double as_float(const string& func, const wstring& s, size_t* idx) { 2190b57cec5SDimitry Andric return as_float_helper<long double>(func, s, idx, wcstold); 2200b57cec5SDimitry Andric } 221349cc55cSDimitry Andric #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric } // unnamed namespace 2240b57cec5SDimitry Andric 22581ad6265SDimitry Andric int stoi(const string& str, size_t* idx, int base) { 2260b57cec5SDimitry Andric return as_integer<int>("stoi", str, idx, base); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 22981ad6265SDimitry Andric long stol(const string& str, size_t* idx, int base) { 2300b57cec5SDimitry Andric return as_integer<long>("stol", str, idx, base); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 23381ad6265SDimitry Andric unsigned long stoul(const string& str, size_t* idx, int base) { 2340b57cec5SDimitry Andric return as_integer<unsigned long>("stoul", str, idx, base); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 23781ad6265SDimitry Andric long long stoll(const string& str, size_t* idx, int base) { 2380b57cec5SDimitry Andric return as_integer<long long>("stoll", str, idx, base); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 24181ad6265SDimitry Andric unsigned long long stoull(const string& str, size_t* idx, int base) { 2420b57cec5SDimitry Andric return as_integer<unsigned long long>("stoull", str, idx, base); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 24581ad6265SDimitry Andric float stof(const string& str, size_t* idx) { 2460b57cec5SDimitry Andric return as_float<float>("stof", str, idx); 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 24981ad6265SDimitry Andric double stod(const string& str, size_t* idx) { 2500b57cec5SDimitry Andric return as_float<double>("stod", str, idx); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 25381ad6265SDimitry Andric long double stold(const string& str, size_t* idx) { 2540b57cec5SDimitry Andric return as_float<long double>("stold", str, idx); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 257349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 25881ad6265SDimitry Andric int stoi(const wstring& str, size_t* idx, int base) { 25981ad6265SDimitry Andric return as_integer<int>("stoi", str, idx, base); 26081ad6265SDimitry Andric } 26181ad6265SDimitry Andric 26281ad6265SDimitry Andric long stol(const wstring& str, size_t* idx, int base) { 26381ad6265SDimitry Andric return as_integer<long>("stol", str, idx, base); 26481ad6265SDimitry Andric } 26581ad6265SDimitry Andric 26681ad6265SDimitry Andric unsigned long stoul(const wstring& str, size_t* idx, int base) { 26781ad6265SDimitry Andric return as_integer<unsigned long>("stoul", str, idx, base); 26881ad6265SDimitry Andric } 26981ad6265SDimitry Andric 27081ad6265SDimitry Andric long long stoll(const wstring& str, size_t* idx, int base) { 27181ad6265SDimitry Andric return as_integer<long long>("stoll", str, idx, base); 27281ad6265SDimitry Andric } 27381ad6265SDimitry Andric 27481ad6265SDimitry Andric unsigned long long stoull(const wstring& str, size_t* idx, int base) { 27581ad6265SDimitry Andric return as_integer<unsigned long long>("stoull", str, idx, base); 27681ad6265SDimitry Andric } 27781ad6265SDimitry Andric 27881ad6265SDimitry Andric float stof(const wstring& str, size_t* idx) { 27981ad6265SDimitry Andric return as_float<float>("stof", str, idx); 28081ad6265SDimitry Andric } 28181ad6265SDimitry Andric 28281ad6265SDimitry Andric double stod(const wstring& str, size_t* idx) { 28381ad6265SDimitry Andric return as_float<double>("stod", str, idx); 28481ad6265SDimitry Andric } 28581ad6265SDimitry Andric 28681ad6265SDimitry Andric long double stold(const wstring& str, size_t* idx) { 2870b57cec5SDimitry Andric return as_float<long double>("stold", str, idx); 2880b57cec5SDimitry Andric } 28981ad6265SDimitry Andric #endif // !_LIBCPP_HAS_NO_WIDE_CHARACTERS 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // to_string 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric namespace 2940b57cec5SDimitry Andric { 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric // as_string 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric template<typename S, typename P, typename V > 29981ad6265SDimitry Andric inline S as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) { 3000b57cec5SDimitry Andric typedef typename S::size_type size_type; 3010b57cec5SDimitry Andric size_type available = s.size(); 30281ad6265SDimitry Andric while (true) { 3030b57cec5SDimitry Andric int status = sprintf_like(&s[0], available + 1, fmt, a); 30481ad6265SDimitry Andric if (status >= 0) { 3050b57cec5SDimitry Andric size_type used = static_cast<size_type>(status); 30681ad6265SDimitry Andric if (used <= available) { 3070b57cec5SDimitry Andric s.resize(used); 3080b57cec5SDimitry Andric break; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric available = used; // Assume this is advice of how much space we need. 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric else 3130b57cec5SDimitry Andric available = available * 2 + 1; 3140b57cec5SDimitry Andric s.resize(available); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric return s; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric template <class S> 3200b57cec5SDimitry Andric struct initial_string; 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric template <> 32381ad6265SDimitry Andric struct initial_string<string> { 32481ad6265SDimitry Andric string operator()() const { 3250b57cec5SDimitry Andric string s; 3260b57cec5SDimitry Andric s.resize(s.capacity()); 3270b57cec5SDimitry Andric return s; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric }; 3300b57cec5SDimitry Andric 331349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 3320b57cec5SDimitry Andric template <> 33381ad6265SDimitry Andric struct initial_string<wstring> { 33481ad6265SDimitry Andric wstring operator()() const { 3350b57cec5SDimitry Andric wstring s(20, wchar_t()); 3360b57cec5SDimitry Andric s.resize(s.capacity()); 3370b57cec5SDimitry Andric return s; 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric }; 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 3420b57cec5SDimitry Andric 34381ad6265SDimitry Andric inline wide_printf get_swprintf() { 3440b57cec5SDimitry Andric #ifndef _LIBCPP_MSVCRT 3450b57cec5SDimitry Andric return swprintf; 3460b57cec5SDimitry Andric #else 3470b57cec5SDimitry Andric return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf); 3480b57cec5SDimitry Andric #endif 3490b57cec5SDimitry Andric } 350349cc55cSDimitry Andric #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric template <typename S, typename V> 35381ad6265SDimitry Andric S i_to_string(V v) { 3540b57cec5SDimitry Andric // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers. 3550b57cec5SDimitry Andric // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented), 3560b57cec5SDimitry Andric // so we need +1 here. 3570b57cec5SDimitry Andric constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10 3580b57cec5SDimitry Andric char buf[bufsize]; 3590b57cec5SDimitry Andric const auto res = to_chars(buf, buf + bufsize, v); 3600b57cec5SDimitry Andric _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value"); 3610b57cec5SDimitry Andric return S(buf, res.ptr); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric } // unnamed namespace 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric string to_string (int val) { return i_to_string< string>(val); } 3670b57cec5SDimitry Andric string to_string (long val) { return i_to_string< string>(val); } 3680b57cec5SDimitry Andric string to_string (long long val) { return i_to_string< string>(val); } 3690b57cec5SDimitry Andric string to_string (unsigned val) { return i_to_string< string>(val); } 3700b57cec5SDimitry Andric string to_string (unsigned long val) { return i_to_string< string>(val); } 3710b57cec5SDimitry Andric string to_string (unsigned long long val) { return i_to_string< string>(val); } 3720b57cec5SDimitry Andric 373349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 3740b57cec5SDimitry Andric wstring to_wstring(int val) { return i_to_string<wstring>(val); } 3750b57cec5SDimitry Andric wstring to_wstring(long val) { return i_to_string<wstring>(val); } 3760b57cec5SDimitry Andric wstring to_wstring(long long val) { return i_to_string<wstring>(val); } 3770b57cec5SDimitry Andric wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); } 3780b57cec5SDimitry Andric wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); } 3790b57cec5SDimitry Andric wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); } 380349cc55cSDimitry Andric #endif 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } 3830b57cec5SDimitry Andric string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } 3840b57cec5SDimitry Andric string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); } 3850b57cec5SDimitry Andric 386349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 3870b57cec5SDimitry Andric wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); } 3880b57cec5SDimitry Andric wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); } 3890b57cec5SDimitry Andric wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); } 390349cc55cSDimitry Andric #endif 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric _LIBCPP_END_NAMESPACE_STD 393