tools/llvm: Do not build with symbols
[minix3.git] / external / bsd / libc++ / dist / libcxx / src / string.cpp
blobfde52129e9fbbd14a60fde9454518d273bde4e6b
1 //===------------------------- string.cpp ---------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
12 #include "string"
13 #include "cstdlib"
14 #include "cwchar"
15 #include "cerrno"
16 #include "limits"
17 #include "stdexcept"
18 #ifdef _LIBCPP_MSVCRT
19 #include "support/win32/support.h"
20 #endif // _LIBCPP_MSVCRT
21 #include <stdio.h>
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>;
30 template
31 string
32 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
34 namespace
37 template<typename T>
38 inline
39 void throw_helper( const string& msg )
41 #ifndef _LIBCPP_NO_EXCEPTIONS
42 throw T( msg );
43 #else
44 printf("%s\n", msg.c_str());
45 abort();
46 #endif
49 inline
50 void throw_from_string_out_of_range( const string& func )
52 throw_helper<out_of_range>(func + ": out of range");
55 inline
56 void throw_from_string_invalid_arg( const string& func )
58 throw_helper<invalid_argument>(func + ": no conversion");
61 // as_integer
63 template<typename V, typename S, typename F>
64 inline
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;
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;
83 template<typename V, typename S>
84 inline
86 as_integer(const string& func, const S& s, size_t* idx, int base);
88 // string
89 template<>
90 inline
91 int
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);
101 template<>
102 inline
103 long
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 );
109 template<>
110 inline
111 unsigned long
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 );
117 template<>
118 inline
119 long long
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 );
125 template<>
126 inline
127 unsigned long long
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 );
133 // wstring
134 template<>
135 inline
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);
146 template<>
147 inline
148 long
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 );
154 template<>
155 inline
156 unsigned long
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 );
162 template<>
163 inline
164 long long
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 );
170 template<>
171 inline
172 unsigned long long
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 );
178 // as_float
180 template<typename V, typename S, typename F>
181 inline
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;
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;
200 template<typename V, typename S>
201 inline
202 V as_float( const string& func, const S& s, size_t* idx = nullptr );
204 template<>
205 inline
206 float
207 as_float( const string& func, const string& s, size_t* idx )
209 return as_float_helper<float>( func, s, idx, strtof );
212 template<>
213 inline
214 double
215 as_float(const string& func, const string& s, size_t* idx )
217 return as_float_helper<double>( func, s, idx, strtod );
220 template<>
221 inline
222 long double
223 as_float( const string& func, const string& s, size_t* idx )
225 return as_float_helper<long double>( func, s, idx, strtold );
228 template<>
229 inline
230 float
231 as_float( const string& func, const wstring& s, size_t* idx )
233 return as_float_helper<float>( func, s, idx, wcstof );
236 template<>
237 inline
238 double
239 as_float( const string& func, const wstring& s, size_t* idx )
241 return as_float_helper<double>( func, s, idx, wcstod );
244 template<>
245 inline
246 long double
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 );
266 long
267 stol(const string& str, size_t* idx, int base)
269 return as_integer<long>( "stol", str, idx, base );
272 long
273 stol(const wstring& str, size_t* idx, int base)
275 return as_integer<long>( "stol", str, idx, base );
278 unsigned long
279 stoul(const string& str, size_t* idx, int base)
281 return as_integer<unsigned long>( "stoul", str, idx, base );
284 unsigned long
285 stoul(const wstring& str, size_t* idx, int base)
287 return as_integer<unsigned long>( "stoul", str, idx, base );
290 long long
291 stoll(const string& str, size_t* idx, int base)
293 return as_integer<long long>( "stoll", str, idx, base );
296 long long
297 stoll(const wstring& str, size_t* idx, int base)
299 return as_integer<long long>( "stoll", str, idx, base );
302 unsigned long long
303 stoull(const string& str, size_t* idx, int base)
305 return as_integer<unsigned long long>( "stoull", str, idx, base );
308 unsigned long long
309 stoull(const wstring& str, size_t* idx, int base)
311 return as_integer<unsigned long long>( "stoull", str, idx, base );
314 float
315 stof(const string& str, size_t* idx)
317 return as_float<float>( "stof", str, idx );
320 float
321 stof(const wstring& str, size_t* idx)
323 return as_float<float>( "stof", str, idx );
326 double
327 stod(const string& str, size_t* idx)
329 return as_float<double>( "stod", str, idx );
332 double
333 stod(const wstring& str, size_t* idx)
335 return as_float<double>( "stod", str, idx );
338 long double
339 stold(const string& str, size_t* idx)
341 return as_float<long double>( "stold", str, idx );
344 long double
345 stold(const wstring& str, size_t* idx)
347 return as_float<long double>( "stold", str, idx );
350 // to_string
352 namespace
355 // as_string
357 template<typename S, typename P, typename V >
358 inline
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();
364 while (true)
366 int status = sprintf_like(&s[0], available + 1, fmt, a);
367 if ( status >= 0 )
369 size_type used = static_cast<size_type>(status);
370 if ( used <= available )
372 s.resize( used );
373 break;
375 available = used; // Assume this is advice of how much space we need.
377 else
378 available = available * 2 + 1;
379 s.resize(available);
381 return s;
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>
390 string
391 operator()() const
393 string s;
394 s.resize(s.capacity());
395 return s;
399 template <class V>
400 struct initial_string<wstring, V, false>
402 wstring
403 operator()() const
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;
414 template <class V>
415 struct initial_string<wstring, V, true>
417 wstring
418 operator()() const
420 wstring s(20, wchar_t());
421 s.resize(s.capacity());
422 return s;
426 typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
428 inline
429 wide_printf
430 get_swprintf()
432 #ifndef _LIBCPP_MSVCRT
433 return swprintf;
434 #else
435 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
436 #endif
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