comparison libcxx/src/string.cpp @ 236:c4bab56944e8 llvm-original

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