blob: 8db129520ee501d8757cd927875fb7245eff43f0 [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
Louis Dionne9bdbeb32022-02-14 13:41:09 -05009#include <__assert>
Arthur O'Dwyercf9bf392022-02-11 13:00:39 -050010#include <cerrno>
11#include <charconv>
12#include <cstdlib>
13#include <limits>
14#include <stdexcept>
Howard Hinnant84f697e2013-07-23 16:05:56 +000015#include <stdio.h>
Arthur O'Dwyercf9bf392022-02-11 13:00:39 -050016#include <string>
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000017
Louis Dionne89258142021-08-23 15:32:36 -040018#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Arthur O'Dwyercf9bf392022-02-11 13:00:39 -050019# include <cwchar>
Louis Dionne89258142021-08-23 15:32:36 -040020#endif
21
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000022_LIBCPP_BEGIN_NAMESPACE_STD
23
Nikolas Klausera2453e82022-02-02 20:15:40 +010024#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
25
26template <bool>
27struct __basic_string_common;
28
29// The struct isn't declared anymore in the headers. It's only here for ABI compatibility.
30template <>
31struct __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
Louis Dionneb6aabd92021-08-19 12:21:06 -040036void __basic_string_common<true>::__throw_length_error() const {
Nikolas Klausera2453e82022-02-02 20:15:40 +010037 std::__throw_length_error("basic_string");
38}
39void __basic_string_common<true>::__throw_out_of_range() const {
40 std::__throw_out_of_range("basic_string");
Louis Dionneb6aabd92021-08-19 12:21:06 -040041}
42
Nikolas Klausera2453e82022-02-02 20:15:40 +010043#endif // _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000044
Louis Dionne732192e2021-06-09 09:41:27 -040045#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
Martijn Velsb17d5802020-03-02 10:11:35 -050046#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
Louis Dionne89258142021-08-23 15:32:36 -040047 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
48# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
49 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
50# endif
Martijn Vels1e63ba02020-02-19 16:27:50 -050051#else
Louis Dionne89258142021-08-23 15:32:36 -040052 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
53# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
54 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
55# endif
Martijn Vels1e63ba02020-02-19 16:27:50 -050056#endif
Louis Dionne732192e2021-06-09 09:41:27 -040057#undef _LIBCPP_EXTERN_TEMPLATE_DEFINE
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000058
Louis Dionne2153e682022-05-24 11:31:31 -040059template string operator+<char, char_traits<char>, allocator<char>>(char const*, string const&);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000060
Howard Hinnantae2378a2013-05-16 17:13:40 +000061namespace
62{
63
64template<typename T>
Louis Dionne2153e682022-05-24 11:31:31 -040065inline void throw_helper(const string& msg) {
Howard Hinnantae2378a2013-05-16 17:13:40 +000066#ifndef _LIBCPP_NO_EXCEPTIONS
Louis Dionne2153e682022-05-24 11:31:31 -040067 throw T(msg);
Howard Hinnantae2378a2013-05-16 17:13:40 +000068#else
Ed Schouten7a441452015-03-10 07:57:43 +000069 fprintf(stderr, "%s\n", msg.c_str());
Marshall Clow8fea1612016-08-25 15:09:01 +000070 _VSTD::abort();
Howard Hinnantae2378a2013-05-16 17:13:40 +000071#endif
72}
73
Louis Dionne2153e682022-05-24 11:31:31 -040074inline void throw_from_string_out_of_range(const string& func) {
Howard Hinnantae2378a2013-05-16 17:13:40 +000075 throw_helper<out_of_range>(func + ": out of range");
76}
77
Louis Dionne2153e682022-05-24 11:31:31 -040078inline void throw_from_string_invalid_arg(const string& func) {
Howard Hinnantae2378a2013-05-16 17:13:40 +000079 throw_helper<invalid_argument>(func + ": no conversion");
80}
81
82// as_integer
83
84template<typename V, typename S, typename F>
Louis Dionne2153e682022-05-24 11:31:31 -040085inline V as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) {
Eric Fiselier002dc672014-11-14 22:23:57 +000086 typename S::value_type* ptr = nullptr;
Howard Hinnantae2378a2013-05-16 17:13:40 +000087 const typename S::value_type* const p = str.c_str();
88 typename remove_reference<decltype(errno)>::type errno_save = errno;
89 errno = 0;
90 V r = f(p, &ptr, base);
91 swap(errno, errno_save);
92 if (errno_save == ERANGE)
93 throw_from_string_out_of_range(func);
94 if (ptr == p)
95 throw_from_string_invalid_arg(func);
96 if (idx)
97 *idx = static_cast<size_t>(ptr - p);
98 return r;
99}
100
101template<typename V, typename S>
Louis Dionne2153e682022-05-24 11:31:31 -0400102inline V as_integer(const string& func, const S& s, size_t* idx, int base);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000103
104// string
105template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400106inline int as_integer(const string& func, const string& s, size_t* idx, int base) {
Joerg Sonnenbergere211bc02013-09-17 08:46:53 +0000107 // Use long as no Standard string to integer exists.
Louis Dionne2153e682022-05-24 11:31:31 -0400108 long r = as_integer_helper<long>(func, s, idx, base, strtol);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000109 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
110 throw_from_string_out_of_range(func);
111 return static_cast<int>(r);
112}
113
114template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400115inline long as_integer(const string& func, const string& s, size_t* idx, int base) {
116 return as_integer_helper<long>(func, s, idx, base, strtol);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000117}
118
119template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400120inline unsigned long as_integer(const string& func, const string& s, size_t* idx, int base) {
121 return as_integer_helper<unsigned long>(func, s, idx, base, strtoul);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000122}
123
124template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400125inline long long as_integer(const string& func, const string& s, size_t* idx, int base) {
126 return as_integer_helper<long long>(func, s, idx, base, strtoll);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000127}
128
129template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400130inline unsigned long long as_integer(const string& func, const string& s, size_t* idx, int base) {
131 return as_integer_helper<unsigned long long>(func, s, idx, base, strtoull);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000132}
133
Louis Dionne89258142021-08-23 15:32:36 -0400134#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000135// wstring
136template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400137inline int as_integer(const string& func, const wstring& s, size_t* idx, int base) {
Howard Hinnantae2378a2013-05-16 17:13:40 +0000138 // Use long as no Stantard string to integer exists.
Louis Dionne2153e682022-05-24 11:31:31 -0400139 long r = as_integer_helper<long>(func, s, idx, base, wcstol);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000140 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
141 throw_from_string_out_of_range(func);
142 return static_cast<int>(r);
143}
144
145template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400146inline long as_integer(const string& func, const wstring& s, size_t* idx, int base) {
147 return as_integer_helper<long>(func, s, idx, base, wcstol);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000148}
149
150template<>
151inline
152unsigned long
Louis Dionne2153e682022-05-24 11:31:31 -0400153as_integer(const string& func, const wstring& s, size_t* idx, int base)
Howard Hinnantae2378a2013-05-16 17:13:40 +0000154{
Louis Dionne2153e682022-05-24 11:31:31 -0400155 return as_integer_helper<unsigned long>(func, s, idx, base, wcstoul);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000156}
157
158template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400159inline long long as_integer(const string& func, const wstring& s, size_t* idx, int base) {
160 return as_integer_helper<long long>(func, s, idx, base, wcstoll);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000161}
162
163template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400164inline unsigned long long as_integer(const string& func, const wstring& s, size_t* idx, int base) {
165 return as_integer_helper<unsigned long long>(func, s, idx, base, wcstoull);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000166}
Louis Dionne89258142021-08-23 15:32:36 -0400167#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000168
169// as_float
170
Marshall Clow54e41492019-06-10 23:20:01 +0000171template<typename V, typename S, typename F>
Louis Dionne2153e682022-05-24 11:31:31 -0400172inline V as_float_helper(const string& func, const S& str, size_t* idx, F f) {
Eric Fiselier002dc672014-11-14 22:23:57 +0000173 typename S::value_type* ptr = nullptr;
Howard Hinnantae2378a2013-05-16 17:13:40 +0000174 const typename S::value_type* const p = str.c_str();
175 typename remove_reference<decltype(errno)>::type errno_save = errno;
176 errno = 0;
177 V r = f(p, &ptr);
178 swap(errno, errno_save);
179 if (errno_save == ERANGE)
180 throw_from_string_out_of_range(func);
181 if (ptr == p)
182 throw_from_string_invalid_arg(func);
183 if (idx)
184 *idx = static_cast<size_t>(ptr - p);
185 return r;
186}
187
188template<typename V, typename S>
Louis Dionne2153e682022-05-24 11:31:31 -0400189inline V as_float(const string& func, const S& s, size_t* idx = nullptr);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000190
191template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400192inline float as_float(const string& func, const string& s, size_t* idx) {
193 return as_float_helper<float>(func, s, idx, strtof);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000194}
195
196template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400197inline double as_float(const string& func, const string& s, size_t* idx) {
198 return as_float_helper<double>(func, s, idx, strtod);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000199}
200
201template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400202inline long double as_float(const string& func, const string& s, size_t* idx) {
203 return as_float_helper<long double>(func, s, idx, strtold);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000204}
205
Louis Dionne89258142021-08-23 15:32:36 -0400206#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000207template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400208inline float as_float(const string& func, const wstring& s, size_t* idx) {
209 return as_float_helper<float>(func, s, idx, wcstof);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000210}
211
212template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400213inline double as_float(const string& func, const wstring& s, size_t* idx) {
214 return as_float_helper<double>(func, s, idx, wcstod);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000215}
216
217template<>
Louis Dionne2153e682022-05-24 11:31:31 -0400218inline long double as_float(const string& func, const wstring& s, size_t* idx) {
219 return as_float_helper<long double>(func, s, idx, wcstold);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000220}
Louis Dionne89258142021-08-23 15:32:36 -0400221#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000222
223} // unnamed namespace
224
Louis Dionne2153e682022-05-24 11:31:31 -0400225int stoi(const string& str, size_t* idx, int base) {
226 return as_integer<int>("stoi", str, idx, base);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000227}
228
Louis Dionne2153e682022-05-24 11:31:31 -0400229long stol(const string& str, size_t* idx, int base) {
230 return as_integer<long>("stol", str, idx, base);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000231}
232
Louis Dionne2153e682022-05-24 11:31:31 -0400233unsigned long stoul(const string& str, size_t* idx, int base) {
234 return as_integer<unsigned long>("stoul", str, idx, base);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000235}
236
Louis Dionne2153e682022-05-24 11:31:31 -0400237long long stoll(const string& str, size_t* idx, int base) {
238 return as_integer<long long>("stoll", str, idx, base);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000239}
240
Louis Dionne2153e682022-05-24 11:31:31 -0400241unsigned long long stoull(const string& str, size_t* idx, int base) {
242 return as_integer<unsigned long long>("stoull", str, idx, base);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000243}
244
Louis Dionne2153e682022-05-24 11:31:31 -0400245float stof(const string& str, size_t* idx) {
246 return as_float<float>("stof", str, idx);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000247}
248
Louis Dionne2153e682022-05-24 11:31:31 -0400249double stod(const string& str, size_t* idx) {
250 return as_float<double>("stod", str, idx);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000251}
252
Louis Dionne2153e682022-05-24 11:31:31 -0400253long double stold(const string& str, size_t* idx) {
254 return as_float<long double>("stold", str, idx);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000255}
256
Louis Dionne89258142021-08-23 15:32:36 -0400257#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Louis Dionne2153e682022-05-24 11:31:31 -0400258int stoi(const wstring& str, size_t* idx, int base) {
259 return as_integer<int>("stoi", str, idx, base);
Louis Dionne417986b2022-05-24 11:22:43 -0400260}
261
Louis Dionne2153e682022-05-24 11:31:31 -0400262long stol(const wstring& str, size_t* idx, int base) {
263 return as_integer<long>("stol", str, idx, base);
Louis Dionne417986b2022-05-24 11:22:43 -0400264}
265
Louis Dionne2153e682022-05-24 11:31:31 -0400266unsigned long stoul(const wstring& str, size_t* idx, int base) {
267 return as_integer<unsigned long>("stoul", str, idx, base);
Louis Dionne417986b2022-05-24 11:22:43 -0400268}
269
Louis Dionne2153e682022-05-24 11:31:31 -0400270long long stoll(const wstring& str, size_t* idx, int base) {
271 return as_integer<long long>("stoll", str, idx, base);
Louis Dionne417986b2022-05-24 11:22:43 -0400272}
273
Louis Dionne2153e682022-05-24 11:31:31 -0400274unsigned long long stoull(const wstring& str, size_t* idx, int base) {
275 return as_integer<unsigned long long>("stoull", str, idx, base);
Louis Dionne417986b2022-05-24 11:22:43 -0400276}
277
Louis Dionne2153e682022-05-24 11:31:31 -0400278float stof(const wstring& str, size_t* idx) {
279 return as_float<float>("stof", str, idx);
Louis Dionne417986b2022-05-24 11:22:43 -0400280}
281
Louis Dionne2153e682022-05-24 11:31:31 -0400282double stod(const wstring& str, size_t* idx) {
283 return as_float<double>("stod", str, idx);
Louis Dionne417986b2022-05-24 11:22:43 -0400284}
285
Louis Dionne2153e682022-05-24 11:31:31 -0400286long double stold(const wstring& str, size_t* idx) {
287 return as_float<long double>("stold", str, idx);
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000288}
Louis Dionne417986b2022-05-24 11:22:43 -0400289#endif // !_LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000290
Howard Hinnantae2378a2013-05-16 17:13:40 +0000291// to_string
292
293namespace
294{
295
296// as_string
297
298template<typename S, typename P, typename V >
Louis Dionne2153e682022-05-24 11:31:31 -0400299inline S as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) {
Howard Hinnantae2378a2013-05-16 17:13:40 +0000300 typedef typename S::size_type size_type;
301 size_type available = s.size();
Louis Dionne2153e682022-05-24 11:31:31 -0400302 while (true) {
Howard Hinnantae2378a2013-05-16 17:13:40 +0000303 int status = sprintf_like(&s[0], available + 1, fmt, a);
Louis Dionne2153e682022-05-24 11:31:31 -0400304 if (status >= 0) {
Howard Hinnantae2378a2013-05-16 17:13:40 +0000305 size_type used = static_cast<size_type>(status);
Louis Dionne2153e682022-05-24 11:31:31 -0400306 if (used <= available) {
307 s.resize(used);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000308 break;
309 }
310 available = used; // Assume this is advice of how much space we need.
311 }
312 else
313 available = available * 2 + 1;
314 s.resize(available);
315 }
316 return s;
317}
318
Marshall Clow54e41492019-06-10 23:20:01 +0000319template <class S>
Howard Hinnantae2378a2013-05-16 17:13:40 +0000320struct initial_string;
321
Marshall Clow54e41492019-06-10 23:20:01 +0000322template <>
Louis Dionne2153e682022-05-24 11:31:31 -0400323struct initial_string<string> {
324 string operator()() const {
Howard Hinnantae2378a2013-05-16 17:13:40 +0000325 string s;
326 s.resize(s.capacity());
327 return s;
328 }
329};
330
Louis Dionne89258142021-08-23 15:32:36 -0400331#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Marshall Clow54e41492019-06-10 23:20:01 +0000332template <>
Louis Dionne2153e682022-05-24 11:31:31 -0400333struct initial_string<wstring> {
334 wstring operator()() const {
Howard Hinnantae2378a2013-05-16 17:13:40 +0000335 wstring s(20, wchar_t());
336 s.resize(s.capacity());
337 return s;
338 }
339};
340
341typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
342
Louis Dionne2153e682022-05-24 11:31:31 -0400343inline wide_printf get_swprintf() {
Howard Hinnant13d8bc12013-08-01 18:17:34 +0000344#ifndef _LIBCPP_MSVCRT
Howard Hinnantae2378a2013-05-16 17:13:40 +0000345 return swprintf;
346#else
Eric Fiselier4a984f02017-05-10 20:57:45 +0000347 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf);
Howard Hinnantae2378a2013-05-16 17:13:40 +0000348#endif
349}
Louis Dionne89258142021-08-23 15:32:36 -0400350#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantae2378a2013-05-16 17:13:40 +0000351
Marshall Clow54e41492019-06-10 23:20:01 +0000352template <typename S, typename V>
Louis Dionne2153e682022-05-24 11:31:31 -0400353S i_to_string(V v) {
Marshall Clow54e41492019-06-10 23:20:01 +0000354// numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
355// For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
356// so we need +1 here.
357 constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10
358 char buf[bufsize];
359 const auto res = to_chars(buf, buf + bufsize, v);
360 _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
361 return S(buf, res.ptr);
362}
363
Howard Hinnantae2378a2013-05-16 17:13:40 +0000364} // unnamed namespace
365
Marshall Clow54e41492019-06-10 23:20:01 +0000366string to_string (int val) { return i_to_string< string>(val); }
367string to_string (long val) { return i_to_string< string>(val); }
368string to_string (long long val) { return i_to_string< string>(val); }
369string to_string (unsigned val) { return i_to_string< string>(val); }
370string to_string (unsigned long val) { return i_to_string< string>(val); }
371string to_string (unsigned long long val) { return i_to_string< string>(val); }
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000372
Louis Dionne89258142021-08-23 15:32:36 -0400373#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Marshall Clow54e41492019-06-10 23:20:01 +0000374wstring to_wstring(int val) { return i_to_string<wstring>(val); }
375wstring to_wstring(long val) { return i_to_string<wstring>(val); }
376wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
377wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
378wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
379wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
Louis Dionne89258142021-08-23 15:32:36 -0400380#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000381
Marshall Clow54e41492019-06-10 23:20:01 +0000382string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
383string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
384string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); }
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000385
Louis Dionne89258142021-08-23 15:32:36 -0400386#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Marshall Clow54e41492019-06-10 23:20:01 +0000387wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
388wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
389wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); }
Louis Dionne89258142021-08-23 15:32:36 -0400390#endif
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000391
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000392_LIBCPP_END_NAMESPACE_STD