blob: fde52129e9fbbd14a60fde9454518d273bde4e6b [file] [log] [blame]
Howard Hinnanta6a062d2010-06-02 18:20:39 +00001//===------------------------- string.cpp ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnanta6a062d2010-06-02 18:20:39 +00007//
8//===----------------------------------------------------------------------===//
9
Howard Hinnant04a2c712013-08-29 20:56:53 +000010#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
11
Howard Hinnanta6a062d2010-06-02 18:20:39 +000012#include "string"
13#include "cstdlib"
14#include "cwchar"
15#include "cerrno"
Howard Hinnant9e98b342013-05-16 17:13:40 +000016#include "limits"
17#include "stdexcept"
Howard Hinnante9df0a52013-08-01 18:17:34 +000018#ifdef _LIBCPP_MSVCRT
Howard Hinnant6cd05ee2011-09-23 16:11:27 +000019#include "support/win32/support.h"
Howard Hinnante9df0a52013-08-01 18:17:34 +000020#endif // _LIBCPP_MSVCRT
Howard Hinnanted14a762013-07-23 16:05:56 +000021#include <stdio.h>
Howard Hinnanta6a062d2010-06-02 18:20:39 +000022
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template class __basic_string_common<true>;
26
27template class basic_string<char>;
28template class basic_string<wchar_t>;
29
Howard Hinnanta6a062d2010-06-02 18:20:39 +000030template
31 string
32 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
33
Howard Hinnant9e98b342013-05-16 17:13:40 +000034namespace
35{
36
37template<typename T>
38inline
39void throw_helper( const string& msg )
40{
41#ifndef _LIBCPP_NO_EXCEPTIONS
42 throw T( msg );
43#else
Howard Hinnanted14a762013-07-23 16:05:56 +000044 printf("%s\n", msg.c_str());
Howard Hinnant9e98b342013-05-16 17:13:40 +000045 abort();
46#endif
47}
48
49inline
50void throw_from_string_out_of_range( const string& func )
51{
52 throw_helper<out_of_range>(func + ": out of range");
53}
54
55inline
56void throw_from_string_invalid_arg( const string& func )
57{
58 throw_helper<invalid_argument>(func + ": no conversion");
59}
60
61// as_integer
62
63template<typename V, typename S, typename F>
64inline
65V
66as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
67{
68 typename S::value_type* ptr;
69 const typename S::value_type* const p = str.c_str();
70 typename remove_reference<decltype(errno)>::type errno_save = errno;
71 errno = 0;
72 V r = f(p, &ptr, base);
73 swap(errno, errno_save);
74 if (errno_save == ERANGE)
75 throw_from_string_out_of_range(func);
76 if (ptr == p)
77 throw_from_string_invalid_arg(func);
78 if (idx)
79 *idx = static_cast<size_t>(ptr - p);
80 return r;
81}
82
83template<typename V, typename S>
84inline
85V
86as_integer(const string& func, const S& s, size_t* idx, int base);
87
88// string
89template<>
90inline
91int
92as_integer(const string& func, const string& s, size_t* idx, int base )
93{
Joerg Sonnenbergerbd64f142013-09-17 08:46:53 +000094 // Use long as no Standard string to integer exists.
Howard Hinnant9e98b342013-05-16 17:13:40 +000095 long r = as_integer_helper<long>( func, s, idx, base, strtol );
96 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
97 throw_from_string_out_of_range(func);
98 return static_cast<int>(r);
99}
100
101template<>
102inline
103long
104as_integer(const string& func, const string& s, size_t* idx, int base )
105{
106 return as_integer_helper<long>( func, s, idx, base, strtol );
107}
108
109template<>
110inline
111unsigned long
112as_integer( const string& func, const string& s, size_t* idx, int base )
113{
114 return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
115}
116
117template<>
118inline
119long long
120as_integer( const string& func, const string& s, size_t* idx, int base )
121{
122 return as_integer_helper<long long>( func, s, idx, base, strtoll );
123}
124
125template<>
126inline
127unsigned long long
128as_integer( const string& func, const string& s, size_t* idx, int base )
129{
130 return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
131}
132
133// wstring
134template<>
135inline
136int
137as_integer( const string& func, const wstring& s, size_t* idx, int base )
138{
139 // Use long as no Stantard string to integer exists.
140 long r = as_integer_helper<long>( func, s, idx, base, wcstol );
141 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
142 throw_from_string_out_of_range(func);
143 return static_cast<int>(r);
144}
145
146template<>
147inline
148long
149as_integer( const string& func, const wstring& s, size_t* idx, int base )
150{
151 return as_integer_helper<long>( func, s, idx, base, wcstol );
152}
153
154template<>
155inline
156unsigned long
157as_integer( const string& func, const wstring& s, size_t* idx, int base )
158{
159 return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
160}
161
162template<>
163inline
164long long
165as_integer( const string& func, const wstring& s, size_t* idx, int base )
166{
167 return as_integer_helper<long long>( func, s, idx, base, wcstoll );
168}
169
170template<>
171inline
172unsigned long long
173as_integer( const string& func, const wstring& s, size_t* idx, int base )
174{
175 return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
176}
177
178// as_float
179
180template<typename V, typename S, typename F>
181inline
182V
183as_float_helper(const string& func, const S& str, size_t* idx, F f )
184{
185 typename S::value_type* ptr;
186 const typename S::value_type* const p = str.c_str();
187 typename remove_reference<decltype(errno)>::type errno_save = errno;
188 errno = 0;
189 V r = f(p, &ptr);
190 swap(errno, errno_save);
191 if (errno_save == ERANGE)
192 throw_from_string_out_of_range(func);
193 if (ptr == p)
194 throw_from_string_invalid_arg(func);
195 if (idx)
196 *idx = static_cast<size_t>(ptr - p);
197 return r;
198}
199
200template<typename V, typename S>
201inline
202V as_float( const string& func, const S& s, size_t* idx = nullptr );
203
204template<>
205inline
206float
207as_float( const string& func, const string& s, size_t* idx )
208{
209 return as_float_helper<float>( func, s, idx, strtof );
210}
211
212template<>
213inline
214double
215as_float(const string& func, const string& s, size_t* idx )
216{
217 return as_float_helper<double>( func, s, idx, strtod );
218}
219
220template<>
221inline
222long double
223as_float( const string& func, const string& s, size_t* idx )
224{
225 return as_float_helper<long double>( func, s, idx, strtold );
226}
227
228template<>
229inline
230float
231as_float( const string& func, const wstring& s, size_t* idx )
232{
233 return as_float_helper<float>( func, s, idx, wcstof );
234}
235
236template<>
237inline
238double
239as_float( const string& func, const wstring& s, size_t* idx )
240{
241 return as_float_helper<double>( func, s, idx, wcstod );
242}
243
244template<>
245inline
246long double
247as_float( const string& func, const wstring& s, size_t* idx )
248{
249 return as_float_helper<long double>( func, s, idx, wcstold );
250}
251
252} // unnamed namespace
253
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000254int
255stoi(const string& str, size_t* idx, int base)
256{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000257 return as_integer<int>( "stoi", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000258}
259
260int
261stoi(const wstring& str, size_t* idx, int base)
262{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000263 return as_integer<int>( "stoi", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000264}
265
266long
267stol(const string& str, size_t* idx, int base)
268{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000269 return as_integer<long>( "stol", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000270}
271
272long
273stol(const wstring& str, size_t* idx, int base)
274{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000275 return as_integer<long>( "stol", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000276}
277
278unsigned long
279stoul(const string& str, size_t* idx, int base)
280{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000281 return as_integer<unsigned long>( "stoul", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000282}
283
284unsigned long
285stoul(const wstring& str, size_t* idx, int base)
286{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000287 return as_integer<unsigned long>( "stoul", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000288}
289
290long long
291stoll(const string& str, size_t* idx, int base)
292{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000293 return as_integer<long long>( "stoll", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000294}
295
296long long
297stoll(const wstring& str, size_t* idx, int base)
298{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000299 return as_integer<long long>( "stoll", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000300}
301
302unsigned long long
303stoull(const string& str, size_t* idx, int base)
304{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000305 return as_integer<unsigned long long>( "stoull", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000306}
307
308unsigned long long
309stoull(const wstring& str, size_t* idx, int base)
310{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000311 return as_integer<unsigned long long>( "stoull", str, idx, base );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000312}
313
314float
315stof(const string& str, size_t* idx)
316{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000317 return as_float<float>( "stof", str, idx );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000318}
319
320float
321stof(const wstring& str, size_t* idx)
322{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000323 return as_float<float>( "stof", str, idx );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000324}
325
326double
327stod(const string& str, size_t* idx)
328{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000329 return as_float<double>( "stod", str, idx );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000330}
331
332double
333stod(const wstring& str, size_t* idx)
334{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000335 return as_float<double>( "stod", str, idx );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000336}
337
338long double
339stold(const string& str, size_t* idx)
340{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000341 return as_float<long double>( "stold", str, idx );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000342}
343
344long double
345stold(const wstring& str, size_t* idx)
346{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000347 return as_float<long double>( "stold", str, idx );
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000348}
349
Howard Hinnant9e98b342013-05-16 17:13:40 +0000350// to_string
351
352namespace
353{
354
355// as_string
356
357template<typename S, typename P, typename V >
358inline
359S
360as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
361{
362 typedef typename S::size_type size_type;
363 size_type available = s.size();
364 while (true)
365 {
366 int status = sprintf_like(&s[0], available + 1, fmt, a);
367 if ( status >= 0 )
368 {
369 size_type used = static_cast<size_type>(status);
370 if ( used <= available )
371 {
372 s.resize( used );
373 break;
374 }
375 available = used; // Assume this is advice of how much space we need.
376 }
377 else
378 available = available * 2 + 1;
379 s.resize(available);
380 }
381 return s;
382}
383
384template <class S, class V, bool = is_floating_point<V>::value>
385struct initial_string;
386
387template <class V, bool b>
388struct initial_string<string, V, b>
389{
390 string
391 operator()() const
392 {
393 string s;
394 s.resize(s.capacity());
395 return s;
396 }
397};
398
399template <class V>
400struct initial_string<wstring, V, false>
401{
402 wstring
403 operator()() const
404 {
405 const size_t n = (numeric_limits<unsigned long long>::digits / 3)
406 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
407 + 1;
408 wstring s(n, wchar_t());
409 s.resize(s.capacity());
410 return s;
411 }
412};
413
414template <class V>
415struct initial_string<wstring, V, true>
416{
417 wstring
418 operator()() const
419 {
420 wstring s(20, wchar_t());
421 s.resize(s.capacity());
422 return s;
423 }
424};
425
426typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
427
428inline
429wide_printf
430get_swprintf()
431{
Howard Hinnante9df0a52013-08-01 18:17:34 +0000432#ifndef _LIBCPP_MSVCRT
Howard Hinnant9e98b342013-05-16 17:13:40 +0000433 return swprintf;
434#else
435 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
436#endif
437}
438
439} // unnamed namespace
440
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000441string to_string(int val)
442{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000443 return as_string(snprintf, initial_string<string, int>()(), "%d", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000444}
445
446string to_string(unsigned val)
447{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000448 return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000449}
450
451string to_string(long val)
452{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000453 return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000454}
455
456string to_string(unsigned long val)
457{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000458 return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000459}
460
461string to_string(long long val)
462{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000463 return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000464}
465
466string to_string(unsigned long long val)
467{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000468 return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000469}
470
471string to_string(float val)
472{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000473 return as_string(snprintf, initial_string<string, float>()(), "%f", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000474}
475
476string to_string(double val)
477{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000478 return as_string(snprintf, initial_string<string, double>()(), "%f", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000479}
480
481string to_string(long double val)
482{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000483 return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000484}
485
486wstring to_wstring(int val)
487{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000488 return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000489}
490
491wstring to_wstring(unsigned val)
492{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000493 return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000494}
495
496wstring to_wstring(long val)
497{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000498 return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000499}
500
501wstring to_wstring(unsigned long val)
502{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000503 return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000504}
505
506wstring to_wstring(long long val)
507{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000508 return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000509}
510
511wstring to_wstring(unsigned long long val)
512{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000513 return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000514}
515
516wstring to_wstring(float val)
517{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000518 return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000519}
520
521wstring to_wstring(double val)
522{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000523 return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000524}
525
526wstring to_wstring(long double val)
527{
Howard Hinnant9e98b342013-05-16 17:13:40 +0000528 return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000529}
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000530_LIBCPP_END_NAMESPACE_STD