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