1227825Stheraven//===------------------------- string.cpp ---------------------------------===//
2227825Stheraven//
3227825Stheraven//                     The LLVM Compiler Infrastructure
4227825Stheraven//
5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
6227825Stheraven// Source Licenses. See LICENSE.TXT for details.
7227825Stheraven//
8227825Stheraven//===----------------------------------------------------------------------===//
9227825Stheraven
10227825Stheraven#include "string"
11227825Stheraven#include "cstdlib"
12227825Stheraven#include "cwchar"
13227825Stheraven#include "cerrno"
14253159Stheraven#include "limits"
15253159Stheraven#include "stdexcept"
16249998Sdim#ifdef _WIN32
17227825Stheraven#include "support/win32/support.h"
18227825Stheraven#endif // _WIN32
19227825Stheraven
20227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
21227825Stheraven
22227825Stheraventemplate class __basic_string_common<true>;
23227825Stheraven
24227825Stheraventemplate class basic_string<char>;
25227825Stheraventemplate class basic_string<wchar_t>;
26227825Stheraven
27227825Stheraventemplate
28227825Stheraven    string
29227825Stheraven    operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
30227825Stheraven
31253159Stheravennamespace
32227825Stheraven{
33253159Stheraven
34253159Stheraventemplate<typename T>
35253159Stheraveninline
36253159Stheravenvoid throw_helper( const string& msg )
37253159Stheraven{
38253159Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
39253159Stheraven    throw T( msg );
40253159Stheraven#else
41253159Stheraven    abort();
42253159Stheraven#endif
43253159Stheraven}
44253159Stheraven
45253159Stheraveninline
46253159Stheravenvoid throw_from_string_out_of_range( const string& func )
47253159Stheraven{
48253159Stheraven    throw_helper<out_of_range>(func + ": out of range");
49253159Stheraven}
50253159Stheraven
51253159Stheraveninline
52253159Stheravenvoid throw_from_string_invalid_arg( const string& func )
53253159Stheraven{
54253159Stheraven    throw_helper<invalid_argument>(func + ": no conversion");
55253159Stheraven}
56253159Stheraven
57253159Stheraven// as_integer
58253159Stheraven
59253159Stheraventemplate<typename V, typename S, typename F>
60253159Stheraveninline
61253159StheravenV
62253159Stheravenas_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
63253159Stheraven{
64253159Stheraven    typename S::value_type* ptr;
65253159Stheraven    const typename S::value_type* const p = str.c_str();
66246487Stheraven    typename remove_reference<decltype(errno)>::type errno_save = errno;
67246487Stheraven    errno = 0;
68253159Stheraven    V r = f(p, &ptr, base);
69246487Stheraven    swap(errno, errno_save);
70253159Stheraven    if (errno_save == ERANGE)
71253159Stheraven        throw_from_string_out_of_range(func);
72246487Stheraven    if (ptr == p)
73253159Stheraven        throw_from_string_invalid_arg(func);
74227825Stheraven    if (idx)
75227825Stheraven        *idx = static_cast<size_t>(ptr - p);
76253159Stheraven    return r;
77253159Stheraven}
78253159Stheraven
79253159Stheraventemplate<typename V, typename S>
80253159Stheraveninline
81253159StheravenV
82253159Stheravenas_integer(const string& func, const S& s, size_t* idx, int base);
83253159Stheraven
84253159Stheraven// string
85253159Stheraventemplate<>
86253159Stheraveninline
87253159Stheravenint
88253159Stheravenas_integer(const string& func, const string& s, size_t* idx, int base )
89253159Stheraven{
90253159Stheraven    // Use long as no Stantard string to integer exists.
91253159Stheraven    long r = as_integer_helper<long>( func, s, idx, base, strtol );
92253159Stheraven    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
93253159Stheraven        throw_from_string_out_of_range(func);
94227825Stheraven    return static_cast<int>(r);
95227825Stheraven}
96227825Stheraven
97253159Stheraventemplate<>
98253159Stheraveninline
99253159Stheravenlong
100253159Stheravenas_integer(const string& func, const string& s, size_t* idx, int base )
101253159Stheraven{
102253159Stheraven    return as_integer_helper<long>( func, s, idx, base, strtol );
103253159Stheraven}
104253159Stheraven
105253159Stheraventemplate<>
106253159Stheraveninline
107253159Stheravenunsigned long
108253159Stheravenas_integer( const string& func, const string& s, size_t* idx, int base )
109253159Stheraven{
110253159Stheraven    return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
111253159Stheraven}
112253159Stheraven
113253159Stheraventemplate<>
114253159Stheraveninline
115253159Stheravenlong long
116253159Stheravenas_integer( const string& func, const string& s, size_t* idx, int base )
117253159Stheraven{
118253159Stheraven    return as_integer_helper<long long>( func, s, idx, base, strtoll );
119253159Stheraven}
120253159Stheraven
121253159Stheraventemplate<>
122253159Stheraveninline
123253159Stheravenunsigned long long
124253159Stheravenas_integer( const string& func, const string& s, size_t* idx, int base )
125253159Stheraven{
126253159Stheraven    return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
127253159Stheraven}
128253159Stheraven
129253159Stheraven// wstring
130253159Stheraventemplate<>
131253159Stheraveninline
132227825Stheravenint
133253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
134227825Stheraven{
135253159Stheraven    // Use long as no Stantard string to integer exists.
136253159Stheraven    long r = as_integer_helper<long>( func, s, idx, base, wcstol );
137253159Stheraven    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
138253159Stheraven        throw_from_string_out_of_range(func);
139227825Stheraven    return static_cast<int>(r);
140227825Stheraven}
141227825Stheraven
142253159Stheraventemplate<>
143253159Stheraveninline
144227825Stheravenlong
145253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
146227825Stheraven{
147253159Stheraven    return as_integer_helper<long>( func, s, idx, base, wcstol );
148253159Stheraven}
149253159Stheraven
150253159Stheraventemplate<>
151253159Stheraveninline
152253159Stheravenunsigned long
153253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
154253159Stheraven{
155253159Stheraven    return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
156253159Stheraven}
157253159Stheraven
158253159Stheraventemplate<>
159253159Stheraveninline
160253159Stheravenlong long
161253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
162253159Stheraven{
163253159Stheraven    return as_integer_helper<long long>( func, s, idx, base, wcstoll );
164253159Stheraven}
165253159Stheraven
166253159Stheraventemplate<>
167253159Stheraveninline
168253159Stheravenunsigned long long
169253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
170253159Stheraven{
171253159Stheraven    return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
172253159Stheraven}
173253159Stheraven
174253159Stheraven// as_float
175253159Stheraven
176253159Stheraventemplate<typename V, typename S, typename F>
177253159Stheraveninline
178253159StheravenV
179253159Stheravenas_float_helper(const string& func, const S& str, size_t* idx, F f )
180253159Stheraven{
181253159Stheraven    typename S::value_type* ptr;
182253159Stheraven    const typename S::value_type* const p = str.c_str();
183246487Stheraven    typename remove_reference<decltype(errno)>::type errno_save = errno;
184246487Stheraven    errno = 0;
185253159Stheraven    V r = f(p, &ptr);
186246487Stheraven    swap(errno, errno_save);
187246487Stheraven    if (errno_save == ERANGE)
188253159Stheraven        throw_from_string_out_of_range(func);
189246487Stheraven    if (ptr == p)
190253159Stheraven        throw_from_string_invalid_arg(func);
191227825Stheraven    if (idx)
192227825Stheraven        *idx = static_cast<size_t>(ptr - p);
193227825Stheraven    return r;
194227825Stheraven}
195227825Stheraven
196253159Stheraventemplate<typename V, typename S>
197253159Stheraveninline
198253159StheravenV as_float( const string& func, const S& s, size_t* idx = nullptr );
199253159Stheraven
200253159Stheraventemplate<>
201253159Stheraveninline
202253159Stheravenfloat
203253159Stheravenas_float( const string& func, const string& s, size_t* idx )
204253159Stheraven{
205253159Stheraven    return as_float_helper<float>( func, s, idx, strtof );
206253159Stheraven}
207253159Stheraven
208253159Stheraventemplate<>
209253159Stheraveninline
210253159Stheravendouble
211253159Stheravenas_float(const string& func, const string& s, size_t* idx )
212253159Stheraven{
213253159Stheraven    return as_float_helper<double>( func, s, idx, strtod );
214253159Stheraven}
215253159Stheraven
216253159Stheraventemplate<>
217253159Stheraveninline
218253159Stheravenlong double
219253159Stheravenas_float( const string& func, const string& s, size_t* idx )
220253159Stheraven{
221253159Stheraven    return as_float_helper<long double>( func, s, idx, strtold );
222253159Stheraven}
223253159Stheraven
224253159Stheraventemplate<>
225253159Stheraveninline
226253159Stheravenfloat
227253159Stheravenas_float( const string& func, const wstring& s, size_t* idx )
228253159Stheraven{
229253159Stheraven    return as_float_helper<float>( func, s, idx, wcstof );
230253159Stheraven}
231253159Stheraven
232253159Stheraventemplate<>
233253159Stheraveninline
234253159Stheravendouble
235253159Stheravenas_float( const string& func, const wstring& s, size_t* idx )
236253159Stheraven{
237253159Stheraven    return as_float_helper<double>( func, s, idx, wcstod );
238253159Stheraven}
239253159Stheraven
240253159Stheraventemplate<>
241253159Stheraveninline
242253159Stheravenlong double
243253159Stheravenas_float( const string& func, const wstring& s, size_t* idx )
244253159Stheraven{
245253159Stheraven    return as_float_helper<long double>( func, s, idx, wcstold );
246253159Stheraven}
247253159Stheraven
248253159Stheraven}  // unnamed namespace
249253159Stheraven
250253159Stheravenint
251253159Stheravenstoi(const string& str, size_t* idx, int base)
252253159Stheraven{
253253159Stheraven    return as_integer<int>( "stoi", str, idx, base );
254253159Stheraven}
255253159Stheraven
256253159Stheravenint
257253159Stheravenstoi(const wstring& str, size_t* idx, int base)
258253159Stheraven{
259253159Stheraven    return as_integer<int>( "stoi", str, idx, base );
260253159Stheraven}
261253159Stheraven
262227825Stheravenlong
263253159Stheravenstol(const string& str, size_t* idx, int base)
264253159Stheraven{
265253159Stheraven    return as_integer<long>( "stol", str, idx, base );
266253159Stheraven}
267253159Stheraven
268253159Stheravenlong
269227825Stheravenstol(const wstring& str, size_t* idx, int base)
270227825Stheraven{
271253159Stheraven    return as_integer<long>( "stol", str, idx, base );
272227825Stheraven}
273227825Stheraven
274227825Stheravenunsigned long
275227825Stheravenstoul(const string& str, size_t* idx, int base)
276227825Stheraven{
277253159Stheraven    return as_integer<unsigned long>( "stoul", str, idx, base );
278227825Stheraven}
279227825Stheraven
280227825Stheravenunsigned long
281227825Stheravenstoul(const wstring& str, size_t* idx, int base)
282227825Stheraven{
283253159Stheraven    return as_integer<unsigned long>( "stoul", str, idx, base );
284227825Stheraven}
285227825Stheraven
286227825Stheravenlong long
287227825Stheravenstoll(const string& str, size_t* idx, int base)
288227825Stheraven{
289253159Stheraven    return as_integer<long long>( "stoll", str, idx, base );
290227825Stheraven}
291227825Stheraven
292227825Stheravenlong long
293227825Stheravenstoll(const wstring& str, size_t* idx, int base)
294227825Stheraven{
295253159Stheraven    return as_integer<long long>( "stoll", str, idx, base );
296227825Stheraven}
297227825Stheraven
298227825Stheravenunsigned long long
299227825Stheravenstoull(const string& str, size_t* idx, int base)
300227825Stheraven{
301253159Stheraven    return as_integer<unsigned long long>( "stoull", str, idx, base );
302227825Stheraven}
303227825Stheraven
304227825Stheravenunsigned long long
305227825Stheravenstoull(const wstring& str, size_t* idx, int base)
306227825Stheraven{
307253159Stheraven    return as_integer<unsigned long long>( "stoull", str, idx, base );
308227825Stheraven}
309227825Stheraven
310227825Stheravenfloat
311227825Stheravenstof(const string& str, size_t* idx)
312227825Stheraven{
313253159Stheraven    return as_float<float>( "stof", str, idx );
314227825Stheraven}
315227825Stheraven
316227825Stheravenfloat
317227825Stheravenstof(const wstring& str, size_t* idx)
318227825Stheraven{
319253159Stheraven    return as_float<float>( "stof", str, idx );
320227825Stheraven}
321227825Stheraven
322227825Stheravendouble
323227825Stheravenstod(const string& str, size_t* idx)
324227825Stheraven{
325253159Stheraven    return as_float<double>( "stod", str, idx );
326227825Stheraven}
327227825Stheraven
328227825Stheravendouble
329227825Stheravenstod(const wstring& str, size_t* idx)
330227825Stheraven{
331253159Stheraven    return as_float<double>( "stod", str, idx );
332227825Stheraven}
333227825Stheraven
334227825Stheravenlong double
335227825Stheravenstold(const string& str, size_t* idx)
336227825Stheraven{
337253159Stheraven    return as_float<long double>( "stold", str, idx );
338227825Stheraven}
339227825Stheraven
340227825Stheravenlong double
341227825Stheravenstold(const wstring& str, size_t* idx)
342227825Stheraven{
343253159Stheraven    return as_float<long double>( "stold", str, idx );
344227825Stheraven}
345227825Stheraven
346253159Stheraven// to_string
347253159Stheraven
348253159Stheravennamespace
349227825Stheraven{
350253159Stheraven
351253159Stheraven// as_string
352253159Stheraven
353253159Stheraventemplate<typename S, typename P, typename V >
354253159Stheraveninline
355253159StheravenS
356253159Stheravenas_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
357253159Stheraven{
358253159Stheraven    typedef typename S::size_type size_type;
359253159Stheraven    size_type available = s.size();
360227825Stheraven    while (true)
361227825Stheraven    {
362253159Stheraven        int status = sprintf_like(&s[0], available + 1, fmt, a);
363253159Stheraven        if ( status >= 0 )
364227825Stheraven        {
365253159Stheraven            size_type used = static_cast<size_type>(status);
366253159Stheraven            if ( used <= available )
367253159Stheraven            {
368253159Stheraven                s.resize( used );
369253159Stheraven                break;
370253159Stheraven            }
371253159Stheraven            available = used; // Assume this is advice of how much space we need.
372227825Stheraven        }
373253159Stheraven        else
374253159Stheraven            available = available * 2 + 1;
375253159Stheraven        s.resize(available);
376227825Stheraven    }
377227825Stheraven    return s;
378227825Stheraven}
379227825Stheraven
380253159Stheraventemplate <class S, class V, bool = is_floating_point<V>::value>
381253159Stheravenstruct initial_string;
382253159Stheraven
383253159Stheraventemplate <class V, bool b>
384253159Stheravenstruct initial_string<string, V, b>
385227825Stheraven{
386253159Stheraven    string
387253159Stheraven    operator()() const
388227825Stheraven    {
389253159Stheraven        string s;
390253159Stheraven        s.resize(s.capacity());
391253159Stheraven        return s;
392227825Stheraven    }
393253159Stheraven};
394227825Stheraven
395253159Stheraventemplate <class V>
396253159Stheravenstruct initial_string<wstring, V, false>
397227825Stheraven{
398253159Stheraven    wstring
399253159Stheraven    operator()() const
400227825Stheraven    {
401253159Stheraven        const size_t n = (numeric_limits<unsigned long long>::digits / 3)
402253159Stheraven          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
403253159Stheraven          + 1;
404253159Stheraven        wstring s(n, wchar_t());
405253159Stheraven        s.resize(s.capacity());
406253159Stheraven        return s;
407227825Stheraven    }
408253159Stheraven};
409227825Stheraven
410253159Stheraventemplate <class V>
411253159Stheravenstruct initial_string<wstring, V, true>
412227825Stheraven{
413253159Stheraven    wstring
414253159Stheraven    operator()() const
415227825Stheraven    {
416253159Stheraven        wstring s(20, wchar_t());
417253159Stheraven        s.resize(s.capacity());
418253159Stheraven        return s;
419227825Stheraven    }
420253159Stheraven};
421253159Stheraven
422253159Stheraventypedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
423253159Stheraven
424253159Stheraveninline
425253159Stheravenwide_printf
426253159Stheravenget_swprintf()
427253159Stheraven{
428253159Stheraven#ifndef _WIN32
429253159Stheraven    return swprintf;
430253159Stheraven#else
431253159Stheraven    return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
432253159Stheraven#endif
433227825Stheraven}
434227825Stheraven
435253159Stheraven}  // unnamed namespace
436253159Stheraven
437253159Stheravenstring to_string(int val)
438253159Stheraven{
439253159Stheraven    return as_string(snprintf, initial_string<string, int>()(), "%d", val);
440253159Stheraven}
441253159Stheraven
442253159Stheravenstring to_string(unsigned val)
443253159Stheraven{
444253159Stheraven    return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
445253159Stheraven}
446253159Stheraven
447253159Stheravenstring to_string(long val)
448253159Stheraven{
449253159Stheraven    return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
450253159Stheraven}
451253159Stheraven
452253159Stheravenstring to_string(unsigned long val)
453253159Stheraven{
454253159Stheraven    return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
455253159Stheraven}
456253159Stheraven
457227825Stheravenstring to_string(long long val)
458227825Stheraven{
459253159Stheraven    return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
460227825Stheraven}
461227825Stheraven
462227825Stheravenstring to_string(unsigned long long val)
463227825Stheraven{
464253159Stheraven    return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
465227825Stheraven}
466227825Stheraven
467227825Stheravenstring to_string(float val)
468227825Stheraven{
469253159Stheraven    return as_string(snprintf, initial_string<string, float>()(), "%f", val);
470227825Stheraven}
471227825Stheraven
472227825Stheravenstring to_string(double val)
473227825Stheraven{
474253159Stheraven    return as_string(snprintf, initial_string<string, double>()(), "%f", val);
475227825Stheraven}
476227825Stheraven
477227825Stheravenstring to_string(long double val)
478227825Stheraven{
479253159Stheraven    return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
480227825Stheraven}
481227825Stheraven
482227825Stheravenwstring to_wstring(int val)
483227825Stheraven{
484253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
485227825Stheraven}
486227825Stheraven
487227825Stheravenwstring to_wstring(unsigned val)
488227825Stheraven{
489253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
490227825Stheraven}
491227825Stheraven
492227825Stheravenwstring to_wstring(long val)
493227825Stheraven{
494253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
495227825Stheraven}
496227825Stheraven
497227825Stheravenwstring to_wstring(unsigned long val)
498227825Stheraven{
499253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
500227825Stheraven}
501227825Stheraven
502227825Stheravenwstring to_wstring(long long val)
503227825Stheraven{
504253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
505227825Stheraven}
506227825Stheraven
507227825Stheravenwstring to_wstring(unsigned long long val)
508227825Stheraven{
509253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
510227825Stheraven}
511227825Stheraven
512227825Stheravenwstring to_wstring(float val)
513227825Stheraven{
514253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
515227825Stheraven}
516227825Stheraven
517227825Stheravenwstring to_wstring(double val)
518227825Stheraven{
519253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
520227825Stheraven}
521227825Stheraven
522227825Stheravenwstring to_wstring(long double val)
523227825Stheraven{
524253159Stheraven    return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
525227825Stheraven}
526227825Stheraven_LIBCPP_END_NAMESPACE_STD
527