blob: 6c89a5d7e068fe40423ad4ab38964c03d75f6105 [file] [log] [blame]
Howard Hinnantcbbf6332010-06-02 18:20:391//===------------------------- string.cpp ---------------------------------===//
2//
Chandler Carruth57b08b02019-01-19 10:56:403// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantcbbf6332010-06-02 18:20:396//
7//===----------------------------------------------------------------------===//
8
9#include "string"
10#include "cstdlib"
11#include "cwchar"
12#include "cerrno"
Howard Hinnant9daaf572013-05-16 17:13:4013#include "limits"
14#include "stdexcept"
Howard Hinnant1468d0c2013-07-23 16:05:5615#include <stdio.h>
Howard Hinnantcbbf6332010-06-02 18:20:3916
17_LIBCPP_BEGIN_NAMESPACE_STD
18
Shoaib Meenai190994e2016-09-19 18:29:0719template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
Howard Hinnantcbbf6332010-06-02 18:20:3920
Shoaib Meenai190994e2016-09-19 18:29:0721template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<char>;
22template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<wchar_t>;
Howard Hinnantcbbf6332010-06-02 18:20:3923
Howard Hinnantcbbf6332010-06-02 18:20:3924template
25 string
26 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
27
Howard Hinnant9daaf572013-05-16 17:13:4028namespace
29{
30
31template<typename T>
32inline
33void throw_helper( const string& msg )
34{
35#ifndef _LIBCPP_NO_EXCEPTIONS
36 throw T( msg );
37#else
Ed Schoutenc19393c2015-03-10 07:57:4338 fprintf(stderr, "%s\n", msg.c_str());
Marshall Clowd437fa52016-08-25 15:09:0139 _VSTD::abort();
Howard Hinnant9daaf572013-05-16 17:13:4040#endif
41}
42
43inline
44void throw_from_string_out_of_range( const string& func )
45{
46 throw_helper<out_of_range>(func + ": out of range");
47}
48
49inline
50void throw_from_string_invalid_arg( const string& func )
51{
52 throw_helper<invalid_argument>(func + ": no conversion");
53}
54
55// as_integer
56
57template<typename V, typename S, typename F>
58inline
59V
60as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
61{
Eric Fiselierd6bd7bf2014-11-14 22:23:5762 typename S::value_type* ptr = nullptr;
Howard Hinnant9daaf572013-05-16 17:13:4063 const typename S::value_type* const p = str.c_str();
64 typename remove_reference<decltype(errno)>::type errno_save = errno;
65 errno = 0;
66 V r = f(p, &ptr, base);
67 swap(errno, errno_save);
68 if (errno_save == ERANGE)
69 throw_from_string_out_of_range(func);
70 if (ptr == p)
71 throw_from_string_invalid_arg(func);
72 if (idx)
73 *idx = static_cast<size_t>(ptr - p);
74 return r;
75}
76
77template<typename V, typename S>
78inline
79V
80as_integer(const string& func, const S& s, size_t* idx, int base);
81
82// string
83template<>
84inline
85int
86as_integer(const string& func, const string& s, size_t* idx, int base )
87{
Joerg Sonnenberger8092c952013-09-17 08:46:5388 // Use long as no Standard string to integer exists.
Howard Hinnant9daaf572013-05-16 17:13:4089 long r = as_integer_helper<long>( func, s, idx, base, strtol );
90 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
91 throw_from_string_out_of_range(func);
92 return static_cast<int>(r);
93}
94
95template<>
96inline
97long
98as_integer(const string& func, const string& s, size_t* idx, int base )
99{
100 return as_integer_helper<long>( func, s, idx, base, strtol );
101}
102
103template<>
104inline
105unsigned long
106as_integer( const string& func, const string& s, size_t* idx, int base )
107{
108 return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
109}
110
111template<>
112inline
113long long
114as_integer( const string& func, const string& s, size_t* idx, int base )
115{
116 return as_integer_helper<long long>( func, s, idx, base, strtoll );
117}
118
119template<>
120inline
121unsigned long long
122as_integer( const string& func, const string& s, size_t* idx, int base )
123{
124 return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
125}
126
127// wstring
128template<>
129inline
130int
131as_integer( const string& func, const wstring& s, size_t* idx, int base )
132{
133 // Use long as no Stantard string to integer exists.
134 long r = as_integer_helper<long>( func, s, idx, base, wcstol );
135 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
136 throw_from_string_out_of_range(func);
137 return static_cast<int>(r);
138}
139
140template<>
141inline
142long
143as_integer( const string& func, const wstring& s, size_t* idx, int base )
144{
145 return as_integer_helper<long>( func, s, idx, base, wcstol );
146}
147
148template<>
149inline
150unsigned long
151as_integer( const string& func, const wstring& s, size_t* idx, int base )
152{
153 return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
154}
155
156template<>
157inline
158long long
159as_integer( const string& func, const wstring& s, size_t* idx, int base )
160{
161 return as_integer_helper<long long>( func, s, idx, base, wcstoll );
162}
163
164template<>
165inline
166unsigned long long
167as_integer( const string& func, const wstring& s, size_t* idx, int base )
168{
169 return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
170}
171
172// as_float
173
174template<typename V, typename S, typename F>
175inline
176V
177as_float_helper(const string& func, const S& str, size_t* idx, F f )
178{
Eric Fiselierd6bd7bf2014-11-14 22:23:57179 typename S::value_type* ptr = nullptr;
Howard Hinnant9daaf572013-05-16 17:13:40180 const typename S::value_type* const p = str.c_str();
181 typename remove_reference<decltype(errno)>::type errno_save = errno;
182 errno = 0;
183 V r = f(p, &ptr);
184 swap(errno, errno_save);
185 if (errno_save == ERANGE)
186 throw_from_string_out_of_range(func);
187 if (ptr == p)
188 throw_from_string_invalid_arg(func);
189 if (idx)
190 *idx = static_cast<size_t>(ptr - p);
191 return r;
192}
193
194template<typename V, typename S>
195inline
196V as_float( const string& func, const S& s, size_t* idx = nullptr );
197
198template<>
199inline
200float
201as_float( const string& func, const string& s, size_t* idx )
202{
203 return as_float_helper<float>( func, s, idx, strtof );
204}
205
206template<>
207inline
208double
209as_float(const string& func, const string& s, size_t* idx )
210{
211 return as_float_helper<double>( func, s, idx, strtod );
212}
213
214template<>
215inline
216long double
217as_float( const string& func, const string& s, size_t* idx )
218{
219 return as_float_helper<long double>( func, s, idx, strtold );
220}
221
222template<>
223inline
224float
225as_float( const string& func, const wstring& s, size_t* idx )
226{
227 return as_float_helper<float>( func, s, idx, wcstof );
228}
229
230template<>
231inline
232double
233as_float( const string& func, const wstring& s, size_t* idx )
234{
235 return as_float_helper<double>( func, s, idx, wcstod );
236}
237
238template<>
239inline
240long double
241as_float( const string& func, const wstring& s, size_t* idx )
242{
243 return as_float_helper<long double>( func, s, idx, wcstold );
244}
245
246} // unnamed namespace
247
Howard Hinnantcbbf6332010-06-02 18:20:39248int
249stoi(const string& str, size_t* idx, int base)
250{
Howard Hinnant9daaf572013-05-16 17:13:40251 return as_integer<int>( "stoi", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39252}
253
254int
255stoi(const wstring& str, size_t* idx, int base)
256{
Howard Hinnant9daaf572013-05-16 17:13:40257 return as_integer<int>( "stoi", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39258}
259
260long
261stol(const string& str, size_t* idx, int base)
262{
Howard Hinnant9daaf572013-05-16 17:13:40263 return as_integer<long>( "stol", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39264}
265
266long
267stol(const wstring& str, size_t* idx, int base)
268{
Howard Hinnant9daaf572013-05-16 17:13:40269 return as_integer<long>( "stol", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39270}
271
272unsigned long
273stoul(const string& str, size_t* idx, int base)
274{
Howard Hinnant9daaf572013-05-16 17:13:40275 return as_integer<unsigned long>( "stoul", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39276}
277
278unsigned long
279stoul(const wstring& str, size_t* idx, int base)
280{
Howard Hinnant9daaf572013-05-16 17:13:40281 return as_integer<unsigned long>( "stoul", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39282}
283
284long long
285stoll(const string& str, size_t* idx, int base)
286{
Howard Hinnant9daaf572013-05-16 17:13:40287 return as_integer<long long>( "stoll", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39288}
289
290long long
291stoll(const wstring& str, size_t* idx, int base)
292{
Howard Hinnant9daaf572013-05-16 17:13:40293 return as_integer<long long>( "stoll", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39294}
295
296unsigned long long
297stoull(const string& str, size_t* idx, int base)
298{
Howard Hinnant9daaf572013-05-16 17:13:40299 return as_integer<unsigned long long>( "stoull", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39300}
301
302unsigned long long
303stoull(const wstring& str, size_t* idx, int base)
304{
Howard Hinnant9daaf572013-05-16 17:13:40305 return as_integer<unsigned long long>( "stoull", str, idx, base );
Howard Hinnantcbbf6332010-06-02 18:20:39306}
307
308float
309stof(const string& str, size_t* idx)
310{
Howard Hinnant9daaf572013-05-16 17:13:40311 return as_float<float>( "stof", str, idx );
Howard Hinnantcbbf6332010-06-02 18:20:39312}
313
314float
315stof(const wstring& str, size_t* idx)
316{
Howard Hinnant9daaf572013-05-16 17:13:40317 return as_float<float>( "stof", str, idx );
Howard Hinnantcbbf6332010-06-02 18:20:39318}
319
320double
321stod(const string& str, size_t* idx)
322{
Howard Hinnant9daaf572013-05-16 17:13:40323 return as_float<double>( "stod", str, idx );
Howard Hinnantcbbf6332010-06-02 18:20:39324}
325
326double
327stod(const wstring& str, size_t* idx)
328{
Howard Hinnant9daaf572013-05-16 17:13:40329 return as_float<double>( "stod", str, idx );
Howard Hinnantcbbf6332010-06-02 18:20:39330}
331
332long double
333stold(const string& str, size_t* idx)
334{
Howard Hinnant9daaf572013-05-16 17:13:40335 return as_float<long double>( "stold", str, idx );
Howard Hinnantcbbf6332010-06-02 18:20:39336}
337
338long double
339stold(const wstring& str, size_t* idx)
340{
Howard Hinnant9daaf572013-05-16 17:13:40341 return as_float<long double>( "stold", str, idx );
Howard Hinnantcbbf6332010-06-02 18:20:39342}
343
Howard Hinnant9daaf572013-05-16 17:13:40344// to_string
345
346namespace
347{
348
349// as_string
350
351template<typename S, typename P, typename V >
352inline
353S
354as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
355{
356 typedef typename S::size_type size_type;
357 size_type available = s.size();
358 while (true)
359 {
360 int status = sprintf_like(&s[0], available + 1, fmt, a);
361 if ( status >= 0 )
362 {
363 size_type used = static_cast<size_type>(status);
364 if ( used <= available )
365 {
366 s.resize( used );
367 break;
368 }
369 available = used; // Assume this is advice of how much space we need.
370 }
371 else
372 available = available * 2 + 1;
373 s.resize(available);
374 }
375 return s;
376}
377
378template <class S, class V, bool = is_floating_point<V>::value>
379struct initial_string;
380
381template <class V, bool b>
382struct initial_string<string, V, b>
383{
384 string
385 operator()() const
386 {
387 string s;
388 s.resize(s.capacity());
389 return s;
390 }
391};
392
393template <class V>
394struct initial_string<wstring, V, false>
395{
396 wstring
397 operator()() const
398 {
399 const size_t n = (numeric_limits<unsigned long long>::digits / 3)
400 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
401 + 1;
402 wstring s(n, wchar_t());
403 s.resize(s.capacity());
404 return s;
405 }
406};
407
408template <class V>
409struct initial_string<wstring, V, true>
410{
411 wstring
412 operator()() const
413 {
414 wstring s(20, wchar_t());
415 s.resize(s.capacity());
416 return s;
417 }
418};
419
420typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
421
422inline
423wide_printf
424get_swprintf()
425{
Howard Hinnant0be8f642013-08-01 18:17:34426#ifndef _LIBCPP_MSVCRT
Howard Hinnant9daaf572013-05-16 17:13:40427 return swprintf;
428#else
Eric Fiselier5d50aa32017-05-10 20:57:45429 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf);
Howard Hinnant9daaf572013-05-16 17:13:40430#endif
431}
432
433} // unnamed namespace
434
Howard Hinnantcbbf6332010-06-02 18:20:39435string to_string(int val)
436{
Howard Hinnant9daaf572013-05-16 17:13:40437 return as_string(snprintf, initial_string<string, int>()(), "%d", val);
Howard Hinnantcbbf6332010-06-02 18:20:39438}
439
440string to_string(unsigned val)
441{
Howard Hinnant9daaf572013-05-16 17:13:40442 return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
Howard Hinnantcbbf6332010-06-02 18:20:39443}
444
445string to_string(long val)
446{
Howard Hinnant9daaf572013-05-16 17:13:40447 return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
Howard Hinnantcbbf6332010-06-02 18:20:39448}
449
450string to_string(unsigned long val)
451{
Howard Hinnant9daaf572013-05-16 17:13:40452 return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
Howard Hinnantcbbf6332010-06-02 18:20:39453}
454
455string to_string(long long val)
456{
Howard Hinnant9daaf572013-05-16 17:13:40457 return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
Howard Hinnantcbbf6332010-06-02 18:20:39458}
459
460string to_string(unsigned long long val)
461{
Howard Hinnant9daaf572013-05-16 17:13:40462 return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
Howard Hinnantcbbf6332010-06-02 18:20:39463}
464
465string to_string(float val)
466{
Howard Hinnant9daaf572013-05-16 17:13:40467 return as_string(snprintf, initial_string<string, float>()(), "%f", val);
Howard Hinnantcbbf6332010-06-02 18:20:39468}
469
470string to_string(double val)
471{
Howard Hinnant9daaf572013-05-16 17:13:40472 return as_string(snprintf, initial_string<string, double>()(), "%f", val);
Howard Hinnantcbbf6332010-06-02 18:20:39473}
474
475string to_string(long double val)
476{
Howard Hinnant9daaf572013-05-16 17:13:40477 return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
Howard Hinnantcbbf6332010-06-02 18:20:39478}
479
480wstring to_wstring(int val)
481{
Howard Hinnant9daaf572013-05-16 17:13:40482 return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
Howard Hinnantcbbf6332010-06-02 18:20:39483}
484
485wstring to_wstring(unsigned val)
486{
Howard Hinnant9daaf572013-05-16 17:13:40487 return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
Howard Hinnantcbbf6332010-06-02 18:20:39488}
489
490wstring to_wstring(long val)
491{
Howard Hinnant9daaf572013-05-16 17:13:40492 return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
Howard Hinnantcbbf6332010-06-02 18:20:39493}
494
495wstring to_wstring(unsigned long val)
496{
Howard Hinnant9daaf572013-05-16 17:13:40497 return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
Howard Hinnantcbbf6332010-06-02 18:20:39498}
499
500wstring to_wstring(long long val)
501{
Howard Hinnant9daaf572013-05-16 17:13:40502 return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
Howard Hinnantcbbf6332010-06-02 18:20:39503}
504
505wstring to_wstring(unsigned long long val)
506{
Howard Hinnant9daaf572013-05-16 17:13:40507 return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
Howard Hinnantcbbf6332010-06-02 18:20:39508}
509
510wstring to_wstring(float val)
511{
Howard Hinnant9daaf572013-05-16 17:13:40512 return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
Howard Hinnantcbbf6332010-06-02 18:20:39513}
514
515wstring to_wstring(double val)
516{
Howard Hinnant9daaf572013-05-16 17:13:40517 return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
Howard Hinnantcbbf6332010-06-02 18:20:39518}
519
520wstring to_wstring(long double val)
521{
Howard Hinnant9daaf572013-05-16 17:13:40522 return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
Howard Hinnantcbbf6332010-06-02 18:20:39523}
Howard Hinnantcbbf6332010-06-02 18:20:39524_LIBCPP_END_NAMESPACE_STD