annotate libcxx/src/string.cpp @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===------------------------- string.cpp ---------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "string"
anatofuz
parents:
diff changeset
10 #include "charconv"
anatofuz
parents:
diff changeset
11 #include "cstdlib"
anatofuz
parents:
diff changeset
12 #include "cwchar"
anatofuz
parents:
diff changeset
13 #include "cerrno"
anatofuz
parents:
diff changeset
14 #include "limits"
anatofuz
parents:
diff changeset
15 #include "stdexcept"
anatofuz
parents:
diff changeset
16 #include <stdio.h>
anatofuz
parents:
diff changeset
17 #include "__debug"
anatofuz
parents:
diff changeset
18
anatofuz
parents:
diff changeset
19 _LIBCPP_BEGIN_NAMESPACE_STD
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 _LIBCPP_STRING_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
anatofuz
parents:
diff changeset
24 _LIBCPP_STRING_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 template
anatofuz
parents:
diff changeset
27 string
anatofuz
parents:
diff changeset
28 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
anatofuz
parents:
diff changeset
29
anatofuz
parents:
diff changeset
30 namespace
anatofuz
parents:
diff changeset
31 {
anatofuz
parents:
diff changeset
32
anatofuz
parents:
diff changeset
33 template<typename T>
anatofuz
parents:
diff changeset
34 inline
anatofuz
parents:
diff changeset
35 void throw_helper( const string& msg )
anatofuz
parents:
diff changeset
36 {
anatofuz
parents:
diff changeset
37 #ifndef _LIBCPP_NO_EXCEPTIONS
anatofuz
parents:
diff changeset
38 throw T( msg );
anatofuz
parents:
diff changeset
39 #else
anatofuz
parents:
diff changeset
40 fprintf(stderr, "%s\n", msg.c_str());
anatofuz
parents:
diff changeset
41 _VSTD::abort();
anatofuz
parents:
diff changeset
42 #endif
anatofuz
parents:
diff changeset
43 }
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 inline
anatofuz
parents:
diff changeset
46 void throw_from_string_out_of_range( const string& func )
anatofuz
parents:
diff changeset
47 {
anatofuz
parents:
diff changeset
48 throw_helper<out_of_range>(func + ": out of range");
anatofuz
parents:
diff changeset
49 }
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 inline
anatofuz
parents:
diff changeset
52 void throw_from_string_invalid_arg( const string& func )
anatofuz
parents:
diff changeset
53 {
anatofuz
parents:
diff changeset
54 throw_helper<invalid_argument>(func + ": no conversion");
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 // as_integer
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 template<typename V, typename S, typename F>
anatofuz
parents:
diff changeset
60 inline
anatofuz
parents:
diff changeset
61 V
anatofuz
parents:
diff changeset
62 as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
anatofuz
parents:
diff changeset
63 {
anatofuz
parents:
diff changeset
64 typename S::value_type* ptr = nullptr;
anatofuz
parents:
diff changeset
65 const typename S::value_type* const p = str.c_str();
anatofuz
parents:
diff changeset
66 typename remove_reference<decltype(errno)>::type errno_save = errno;
anatofuz
parents:
diff changeset
67 errno = 0;
anatofuz
parents:
diff changeset
68 V r = f(p, &ptr, base);
anatofuz
parents:
diff changeset
69 swap(errno, errno_save);
anatofuz
parents:
diff changeset
70 if (errno_save == ERANGE)
anatofuz
parents:
diff changeset
71 throw_from_string_out_of_range(func);
anatofuz
parents:
diff changeset
72 if (ptr == p)
anatofuz
parents:
diff changeset
73 throw_from_string_invalid_arg(func);
anatofuz
parents:
diff changeset
74 if (idx)
anatofuz
parents:
diff changeset
75 *idx = static_cast<size_t>(ptr - p);
anatofuz
parents:
diff changeset
76 return r;
anatofuz
parents:
diff changeset
77 }
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 template<typename V, typename S>
anatofuz
parents:
diff changeset
80 inline
anatofuz
parents:
diff changeset
81 V
anatofuz
parents:
diff changeset
82 as_integer(const string& func, const S& s, size_t* idx, int base);
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 // string
anatofuz
parents:
diff changeset
85 template<>
anatofuz
parents:
diff changeset
86 inline
anatofuz
parents:
diff changeset
87 int
anatofuz
parents:
diff changeset
88 as_integer(const string& func, const string& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
89 {
anatofuz
parents:
diff changeset
90 // Use long as no Standard string to integer exists.
anatofuz
parents:
diff changeset
91 long r = as_integer_helper<long>( func, s, idx, base, strtol );
anatofuz
parents:
diff changeset
92 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
anatofuz
parents:
diff changeset
93 throw_from_string_out_of_range(func);
anatofuz
parents:
diff changeset
94 return static_cast<int>(r);
anatofuz
parents:
diff changeset
95 }
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 template<>
anatofuz
parents:
diff changeset
98 inline
anatofuz
parents:
diff changeset
99 long
anatofuz
parents:
diff changeset
100 as_integer(const string& func, const string& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
101 {
anatofuz
parents:
diff changeset
102 return as_integer_helper<long>( func, s, idx, base, strtol );
anatofuz
parents:
diff changeset
103 }
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 template<>
anatofuz
parents:
diff changeset
106 inline
anatofuz
parents:
diff changeset
107 unsigned long
anatofuz
parents:
diff changeset
108 as_integer( const string& func, const string& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
109 {
anatofuz
parents:
diff changeset
110 return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
anatofuz
parents:
diff changeset
111 }
anatofuz
parents:
diff changeset
112
anatofuz
parents:
diff changeset
113 template<>
anatofuz
parents:
diff changeset
114 inline
anatofuz
parents:
diff changeset
115 long long
anatofuz
parents:
diff changeset
116 as_integer( const string& func, const string& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
117 {
anatofuz
parents:
diff changeset
118 return as_integer_helper<long long>( func, s, idx, base, strtoll );
anatofuz
parents:
diff changeset
119 }
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 template<>
anatofuz
parents:
diff changeset
122 inline
anatofuz
parents:
diff changeset
123 unsigned long long
anatofuz
parents:
diff changeset
124 as_integer( const string& func, const string& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
125 {
anatofuz
parents:
diff changeset
126 return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
anatofuz
parents:
diff changeset
127 }
anatofuz
parents:
diff changeset
128
anatofuz
parents:
diff changeset
129 // wstring
anatofuz
parents:
diff changeset
130 template<>
anatofuz
parents:
diff changeset
131 inline
anatofuz
parents:
diff changeset
132 int
anatofuz
parents:
diff changeset
133 as_integer( const string& func, const wstring& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
134 {
anatofuz
parents:
diff changeset
135 // Use long as no Stantard string to integer exists.
anatofuz
parents:
diff changeset
136 long r = as_integer_helper<long>( func, s, idx, base, wcstol );
anatofuz
parents:
diff changeset
137 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
anatofuz
parents:
diff changeset
138 throw_from_string_out_of_range(func);
anatofuz
parents:
diff changeset
139 return static_cast<int>(r);
anatofuz
parents:
diff changeset
140 }
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 template<>
anatofuz
parents:
diff changeset
143 inline
anatofuz
parents:
diff changeset
144 long
anatofuz
parents:
diff changeset
145 as_integer( const string& func, const wstring& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
146 {
anatofuz
parents:
diff changeset
147 return as_integer_helper<long>( func, s, idx, base, wcstol );
anatofuz
parents:
diff changeset
148 }
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 template<>
anatofuz
parents:
diff changeset
151 inline
anatofuz
parents:
diff changeset
152 unsigned long
anatofuz
parents:
diff changeset
153 as_integer( const string& func, const wstring& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
154 {
anatofuz
parents:
diff changeset
155 return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
anatofuz
parents:
diff changeset
156 }
anatofuz
parents:
diff changeset
157
anatofuz
parents:
diff changeset
158 template<>
anatofuz
parents:
diff changeset
159 inline
anatofuz
parents:
diff changeset
160 long long
anatofuz
parents:
diff changeset
161 as_integer( const string& func, const wstring& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
162 {
anatofuz
parents:
diff changeset
163 return as_integer_helper<long long>( func, s, idx, base, wcstoll );
anatofuz
parents:
diff changeset
164 }
anatofuz
parents:
diff changeset
165
anatofuz
parents:
diff changeset
166 template<>
anatofuz
parents:
diff changeset
167 inline
anatofuz
parents:
diff changeset
168 unsigned long long
anatofuz
parents:
diff changeset
169 as_integer( const string& func, const wstring& s, size_t* idx, int base )
anatofuz
parents:
diff changeset
170 {
anatofuz
parents:
diff changeset
171 return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
anatofuz
parents:
diff changeset
172 }
anatofuz
parents:
diff changeset
173
anatofuz
parents:
diff changeset
174 // as_float
anatofuz
parents:
diff changeset
175
anatofuz
parents:
diff changeset
176 template<typename V, typename S, typename F>
anatofuz
parents:
diff changeset
177 inline
anatofuz
parents:
diff changeset
178 V
anatofuz
parents:
diff changeset
179 as_float_helper(const string& func, const S& str, size_t* idx, F f )
anatofuz
parents:
diff changeset
180 {
anatofuz
parents:
diff changeset
181 typename S::value_type* ptr = nullptr;
anatofuz
parents:
diff changeset
182 const typename S::value_type* const p = str.c_str();
anatofuz
parents:
diff changeset
183 typename remove_reference<decltype(errno)>::type errno_save = errno;
anatofuz
parents:
diff changeset
184 errno = 0;
anatofuz
parents:
diff changeset
185 V r = f(p, &ptr);
anatofuz
parents:
diff changeset
186 swap(errno, errno_save);
anatofuz
parents:
diff changeset
187 if (errno_save == ERANGE)
anatofuz
parents:
diff changeset
188 throw_from_string_out_of_range(func);
anatofuz
parents:
diff changeset
189 if (ptr == p)
anatofuz
parents:
diff changeset
190 throw_from_string_invalid_arg(func);
anatofuz
parents:
diff changeset
191 if (idx)
anatofuz
parents:
diff changeset
192 *idx = static_cast<size_t>(ptr - p);
anatofuz
parents:
diff changeset
193 return r;
anatofuz
parents:
diff changeset
194 }
anatofuz
parents:
diff changeset
195
anatofuz
parents:
diff changeset
196 template<typename V, typename S>
anatofuz
parents:
diff changeset
197 inline
anatofuz
parents:
diff changeset
198 V as_float( const string& func, const S& s, size_t* idx = nullptr );
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 template<>
anatofuz
parents:
diff changeset
201 inline
anatofuz
parents:
diff changeset
202 float
anatofuz
parents:
diff changeset
203 as_float( const string& func, const string& s, size_t* idx )
anatofuz
parents:
diff changeset
204 {
anatofuz
parents:
diff changeset
205 return as_float_helper<float>( func, s, idx, strtof );
anatofuz
parents:
diff changeset
206 }
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 template<>
anatofuz
parents:
diff changeset
209 inline
anatofuz
parents:
diff changeset
210 double
anatofuz
parents:
diff changeset
211 as_float(const string& func, const string& s, size_t* idx )
anatofuz
parents:
diff changeset
212 {
anatofuz
parents:
diff changeset
213 return as_float_helper<double>( func, s, idx, strtod );
anatofuz
parents:
diff changeset
214 }
anatofuz
parents:
diff changeset
215
anatofuz
parents:
diff changeset
216 template<>
anatofuz
parents:
diff changeset
217 inline
anatofuz
parents:
diff changeset
218 long double
anatofuz
parents:
diff changeset
219 as_float( const string& func, const string& s, size_t* idx )
anatofuz
parents:
diff changeset
220 {
anatofuz
parents:
diff changeset
221 return as_float_helper<long double>( func, s, idx, strtold );
anatofuz
parents:
diff changeset
222 }
anatofuz
parents:
diff changeset
223
anatofuz
parents:
diff changeset
224 template<>
anatofuz
parents:
diff changeset
225 inline
anatofuz
parents:
diff changeset
226 float
anatofuz
parents:
diff changeset
227 as_float( const string& func, const wstring& s, size_t* idx )
anatofuz
parents:
diff changeset
228 {
anatofuz
parents:
diff changeset
229 return as_float_helper<float>( func, s, idx, wcstof );
anatofuz
parents:
diff changeset
230 }
anatofuz
parents:
diff changeset
231
anatofuz
parents:
diff changeset
232 template<>
anatofuz
parents:
diff changeset
233 inline
anatofuz
parents:
diff changeset
234 double
anatofuz
parents:
diff changeset
235 as_float( const string& func, const wstring& s, size_t* idx )
anatofuz
parents:
diff changeset
236 {
anatofuz
parents:
diff changeset
237 return as_float_helper<double>( func, s, idx, wcstod );
anatofuz
parents:
diff changeset
238 }
anatofuz
parents:
diff changeset
239
anatofuz
parents:
diff changeset
240 template<>
anatofuz
parents:
diff changeset
241 inline
anatofuz
parents:
diff changeset
242 long double
anatofuz
parents:
diff changeset
243 as_float( const string& func, const wstring& s, size_t* idx )
anatofuz
parents:
diff changeset
244 {
anatofuz
parents:
diff changeset
245 return as_float_helper<long double>( func, s, idx, wcstold );
anatofuz
parents:
diff changeset
246 }
anatofuz
parents:
diff changeset
247
anatofuz
parents:
diff changeset
248 } // unnamed namespace
anatofuz
parents:
diff changeset
249
anatofuz
parents:
diff changeset
250 int
anatofuz
parents:
diff changeset
251 stoi(const string& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
252 {
anatofuz
parents:
diff changeset
253 return as_integer<int>( "stoi", str, idx, base );
anatofuz
parents:
diff changeset
254 }
anatofuz
parents:
diff changeset
255
anatofuz
parents:
diff changeset
256 int
anatofuz
parents:
diff changeset
257 stoi(const wstring& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
258 {
anatofuz
parents:
diff changeset
259 return as_integer<int>( "stoi", str, idx, base );
anatofuz
parents:
diff changeset
260 }
anatofuz
parents:
diff changeset
261
anatofuz
parents:
diff changeset
262 long
anatofuz
parents:
diff changeset
263 stol(const string& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
264 {
anatofuz
parents:
diff changeset
265 return as_integer<long>( "stol", str, idx, base );
anatofuz
parents:
diff changeset
266 }
anatofuz
parents:
diff changeset
267
anatofuz
parents:
diff changeset
268 long
anatofuz
parents:
diff changeset
269 stol(const wstring& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
270 {
anatofuz
parents:
diff changeset
271 return as_integer<long>( "stol", str, idx, base );
anatofuz
parents:
diff changeset
272 }
anatofuz
parents:
diff changeset
273
anatofuz
parents:
diff changeset
274 unsigned long
anatofuz
parents:
diff changeset
275 stoul(const string& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
276 {
anatofuz
parents:
diff changeset
277 return as_integer<unsigned long>( "stoul", str, idx, base );
anatofuz
parents:
diff changeset
278 }
anatofuz
parents:
diff changeset
279
anatofuz
parents:
diff changeset
280 unsigned long
anatofuz
parents:
diff changeset
281 stoul(const wstring& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
282 {
anatofuz
parents:
diff changeset
283 return as_integer<unsigned long>( "stoul", str, idx, base );
anatofuz
parents:
diff changeset
284 }
anatofuz
parents:
diff changeset
285
anatofuz
parents:
diff changeset
286 long long
anatofuz
parents:
diff changeset
287 stoll(const string& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
288 {
anatofuz
parents:
diff changeset
289 return as_integer<long long>( "stoll", str, idx, base );
anatofuz
parents:
diff changeset
290 }
anatofuz
parents:
diff changeset
291
anatofuz
parents:
diff changeset
292 long long
anatofuz
parents:
diff changeset
293 stoll(const wstring& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
294 {
anatofuz
parents:
diff changeset
295 return as_integer<long long>( "stoll", str, idx, base );
anatofuz
parents:
diff changeset
296 }
anatofuz
parents:
diff changeset
297
anatofuz
parents:
diff changeset
298 unsigned long long
anatofuz
parents:
diff changeset
299 stoull(const string& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
300 {
anatofuz
parents:
diff changeset
301 return as_integer<unsigned long long>( "stoull", str, idx, base );
anatofuz
parents:
diff changeset
302 }
anatofuz
parents:
diff changeset
303
anatofuz
parents:
diff changeset
304 unsigned long long
anatofuz
parents:
diff changeset
305 stoull(const wstring& str, size_t* idx, int base)
anatofuz
parents:
diff changeset
306 {
anatofuz
parents:
diff changeset
307 return as_integer<unsigned long long>( "stoull", str, idx, base );
anatofuz
parents:
diff changeset
308 }
anatofuz
parents:
diff changeset
309
anatofuz
parents:
diff changeset
310 float
anatofuz
parents:
diff changeset
311 stof(const string& str, size_t* idx)
anatofuz
parents:
diff changeset
312 {
anatofuz
parents:
diff changeset
313 return as_float<float>( "stof", str, idx );
anatofuz
parents:
diff changeset
314 }
anatofuz
parents:
diff changeset
315
anatofuz
parents:
diff changeset
316 float
anatofuz
parents:
diff changeset
317 stof(const wstring& str, size_t* idx)
anatofuz
parents:
diff changeset
318 {
anatofuz
parents:
diff changeset
319 return as_float<float>( "stof", str, idx );
anatofuz
parents:
diff changeset
320 }
anatofuz
parents:
diff changeset
321
anatofuz
parents:
diff changeset
322 double
anatofuz
parents:
diff changeset
323 stod(const string& str, size_t* idx)
anatofuz
parents:
diff changeset
324 {
anatofuz
parents:
diff changeset
325 return as_float<double>( "stod", str, idx );
anatofuz
parents:
diff changeset
326 }
anatofuz
parents:
diff changeset
327
anatofuz
parents:
diff changeset
328 double
anatofuz
parents:
diff changeset
329 stod(const wstring& str, size_t* idx)
anatofuz
parents:
diff changeset
330 {
anatofuz
parents:
diff changeset
331 return as_float<double>( "stod", str, idx );
anatofuz
parents:
diff changeset
332 }
anatofuz
parents:
diff changeset
333
anatofuz
parents:
diff changeset
334 long double
anatofuz
parents:
diff changeset
335 stold(const string& str, size_t* idx)
anatofuz
parents:
diff changeset
336 {
anatofuz
parents:
diff changeset
337 return as_float<long double>( "stold", str, idx );
anatofuz
parents:
diff changeset
338 }
anatofuz
parents:
diff changeset
339
anatofuz
parents:
diff changeset
340 long double
anatofuz
parents:
diff changeset
341 stold(const wstring& str, size_t* idx)
anatofuz
parents:
diff changeset
342 {
anatofuz
parents:
diff changeset
343 return as_float<long double>( "stold", str, idx );
anatofuz
parents:
diff changeset
344 }
anatofuz
parents:
diff changeset
345
anatofuz
parents:
diff changeset
346 // to_string
anatofuz
parents:
diff changeset
347
anatofuz
parents:
diff changeset
348 namespace
anatofuz
parents:
diff changeset
349 {
anatofuz
parents:
diff changeset
350
anatofuz
parents:
diff changeset
351 // as_string
anatofuz
parents:
diff changeset
352
anatofuz
parents:
diff changeset
353 template<typename S, typename P, typename V >
anatofuz
parents:
diff changeset
354 inline
anatofuz
parents:
diff changeset
355 S
anatofuz
parents:
diff changeset
356 as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
anatofuz
parents:
diff changeset
357 {
anatofuz
parents:
diff changeset
358 typedef typename S::size_type size_type;
anatofuz
parents:
diff changeset
359 size_type available = s.size();
anatofuz
parents:
diff changeset
360 while (true)
anatofuz
parents:
diff changeset
361 {
anatofuz
parents:
diff changeset
362 int status = sprintf_like(&s[0], available + 1, fmt, a);
anatofuz
parents:
diff changeset
363 if ( status >= 0 )
anatofuz
parents:
diff changeset
364 {
anatofuz
parents:
diff changeset
365 size_type used = static_cast<size_type>(status);
anatofuz
parents:
diff changeset
366 if ( used <= available )
anatofuz
parents:
diff changeset
367 {
anatofuz
parents:
diff changeset
368 s.resize( used );
anatofuz
parents:
diff changeset
369 break;
anatofuz
parents:
diff changeset
370 }
anatofuz
parents:
diff changeset
371 available = used; // Assume this is advice of how much space we need.
anatofuz
parents:
diff changeset
372 }
anatofuz
parents:
diff changeset
373 else
anatofuz
parents:
diff changeset
374 available = available * 2 + 1;
anatofuz
parents:
diff changeset
375 s.resize(available);
anatofuz
parents:
diff changeset
376 }
anatofuz
parents:
diff changeset
377 return s;
anatofuz
parents:
diff changeset
378 }
anatofuz
parents:
diff changeset
379
anatofuz
parents:
diff changeset
380 template <class S>
anatofuz
parents:
diff changeset
381 struct initial_string;
anatofuz
parents:
diff changeset
382
anatofuz
parents:
diff changeset
383 template <>
anatofuz
parents:
diff changeset
384 struct initial_string<string>
anatofuz
parents:
diff changeset
385 {
anatofuz
parents:
diff changeset
386 string
anatofuz
parents:
diff changeset
387 operator()() const
anatofuz
parents:
diff changeset
388 {
anatofuz
parents:
diff changeset
389 string s;
anatofuz
parents:
diff changeset
390 s.resize(s.capacity());
anatofuz
parents:
diff changeset
391 return s;
anatofuz
parents:
diff changeset
392 }
anatofuz
parents:
diff changeset
393 };
anatofuz
parents:
diff changeset
394
anatofuz
parents:
diff changeset
395 template <>
anatofuz
parents:
diff changeset
396 struct initial_string<wstring>
anatofuz
parents:
diff changeset
397 {
anatofuz
parents:
diff changeset
398 wstring
anatofuz
parents:
diff changeset
399 operator()() const
anatofuz
parents:
diff changeset
400 {
anatofuz
parents:
diff changeset
401 wstring s(20, wchar_t());
anatofuz
parents:
diff changeset
402 s.resize(s.capacity());
anatofuz
parents:
diff changeset
403 return s;
anatofuz
parents:
diff changeset
404 }
anatofuz
parents:
diff changeset
405 };
anatofuz
parents:
diff changeset
406
anatofuz
parents:
diff changeset
407 typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
anatofuz
parents:
diff changeset
408
anatofuz
parents:
diff changeset
409 inline
anatofuz
parents:
diff changeset
410 wide_printf
anatofuz
parents:
diff changeset
411 get_swprintf()
anatofuz
parents:
diff changeset
412 {
anatofuz
parents:
diff changeset
413 #ifndef _LIBCPP_MSVCRT
anatofuz
parents:
diff changeset
414 return swprintf;
anatofuz
parents:
diff changeset
415 #else
anatofuz
parents:
diff changeset
416 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf);
anatofuz
parents:
diff changeset
417 #endif
anatofuz
parents:
diff changeset
418 }
anatofuz
parents:
diff changeset
419
anatofuz
parents:
diff changeset
420 template <typename S, typename V>
anatofuz
parents:
diff changeset
421 S i_to_string(const V v)
anatofuz
parents:
diff changeset
422 {
anatofuz
parents:
diff changeset
423 // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
anatofuz
parents:
diff changeset
424 // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
anatofuz
parents:
diff changeset
425 // so we need +1 here.
anatofuz
parents:
diff changeset
426 constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10
anatofuz
parents:
diff changeset
427 char buf[bufsize];
anatofuz
parents:
diff changeset
428 const auto res = to_chars(buf, buf + bufsize, v);
anatofuz
parents:
diff changeset
429 _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
anatofuz
parents:
diff changeset
430 return S(buf, res.ptr);
anatofuz
parents:
diff changeset
431 }
anatofuz
parents:
diff changeset
432
anatofuz
parents:
diff changeset
433 } // unnamed namespace
anatofuz
parents:
diff changeset
434
anatofuz
parents:
diff changeset
435 string to_string (int val) { return i_to_string< string>(val); }
anatofuz
parents:
diff changeset
436 string to_string (long val) { return i_to_string< string>(val); }
anatofuz
parents:
diff changeset
437 string to_string (long long val) { return i_to_string< string>(val); }
anatofuz
parents:
diff changeset
438 string to_string (unsigned val) { return i_to_string< string>(val); }
anatofuz
parents:
diff changeset
439 string to_string (unsigned long val) { return i_to_string< string>(val); }
anatofuz
parents:
diff changeset
440 string to_string (unsigned long long val) { return i_to_string< string>(val); }
anatofuz
parents:
diff changeset
441
anatofuz
parents:
diff changeset
442 wstring to_wstring(int val) { return i_to_string<wstring>(val); }
anatofuz
parents:
diff changeset
443 wstring to_wstring(long val) { return i_to_string<wstring>(val); }
anatofuz
parents:
diff changeset
444 wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
anatofuz
parents:
diff changeset
445 wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
anatofuz
parents:
diff changeset
446 wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
anatofuz
parents:
diff changeset
447 wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
anatofuz
parents:
diff changeset
448
anatofuz
parents:
diff changeset
449
anatofuz
parents:
diff changeset
450 string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
anatofuz
parents:
diff changeset
451 string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
anatofuz
parents:
diff changeset
452 string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); }
anatofuz
parents:
diff changeset
453
anatofuz
parents:
diff changeset
454 wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
anatofuz
parents:
diff changeset
455 wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
anatofuz
parents:
diff changeset
456 wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); }
anatofuz
parents:
diff changeset
457
anatofuz
parents:
diff changeset
458 _LIBCPP_END_NAMESPACE_STD