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 //===----------------------------------------------------------------------===//
10 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
19 #include "support/win32/support.h"
20 #endif // _LIBCPP_MSVCRT
23 _LIBCPP_BEGIN_NAMESPACE_STD
25 template class __basic_string_common
<true>;
27 template class basic_string
<char>;
28 template class basic_string
<wchar_t>;
32 operator+<char, char_traits
<char>, allocator
<char> >(char const*, string
const&);
39 void throw_helper( const string
& msg
)
41 #ifndef _LIBCPP_NO_EXCEPTIONS
44 printf("%s\n", msg
.c_str());
50 void throw_from_string_out_of_range( const string
& func
)
52 throw_helper
<out_of_range
>(func
+ ": out of range");
56 void throw_from_string_invalid_arg( const string
& func
)
58 throw_helper
<invalid_argument
>(func
+ ": no conversion");
63 template<typename V
, typename S
, typename F
>
66 as_integer_helper(const string
& func
, const S
& str
, size_t* idx
, int base
, F f
)
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
;
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
);
77 throw_from_string_invalid_arg(func
);
79 *idx
= static_cast<size_t>(ptr
- p
);
83 template<typename V
, typename S
>
86 as_integer(const string
& func
, const S
& s
, size_t* idx
, int base
);
92 as_integer(const string
& func
, const string
& s
, size_t* idx
, int base
)
94 // Use long as no Standard string to integer exists.
95 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
);
104 as_integer(const string
& func
, const string
& s
, size_t* idx
, int base
)
106 return as_integer_helper
<long>( func
, s
, idx
, base
, strtol
);
112 as_integer( const string
& func
, const string
& s
, size_t* idx
, int base
)
114 return as_integer_helper
<unsigned long>( func
, s
, idx
, base
, strtoul
);
120 as_integer( const string
& func
, const string
& s
, size_t* idx
, int base
)
122 return as_integer_helper
<long long>( func
, s
, idx
, base
, strtoll
);
128 as_integer( const string
& func
, const string
& s
, size_t* idx
, int base
)
130 return as_integer_helper
<unsigned long long>( func
, s
, idx
, base
, strtoull
);
137 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
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
);
149 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
151 return as_integer_helper
<long>( func
, s
, idx
, base
, wcstol
);
157 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
159 return as_integer_helper
<unsigned long>( func
, s
, idx
, base
, wcstoul
);
165 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
167 return as_integer_helper
<long long>( func
, s
, idx
, base
, wcstoll
);
173 as_integer( const string
& func
, const wstring
& s
, size_t* idx
, int base
)
175 return as_integer_helper
<unsigned long long>( func
, s
, idx
, base
, wcstoull
);
180 template<typename V
, typename S
, typename F
>
183 as_float_helper(const string
& func
, const S
& str
, size_t* idx
, F f
)
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
;
190 swap(errno
, errno_save
);
191 if (errno_save
== ERANGE
)
192 throw_from_string_out_of_range(func
);
194 throw_from_string_invalid_arg(func
);
196 *idx
= static_cast<size_t>(ptr
- p
);
200 template<typename V
, typename S
>
202 V
as_float( const string
& func
, const S
& s
, size_t* idx
= nullptr );
207 as_float( const string
& func
, const string
& s
, size_t* idx
)
209 return as_float_helper
<float>( func
, s
, idx
, strtof
);
215 as_float(const string
& func
, const string
& s
, size_t* idx
)
217 return as_float_helper
<double>( func
, s
, idx
, strtod
);
223 as_float( const string
& func
, const string
& s
, size_t* idx
)
225 return as_float_helper
<long double>( func
, s
, idx
, strtold
);
231 as_float( const string
& func
, const wstring
& s
, size_t* idx
)
233 return as_float_helper
<float>( func
, s
, idx
, wcstof
);
239 as_float( const string
& func
, const wstring
& s
, size_t* idx
)
241 return as_float_helper
<double>( func
, s
, idx
, wcstod
);
247 as_float( const string
& func
, const wstring
& s
, size_t* idx
)
249 return as_float_helper
<long double>( func
, s
, idx
, wcstold
);
252 } // unnamed namespace
255 stoi(const string
& str
, size_t* idx
, int base
)
257 return as_integer
<int>( "stoi", str
, idx
, base
);
261 stoi(const wstring
& str
, size_t* idx
, int base
)
263 return as_integer
<int>( "stoi", str
, idx
, base
);
267 stol(const string
& str
, size_t* idx
, int base
)
269 return as_integer
<long>( "stol", str
, idx
, base
);
273 stol(const wstring
& str
, size_t* idx
, int base
)
275 return as_integer
<long>( "stol", str
, idx
, base
);
279 stoul(const string
& str
, size_t* idx
, int base
)
281 return as_integer
<unsigned long>( "stoul", str
, idx
, base
);
285 stoul(const wstring
& str
, size_t* idx
, int base
)
287 return as_integer
<unsigned long>( "stoul", str
, idx
, base
);
291 stoll(const string
& str
, size_t* idx
, int base
)
293 return as_integer
<long long>( "stoll", str
, idx
, base
);
297 stoll(const wstring
& str
, size_t* idx
, int base
)
299 return as_integer
<long long>( "stoll", str
, idx
, base
);
303 stoull(const string
& str
, size_t* idx
, int base
)
305 return as_integer
<unsigned long long>( "stoull", str
, idx
, base
);
309 stoull(const wstring
& str
, size_t* idx
, int base
)
311 return as_integer
<unsigned long long>( "stoull", str
, idx
, base
);
315 stof(const string
& str
, size_t* idx
)
317 return as_float
<float>( "stof", str
, idx
);
321 stof(const wstring
& str
, size_t* idx
)
323 return as_float
<float>( "stof", str
, idx
);
327 stod(const string
& str
, size_t* idx
)
329 return as_float
<double>( "stod", str
, idx
);
333 stod(const wstring
& str
, size_t* idx
)
335 return as_float
<double>( "stod", str
, idx
);
339 stold(const string
& str
, size_t* idx
)
341 return as_float
<long double>( "stold", str
, idx
);
345 stold(const wstring
& str
, size_t* idx
)
347 return as_float
<long double>( "stold", str
, idx
);
357 template<typename S
, typename P
, typename V
>
360 as_string(P sprintf_like
, S s
, const typename
S::value_type
* fmt
, V a
)
362 typedef typename
S::size_type size_type
;
363 size_type available
= s
.size();
366 int status
= sprintf_like(&s
[0], available
+ 1, fmt
, a
);
369 size_type used
= static_cast<size_type
>(status
);
370 if ( used
<= available
)
375 available
= used
; // Assume this is advice of how much space we need.
378 available
= available
* 2 + 1;
384 template <class S
, class V
, bool = is_floating_point
<V
>::value
>
385 struct initial_string
;
387 template <class V
, bool b
>
388 struct initial_string
<string
, V
, b
>
394 s
.resize(s
.capacity());
400 struct initial_string
<wstring
, V
, false>
405 const size_t n
= (numeric_limits
<unsigned long long>::digits
/ 3)
406 + ((numeric_limits
<unsigned long long>::digits
% 3) != 0)
408 wstring
s(n
, wchar_t());
409 s
.resize(s
.capacity());
415 struct initial_string
<wstring
, V
, true>
420 wstring
s(20, wchar_t());
421 s
.resize(s
.capacity());
426 typedef int (*wide_printf
)(wchar_t* __restrict
, size_t, const wchar_t*__restrict
, ...);
432 #ifndef _LIBCPP_MSVCRT
435 return static_cast<int (__cdecl
*)(wchar_t* __restrict
, size_t, const wchar_t*__restrict
, ...)>(swprintf
);
439 } // unnamed namespace
441 string
to_string(int val
)
443 return as_string(snprintf
, initial_string
<string
, int>()(), "%d", val
);
446 string
to_string(unsigned val
)
448 return as_string(snprintf
, initial_string
<string
, unsigned>()(), "%u", val
);
451 string
to_string(long val
)
453 return as_string(snprintf
, initial_string
<string
, long>()(), "%ld", val
);
456 string
to_string(unsigned long val
)
458 return as_string(snprintf
, initial_string
<string
, unsigned long>()(), "%lu", val
);
461 string
to_string(long long val
)
463 return as_string(snprintf
, initial_string
<string
, long long>()(), "%lld", val
);
466 string
to_string(unsigned long long val
)
468 return as_string(snprintf
, initial_string
<string
, unsigned long long>()(), "%llu", val
);
471 string
to_string(float val
)
473 return as_string(snprintf
, initial_string
<string
, float>()(), "%f", val
);
476 string
to_string(double val
)
478 return as_string(snprintf
, initial_string
<string
, double>()(), "%f", val
);
481 string
to_string(long double val
)
483 return as_string(snprintf
, initial_string
<string
, long double>()(), "%Lf", val
);
486 wstring
to_wstring(int val
)
488 return as_string(get_swprintf(), initial_string
<wstring
, int>()(), L
"%d", val
);
491 wstring
to_wstring(unsigned val
)
493 return as_string(get_swprintf(), initial_string
<wstring
, unsigned>()(), L
"%u", val
);
496 wstring
to_wstring(long val
)
498 return as_string(get_swprintf(), initial_string
<wstring
, long>()(), L
"%ld", val
);
501 wstring
to_wstring(unsigned long val
)
503 return as_string(get_swprintf(), initial_string
<wstring
, unsigned long>()(), L
"%lu", val
);
506 wstring
to_wstring(long long val
)
508 return as_string(get_swprintf(), initial_string
<wstring
, long long>()(), L
"%lld", val
);
511 wstring
to_wstring(unsigned long long val
)
513 return as_string(get_swprintf(), initial_string
<wstring
, unsigned long long>()(), L
"%llu", val
);
516 wstring
to_wstring(float val
)
518 return as_string(get_swprintf(), initial_string
<wstring
, float>()(), L
"%f", val
);
521 wstring
to_wstring(double val
)
523 return as_string(get_swprintf(), initial_string
<wstring
, double>()(), L
"%f", val
);
526 wstring
to_wstring(long double val
)
528 return as_string(get_swprintf(), initial_string
<wstring
, long double>()(), L
"%Lf", val
);
530 _LIBCPP_END_NAMESPACE_STD