string.cpp revision 314564
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"
14253146Stheraven#include "limits"
15253146Stheraven#include "stdexcept"
16261272Sdim#ifdef _LIBCPP_MSVCRT
17227825Stheraven#include "support/win32/support.h"
18261272Sdim#endif // _LIBCPP_MSVCRT
19261272Sdim#include <stdio.h>
20227825Stheraven
21227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
22227825Stheraven
23314564Sdimtemplate class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
24227825Stheraven
25314564Sdimtemplate class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<char>;
26314564Sdimtemplate class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<wchar_t>;
27227825Stheraven
28227825Stheraventemplate
29227825Stheraven    string
30227825Stheraven    operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
31227825Stheraven
32253146Stheravennamespace
33227825Stheraven{
34253146Stheraven
35253146Stheraventemplate<typename T>
36253146Stheraveninline
37253146Stheravenvoid throw_helper( const string& msg )
38253146Stheraven{
39253146Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
40253146Stheraven    throw T( msg );
41253146Stheraven#else
42288943Sdim    fprintf(stderr, "%s\n", msg.c_str());
43314564Sdim    _VSTD::abort();
44253146Stheraven#endif
45253146Stheraven}
46253146Stheraven
47253146Stheraveninline
48253146Stheravenvoid throw_from_string_out_of_range( const string& func )
49253146Stheraven{
50253146Stheraven    throw_helper<out_of_range>(func + ": out of range");
51253146Stheraven}
52253146Stheraven
53253146Stheraveninline
54253146Stheravenvoid throw_from_string_invalid_arg( const string& func )
55253146Stheraven{
56253146Stheraven    throw_helper<invalid_argument>(func + ": no conversion");
57253146Stheraven}
58253146Stheraven
59253146Stheraven// as_integer
60253146Stheraven
61253146Stheraventemplate<typename V, typename S, typename F>
62253146Stheraveninline
63253146StheravenV
64253146Stheravenas_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
65253146Stheraven{
66276792Sdim    typename S::value_type* ptr = nullptr;
67253146Stheraven    const typename S::value_type* const p = str.c_str();
68246468Stheraven    typename remove_reference<decltype(errno)>::type errno_save = errno;
69246468Stheraven    errno = 0;
70253146Stheraven    V r = f(p, &ptr, base);
71246468Stheraven    swap(errno, errno_save);
72253146Stheraven    if (errno_save == ERANGE)
73253146Stheraven        throw_from_string_out_of_range(func);
74246468Stheraven    if (ptr == p)
75253146Stheraven        throw_from_string_invalid_arg(func);
76227825Stheraven    if (idx)
77227825Stheraven        *idx = static_cast<size_t>(ptr - p);
78253146Stheraven    return r;
79253146Stheraven}
80253146Stheraven
81253146Stheraventemplate<typename V, typename S>
82253146Stheraveninline
83253146StheravenV
84253146Stheravenas_integer(const string& func, const S& s, size_t* idx, int base);
85253146Stheraven
86253146Stheraven// string
87253146Stheraventemplate<>
88253146Stheraveninline
89253146Stheravenint
90253146Stheravenas_integer(const string& func, const string& s, size_t* idx, int base )
91253146Stheraven{
92261272Sdim    // Use long as no Standard string to integer exists.
93253146Stheraven    long r = as_integer_helper<long>( func, s, idx, base, strtol );
94253146Stheraven    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
95253146Stheraven        throw_from_string_out_of_range(func);
96227825Stheraven    return static_cast<int>(r);
97227825Stheraven}
98227825Stheraven
99253146Stheraventemplate<>
100253146Stheraveninline
101253146Stheravenlong
102253146Stheravenas_integer(const string& func, const string& s, size_t* idx, int base )
103253146Stheraven{
104253146Stheraven    return as_integer_helper<long>( func, s, idx, base, strtol );
105253146Stheraven}
106253146Stheraven
107253146Stheraventemplate<>
108253146Stheraveninline
109253146Stheravenunsigned long
110253146Stheravenas_integer( const string& func, const string& s, size_t* idx, int base )
111253146Stheraven{
112253146Stheraven    return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
113253146Stheraven}
114253146Stheraven
115253146Stheraventemplate<>
116253146Stheraveninline
117253146Stheravenlong long
118253146Stheravenas_integer( const string& func, const string& s, size_t* idx, int base )
119253146Stheraven{
120253146Stheraven    return as_integer_helper<long long>( func, s, idx, base, strtoll );
121253146Stheraven}
122253146Stheraven
123253146Stheraventemplate<>
124253146Stheraveninline
125253146Stheravenunsigned long long
126253146Stheravenas_integer( const string& func, const string& s, size_t* idx, int base )
127253146Stheraven{
128253146Stheraven    return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
129253146Stheraven}
130253146Stheraven
131253146Stheraven// wstring
132253146Stheraventemplate<>
133253146Stheraveninline
134227825Stheravenint
135253146Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
136227825Stheraven{
137253146Stheraven    // Use long as no Stantard string to integer exists.
138253146Stheraven    long r = as_integer_helper<long>( func, s, idx, base, wcstol );
139253146Stheraven    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
140253146Stheraven        throw_from_string_out_of_range(func);
141227825Stheraven    return static_cast<int>(r);
142227825Stheraven}
143227825Stheraven
144253146Stheraventemplate<>
145253146Stheraveninline
146227825Stheravenlong
147253146Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
148227825Stheraven{
149253146Stheraven    return as_integer_helper<long>( func, s, idx, base, wcstol );
150253146Stheraven}
151253146Stheraven
152253146Stheraventemplate<>
153253146Stheraveninline
154253146Stheravenunsigned long
155253146Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
156253146Stheraven{
157253146Stheraven    return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
158253146Stheraven}
159253146Stheraven
160253146Stheraventemplate<>
161253146Stheraveninline
162253146Stheravenlong long
163253146Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
164253146Stheraven{
165253146Stheraven    return as_integer_helper<long long>( func, s, idx, base, wcstoll );
166253146Stheraven}
167253146Stheraven
168253146Stheraventemplate<>
169253146Stheraveninline
170253146Stheravenunsigned long long
171253146Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base )
172253146Stheraven{
173253146Stheraven    return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
174253146Stheraven}
175253146Stheraven
176253146Stheraven// as_float
177253146Stheraven
178253146Stheraventemplate<typename V, typename S, typename F>
179253146Stheraveninline
180253146StheravenV
181253146Stheravenas_float_helper(const string& func, const S& str, size_t* idx, F f )
182253146Stheraven{
183276792Sdim    typename S::value_type* ptr = nullptr;
184253146Stheraven    const typename S::value_type* const p = str.c_str();
185246468Stheraven    typename remove_reference<decltype(errno)>::type errno_save = errno;
186246468Stheraven    errno = 0;
187253146Stheraven    V r = f(p, &ptr);
188246468Stheraven    swap(errno, errno_save);
189246468Stheraven    if (errno_save == ERANGE)
190253146Stheraven        throw_from_string_out_of_range(func);
191246468Stheraven    if (ptr == p)
192253146Stheraven        throw_from_string_invalid_arg(func);
193227825Stheraven    if (idx)
194227825Stheraven        *idx = static_cast<size_t>(ptr - p);
195227825Stheraven    return r;
196227825Stheraven}
197227825Stheraven
198253146Stheraventemplate<typename V, typename S>
199253146Stheraveninline
200253146StheravenV as_float( const string& func, const S& s, size_t* idx = nullptr );
201253146Stheraven
202253146Stheraventemplate<>
203253146Stheraveninline
204253146Stheravenfloat
205253146Stheravenas_float( const string& func, const string& s, size_t* idx )
206253146Stheraven{
207253146Stheraven    return as_float_helper<float>( func, s, idx, strtof );
208253146Stheraven}
209253146Stheraven
210253146Stheraventemplate<>
211253146Stheraveninline
212253146Stheravendouble
213253146Stheravenas_float(const string& func, const string& s, size_t* idx )
214253146Stheraven{
215253146Stheraven    return as_float_helper<double>( func, s, idx, strtod );
216253146Stheraven}
217253146Stheraven
218253146Stheraventemplate<>
219253146Stheraveninline
220253146Stheravenlong double
221253146Stheravenas_float( const string& func, const string& s, size_t* idx )
222253146Stheraven{
223253146Stheraven    return as_float_helper<long double>( func, s, idx, strtold );
224253146Stheraven}
225253146Stheraven
226253146Stheraventemplate<>
227253146Stheraveninline
228253146Stheravenfloat
229253146Stheravenas_float( const string& func, const wstring& s, size_t* idx )
230253146Stheraven{
231253146Stheraven    return as_float_helper<float>( func, s, idx, wcstof );
232253146Stheraven}
233253146Stheraven
234253146Stheraventemplate<>
235253146Stheraveninline
236253146Stheravendouble
237253146Stheravenas_float( const string& func, const wstring& s, size_t* idx )
238253146Stheraven{
239253146Stheraven    return as_float_helper<double>( func, s, idx, wcstod );
240253146Stheraven}
241253146Stheraven
242253146Stheraventemplate<>
243253146Stheraveninline
244253146Stheravenlong double
245253146Stheravenas_float( const string& func, const wstring& s, size_t* idx )
246253146Stheraven{
247253146Stheraven    return as_float_helper<long double>( func, s, idx, wcstold );
248253146Stheraven}
249253146Stheraven
250253146Stheraven}  // unnamed namespace
251253146Stheraven
252253146Stheravenint
253253146Stheravenstoi(const string& str, size_t* idx, int base)
254253146Stheraven{
255253146Stheraven    return as_integer<int>( "stoi", str, idx, base );
256253146Stheraven}
257253146Stheraven
258253146Stheravenint
259253146Stheravenstoi(const wstring& str, size_t* idx, int base)
260253146Stheraven{
261253146Stheraven    return as_integer<int>( "stoi", str, idx, base );
262253146Stheraven}
263253146Stheraven
264227825Stheravenlong
265253146Stheravenstol(const string& str, size_t* idx, int base)
266253146Stheraven{
267253146Stheraven    return as_integer<long>( "stol", str, idx, base );
268253146Stheraven}
269253146Stheraven
270253146Stheravenlong
271227825Stheravenstol(const wstring& str, size_t* idx, int base)
272227825Stheraven{
273253146Stheraven    return as_integer<long>( "stol", str, idx, base );
274227825Stheraven}
275227825Stheraven
276227825Stheravenunsigned long
277227825Stheravenstoul(const string& str, size_t* idx, int base)
278227825Stheraven{
279253146Stheraven    return as_integer<unsigned long>( "stoul", str, idx, base );
280227825Stheraven}
281227825Stheraven
282227825Stheravenunsigned long
283227825Stheravenstoul(const wstring& str, size_t* idx, int base)
284227825Stheraven{
285253146Stheraven    return as_integer<unsigned long>( "stoul", str, idx, base );
286227825Stheraven}
287227825Stheraven
288227825Stheravenlong long
289227825Stheravenstoll(const string& str, size_t* idx, int base)
290227825Stheraven{
291253146Stheraven    return as_integer<long long>( "stoll", str, idx, base );
292227825Stheraven}
293227825Stheraven
294227825Stheravenlong long
295227825Stheravenstoll(const wstring& str, size_t* idx, int base)
296227825Stheraven{
297253146Stheraven    return as_integer<long long>( "stoll", str, idx, base );
298227825Stheraven}
299227825Stheraven
300227825Stheravenunsigned long long
301227825Stheravenstoull(const string& str, size_t* idx, int base)
302227825Stheraven{
303253146Stheraven    return as_integer<unsigned long long>( "stoull", str, idx, base );
304227825Stheraven}
305227825Stheraven
306227825Stheravenunsigned long long
307227825Stheravenstoull(const wstring& str, size_t* idx, int base)
308227825Stheraven{
309253146Stheraven    return as_integer<unsigned long long>( "stoull", str, idx, base );
310227825Stheraven}
311227825Stheraven
312227825Stheravenfloat
313227825Stheravenstof(const string& str, size_t* idx)
314227825Stheraven{
315253146Stheraven    return as_float<float>( "stof", str, idx );
316227825Stheraven}
317227825Stheraven
318227825Stheravenfloat
319227825Stheravenstof(const wstring& str, size_t* idx)
320227825Stheraven{
321253146Stheraven    return as_float<float>( "stof", str, idx );
322227825Stheraven}
323227825Stheraven
324227825Stheravendouble
325227825Stheravenstod(const string& str, size_t* idx)
326227825Stheraven{
327253146Stheraven    return as_float<double>( "stod", str, idx );
328227825Stheraven}
329227825Stheraven
330227825Stheravendouble
331227825Stheravenstod(const wstring& str, size_t* idx)
332227825Stheraven{
333253146Stheraven    return as_float<double>( "stod", str, idx );
334227825Stheraven}
335227825Stheraven
336227825Stheravenlong double
337227825Stheravenstold(const string& str, size_t* idx)
338227825Stheraven{
339253146Stheraven    return as_float<long double>( "stold", str, idx );
340227825Stheraven}
341227825Stheraven
342227825Stheravenlong double
343227825Stheravenstold(const wstring& str, size_t* idx)
344227825Stheraven{
345253146Stheraven    return as_float<long double>( "stold", str, idx );
346227825Stheraven}
347227825Stheraven
348253146Stheraven// to_string
349253146Stheraven
350253146Stheravennamespace
351227825Stheraven{
352253146Stheraven
353253146Stheraven// as_string
354253146Stheraven
355253146Stheraventemplate<typename S, typename P, typename V >
356253146Stheraveninline
357253146StheravenS
358253146Stheravenas_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
359253146Stheraven{
360253146Stheraven    typedef typename S::size_type size_type;
361253146Stheraven    size_type available = s.size();
362227825Stheraven    while (true)
363227825Stheraven    {
364253146Stheraven        int status = sprintf_like(&s[0], available + 1, fmt, a);
365253146Stheraven        if ( status >= 0 )
366227825Stheraven        {
367253146Stheraven            size_type used = static_cast<size_type>(status);
368253146Stheraven            if ( used <= available )
369253146Stheraven            {
370253146Stheraven                s.resize( used );
371253146Stheraven                break;
372253146Stheraven            }
373253146Stheraven            available = used; // Assume this is advice of how much space we need.
374227825Stheraven        }
375253146Stheraven        else
376253146Stheraven            available = available * 2 + 1;
377253146Stheraven        s.resize(available);
378227825Stheraven    }
379227825Stheraven    return s;
380227825Stheraven}
381227825Stheraven
382253146Stheraventemplate <class S, class V, bool = is_floating_point<V>::value>
383253146Stheravenstruct initial_string;
384253146Stheraven
385253146Stheraventemplate <class V, bool b>
386253146Stheravenstruct initial_string<string, V, b>
387227825Stheraven{
388253146Stheraven    string
389253146Stheraven    operator()() const
390227825Stheraven    {
391253146Stheraven        string s;
392253146Stheraven        s.resize(s.capacity());
393253146Stheraven        return s;
394227825Stheraven    }
395253146Stheraven};
396227825Stheraven
397253146Stheraventemplate <class V>
398253146Stheravenstruct initial_string<wstring, V, false>
399227825Stheraven{
400253146Stheraven    wstring
401253146Stheraven    operator()() const
402227825Stheraven    {
403253146Stheraven        const size_t n = (numeric_limits<unsigned long long>::digits / 3)
404253146Stheraven          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
405253146Stheraven          + 1;
406253146Stheraven        wstring s(n, wchar_t());
407253146Stheraven        s.resize(s.capacity());
408253146Stheraven        return s;
409227825Stheraven    }
410253146Stheraven};
411227825Stheraven
412253146Stheraventemplate <class V>
413253146Stheravenstruct initial_string<wstring, V, true>
414227825Stheraven{
415253146Stheraven    wstring
416253146Stheraven    operator()() const
417227825Stheraven    {
418253146Stheraven        wstring s(20, wchar_t());
419253146Stheraven        s.resize(s.capacity());
420253146Stheraven        return s;
421227825Stheraven    }
422253146Stheraven};
423253146Stheraven
424253146Stheraventypedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
425253146Stheraven
426253146Stheraveninline
427253146Stheravenwide_printf
428253146Stheravenget_swprintf()
429253146Stheraven{
430261272Sdim#ifndef _LIBCPP_MSVCRT
431253146Stheraven    return swprintf;
432253146Stheraven#else
433253146Stheraven    return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
434253146Stheraven#endif
435227825Stheraven}
436227825Stheraven
437253146Stheraven}  // unnamed namespace
438253146Stheraven
439253146Stheravenstring to_string(int val)
440253146Stheraven{
441253146Stheraven    return as_string(snprintf, initial_string<string, int>()(), "%d", val);
442253146Stheraven}
443253146Stheraven
444253146Stheravenstring to_string(unsigned val)
445253146Stheraven{
446253146Stheraven    return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
447253146Stheraven}
448253146Stheraven
449253146Stheravenstring to_string(long val)
450253146Stheraven{
451253146Stheraven    return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
452253146Stheraven}
453253146Stheraven
454253146Stheravenstring to_string(unsigned long val)
455253146Stheraven{
456253146Stheraven    return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
457253146Stheraven}
458253146Stheraven
459227825Stheravenstring to_string(long long val)
460227825Stheraven{
461253146Stheraven    return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
462227825Stheraven}
463227825Stheraven
464227825Stheravenstring to_string(unsigned long long val)
465227825Stheraven{
466253146Stheraven    return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
467227825Stheraven}
468227825Stheraven
469227825Stheravenstring to_string(float val)
470227825Stheraven{
471253146Stheraven    return as_string(snprintf, initial_string<string, float>()(), "%f", val);
472227825Stheraven}
473227825Stheraven
474227825Stheravenstring to_string(double val)
475227825Stheraven{
476253146Stheraven    return as_string(snprintf, initial_string<string, double>()(), "%f", val);
477227825Stheraven}
478227825Stheraven
479227825Stheravenstring to_string(long double val)
480227825Stheraven{
481253146Stheraven    return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
482227825Stheraven}
483227825Stheraven
484227825Stheravenwstring to_wstring(int val)
485227825Stheraven{
486253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
487227825Stheraven}
488227825Stheraven
489227825Stheravenwstring to_wstring(unsigned val)
490227825Stheraven{
491253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
492227825Stheraven}
493227825Stheraven
494227825Stheravenwstring to_wstring(long val)
495227825Stheraven{
496253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
497227825Stheraven}
498227825Stheraven
499227825Stheravenwstring to_wstring(unsigned long val)
500227825Stheraven{
501253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
502227825Stheraven}
503227825Stheraven
504227825Stheravenwstring to_wstring(long long val)
505227825Stheraven{
506253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
507227825Stheraven}
508227825Stheraven
509227825Stheravenwstring to_wstring(unsigned long long val)
510227825Stheraven{
511253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
512227825Stheraven}
513227825Stheraven
514227825Stheravenwstring to_wstring(float val)
515227825Stheraven{
516253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
517227825Stheraven}
518227825Stheraven
519227825Stheravenwstring to_wstring(double val)
520227825Stheraven{
521253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
522227825Stheraven}
523227825Stheraven
524227825Stheravenwstring to_wstring(long double val)
525227825Stheraven{
526253146Stheraven    return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
527227825Stheraven}
528227825Stheraven_LIBCPP_END_NAMESPACE_STD
529