1 //===------------------------- string.cpp ---------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
17 #include "support/win32/support.h"
18 #endif // _LIBCPP_MSVCRT
21 _LIBCPP_BEGIN_NAMESPACE_STD
23 template class __basic_string_common
<true>;
25 template class basic_string
<char>;
26 template class basic_string
<wchar_t>;
30 operator+<char, char_traits
<char>, allocator
<char> >(char const*, string
const&);
37 void throw_helper( const string
& msg
)
39 #ifndef _LIBCPP_NO_EXCEPTIONS
42 fprintf(stderr
, "%s\n", msg
.c_str());
48 void throw_from_string_out_of_range( const string
& func
)
50 throw_helper
<out_of_range
>(func
+ ": out of range");
54 void throw_from_string_invalid_arg( const string
& func
)
56 throw_helper
<invalid_argument
>(func
+ ": no conversion");
61 template<typename V
, typename S
, typename F
>
64 as_integer_helper(const string
& func
, const S
& str
, size_t* idx
, int base
, F f
)
66 typename
S::value_type
* ptr
= nullptr;
67 const typename
S::value_type
* const p
= str
.c_str();
68 typename remove_reference
<decltype(errno
)>::type errno_save
= errno
;
70 V r
= f(p
, &ptr
, base
);
71 swap(errno
, errno_save
);
72 if (errno_save
== ERANGE
)
73 throw_from_string_out_of_range(func
);
75 throw_from_string_invalid_arg(func
);
77 *idx
= static_cast<size_t>(ptr
- p
);
81 template<typename V
, typename S
>
84 as_integer(const string
& func
, const S
& s
, size_t* idx
, int base
);
90 as_integer(const string
& func
, const string
& s
, size_t* idx
, int base
)
92 // Use long as no Standard string to integer exists.
93 long r
= as_integer_helper
<long>( func
, s
, idx
, base
, strtol
);
94 if (r
< numeric_limits
<int>::min() || numeric_limits
<int>::max() < r
)
95 throw_from_string_out_of_range(func
);
96 return static_cast<int>(r
);
102 as_integer(const string
& func
, const string
& s
, size_t* idx
, int base
)
104 return as_integer_helper
<long>( func
, s
, idx
, base
, strtol
);
110 as_integer( const string
& func
, const string
& s
, size_t* idx
, int base
)
112 return as_integer_helper
<unsigned long>( func
, s
, idx
, base
, strtoul
);
118 as_integer( const string
& func
, const string
& s
, size_t* idx
, int base
)
120 return as_integer_helper
<long long>( func
, s
, idx
, base
, strtoll
);
126 as_integer( const string
& func
, const string
& s
, size_t* idx
, int base
)
128 return as_integer_helper
<unsigned long long>( func
, s
, idx
, base
, strtoull
);
135 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
137 // Use long as no Stantard string to integer exists.
138 long r
= as_integer_helper
<long>( func
, s
, idx
, base
, wcstol
);
139 if (r
< numeric_limits
<int>::min() || numeric_limits
<int>::max() < r
)
140 throw_from_string_out_of_range(func
);
141 return static_cast<int>(r
);
147 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
149 return as_integer_helper
<long>( func
, s
, idx
, base
, wcstol
);
155 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
157 return as_integer_helper
<unsigned long>( func
, s
, idx
, base
, wcstoul
);
163 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
165 return as_integer_helper
<long long>( func
, s
, idx
, base
, wcstoll
);
171 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
173 return as_integer_helper
<unsigned long long>( func
, s
, idx
, base
, wcstoull
);
178 template<typename V
, typename S
, typename F
>
181 as_float_helper(const string
& func
, const S
& str
, size_t* idx
, F f
)
183 typename
S::value_type
* ptr
= nullptr;
184 const typename
S::value_type
* const p
= str
.c_str();
185 typename remove_reference
<decltype(errno
)>::type errno_save
= errno
;
188 swap(errno
, errno_save
);
189 if (errno_save
== ERANGE
)
190 throw_from_string_out_of_range(func
);
192 throw_from_string_invalid_arg(func
);
194 *idx
= static_cast<size_t>(ptr
- p
);
198 template<typename V
, typename S
>
200 V
as_float( const string
& func
, const S
& s
, size_t* idx
= nullptr );
205 as_float( const string
& func
, const string
& s
, size_t* idx
)
207 return as_float_helper
<float>( func
, s
, idx
, strtof
);
213 as_float(const string
& func
, const string
& s
, size_t* idx
)
215 return as_float_helper
<double>( func
, s
, idx
, strtod
);
221 as_float( const string
& func
, const string
& s
, size_t* idx
)
223 return as_float_helper
<long double>( func
, s
, idx
, strtold
);
229 as_float( const string
& func
, const wstring
& s
, size_t* idx
)
231 return as_float_helper
<float>( func
, s
, idx
, wcstof
);
237 as_float( const string
& func
, const wstring
& s
, size_t* idx
)
239 return as_float_helper
<double>( func
, s
, idx
, wcstod
);
245 as_float( const string
& func
, const wstring
& s
, size_t* idx
)
247 return as_float_helper
<long double>( func
, s
, idx
, wcstold
);
250 } // unnamed namespace
253 stoi(const string
& str
, size_t* idx
, int base
)
255 return as_integer
<int>( "stoi", str
, idx
, base
);
259 stoi(const wstring
& str
, size_t* idx
, int base
)
261 return as_integer
<int>( "stoi", str
, idx
, base
);
265 stol(const string
& str
, size_t* idx
, int base
)
267 return as_integer
<long>( "stol", str
, idx
, base
);
271 stol(const wstring
& str
, size_t* idx
, int base
)
273 return as_integer
<long>( "stol", str
, idx
, base
);
277 stoul(const string
& str
, size_t* idx
, int base
)
279 return as_integer
<unsigned long>( "stoul", str
, idx
, base
);
283 stoul(const wstring
& str
, size_t* idx
, int base
)
285 return as_integer
<unsigned long>( "stoul", str
, idx
, base
);
289 stoll(const string
& str
, size_t* idx
, int base
)
291 return as_integer
<long long>( "stoll", str
, idx
, base
);
295 stoll(const wstring
& str
, size_t* idx
, int base
)
297 return as_integer
<long long>( "stoll", str
, idx
, base
);
301 stoull(const string
& str
, size_t* idx
, int base
)
303 return as_integer
<unsigned long long>( "stoull", str
, idx
, base
);
307 stoull(const wstring
& str
, size_t* idx
, int base
)
309 return as_integer
<unsigned long long>( "stoull", str
, idx
, base
);
313 stof(const string
& str
, size_t* idx
)
315 return as_float
<float>( "stof", str
, idx
);
319 stof(const wstring
& str
, size_t* idx
)
321 return as_float
<float>( "stof", str
, idx
);
325 stod(const string
& str
, size_t* idx
)
327 return as_float
<double>( "stod", str
, idx
);
331 stod(const wstring
& str
, size_t* idx
)
333 return as_float
<double>( "stod", str
, idx
);
337 stold(const string
& str
, size_t* idx
)
339 return as_float
<long double>( "stold", str
, idx
);
343 stold(const wstring
& str
, size_t* idx
)
345 return as_float
<long double>( "stold", str
, idx
);
355 template<typename S
, typename P
, typename V
>
358 as_string(P sprintf_like
, S s
, const typename
S::value_type
* fmt
, V a
)
360 typedef typename
S::size_type size_type
;
361 size_type available
= s
.size();
364 int status
= sprintf_like(&s
[0], available
+ 1, fmt
, a
);
367 size_type used
= static_cast<size_type
>(status
);
368 if ( used
<= available
)
373 available
= used
; // Assume this is advice of how much space we need.
376 available
= available
* 2 + 1;
382 template <class S
, class V
, bool = is_floating_point
<V
>::value
>
383 struct initial_string
;
385 template <class V
, bool b
>
386 struct initial_string
<string
, V
, b
>
392 s
.resize(s
.capacity());
398 struct initial_string
<wstring
, V
, false>
403 const size_t n
= (numeric_limits
<unsigned long long>::digits
/ 3)
404 + ((numeric_limits
<unsigned long long>::digits
% 3) != 0)
406 wstring
s(n
, wchar_t());
407 s
.resize(s
.capacity());
413 struct initial_string
<wstring
, V
, true>
418 wstring
s(20, wchar_t());
419 s
.resize(s
.capacity());
424 typedef int (*wide_printf
)(wchar_t* __restrict
, size_t, const wchar_t*__restrict
, ...);
430 #ifndef _LIBCPP_MSVCRT
433 return static_cast<int (__cdecl
*)(wchar_t* __restrict
, size_t, const wchar_t*__restrict
, ...)>(swprintf
);
437 } // unnamed namespace
439 string
to_string(int val
)
441 return as_string(snprintf
, initial_string
<string
, int>()(), "%d", val
);
444 string
to_string(unsigned val
)
446 return as_string(snprintf
, initial_string
<string
, unsigned>()(), "%u", val
);
449 string
to_string(long val
)
451 return as_string(snprintf
, initial_string
<string
, long>()(), "%ld", val
);
454 string
to_string(unsigned long val
)
456 return as_string(snprintf
, initial_string
<string
, unsigned long>()(), "%lu", val
);
459 string
to_string(long long val
)
461 return as_string(snprintf
, initial_string
<string
, long long>()(), "%lld", val
);
464 string
to_string(unsigned long long val
)
466 return as_string(snprintf
, initial_string
<string
, unsigned long long>()(), "%llu", val
);
469 string
to_string(float val
)
471 return as_string(snprintf
, initial_string
<string
, float>()(), "%f", val
);
474 string
to_string(double val
)
476 return as_string(snprintf
, initial_string
<string
, double>()(), "%f", val
);
479 string
to_string(long double val
)
481 return as_string(snprintf
, initial_string
<string
, long double>()(), "%Lf", val
);
484 wstring
to_wstring(int val
)
486 return as_string(get_swprintf(), initial_string
<wstring
, int>()(), L
"%d", val
);
489 wstring
to_wstring(unsigned val
)
491 return as_string(get_swprintf(), initial_string
<wstring
, unsigned>()(), L
"%u", val
);
494 wstring
to_wstring(long val
)
496 return as_string(get_swprintf(), initial_string
<wstring
, long>()(), L
"%ld", val
);
499 wstring
to_wstring(unsigned long val
)
501 return as_string(get_swprintf(), initial_string
<wstring
, unsigned long>()(), L
"%lu", val
);
504 wstring
to_wstring(long long val
)
506 return as_string(get_swprintf(), initial_string
<wstring
, long long>()(), L
"%lld", val
);
509 wstring
to_wstring(unsigned long long val
)
511 return as_string(get_swprintf(), initial_string
<wstring
, unsigned long long>()(), L
"%llu", val
);
514 wstring
to_wstring(float val
)
516 return as_string(get_swprintf(), initial_string
<wstring
, float>()(), L
"%f", val
);
519 wstring
to_wstring(double val
)
521 return as_string(get_swprintf(), initial_string
<wstring
, double>()(), L
"%f", val
);
524 wstring
to_wstring(long double val
)
526 return as_string(get_swprintf(), initial_string
<wstring
, long double>()(), L
"%Lf", val
);
528 _LIBCPP_END_NAMESPACE_STD