xref: /llvm-project-15.0.7/libcxx/src/string.cpp (revision c19393c7)
1cbbf633eSHoward Hinnant //===------------------------- string.cpp ---------------------------------===//
2cbbf633eSHoward Hinnant //
3cbbf633eSHoward Hinnant //                     The LLVM Compiler Infrastructure
4cbbf633eSHoward Hinnant //
5412dbebeSHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open
6412dbebeSHoward Hinnant // Source Licenses. See LICENSE.TXT for details.
7cbbf633eSHoward Hinnant //
8cbbf633eSHoward Hinnant //===----------------------------------------------------------------------===//
9cbbf633eSHoward Hinnant 
10cbbf633eSHoward Hinnant #include "string"
11cbbf633eSHoward Hinnant #include "cstdlib"
12cbbf633eSHoward Hinnant #include "cwchar"
13cbbf633eSHoward Hinnant #include "cerrno"
149daaf577SHoward Hinnant #include "limits"
159daaf577SHoward Hinnant #include "stdexcept"
160be8f64cSHoward Hinnant #ifdef _LIBCPP_MSVCRT
17dbe81119SHoward Hinnant #include "support/win32/support.h"
180be8f64cSHoward Hinnant #endif // _LIBCPP_MSVCRT
191468d0ceSHoward Hinnant #include <stdio.h>
20cbbf633eSHoward Hinnant 
21cbbf633eSHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD
22cbbf633eSHoward Hinnant 
23cbbf633eSHoward Hinnant template class __basic_string_common<true>;
24cbbf633eSHoward Hinnant 
25cbbf633eSHoward Hinnant template class basic_string<char>;
26cbbf633eSHoward Hinnant template class basic_string<wchar_t>;
27cbbf633eSHoward Hinnant 
28cbbf633eSHoward Hinnant template
29cbbf633eSHoward Hinnant     string
30cbbf633eSHoward Hinnant     operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
31cbbf633eSHoward Hinnant 
329daaf577SHoward Hinnant namespace
339daaf577SHoward Hinnant {
349daaf577SHoward Hinnant 
359daaf577SHoward Hinnant template<typename T>
369daaf577SHoward Hinnant inline
379daaf577SHoward Hinnant void throw_helper( const string& msg )
389daaf577SHoward Hinnant {
399daaf577SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
409daaf577SHoward Hinnant     throw T( msg );
419daaf577SHoward Hinnant #else
42*c19393c7SEd Schouten     fprintf(stderr, "%s\n", msg.c_str());
439daaf577SHoward Hinnant     abort();
449daaf577SHoward Hinnant #endif
459daaf577SHoward Hinnant }
469daaf577SHoward Hinnant 
479daaf577SHoward Hinnant inline
489daaf577SHoward Hinnant void throw_from_string_out_of_range( const string& func )
499daaf577SHoward Hinnant {
509daaf577SHoward Hinnant     throw_helper<out_of_range>(func + ": out of range");
519daaf577SHoward Hinnant }
529daaf577SHoward Hinnant 
539daaf577SHoward Hinnant inline
549daaf577SHoward Hinnant void throw_from_string_invalid_arg( const string& func )
559daaf577SHoward Hinnant {
569daaf577SHoward Hinnant     throw_helper<invalid_argument>(func + ": no conversion");
579daaf577SHoward Hinnant }
589daaf577SHoward Hinnant 
599daaf577SHoward Hinnant // as_integer
609daaf577SHoward Hinnant 
619daaf577SHoward Hinnant template<typename V, typename S, typename F>
629daaf577SHoward Hinnant inline
639daaf577SHoward Hinnant V
649daaf577SHoward Hinnant as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
659daaf577SHoward Hinnant {
66d6bd7bf6SEric Fiselier     typename S::value_type* ptr = nullptr;
679daaf577SHoward Hinnant     const typename S::value_type* const p = str.c_str();
689daaf577SHoward Hinnant     typename remove_reference<decltype(errno)>::type errno_save = errno;
699daaf577SHoward Hinnant     errno = 0;
709daaf577SHoward Hinnant     V r = f(p, &ptr, base);
719daaf577SHoward Hinnant     swap(errno, errno_save);
729daaf577SHoward Hinnant     if (errno_save == ERANGE)
739daaf577SHoward Hinnant         throw_from_string_out_of_range(func);
749daaf577SHoward Hinnant     if (ptr == p)
759daaf577SHoward Hinnant         throw_from_string_invalid_arg(func);
769daaf577SHoward Hinnant     if (idx)
779daaf577SHoward Hinnant         *idx = static_cast<size_t>(ptr - p);
789daaf577SHoward Hinnant     return r;
799daaf577SHoward Hinnant }
809daaf577SHoward Hinnant 
819daaf577SHoward Hinnant template<typename V, typename S>
829daaf577SHoward Hinnant inline
839daaf577SHoward Hinnant V
849daaf577SHoward Hinnant as_integer(const string& func, const S& s, size_t* idx, int base);
859daaf577SHoward Hinnant 
869daaf577SHoward Hinnant // string
879daaf577SHoward Hinnant template<>
889daaf577SHoward Hinnant inline
899daaf577SHoward Hinnant int
909daaf577SHoward Hinnant as_integer(const string& func, const string& s, size_t* idx, int base )
919daaf577SHoward Hinnant {
928092c957SJoerg Sonnenberger     // Use long as no Standard string to integer exists.
939daaf577SHoward Hinnant     long r = as_integer_helper<long>( func, s, idx, base, strtol );
949daaf577SHoward Hinnant     if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
959daaf577SHoward Hinnant         throw_from_string_out_of_range(func);
969daaf577SHoward Hinnant     return static_cast<int>(r);
979daaf577SHoward Hinnant }
989daaf577SHoward Hinnant 
999daaf577SHoward Hinnant template<>
1009daaf577SHoward Hinnant inline
1019daaf577SHoward Hinnant long
1029daaf577SHoward Hinnant as_integer(const string& func, const string& s, size_t* idx, int base )
1039daaf577SHoward Hinnant {
1049daaf577SHoward Hinnant     return as_integer_helper<long>( func, s, idx, base, strtol );
1059daaf577SHoward Hinnant }
1069daaf577SHoward Hinnant 
1079daaf577SHoward Hinnant template<>
1089daaf577SHoward Hinnant inline
1099daaf577SHoward Hinnant unsigned long
1109daaf577SHoward Hinnant as_integer( const string& func, const string& s, size_t* idx, int base )
1119daaf577SHoward Hinnant {
1129daaf577SHoward Hinnant     return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
1139daaf577SHoward Hinnant }
1149daaf577SHoward Hinnant 
1159daaf577SHoward Hinnant template<>
1169daaf577SHoward Hinnant inline
1179daaf577SHoward Hinnant long long
1189daaf577SHoward Hinnant as_integer( const string& func, const string& s, size_t* idx, int base )
1199daaf577SHoward Hinnant {
1209daaf577SHoward Hinnant     return as_integer_helper<long long>( func, s, idx, base, strtoll );
1219daaf577SHoward Hinnant }
1229daaf577SHoward Hinnant 
1239daaf577SHoward Hinnant template<>
1249daaf577SHoward Hinnant inline
1259daaf577SHoward Hinnant unsigned long long
1269daaf577SHoward Hinnant as_integer( const string& func, const string& s, size_t* idx, int base )
1279daaf577SHoward Hinnant {
1289daaf577SHoward Hinnant     return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
1299daaf577SHoward Hinnant }
1309daaf577SHoward Hinnant 
1319daaf577SHoward Hinnant // wstring
1329daaf577SHoward Hinnant template<>
1339daaf577SHoward Hinnant inline
1349daaf577SHoward Hinnant int
1359daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base )
1369daaf577SHoward Hinnant {
1379daaf577SHoward Hinnant     // Use long as no Stantard string to integer exists.
1389daaf577SHoward Hinnant     long r = as_integer_helper<long>( func, s, idx, base, wcstol );
1399daaf577SHoward Hinnant     if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
1409daaf577SHoward Hinnant         throw_from_string_out_of_range(func);
1419daaf577SHoward Hinnant     return static_cast<int>(r);
1429daaf577SHoward Hinnant }
1439daaf577SHoward Hinnant 
1449daaf577SHoward Hinnant template<>
1459daaf577SHoward Hinnant inline
1469daaf577SHoward Hinnant long
1479daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base )
1489daaf577SHoward Hinnant {
1499daaf577SHoward Hinnant     return as_integer_helper<long>( func, s, idx, base, wcstol );
1509daaf577SHoward Hinnant }
1519daaf577SHoward Hinnant 
1529daaf577SHoward Hinnant template<>
1539daaf577SHoward Hinnant inline
1549daaf577SHoward Hinnant unsigned long
1559daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base )
1569daaf577SHoward Hinnant {
1579daaf577SHoward Hinnant     return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
1589daaf577SHoward Hinnant }
1599daaf577SHoward Hinnant 
1609daaf577SHoward Hinnant template<>
1619daaf577SHoward Hinnant inline
1629daaf577SHoward Hinnant long long
1639daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base )
1649daaf577SHoward Hinnant {
1659daaf577SHoward Hinnant     return as_integer_helper<long long>( func, s, idx, base, wcstoll );
1669daaf577SHoward Hinnant }
1679daaf577SHoward Hinnant 
1689daaf577SHoward Hinnant template<>
1699daaf577SHoward Hinnant inline
1709daaf577SHoward Hinnant unsigned long long
1719daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base )
1729daaf577SHoward Hinnant {
1739daaf577SHoward Hinnant     return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
1749daaf577SHoward Hinnant }
1759daaf577SHoward Hinnant 
1769daaf577SHoward Hinnant // as_float
1779daaf577SHoward Hinnant 
1789daaf577SHoward Hinnant template<typename V, typename S, typename F>
1799daaf577SHoward Hinnant inline
1809daaf577SHoward Hinnant V
1819daaf577SHoward Hinnant as_float_helper(const string& func, const S& str, size_t* idx, F f )
1829daaf577SHoward Hinnant {
183d6bd7bf6SEric Fiselier     typename S::value_type* ptr = nullptr;
1849daaf577SHoward Hinnant     const typename S::value_type* const p = str.c_str();
1859daaf577SHoward Hinnant     typename remove_reference<decltype(errno)>::type errno_save = errno;
1869daaf577SHoward Hinnant     errno = 0;
1879daaf577SHoward Hinnant     V r = f(p, &ptr);
1889daaf577SHoward Hinnant     swap(errno, errno_save);
1899daaf577SHoward Hinnant     if (errno_save == ERANGE)
1909daaf577SHoward Hinnant         throw_from_string_out_of_range(func);
1919daaf577SHoward Hinnant     if (ptr == p)
1929daaf577SHoward Hinnant         throw_from_string_invalid_arg(func);
1939daaf577SHoward Hinnant     if (idx)
1949daaf577SHoward Hinnant         *idx = static_cast<size_t>(ptr - p);
1959daaf577SHoward Hinnant     return r;
1969daaf577SHoward Hinnant }
1979daaf577SHoward Hinnant 
1989daaf577SHoward Hinnant template<typename V, typename S>
1999daaf577SHoward Hinnant inline
2009daaf577SHoward Hinnant V as_float( const string& func, const S& s, size_t* idx = nullptr );
2019daaf577SHoward Hinnant 
2029daaf577SHoward Hinnant template<>
2039daaf577SHoward Hinnant inline
2049daaf577SHoward Hinnant float
2059daaf577SHoward Hinnant as_float( const string& func, const string& s, size_t* idx )
2069daaf577SHoward Hinnant {
2079daaf577SHoward Hinnant     return as_float_helper<float>( func, s, idx, strtof );
2089daaf577SHoward Hinnant }
2099daaf577SHoward Hinnant 
2109daaf577SHoward Hinnant template<>
2119daaf577SHoward Hinnant inline
2129daaf577SHoward Hinnant double
2139daaf577SHoward Hinnant as_float(const string& func, const string& s, size_t* idx )
2149daaf577SHoward Hinnant {
2159daaf577SHoward Hinnant     return as_float_helper<double>( func, s, idx, strtod );
2169daaf577SHoward Hinnant }
2179daaf577SHoward Hinnant 
2189daaf577SHoward Hinnant template<>
2199daaf577SHoward Hinnant inline
2209daaf577SHoward Hinnant long double
2219daaf577SHoward Hinnant as_float( const string& func, const string& s, size_t* idx )
2229daaf577SHoward Hinnant {
2239daaf577SHoward Hinnant     return as_float_helper<long double>( func, s, idx, strtold );
2249daaf577SHoward Hinnant }
2259daaf577SHoward Hinnant 
2269daaf577SHoward Hinnant template<>
2279daaf577SHoward Hinnant inline
2289daaf577SHoward Hinnant float
2299daaf577SHoward Hinnant as_float( const string& func, const wstring& s, size_t* idx )
2309daaf577SHoward Hinnant {
2319daaf577SHoward Hinnant     return as_float_helper<float>( func, s, idx, wcstof );
2329daaf577SHoward Hinnant }
2339daaf577SHoward Hinnant 
2349daaf577SHoward Hinnant template<>
2359daaf577SHoward Hinnant inline
2369daaf577SHoward Hinnant double
2379daaf577SHoward Hinnant as_float( const string& func, const wstring& s, size_t* idx )
2389daaf577SHoward Hinnant {
2399daaf577SHoward Hinnant     return as_float_helper<double>( func, s, idx, wcstod );
2409daaf577SHoward Hinnant }
2419daaf577SHoward Hinnant 
2429daaf577SHoward Hinnant template<>
2439daaf577SHoward Hinnant inline
2449daaf577SHoward Hinnant long double
2459daaf577SHoward Hinnant as_float( const string& func, const wstring& s, size_t* idx )
2469daaf577SHoward Hinnant {
2479daaf577SHoward Hinnant     return as_float_helper<long double>( func, s, idx, wcstold );
2489daaf577SHoward Hinnant }
2499daaf577SHoward Hinnant 
2509daaf577SHoward Hinnant }  // unnamed namespace
2519daaf577SHoward Hinnant 
252cbbf633eSHoward Hinnant int
253cbbf633eSHoward Hinnant stoi(const string& str, size_t* idx, int base)
254cbbf633eSHoward Hinnant {
2559daaf577SHoward Hinnant     return as_integer<int>( "stoi", str, idx, base );
256cbbf633eSHoward Hinnant }
257cbbf633eSHoward Hinnant 
258cbbf633eSHoward Hinnant int
259cbbf633eSHoward Hinnant stoi(const wstring& str, size_t* idx, int base)
260cbbf633eSHoward Hinnant {
2619daaf577SHoward Hinnant     return as_integer<int>( "stoi", str, idx, base );
262cbbf633eSHoward Hinnant }
263cbbf633eSHoward Hinnant 
264cbbf633eSHoward Hinnant long
265cbbf633eSHoward Hinnant stol(const string& str, size_t* idx, int base)
266cbbf633eSHoward Hinnant {
2679daaf577SHoward Hinnant     return as_integer<long>( "stol", str, idx, base );
268cbbf633eSHoward Hinnant }
269cbbf633eSHoward Hinnant 
270cbbf633eSHoward Hinnant long
271cbbf633eSHoward Hinnant stol(const wstring& str, size_t* idx, int base)
272cbbf633eSHoward Hinnant {
2739daaf577SHoward Hinnant     return as_integer<long>( "stol", str, idx, base );
274cbbf633eSHoward Hinnant }
275cbbf633eSHoward Hinnant 
276cbbf633eSHoward Hinnant unsigned long
277cbbf633eSHoward Hinnant stoul(const string& str, size_t* idx, int base)
278cbbf633eSHoward Hinnant {
2799daaf577SHoward Hinnant     return as_integer<unsigned long>( "stoul", str, idx, base );
280cbbf633eSHoward Hinnant }
281cbbf633eSHoward Hinnant 
282cbbf633eSHoward Hinnant unsigned long
283cbbf633eSHoward Hinnant stoul(const wstring& str, size_t* idx, int base)
284cbbf633eSHoward Hinnant {
2859daaf577SHoward Hinnant     return as_integer<unsigned long>( "stoul", str, idx, base );
286cbbf633eSHoward Hinnant }
287cbbf633eSHoward Hinnant 
288cbbf633eSHoward Hinnant long long
289cbbf633eSHoward Hinnant stoll(const string& str, size_t* idx, int base)
290cbbf633eSHoward Hinnant {
2919daaf577SHoward Hinnant     return as_integer<long long>( "stoll", str, idx, base );
292cbbf633eSHoward Hinnant }
293cbbf633eSHoward Hinnant 
294cbbf633eSHoward Hinnant long long
295cbbf633eSHoward Hinnant stoll(const wstring& str, size_t* idx, int base)
296cbbf633eSHoward Hinnant {
2979daaf577SHoward Hinnant     return as_integer<long long>( "stoll", str, idx, base );
298cbbf633eSHoward Hinnant }
299cbbf633eSHoward Hinnant 
300cbbf633eSHoward Hinnant unsigned long long
301cbbf633eSHoward Hinnant stoull(const string& str, size_t* idx, int base)
302cbbf633eSHoward Hinnant {
3039daaf577SHoward Hinnant     return as_integer<unsigned long long>( "stoull", str, idx, base );
304cbbf633eSHoward Hinnant }
305cbbf633eSHoward Hinnant 
306cbbf633eSHoward Hinnant unsigned long long
307cbbf633eSHoward Hinnant stoull(const wstring& str, size_t* idx, int base)
308cbbf633eSHoward Hinnant {
3099daaf577SHoward Hinnant     return as_integer<unsigned long long>( "stoull", str, idx, base );
310cbbf633eSHoward Hinnant }
311cbbf633eSHoward Hinnant 
312cbbf633eSHoward Hinnant float
313cbbf633eSHoward Hinnant stof(const string& str, size_t* idx)
314cbbf633eSHoward Hinnant {
3159daaf577SHoward Hinnant     return as_float<float>( "stof", str, idx );
316cbbf633eSHoward Hinnant }
317cbbf633eSHoward Hinnant 
318cbbf633eSHoward Hinnant float
319cbbf633eSHoward Hinnant stof(const wstring& str, size_t* idx)
320cbbf633eSHoward Hinnant {
3219daaf577SHoward Hinnant     return as_float<float>( "stof", str, idx );
322cbbf633eSHoward Hinnant }
323cbbf633eSHoward Hinnant 
324cbbf633eSHoward Hinnant double
325cbbf633eSHoward Hinnant stod(const string& str, size_t* idx)
326cbbf633eSHoward Hinnant {
3279daaf577SHoward Hinnant     return as_float<double>( "stod", str, idx );
328cbbf633eSHoward Hinnant }
329cbbf633eSHoward Hinnant 
330cbbf633eSHoward Hinnant double
331cbbf633eSHoward Hinnant stod(const wstring& str, size_t* idx)
332cbbf633eSHoward Hinnant {
3339daaf577SHoward Hinnant     return as_float<double>( "stod", str, idx );
334cbbf633eSHoward Hinnant }
335cbbf633eSHoward Hinnant 
336cbbf633eSHoward Hinnant long double
337cbbf633eSHoward Hinnant stold(const string& str, size_t* idx)
338cbbf633eSHoward Hinnant {
3399daaf577SHoward Hinnant     return as_float<long double>( "stold", str, idx );
340cbbf633eSHoward Hinnant }
341cbbf633eSHoward Hinnant 
342cbbf633eSHoward Hinnant long double
343cbbf633eSHoward Hinnant stold(const wstring& str, size_t* idx)
344cbbf633eSHoward Hinnant {
3459daaf577SHoward Hinnant     return as_float<long double>( "stold", str, idx );
346cbbf633eSHoward Hinnant }
347cbbf633eSHoward Hinnant 
3489daaf577SHoward Hinnant // to_string
3499daaf577SHoward Hinnant 
3509daaf577SHoward Hinnant namespace
3519daaf577SHoward Hinnant {
3529daaf577SHoward Hinnant 
3539daaf577SHoward Hinnant // as_string
3549daaf577SHoward Hinnant 
3559daaf577SHoward Hinnant template<typename S, typename P, typename V >
3569daaf577SHoward Hinnant inline
3579daaf577SHoward Hinnant S
3589daaf577SHoward Hinnant as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
3599daaf577SHoward Hinnant {
3609daaf577SHoward Hinnant     typedef typename S::size_type size_type;
3619daaf577SHoward Hinnant     size_type available = s.size();
3629daaf577SHoward Hinnant     while (true)
3639daaf577SHoward Hinnant     {
3649daaf577SHoward Hinnant         int status = sprintf_like(&s[0], available + 1, fmt, a);
3659daaf577SHoward Hinnant         if ( status >= 0 )
3669daaf577SHoward Hinnant         {
3679daaf577SHoward Hinnant             size_type used = static_cast<size_type>(status);
3689daaf577SHoward Hinnant             if ( used <= available )
3699daaf577SHoward Hinnant             {
3709daaf577SHoward Hinnant                 s.resize( used );
3719daaf577SHoward Hinnant                 break;
3729daaf577SHoward Hinnant             }
3739daaf577SHoward Hinnant             available = used; // Assume this is advice of how much space we need.
3749daaf577SHoward Hinnant         }
3759daaf577SHoward Hinnant         else
3769daaf577SHoward Hinnant             available = available * 2 + 1;
3779daaf577SHoward Hinnant         s.resize(available);
3789daaf577SHoward Hinnant     }
3799daaf577SHoward Hinnant     return s;
3809daaf577SHoward Hinnant }
3819daaf577SHoward Hinnant 
3829daaf577SHoward Hinnant template <class S, class V, bool = is_floating_point<V>::value>
3839daaf577SHoward Hinnant struct initial_string;
3849daaf577SHoward Hinnant 
3859daaf577SHoward Hinnant template <class V, bool b>
3869daaf577SHoward Hinnant struct initial_string<string, V, b>
3879daaf577SHoward Hinnant {
3889daaf577SHoward Hinnant     string
3899daaf577SHoward Hinnant     operator()() const
390cbbf633eSHoward Hinnant     {
391cbbf633eSHoward Hinnant         string s;
392cbbf633eSHoward Hinnant         s.resize(s.capacity());
393cbbf633eSHoward Hinnant         return s;
394cbbf633eSHoward Hinnant     }
3959daaf577SHoward Hinnant };
396cbbf633eSHoward Hinnant 
3979daaf577SHoward Hinnant template <class V>
3989daaf577SHoward Hinnant struct initial_string<wstring, V, false>
399cbbf633eSHoward Hinnant {
4009daaf577SHoward Hinnant     wstring
4019daaf577SHoward Hinnant     operator()() const
402cbbf633eSHoward Hinnant     {
403cbbf633eSHoward Hinnant         const size_t n = (numeric_limits<unsigned long long>::digits / 3)
404cbbf633eSHoward Hinnant           + ((numeric_limits<unsigned long long>::digits % 3) != 0)
405cbbf633eSHoward Hinnant           + 1;
406cbbf633eSHoward Hinnant         wstring s(n, wchar_t());
407cbbf633eSHoward Hinnant         s.resize(s.capacity());
408cbbf633eSHoward Hinnant         return s;
409cbbf633eSHoward Hinnant     }
4109daaf577SHoward Hinnant };
4119daaf577SHoward Hinnant 
4129daaf577SHoward Hinnant template <class V>
4139daaf577SHoward Hinnant struct initial_string<wstring, V, true>
4149daaf577SHoward Hinnant {
4159daaf577SHoward Hinnant     wstring
4169daaf577SHoward Hinnant     operator()() const
4179daaf577SHoward Hinnant     {
4189daaf577SHoward Hinnant         wstring s(20, wchar_t());
4199daaf577SHoward Hinnant         s.resize(s.capacity());
4209daaf577SHoward Hinnant         return s;
4219daaf577SHoward Hinnant     }
4229daaf577SHoward Hinnant };
4239daaf577SHoward Hinnant 
4249daaf577SHoward Hinnant typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
4259daaf577SHoward Hinnant 
4269daaf577SHoward Hinnant inline
4279daaf577SHoward Hinnant wide_printf
4289daaf577SHoward Hinnant get_swprintf()
4299daaf577SHoward Hinnant {
4300be8f64cSHoward Hinnant #ifndef _LIBCPP_MSVCRT
4319daaf577SHoward Hinnant     return swprintf;
4329daaf577SHoward Hinnant #else
4339daaf577SHoward Hinnant     return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
4349daaf577SHoward Hinnant #endif
4359daaf577SHoward Hinnant }
4369daaf577SHoward Hinnant 
4379daaf577SHoward Hinnant }  // unnamed namespace
4389daaf577SHoward Hinnant 
4399daaf577SHoward Hinnant string to_string(int val)
4409daaf577SHoward Hinnant {
4419daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, int>()(), "%d", val);
4429daaf577SHoward Hinnant }
4439daaf577SHoward Hinnant 
4449daaf577SHoward Hinnant string to_string(unsigned val)
4459daaf577SHoward Hinnant {
4469daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
4479daaf577SHoward Hinnant }
4489daaf577SHoward Hinnant 
4499daaf577SHoward Hinnant string to_string(long val)
4509daaf577SHoward Hinnant {
4519daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
4529daaf577SHoward Hinnant }
4539daaf577SHoward Hinnant 
4549daaf577SHoward Hinnant string to_string(unsigned long val)
4559daaf577SHoward Hinnant {
4569daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
4579daaf577SHoward Hinnant }
4589daaf577SHoward Hinnant 
4599daaf577SHoward Hinnant string to_string(long long val)
4609daaf577SHoward Hinnant {
4619daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
4629daaf577SHoward Hinnant }
4639daaf577SHoward Hinnant 
4649daaf577SHoward Hinnant string to_string(unsigned long long val)
4659daaf577SHoward Hinnant {
4669daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
4679daaf577SHoward Hinnant }
4689daaf577SHoward Hinnant 
4699daaf577SHoward Hinnant string to_string(float val)
4709daaf577SHoward Hinnant {
4719daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, float>()(), "%f", val);
4729daaf577SHoward Hinnant }
4739daaf577SHoward Hinnant 
4749daaf577SHoward Hinnant string to_string(double val)
4759daaf577SHoward Hinnant {
4769daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, double>()(), "%f", val);
4779daaf577SHoward Hinnant }
4789daaf577SHoward Hinnant 
4799daaf577SHoward Hinnant string to_string(long double val)
4809daaf577SHoward Hinnant {
4819daaf577SHoward Hinnant     return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
4829daaf577SHoward Hinnant }
4839daaf577SHoward Hinnant 
4849daaf577SHoward Hinnant wstring to_wstring(int val)
4859daaf577SHoward Hinnant {
4869daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
4879daaf577SHoward Hinnant }
4889daaf577SHoward Hinnant 
4899daaf577SHoward Hinnant wstring to_wstring(unsigned val)
4909daaf577SHoward Hinnant {
4919daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
4929daaf577SHoward Hinnant }
4939daaf577SHoward Hinnant 
4949daaf577SHoward Hinnant wstring to_wstring(long val)
4959daaf577SHoward Hinnant {
4969daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
4979daaf577SHoward Hinnant }
4989daaf577SHoward Hinnant 
4999daaf577SHoward Hinnant wstring to_wstring(unsigned long val)
5009daaf577SHoward Hinnant {
5019daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
5029daaf577SHoward Hinnant }
5039daaf577SHoward Hinnant 
5049daaf577SHoward Hinnant wstring to_wstring(long long val)
5059daaf577SHoward Hinnant {
5069daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
5079daaf577SHoward Hinnant }
5089daaf577SHoward Hinnant 
5099daaf577SHoward Hinnant wstring to_wstring(unsigned long long val)
5109daaf577SHoward Hinnant {
5119daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
5129daaf577SHoward Hinnant }
513cbbf633eSHoward Hinnant 
514cbbf633eSHoward Hinnant wstring to_wstring(float val)
515cbbf633eSHoward Hinnant {
5169daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
517cbbf633eSHoward Hinnant }
518cbbf633eSHoward Hinnant 
519cbbf633eSHoward Hinnant wstring to_wstring(double val)
520cbbf633eSHoward Hinnant {
5219daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
522cbbf633eSHoward Hinnant }
523cbbf633eSHoward Hinnant 
524cbbf633eSHoward Hinnant wstring to_wstring(long double val)
525cbbf633eSHoward Hinnant {
5269daaf577SHoward Hinnant     return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
527cbbf633eSHoward Hinnant }
528cbbf633eSHoward Hinnant _LIBCPP_END_NAMESPACE_STD
529