xref: /minix3/external/bsd/libc++/dist/libcxx/src/string.cpp (revision 4684ddb6aab0b36791c8099bc705d6140b3d05d0)
1*4684ddb6SLionel Sambuc //===------------------------- string.cpp ---------------------------------===//
2*4684ddb6SLionel Sambuc //
3*4684ddb6SLionel Sambuc //                     The LLVM Compiler Infrastructure
4*4684ddb6SLionel Sambuc //
5*4684ddb6SLionel Sambuc // This file is dual licensed under the MIT and the University of Illinois Open
6*4684ddb6SLionel Sambuc // Source Licenses. See LICENSE.TXT for details.
7*4684ddb6SLionel Sambuc //
8*4684ddb6SLionel Sambuc //===----------------------------------------------------------------------===//
9*4684ddb6SLionel Sambuc 
10*4684ddb6SLionel Sambuc #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
11*4684ddb6SLionel Sambuc 
12*4684ddb6SLionel Sambuc #include "string"
13*4684ddb6SLionel Sambuc #include "cstdlib"
14*4684ddb6SLionel Sambuc #include "cwchar"
15*4684ddb6SLionel Sambuc #include "cerrno"
16*4684ddb6SLionel Sambuc #include "limits"
17*4684ddb6SLionel Sambuc #include "stdexcept"
18*4684ddb6SLionel Sambuc #ifdef _LIBCPP_MSVCRT
19*4684ddb6SLionel Sambuc #include "support/win32/support.h"
20*4684ddb6SLionel Sambuc #endif // _LIBCPP_MSVCRT
21*4684ddb6SLionel Sambuc #include <stdio.h>
22*4684ddb6SLionel Sambuc 
23*4684ddb6SLionel Sambuc _LIBCPP_BEGIN_NAMESPACE_STD
24*4684ddb6SLionel Sambuc 
25*4684ddb6SLionel Sambuc template class __basic_string_common<true>;
26*4684ddb6SLionel Sambuc 
27*4684ddb6SLionel Sambuc template class basic_string<char>;
28*4684ddb6SLionel Sambuc template class basic_string<wchar_t>;
29*4684ddb6SLionel Sambuc 
30*4684ddb6SLionel Sambuc template
31*4684ddb6SLionel Sambuc     string
32*4684ddb6SLionel Sambuc     operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
33*4684ddb6SLionel Sambuc 
34*4684ddb6SLionel Sambuc namespace
35*4684ddb6SLionel Sambuc {
36*4684ddb6SLionel Sambuc 
37*4684ddb6SLionel Sambuc template<typename T>
38*4684ddb6SLionel Sambuc inline
39*4684ddb6SLionel Sambuc void throw_helper( const string& msg )
40*4684ddb6SLionel Sambuc {
41*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
42*4684ddb6SLionel Sambuc     throw T( msg );
43*4684ddb6SLionel Sambuc #else
44*4684ddb6SLionel Sambuc     printf("%s\n", msg.c_str());
45*4684ddb6SLionel Sambuc     abort();
46*4684ddb6SLionel Sambuc #endif
47*4684ddb6SLionel Sambuc }
48*4684ddb6SLionel Sambuc 
49*4684ddb6SLionel Sambuc inline
50*4684ddb6SLionel Sambuc void throw_from_string_out_of_range( const string& func )
51*4684ddb6SLionel Sambuc {
52*4684ddb6SLionel Sambuc     throw_helper<out_of_range>(func + ": out of range");
53*4684ddb6SLionel Sambuc }
54*4684ddb6SLionel Sambuc 
55*4684ddb6SLionel Sambuc inline
56*4684ddb6SLionel Sambuc void throw_from_string_invalid_arg( const string& func )
57*4684ddb6SLionel Sambuc {
58*4684ddb6SLionel Sambuc     throw_helper<invalid_argument>(func + ": no conversion");
59*4684ddb6SLionel Sambuc }
60*4684ddb6SLionel Sambuc 
61*4684ddb6SLionel Sambuc // as_integer
62*4684ddb6SLionel Sambuc 
63*4684ddb6SLionel Sambuc template<typename V, typename S, typename F>
64*4684ddb6SLionel Sambuc inline
65*4684ddb6SLionel Sambuc V
66*4684ddb6SLionel Sambuc as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
67*4684ddb6SLionel Sambuc {
68*4684ddb6SLionel Sambuc     typename S::value_type* ptr;
69*4684ddb6SLionel Sambuc     const typename S::value_type* const p = str.c_str();
70*4684ddb6SLionel Sambuc     typename remove_reference<decltype(errno)>::type errno_save = errno;
71*4684ddb6SLionel Sambuc     errno = 0;
72*4684ddb6SLionel Sambuc     V r = f(p, &ptr, base);
73*4684ddb6SLionel Sambuc     swap(errno, errno_save);
74*4684ddb6SLionel Sambuc     if (errno_save == ERANGE)
75*4684ddb6SLionel Sambuc         throw_from_string_out_of_range(func);
76*4684ddb6SLionel Sambuc     if (ptr == p)
77*4684ddb6SLionel Sambuc         throw_from_string_invalid_arg(func);
78*4684ddb6SLionel Sambuc     if (idx)
79*4684ddb6SLionel Sambuc         *idx = static_cast<size_t>(ptr - p);
80*4684ddb6SLionel Sambuc     return r;
81*4684ddb6SLionel Sambuc }
82*4684ddb6SLionel Sambuc 
83*4684ddb6SLionel Sambuc template<typename V, typename S>
84*4684ddb6SLionel Sambuc inline
85*4684ddb6SLionel Sambuc V
86*4684ddb6SLionel Sambuc as_integer(const string& func, const S& s, size_t* idx, int base);
87*4684ddb6SLionel Sambuc 
88*4684ddb6SLionel Sambuc // string
89*4684ddb6SLionel Sambuc template<>
90*4684ddb6SLionel Sambuc inline
91*4684ddb6SLionel Sambuc int
92*4684ddb6SLionel Sambuc as_integer(const string& func, const string& s, size_t* idx, int base )
93*4684ddb6SLionel Sambuc {
94*4684ddb6SLionel Sambuc     // Use long as no Standard string to integer exists.
95*4684ddb6SLionel Sambuc     long r = as_integer_helper<long>( func, s, idx, base, strtol );
96*4684ddb6SLionel Sambuc     if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
97*4684ddb6SLionel Sambuc         throw_from_string_out_of_range(func);
98*4684ddb6SLionel Sambuc     return static_cast<int>(r);
99*4684ddb6SLionel Sambuc }
100*4684ddb6SLionel Sambuc 
101*4684ddb6SLionel Sambuc template<>
102*4684ddb6SLionel Sambuc inline
103*4684ddb6SLionel Sambuc long
104*4684ddb6SLionel Sambuc as_integer(const string& func, const string& s, size_t* idx, int base )
105*4684ddb6SLionel Sambuc {
106*4684ddb6SLionel Sambuc     return as_integer_helper<long>( func, s, idx, base, strtol );
107*4684ddb6SLionel Sambuc }
108*4684ddb6SLionel Sambuc 
109*4684ddb6SLionel Sambuc template<>
110*4684ddb6SLionel Sambuc inline
111*4684ddb6SLionel Sambuc unsigned long
112*4684ddb6SLionel Sambuc as_integer( const string& func, const string& s, size_t* idx, int base )
113*4684ddb6SLionel Sambuc {
114*4684ddb6SLionel Sambuc     return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
115*4684ddb6SLionel Sambuc }
116*4684ddb6SLionel Sambuc 
117*4684ddb6SLionel Sambuc template<>
118*4684ddb6SLionel Sambuc inline
119*4684ddb6SLionel Sambuc long long
120*4684ddb6SLionel Sambuc as_integer( const string& func, const string& s, size_t* idx, int base )
121*4684ddb6SLionel Sambuc {
122*4684ddb6SLionel Sambuc     return as_integer_helper<long long>( func, s, idx, base, strtoll );
123*4684ddb6SLionel Sambuc }
124*4684ddb6SLionel Sambuc 
125*4684ddb6SLionel Sambuc template<>
126*4684ddb6SLionel Sambuc inline
127*4684ddb6SLionel Sambuc unsigned long long
128*4684ddb6SLionel Sambuc as_integer( const string& func, const string& s, size_t* idx, int base )
129*4684ddb6SLionel Sambuc {
130*4684ddb6SLionel Sambuc     return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
131*4684ddb6SLionel Sambuc }
132*4684ddb6SLionel Sambuc 
133*4684ddb6SLionel Sambuc // wstring
134*4684ddb6SLionel Sambuc template<>
135*4684ddb6SLionel Sambuc inline
136*4684ddb6SLionel Sambuc int
137*4684ddb6SLionel Sambuc as_integer( const string& func, const wstring& s, size_t* idx, int base )
138*4684ddb6SLionel Sambuc {
139*4684ddb6SLionel Sambuc     // Use long as no Stantard string to integer exists.
140*4684ddb6SLionel Sambuc     long r = as_integer_helper<long>( func, s, idx, base, wcstol );
141*4684ddb6SLionel Sambuc     if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
142*4684ddb6SLionel Sambuc         throw_from_string_out_of_range(func);
143*4684ddb6SLionel Sambuc     return static_cast<int>(r);
144*4684ddb6SLionel Sambuc }
145*4684ddb6SLionel Sambuc 
146*4684ddb6SLionel Sambuc template<>
147*4684ddb6SLionel Sambuc inline
148*4684ddb6SLionel Sambuc long
149*4684ddb6SLionel Sambuc as_integer( const string& func, const wstring& s, size_t* idx, int base )
150*4684ddb6SLionel Sambuc {
151*4684ddb6SLionel Sambuc     return as_integer_helper<long>( func, s, idx, base, wcstol );
152*4684ddb6SLionel Sambuc }
153*4684ddb6SLionel Sambuc 
154*4684ddb6SLionel Sambuc template<>
155*4684ddb6SLionel Sambuc inline
156*4684ddb6SLionel Sambuc unsigned long
157*4684ddb6SLionel Sambuc as_integer( const string& func, const wstring& s, size_t* idx, int base )
158*4684ddb6SLionel Sambuc {
159*4684ddb6SLionel Sambuc     return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
160*4684ddb6SLionel Sambuc }
161*4684ddb6SLionel Sambuc 
162*4684ddb6SLionel Sambuc template<>
163*4684ddb6SLionel Sambuc inline
164*4684ddb6SLionel Sambuc long long
165*4684ddb6SLionel Sambuc as_integer( const string& func, const wstring& s, size_t* idx, int base )
166*4684ddb6SLionel Sambuc {
167*4684ddb6SLionel Sambuc     return as_integer_helper<long long>( func, s, idx, base, wcstoll );
168*4684ddb6SLionel Sambuc }
169*4684ddb6SLionel Sambuc 
170*4684ddb6SLionel Sambuc template<>
171*4684ddb6SLionel Sambuc inline
172*4684ddb6SLionel Sambuc unsigned long long
173*4684ddb6SLionel Sambuc as_integer( const string& func, const wstring& s, size_t* idx, int base )
174*4684ddb6SLionel Sambuc {
175*4684ddb6SLionel Sambuc     return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
176*4684ddb6SLionel Sambuc }
177*4684ddb6SLionel Sambuc 
178*4684ddb6SLionel Sambuc // as_float
179*4684ddb6SLionel Sambuc 
180*4684ddb6SLionel Sambuc template<typename V, typename S, typename F>
181*4684ddb6SLionel Sambuc inline
182*4684ddb6SLionel Sambuc V
183*4684ddb6SLionel Sambuc as_float_helper(const string& func, const S& str, size_t* idx, F f )
184*4684ddb6SLionel Sambuc {
185*4684ddb6SLionel Sambuc     typename S::value_type* ptr;
186*4684ddb6SLionel Sambuc     const typename S::value_type* const p = str.c_str();
187*4684ddb6SLionel Sambuc     typename remove_reference<decltype(errno)>::type errno_save = errno;
188*4684ddb6SLionel Sambuc     errno = 0;
189*4684ddb6SLionel Sambuc     V r = f(p, &ptr);
190*4684ddb6SLionel Sambuc     swap(errno, errno_save);
191*4684ddb6SLionel Sambuc     if (errno_save == ERANGE)
192*4684ddb6SLionel Sambuc         throw_from_string_out_of_range(func);
193*4684ddb6SLionel Sambuc     if (ptr == p)
194*4684ddb6SLionel Sambuc         throw_from_string_invalid_arg(func);
195*4684ddb6SLionel Sambuc     if (idx)
196*4684ddb6SLionel Sambuc         *idx = static_cast<size_t>(ptr - p);
197*4684ddb6SLionel Sambuc     return r;
198*4684ddb6SLionel Sambuc }
199*4684ddb6SLionel Sambuc 
200*4684ddb6SLionel Sambuc template<typename V, typename S>
201*4684ddb6SLionel Sambuc inline
202*4684ddb6SLionel Sambuc V as_float( const string& func, const S& s, size_t* idx = nullptr );
203*4684ddb6SLionel Sambuc 
204*4684ddb6SLionel Sambuc template<>
205*4684ddb6SLionel Sambuc inline
206*4684ddb6SLionel Sambuc float
207*4684ddb6SLionel Sambuc as_float( const string& func, const string& s, size_t* idx )
208*4684ddb6SLionel Sambuc {
209*4684ddb6SLionel Sambuc     return as_float_helper<float>( func, s, idx, strtof );
210*4684ddb6SLionel Sambuc }
211*4684ddb6SLionel Sambuc 
212*4684ddb6SLionel Sambuc template<>
213*4684ddb6SLionel Sambuc inline
214*4684ddb6SLionel Sambuc double
215*4684ddb6SLionel Sambuc as_float(const string& func, const string& s, size_t* idx )
216*4684ddb6SLionel Sambuc {
217*4684ddb6SLionel Sambuc     return as_float_helper<double>( func, s, idx, strtod );
218*4684ddb6SLionel Sambuc }
219*4684ddb6SLionel Sambuc 
220*4684ddb6SLionel Sambuc template<>
221*4684ddb6SLionel Sambuc inline
222*4684ddb6SLionel Sambuc long double
223*4684ddb6SLionel Sambuc as_float( const string& func, const string& s, size_t* idx )
224*4684ddb6SLionel Sambuc {
225*4684ddb6SLionel Sambuc     return as_float_helper<long double>( func, s, idx, strtold );
226*4684ddb6SLionel Sambuc }
227*4684ddb6SLionel Sambuc 
228*4684ddb6SLionel Sambuc template<>
229*4684ddb6SLionel Sambuc inline
230*4684ddb6SLionel Sambuc float
231*4684ddb6SLionel Sambuc as_float( const string& func, const wstring& s, size_t* idx )
232*4684ddb6SLionel Sambuc {
233*4684ddb6SLionel Sambuc     return as_float_helper<float>( func, s, idx, wcstof );
234*4684ddb6SLionel Sambuc }
235*4684ddb6SLionel Sambuc 
236*4684ddb6SLionel Sambuc template<>
237*4684ddb6SLionel Sambuc inline
238*4684ddb6SLionel Sambuc double
239*4684ddb6SLionel Sambuc as_float( const string& func, const wstring& s, size_t* idx )
240*4684ddb6SLionel Sambuc {
241*4684ddb6SLionel Sambuc     return as_float_helper<double>( func, s, idx, wcstod );
242*4684ddb6SLionel Sambuc }
243*4684ddb6SLionel Sambuc 
244*4684ddb6SLionel Sambuc template<>
245*4684ddb6SLionel Sambuc inline
246*4684ddb6SLionel Sambuc long double
247*4684ddb6SLionel Sambuc as_float( const string& func, const wstring& s, size_t* idx )
248*4684ddb6SLionel Sambuc {
249*4684ddb6SLionel Sambuc     return as_float_helper<long double>( func, s, idx, wcstold );
250*4684ddb6SLionel Sambuc }
251*4684ddb6SLionel Sambuc 
252*4684ddb6SLionel Sambuc }  // unnamed namespace
253*4684ddb6SLionel Sambuc 
254*4684ddb6SLionel Sambuc int
255*4684ddb6SLionel Sambuc stoi(const string& str, size_t* idx, int base)
256*4684ddb6SLionel Sambuc {
257*4684ddb6SLionel Sambuc     return as_integer<int>( "stoi", str, idx, base );
258*4684ddb6SLionel Sambuc }
259*4684ddb6SLionel Sambuc 
260*4684ddb6SLionel Sambuc int
261*4684ddb6SLionel Sambuc stoi(const wstring& str, size_t* idx, int base)
262*4684ddb6SLionel Sambuc {
263*4684ddb6SLionel Sambuc     return as_integer<int>( "stoi", str, idx, base );
264*4684ddb6SLionel Sambuc }
265*4684ddb6SLionel Sambuc 
266*4684ddb6SLionel Sambuc long
267*4684ddb6SLionel Sambuc stol(const string& str, size_t* idx, int base)
268*4684ddb6SLionel Sambuc {
269*4684ddb6SLionel Sambuc     return as_integer<long>( "stol", str, idx, base );
270*4684ddb6SLionel Sambuc }
271*4684ddb6SLionel Sambuc 
272*4684ddb6SLionel Sambuc long
273*4684ddb6SLionel Sambuc stol(const wstring& str, size_t* idx, int base)
274*4684ddb6SLionel Sambuc {
275*4684ddb6SLionel Sambuc     return as_integer<long>( "stol", str, idx, base );
276*4684ddb6SLionel Sambuc }
277*4684ddb6SLionel Sambuc 
278*4684ddb6SLionel Sambuc unsigned long
279*4684ddb6SLionel Sambuc stoul(const string& str, size_t* idx, int base)
280*4684ddb6SLionel Sambuc {
281*4684ddb6SLionel Sambuc     return as_integer<unsigned long>( "stoul", str, idx, base );
282*4684ddb6SLionel Sambuc }
283*4684ddb6SLionel Sambuc 
284*4684ddb6SLionel Sambuc unsigned long
285*4684ddb6SLionel Sambuc stoul(const wstring& str, size_t* idx, int base)
286*4684ddb6SLionel Sambuc {
287*4684ddb6SLionel Sambuc     return as_integer<unsigned long>( "stoul", str, idx, base );
288*4684ddb6SLionel Sambuc }
289*4684ddb6SLionel Sambuc 
290*4684ddb6SLionel Sambuc long long
291*4684ddb6SLionel Sambuc stoll(const string& str, size_t* idx, int base)
292*4684ddb6SLionel Sambuc {
293*4684ddb6SLionel Sambuc     return as_integer<long long>( "stoll", str, idx, base );
294*4684ddb6SLionel Sambuc }
295*4684ddb6SLionel Sambuc 
296*4684ddb6SLionel Sambuc long long
297*4684ddb6SLionel Sambuc stoll(const wstring& str, size_t* idx, int base)
298*4684ddb6SLionel Sambuc {
299*4684ddb6SLionel Sambuc     return as_integer<long long>( "stoll", str, idx, base );
300*4684ddb6SLionel Sambuc }
301*4684ddb6SLionel Sambuc 
302*4684ddb6SLionel Sambuc unsigned long long
303*4684ddb6SLionel Sambuc stoull(const string& str, size_t* idx, int base)
304*4684ddb6SLionel Sambuc {
305*4684ddb6SLionel Sambuc     return as_integer<unsigned long long>( "stoull", str, idx, base );
306*4684ddb6SLionel Sambuc }
307*4684ddb6SLionel Sambuc 
308*4684ddb6SLionel Sambuc unsigned long long
309*4684ddb6SLionel Sambuc stoull(const wstring& str, size_t* idx, int base)
310*4684ddb6SLionel Sambuc {
311*4684ddb6SLionel Sambuc     return as_integer<unsigned long long>( "stoull", str, idx, base );
312*4684ddb6SLionel Sambuc }
313*4684ddb6SLionel Sambuc 
314*4684ddb6SLionel Sambuc float
315*4684ddb6SLionel Sambuc stof(const string& str, size_t* idx)
316*4684ddb6SLionel Sambuc {
317*4684ddb6SLionel Sambuc     return as_float<float>( "stof", str, idx );
318*4684ddb6SLionel Sambuc }
319*4684ddb6SLionel Sambuc 
320*4684ddb6SLionel Sambuc float
321*4684ddb6SLionel Sambuc stof(const wstring& str, size_t* idx)
322*4684ddb6SLionel Sambuc {
323*4684ddb6SLionel Sambuc     return as_float<float>( "stof", str, idx );
324*4684ddb6SLionel Sambuc }
325*4684ddb6SLionel Sambuc 
326*4684ddb6SLionel Sambuc double
327*4684ddb6SLionel Sambuc stod(const string& str, size_t* idx)
328*4684ddb6SLionel Sambuc {
329*4684ddb6SLionel Sambuc     return as_float<double>( "stod", str, idx );
330*4684ddb6SLionel Sambuc }
331*4684ddb6SLionel Sambuc 
332*4684ddb6SLionel Sambuc double
333*4684ddb6SLionel Sambuc stod(const wstring& str, size_t* idx)
334*4684ddb6SLionel Sambuc {
335*4684ddb6SLionel Sambuc     return as_float<double>( "stod", str, idx );
336*4684ddb6SLionel Sambuc }
337*4684ddb6SLionel Sambuc 
338*4684ddb6SLionel Sambuc long double
339*4684ddb6SLionel Sambuc stold(const string& str, size_t* idx)
340*4684ddb6SLionel Sambuc {
341*4684ddb6SLionel Sambuc     return as_float<long double>( "stold", str, idx );
342*4684ddb6SLionel Sambuc }
343*4684ddb6SLionel Sambuc 
344*4684ddb6SLionel Sambuc long double
345*4684ddb6SLionel Sambuc stold(const wstring& str, size_t* idx)
346*4684ddb6SLionel Sambuc {
347*4684ddb6SLionel Sambuc     return as_float<long double>( "stold", str, idx );
348*4684ddb6SLionel Sambuc }
349*4684ddb6SLionel Sambuc 
350*4684ddb6SLionel Sambuc // to_string
351*4684ddb6SLionel Sambuc 
352*4684ddb6SLionel Sambuc namespace
353*4684ddb6SLionel Sambuc {
354*4684ddb6SLionel Sambuc 
355*4684ddb6SLionel Sambuc // as_string
356*4684ddb6SLionel Sambuc 
357*4684ddb6SLionel Sambuc template<typename S, typename P, typename V >
358*4684ddb6SLionel Sambuc inline
359*4684ddb6SLionel Sambuc S
360*4684ddb6SLionel Sambuc as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
361*4684ddb6SLionel Sambuc {
362*4684ddb6SLionel Sambuc     typedef typename S::size_type size_type;
363*4684ddb6SLionel Sambuc     size_type available = s.size();
364*4684ddb6SLionel Sambuc     while (true)
365*4684ddb6SLionel Sambuc     {
366*4684ddb6SLionel Sambuc         int status = sprintf_like(&s[0], available + 1, fmt, a);
367*4684ddb6SLionel Sambuc         if ( status >= 0 )
368*4684ddb6SLionel Sambuc         {
369*4684ddb6SLionel Sambuc             size_type used = static_cast<size_type>(status);
370*4684ddb6SLionel Sambuc             if ( used <= available )
371*4684ddb6SLionel Sambuc             {
372*4684ddb6SLionel Sambuc                 s.resize( used );
373*4684ddb6SLionel Sambuc                 break;
374*4684ddb6SLionel Sambuc             }
375*4684ddb6SLionel Sambuc             available = used; // Assume this is advice of how much space we need.
376*4684ddb6SLionel Sambuc         }
377*4684ddb6SLionel Sambuc         else
378*4684ddb6SLionel Sambuc             available = available * 2 + 1;
379*4684ddb6SLionel Sambuc         s.resize(available);
380*4684ddb6SLionel Sambuc     }
381*4684ddb6SLionel Sambuc     return s;
382*4684ddb6SLionel Sambuc }
383*4684ddb6SLionel Sambuc 
384*4684ddb6SLionel Sambuc template <class S, class V, bool = is_floating_point<V>::value>
385*4684ddb6SLionel Sambuc struct initial_string;
386*4684ddb6SLionel Sambuc 
387*4684ddb6SLionel Sambuc template <class V, bool b>
388*4684ddb6SLionel Sambuc struct initial_string<string, V, b>
389*4684ddb6SLionel Sambuc {
390*4684ddb6SLionel Sambuc     string
391*4684ddb6SLionel Sambuc     operator()() const
392*4684ddb6SLionel Sambuc     {
393*4684ddb6SLionel Sambuc         string s;
394*4684ddb6SLionel Sambuc         s.resize(s.capacity());
395*4684ddb6SLionel Sambuc         return s;
396*4684ddb6SLionel Sambuc     }
397*4684ddb6SLionel Sambuc };
398*4684ddb6SLionel Sambuc 
399*4684ddb6SLionel Sambuc template <class V>
400*4684ddb6SLionel Sambuc struct initial_string<wstring, V, false>
401*4684ddb6SLionel Sambuc {
402*4684ddb6SLionel Sambuc     wstring
403*4684ddb6SLionel Sambuc     operator()() const
404*4684ddb6SLionel Sambuc     {
405*4684ddb6SLionel Sambuc         const size_t n = (numeric_limits<unsigned long long>::digits / 3)
406*4684ddb6SLionel Sambuc           + ((numeric_limits<unsigned long long>::digits % 3) != 0)
407*4684ddb6SLionel Sambuc           + 1;
408*4684ddb6SLionel Sambuc         wstring s(n, wchar_t());
409*4684ddb6SLionel Sambuc         s.resize(s.capacity());
410*4684ddb6SLionel Sambuc         return s;
411*4684ddb6SLionel Sambuc     }
412*4684ddb6SLionel Sambuc };
413*4684ddb6SLionel Sambuc 
414*4684ddb6SLionel Sambuc template <class V>
415*4684ddb6SLionel Sambuc struct initial_string<wstring, V, true>
416*4684ddb6SLionel Sambuc {
417*4684ddb6SLionel Sambuc     wstring
418*4684ddb6SLionel Sambuc     operator()() const
419*4684ddb6SLionel Sambuc     {
420*4684ddb6SLionel Sambuc         wstring s(20, wchar_t());
421*4684ddb6SLionel Sambuc         s.resize(s.capacity());
422*4684ddb6SLionel Sambuc         return s;
423*4684ddb6SLionel Sambuc     }
424*4684ddb6SLionel Sambuc };
425*4684ddb6SLionel Sambuc 
426*4684ddb6SLionel Sambuc typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
427*4684ddb6SLionel Sambuc 
428*4684ddb6SLionel Sambuc inline
429*4684ddb6SLionel Sambuc wide_printf
430*4684ddb6SLionel Sambuc get_swprintf()
431*4684ddb6SLionel Sambuc {
432*4684ddb6SLionel Sambuc #ifndef _LIBCPP_MSVCRT
433*4684ddb6SLionel Sambuc     return swprintf;
434*4684ddb6SLionel Sambuc #else
435*4684ddb6SLionel Sambuc     return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
436*4684ddb6SLionel Sambuc #endif
437*4684ddb6SLionel Sambuc }
438*4684ddb6SLionel Sambuc 
439*4684ddb6SLionel Sambuc }  // unnamed namespace
440*4684ddb6SLionel Sambuc 
441*4684ddb6SLionel Sambuc string to_string(int val)
442*4684ddb6SLionel Sambuc {
443*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, int>()(), "%d", val);
444*4684ddb6SLionel Sambuc }
445*4684ddb6SLionel Sambuc 
446*4684ddb6SLionel Sambuc string to_string(unsigned val)
447*4684ddb6SLionel Sambuc {
448*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
449*4684ddb6SLionel Sambuc }
450*4684ddb6SLionel Sambuc 
451*4684ddb6SLionel Sambuc string to_string(long val)
452*4684ddb6SLionel Sambuc {
453*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
454*4684ddb6SLionel Sambuc }
455*4684ddb6SLionel Sambuc 
456*4684ddb6SLionel Sambuc string to_string(unsigned long val)
457*4684ddb6SLionel Sambuc {
458*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
459*4684ddb6SLionel Sambuc }
460*4684ddb6SLionel Sambuc 
461*4684ddb6SLionel Sambuc string to_string(long long val)
462*4684ddb6SLionel Sambuc {
463*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
464*4684ddb6SLionel Sambuc }
465*4684ddb6SLionel Sambuc 
466*4684ddb6SLionel Sambuc string to_string(unsigned long long val)
467*4684ddb6SLionel Sambuc {
468*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
469*4684ddb6SLionel Sambuc }
470*4684ddb6SLionel Sambuc 
471*4684ddb6SLionel Sambuc string to_string(float val)
472*4684ddb6SLionel Sambuc {
473*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, float>()(), "%f", val);
474*4684ddb6SLionel Sambuc }
475*4684ddb6SLionel Sambuc 
476*4684ddb6SLionel Sambuc string to_string(double val)
477*4684ddb6SLionel Sambuc {
478*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, double>()(), "%f", val);
479*4684ddb6SLionel Sambuc }
480*4684ddb6SLionel Sambuc 
481*4684ddb6SLionel Sambuc string to_string(long double val)
482*4684ddb6SLionel Sambuc {
483*4684ddb6SLionel Sambuc     return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
484*4684ddb6SLionel Sambuc }
485*4684ddb6SLionel Sambuc 
486*4684ddb6SLionel Sambuc wstring to_wstring(int val)
487*4684ddb6SLionel Sambuc {
488*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
489*4684ddb6SLionel Sambuc }
490*4684ddb6SLionel Sambuc 
491*4684ddb6SLionel Sambuc wstring to_wstring(unsigned val)
492*4684ddb6SLionel Sambuc {
493*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
494*4684ddb6SLionel Sambuc }
495*4684ddb6SLionel Sambuc 
496*4684ddb6SLionel Sambuc wstring to_wstring(long val)
497*4684ddb6SLionel Sambuc {
498*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
499*4684ddb6SLionel Sambuc }
500*4684ddb6SLionel Sambuc 
501*4684ddb6SLionel Sambuc wstring to_wstring(unsigned long val)
502*4684ddb6SLionel Sambuc {
503*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
504*4684ddb6SLionel Sambuc }
505*4684ddb6SLionel Sambuc 
506*4684ddb6SLionel Sambuc wstring to_wstring(long long val)
507*4684ddb6SLionel Sambuc {
508*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
509*4684ddb6SLionel Sambuc }
510*4684ddb6SLionel Sambuc 
511*4684ddb6SLionel Sambuc wstring to_wstring(unsigned long long val)
512*4684ddb6SLionel Sambuc {
513*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
514*4684ddb6SLionel Sambuc }
515*4684ddb6SLionel Sambuc 
516*4684ddb6SLionel Sambuc wstring to_wstring(float val)
517*4684ddb6SLionel Sambuc {
518*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
519*4684ddb6SLionel Sambuc }
520*4684ddb6SLionel Sambuc 
521*4684ddb6SLionel Sambuc wstring to_wstring(double val)
522*4684ddb6SLionel Sambuc {
523*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
524*4684ddb6SLionel Sambuc }
525*4684ddb6SLionel Sambuc 
526*4684ddb6SLionel Sambuc wstring to_wstring(long double val)
527*4684ddb6SLionel Sambuc {
528*4684ddb6SLionel Sambuc     return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
529*4684ddb6SLionel Sambuc }
530*4684ddb6SLionel Sambuc _LIBCPP_END_NAMESPACE_STD
531