annotate libcxx/src/string.cpp @ 223:5f17cb93ff66 llvm-original

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