blob: 3c63f408240d37d50074763eb58243572b95e149 [file] [log] [blame]
Louis Dionne9bd93882021-11-17 16:25:01 -05001//===----------------------------------------------------------------------===//
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +00002//
Chandler Carruthd2012102019-01-19 10:56:40 +00003// 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 Hinnanta5f4f8e2010-06-02 18:20:39 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "string"
Marshall Clow54e41492019-06-10 23:20:01 +000010#include "charconv"
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000011#include "cstdlib"
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000012#include "cerrno"
Howard Hinnantae2378a2013-05-16 17:13:40 +000013#include "limits"
14#include "stdexcept"
Howard Hinnant84f697e2013-07-23 16:05:56 +000015#include <stdio.h>
Marshall Clow54e41492019-06-10 23:20:01 +000016#include "__debug"
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000017
Louis Dionne89258142021-08-23 15:32:36 -040018#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
19# include "cwchar"
20#endif
21
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000022_LIBCPP_BEGIN_NAMESPACE_STD
23
Nikolas Klauserf89bb932022-01-24 19:44:34 +010024#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS
Louis Dionneb6aabd92021-08-19 12:21:06 -040025void __basic_string_common<true>::__throw_length_error() const {
26 _VSTD::__throw_length_error("basic_string");
27}
28
29void __basic_string_common<true>::__throw_out_of_range() const {
30 _VSTD::__throw_out_of_range("basic_string");
31}
Nikolas Klauserf89bb932022-01-24 19:44:34 +010032#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000033
Louis Dionne732192e2021-06-09 09:41:27 -040034#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
Martijn Velsb17d5802020-03-02 10:11:35 -050035#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
Louis Dionne89258142021-08-23 15:32:36 -040036 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
37# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
38 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
39# endif
Martijn Vels1e63ba02020-02-19 16:27:50 -050040#else
Louis Dionne89258142021-08-23 15:32:36 -040041 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
42# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
43 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
44# endif
Martijn Vels1e63ba02020-02-19 16:27:50 -050045#endif
Louis Dionne732192e2021-06-09 09:41:27 -040046#undef _LIBCPP_EXTERN_TEMPLATE_DEFINE
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000047
Louis Dionne732192e2021-06-09 09:41:27 -040048template string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000049
Howard Hinnantae2378a2013-05-16 17:13:40 +000050namespace
51{
52
53template<typename T>
54inline
55void throw_helper( const string& msg )
56{
57#ifndef _LIBCPP_NO_EXCEPTIONS
58 throw T( msg );
59#else
Ed Schouten7a441452015-03-10 07:57:43 +000060 fprintf(stderr, "%s\n", msg.c_str());
Marshall Clow8fea1612016-08-25 15:09:01 +000061 _VSTD::abort();
Howard Hinnantae2378a2013-05-16 17:13:40 +000062#endif
63}
64
65inline
66void throw_from_string_out_of_range( const string& func )
67{
68 throw_helper<out_of_range>(func + ": out of range");
69}
70
71inline
72void throw_from_string_invalid_arg( const string& func )
73{
74 throw_helper<invalid_argument>(func + ": no conversion");
75}
76
77// as_integer
78
79template<typename V, typename S, typename F>
80inline
81V
82as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
83{
Eric Fiselier002dc672014-11-14 22:23:57 +000084 typename S::value_type* ptr = nullptr;
Howard Hinnantae2378a2013-05-16 17:13:40 +000085 const typename S::value_type* const p = str.c_str();
86 typename remove_reference<decltype(errno)>::type errno_save = errno;
87 errno = 0;
88 V r = f(p, &ptr, base);
89 swap(errno, errno_save);
90 if (errno_save == ERANGE)
91 throw_from_string_out_of_range(func);
92 if (ptr == p)
93 throw_from_string_invalid_arg(func);
94 if (idx)
95 *idx = static_cast<size_t>(ptr - p);
96 return r;
97}
98
99template<typename V, typename S>
100inline
101V
102as_integer(const string& func, const S& s, size_t* idx, int base);
103
104// string
105template<>
106inline
107int
108as_integer(const string& func, const string& s, size_t* idx, int base )
109{
Joerg Sonnenbergere211bc02013-09-17 08:46:53 +0000110 // Use long as no Standard string to integer exists.
Howard Hinnantae2378a2013-05-16 17:13:40 +0000111 long r = as_integer_helper<long>( func, s, idx, base, strtol );
112 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
113 throw_from_string_out_of_range(func);
114 return static_cast<int>(r);
115}
116
117template<>
118inline
119long
120as_integer(const string& func, const string& s, size_t* idx, int base )
121{
122 return as_integer_helper<long>( func, s, idx, base, strtol );
123}
124
125template<>
126inline
127unsigned long
128as_integer( const string& func, const string& s, size_t* idx, int base )
129{
130 return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
131}
132
133template<>
134inline
135long long
136as_integer( const string& func, const string& s, size_t* idx, int base )
137{
138 return as_integer_helper<long long>( func, s, idx, base, strtoll );
139}
140
141template<>
142inline
143unsigned long long
144as_integer( const string& func, const string& s, size_t* idx, int base )
145{
146 return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
147}
148
Louis Dionne89258142021-08-23 15:32:36 -0400149#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000150// wstring
151template<>
152inline
153int
154as_integer( const string& func, const wstring& s, size_t* idx, int base )
155{
156 // Use long as no Stantard string to integer exists.
157 long r = as_integer_helper<long>( func, s, idx, base, wcstol );
158 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
159 throw_from_string_out_of_range(func);
160 return static_cast<int>(r);
161}
162
163template<>
164inline
165long
166as_integer( const string& func, const wstring& s, size_t* idx, int base )
167{
168 return as_integer_helper<long>( func, s, idx, base, wcstol );
169}
170
171template<>
172inline
173unsigned long
174as_integer( const string& func, const wstring& s, size_t* idx, int base )
175{
176 return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
177}
178
179template<>
180inline
181long long
182as_integer( const string& func, const wstring& s, size_t* idx, int base )
183{
184 return as_integer_helper<long long>( func, s, idx, base, wcstoll );
185}
186
187template<>
188inline
189unsigned long long
190as_integer( const string& func, const wstring& s, size_t* idx, int base )
191{
192 return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
193}
Louis Dionne89258142021-08-23 15:32:36 -0400194#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000195
196// as_float
197
Marshall Clow54e41492019-06-10 23:20:01 +0000198template<typename V, typename S, typename F>
Howard Hinnantae2378a2013-05-16 17:13:40 +0000199inline
200V
201as_float_helper(const string& func, const S& str, size_t* idx, F f )
202{
Eric Fiselier002dc672014-11-14 22:23:57 +0000203 typename S::value_type* ptr = nullptr;
Howard Hinnantae2378a2013-05-16 17:13:40 +0000204 const typename S::value_type* const p = str.c_str();
205 typename remove_reference<decltype(errno)>::type errno_save = errno;
206 errno = 0;
207 V r = f(p, &ptr);
208 swap(errno, errno_save);
209 if (errno_save == ERANGE)
210 throw_from_string_out_of_range(func);
211 if (ptr == p)
212 throw_from_string_invalid_arg(func);
213 if (idx)
214 *idx = static_cast<size_t>(ptr - p);
215 return r;
216}
217
218template<typename V, typename S>
219inline
220V as_float( const string& func, const S& s, size_t* idx = nullptr );
221
222template<>
223inline
224float
225as_float( const string& func, const string& s, size_t* idx )
226{
227 return as_float_helper<float>( func, s, idx, strtof );
228}
229
230template<>
231inline
232double
233as_float(const string& func, const string& s, size_t* idx )
234{
235 return as_float_helper<double>( func, s, idx, strtod );
236}
237
238template<>
239inline
240long double
241as_float( const string& func, const string& s, size_t* idx )
242{
243 return as_float_helper<long double>( func, s, idx, strtold );
244}
245
Louis Dionne89258142021-08-23 15:32:36 -0400246#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000247template<>
248inline
249float
250as_float( const string& func, const wstring& s, size_t* idx )
251{
252 return as_float_helper<float>( func, s, idx, wcstof );
253}
254
255template<>
256inline
257double
258as_float( const string& func, const wstring& s, size_t* idx )
259{
260 return as_float_helper<double>( func, s, idx, wcstod );
261}
262
263template<>
264inline
265long double
266as_float( const string& func, const wstring& s, size_t* idx )
267{
268 return as_float_helper<long double>( func, s, idx, wcstold );
269}
Louis Dionne89258142021-08-23 15:32:36 -0400270#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000271
272} // unnamed namespace
273
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000274int
275stoi(const string& str, size_t* idx, int base)
276{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000277 return as_integer<int>( "stoi", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000278}
279
Louis Dionne89258142021-08-23 15:32:36 -0400280#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000281int
282stoi(const wstring& str, size_t* idx, int base)
283{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000284 return as_integer<int>( "stoi", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000285}
Louis Dionne89258142021-08-23 15:32:36 -0400286#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000287
288long
289stol(const string& str, size_t* idx, int base)
290{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000291 return as_integer<long>( "stol", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000292}
293
Louis Dionne89258142021-08-23 15:32:36 -0400294#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000295long
296stol(const wstring& str, size_t* idx, int base)
297{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000298 return as_integer<long>( "stol", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000299}
Louis Dionne89258142021-08-23 15:32:36 -0400300#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000301
302unsigned long
303stoul(const string& str, size_t* idx, int base)
304{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000305 return as_integer<unsigned long>( "stoul", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000306}
307
Louis Dionne89258142021-08-23 15:32:36 -0400308#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000309unsigned long
310stoul(const wstring& str, size_t* idx, int base)
311{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000312 return as_integer<unsigned long>( "stoul", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000313}
Louis Dionne89258142021-08-23 15:32:36 -0400314#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000315
316long long
317stoll(const string& str, size_t* idx, int base)
318{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000319 return as_integer<long long>( "stoll", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000320}
321
Louis Dionne89258142021-08-23 15:32:36 -0400322#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000323long long
324stoll(const wstring& str, size_t* idx, int base)
325{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000326 return as_integer<long long>( "stoll", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000327}
Louis Dionne89258142021-08-23 15:32:36 -0400328#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000329
330unsigned long long
331stoull(const string& str, size_t* idx, int base)
332{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000333 return as_integer<unsigned long long>( "stoull", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000334}
335
Louis Dionne89258142021-08-23 15:32:36 -0400336#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000337unsigned long long
338stoull(const wstring& str, size_t* idx, int base)
339{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000340 return as_integer<unsigned long long>( "stoull", str, idx, base );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000341}
Louis Dionne89258142021-08-23 15:32:36 -0400342#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000343
344float
345stof(const string& str, size_t* idx)
346{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000347 return as_float<float>( "stof", str, idx );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000348}
349
Louis Dionne89258142021-08-23 15:32:36 -0400350#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000351float
352stof(const wstring& str, size_t* idx)
353{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000354 return as_float<float>( "stof", str, idx );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000355}
Louis Dionne89258142021-08-23 15:32:36 -0400356#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000357
358double
359stod(const string& str, size_t* idx)
360{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000361 return as_float<double>( "stod", str, idx );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000362}
363
Louis Dionne89258142021-08-23 15:32:36 -0400364#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000365double
366stod(const wstring& str, size_t* idx)
367{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000368 return as_float<double>( "stod", str, idx );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000369}
Louis Dionne89258142021-08-23 15:32:36 -0400370#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000371
372long double
373stold(const string& str, size_t* idx)
374{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000375 return as_float<long double>( "stold", str, idx );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000376}
377
Louis Dionne89258142021-08-23 15:32:36 -0400378#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000379long double
380stold(const wstring& str, size_t* idx)
381{
Howard Hinnantae2378a2013-05-16 17:13:40 +0000382 return as_float<long double>( "stold", str, idx );
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000383}
Louis Dionne89258142021-08-23 15:32:36 -0400384#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000385
Howard Hinnantae2378a2013-05-16 17:13:40 +0000386// to_string
387
388namespace
389{
390
391// as_string
392
393template<typename S, typename P, typename V >
394inline
395S
396as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
397{
398 typedef typename S::size_type size_type;
399 size_type available = s.size();
400 while (true)
401 {
402 int status = sprintf_like(&s[0], available + 1, fmt, a);
403 if ( status >= 0 )
404 {
405 size_type used = static_cast<size_type>(status);
406 if ( used <= available )
407 {
408 s.resize( used );
409 break;
410 }
411 available = used; // Assume this is advice of how much space we need.
412 }
413 else
414 available = available * 2 + 1;
415 s.resize(available);
416 }
417 return s;
418}
419
Marshall Clow54e41492019-06-10 23:20:01 +0000420template <class S>
Howard Hinnantae2378a2013-05-16 17:13:40 +0000421struct initial_string;
422
Marshall Clow54e41492019-06-10 23:20:01 +0000423template <>
424struct initial_string<string>
Howard Hinnantae2378a2013-05-16 17:13:40 +0000425{
426 string
427 operator()() const
428 {
429 string s;
430 s.resize(s.capacity());
431 return s;
432 }
433};
434
Louis Dionne89258142021-08-23 15:32:36 -0400435#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Marshall Clow54e41492019-06-10 23:20:01 +0000436template <>
437struct initial_string<wstring>
Howard Hinnantae2378a2013-05-16 17:13:40 +0000438{
439 wstring
440 operator()() const
441 {
442 wstring s(20, wchar_t());
443 s.resize(s.capacity());
444 return s;
445 }
446};
447
448typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
449
450inline
451wide_printf
452get_swprintf()
453{
Howard Hinnant13d8bc12013-08-01 18:17:34 +0000454#ifndef _LIBCPP_MSVCRT
Howard Hinnantae2378a2013-05-16 17:13:40 +0000455 return swprintf;
456#else
Eric Fiselier4a984f02017-05-10 20:57:45 +0000457 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000458#endif
459}
Louis Dionne89258142021-08-23 15:32:36 -0400460#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000461
Marshall Clow54e41492019-06-10 23:20:01 +0000462template <typename S, typename V>
Louis Dionned9f528e2021-06-29 13:52:26 -0400463S i_to_string(V v)
Marshall Clow54e41492019-06-10 23:20:01 +0000464{
465// numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
466// For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
467// so we need +1 here.
468 constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10
469 char buf[bufsize];
470 const auto res = to_chars(buf, buf + bufsize, v);
471 _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
472 return S(buf, res.ptr);
473}
474
Howard Hinnantae2378a2013-05-16 17:13:40 +0000475} // unnamed namespace
476
Marshall Clow54e41492019-06-10 23:20:01 +0000477string to_string (int val) { return i_to_string< string>(val); }
478string to_string (long val) { return i_to_string< string>(val); }
479string to_string (long long val) { return i_to_string< string>(val); }
480string to_string (unsigned val) { return i_to_string< string>(val); }
481string to_string (unsigned long val) { return i_to_string< string>(val); }
482string to_string (unsigned long long val) { return i_to_string< string>(val); }
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000483
Louis Dionne89258142021-08-23 15:32:36 -0400484#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Marshall Clow54e41492019-06-10 23:20:01 +0000485wstring to_wstring(int val) { return i_to_string<wstring>(val); }
486wstring to_wstring(long val) { return i_to_string<wstring>(val); }
487wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
488wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
489wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
490wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
Louis Dionne89258142021-08-23 15:32:36 -0400491#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000492
Marshall Clow54e41492019-06-10 23:20:01 +0000493string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
494string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
495string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); }
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000496
Louis Dionne89258142021-08-23 15:32:36 -0400497#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Marshall Clow54e41492019-06-10 23:20:01 +0000498wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
499wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
500wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); }
Louis Dionne89258142021-08-23 15:32:36 -0400501#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000502
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000503_LIBCPP_END_NAMESPACE_STD