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_NO_BASIC_STRING_BASE_CLASS 25 void __basic_string_common<true>::__throw_length_error() const { 26 _VSTD::__throw_length_error("basic_string"); 27 } 28 29 void __basic_string_common<true>::__throw_out_of_range() const { 30 _VSTD::__throw_out_of_range("basic_string"); 31 } 32 #endif 33 34 #define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; 35 #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 36 _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 40 #else 41 _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 45 #endif 46 #undef _LIBCPP_EXTERN_TEMPLATE_DEFINE 47 48 template string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 49 50 namespace 51 { 52 53 template<typename T> 54 inline 55 void throw_helper( const string& msg ) 56 { 57 #ifndef _LIBCPP_NO_EXCEPTIONS 58 throw T( msg ); 59 #else 60 fprintf(stderr, "%s\n", msg.c_str()); 61 _VSTD::abort(); 62 #endif 63 } 64 65 inline 66 void throw_from_string_out_of_range( const string& func ) 67 { 68 throw_helper<out_of_range>(func + ": out of range"); 69 } 70 71 inline 72 void throw_from_string_invalid_arg( const string& func ) 73 { 74 throw_helper<invalid_argument>(func + ": no conversion"); 75 } 76 77 // as_integer 78 79 template<typename V, typename S, typename F> 80 inline 81 V 82 as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) 83 { 84 typename S::value_type* ptr = nullptr; 85 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 99 template<typename V, typename S> 100 inline 101 V 102 as_integer(const string& func, const S& s, size_t* idx, int base); 103 104 // string 105 template<> 106 inline 107 int 108 as_integer(const string& func, const string& s, size_t* idx, int base ) 109 { 110 // Use long as no Standard string to integer exists. 111 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 117 template<> 118 inline 119 long 120 as_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 125 template<> 126 inline 127 unsigned long 128 as_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 133 template<> 134 inline 135 long long 136 as_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 141 template<> 142 inline 143 unsigned long long 144 as_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 149 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 150 // wstring 151 template<> 152 inline 153 int 154 as_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 163 template<> 164 inline 165 long 166 as_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 171 template<> 172 inline 173 unsigned long 174 as_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 179 template<> 180 inline 181 long long 182 as_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 187 template<> 188 inline 189 unsigned long long 190 as_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 } 194 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 195 196 // as_float 197 198 template<typename V, typename S, typename F> 199 inline 200 V 201 as_float_helper(const string& func, const S& str, size_t* idx, F f ) 202 { 203 typename S::value_type* ptr = nullptr; 204 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 218 template<typename V, typename S> 219 inline 220 V as_float( const string& func, const S& s, size_t* idx = nullptr ); 221 222 template<> 223 inline 224 float 225 as_float( const string& func, const string& s, size_t* idx ) 226 { 227 return as_float_helper<float>( func, s, idx, strtof ); 228 } 229 230 template<> 231 inline 232 double 233 as_float(const string& func, const string& s, size_t* idx ) 234 { 235 return as_float_helper<double>( func, s, idx, strtod ); 236 } 237 238 template<> 239 inline 240 long double 241 as_float( const string& func, const string& s, size_t* idx ) 242 { 243 return as_float_helper<long double>( func, s, idx, strtold ); 244 } 245 246 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 247 template<> 248 inline 249 float 250 as_float( const string& func, const wstring& s, size_t* idx ) 251 { 252 return as_float_helper<float>( func, s, idx, wcstof ); 253 } 254 255 template<> 256 inline 257 double 258 as_float( const string& func, const wstring& s, size_t* idx ) 259 { 260 return as_float_helper<double>( func, s, idx, wcstod ); 261 } 262 263 template<> 264 inline 265 long double 266 as_float( const string& func, const wstring& s, size_t* idx ) 267 { 268 return as_float_helper<long double>( func, s, idx, wcstold ); 269 } 270 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 271 272 } // unnamed namespace 273 274 int 275 stoi(const string& str, size_t* idx, int base) 276 { 277 return as_integer<int>( "stoi", str, idx, base ); 278 } 279 280 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 281 int 282 stoi(const wstring& str, size_t* idx, int base) 283 { 284 return as_integer<int>( "stoi", str, idx, base ); 285 } 286 #endif 287 288 long 289 stol(const string& str, size_t* idx, int base) 290 { 291 return as_integer<long>( "stol", str, idx, base ); 292 } 293 294 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 295 long 296 stol(const wstring& str, size_t* idx, int base) 297 { 298 return as_integer<long>( "stol", str, idx, base ); 299 } 300 #endif 301 302 unsigned long 303 stoul(const string& str, size_t* idx, int base) 304 { 305 return as_integer<unsigned long>( "stoul", str, idx, base ); 306 } 307 308 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 309 unsigned long 310 stoul(const wstring& str, size_t* idx, int base) 311 { 312 return as_integer<unsigned long>( "stoul", str, idx, base ); 313 } 314 #endif 315 316 long long 317 stoll(const string& str, size_t* idx, int base) 318 { 319 return as_integer<long long>( "stoll", str, idx, base ); 320 } 321 322 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 323 long long 324 stoll(const wstring& str, size_t* idx, int base) 325 { 326 return as_integer<long long>( "stoll", str, idx, base ); 327 } 328 #endif 329 330 unsigned long long 331 stoull(const string& str, size_t* idx, int base) 332 { 333 return as_integer<unsigned long long>( "stoull", str, idx, base ); 334 } 335 336 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 337 unsigned long long 338 stoull(const wstring& str, size_t* idx, int base) 339 { 340 return as_integer<unsigned long long>( "stoull", str, idx, base ); 341 } 342 #endif 343 344 float 345 stof(const string& str, size_t* idx) 346 { 347 return as_float<float>( "stof", str, idx ); 348 } 349 350 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 351 float 352 stof(const wstring& str, size_t* idx) 353 { 354 return as_float<float>( "stof", str, idx ); 355 } 356 #endif 357 358 double 359 stod(const string& str, size_t* idx) 360 { 361 return as_float<double>( "stod", str, idx ); 362 } 363 364 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 365 double 366 stod(const wstring& str, size_t* idx) 367 { 368 return as_float<double>( "stod", str, idx ); 369 } 370 #endif 371 372 long double 373 stold(const string& str, size_t* idx) 374 { 375 return as_float<long double>( "stold", str, idx ); 376 } 377 378 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 379 long double 380 stold(const wstring& str, size_t* idx) 381 { 382 return as_float<long double>( "stold", str, idx ); 383 } 384 #endif 385 386 // to_string 387 388 namespace 389 { 390 391 // as_string 392 393 template<typename S, typename P, typename V > 394 inline 395 S 396 as_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 420 template <class S> 421 struct initial_string; 422 423 template <> 424 struct initial_string<string> 425 { 426 string 427 operator()() const 428 { 429 string s; 430 s.resize(s.capacity()); 431 return s; 432 } 433 }; 434 435 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 436 template <> 437 struct initial_string<wstring> 438 { 439 wstring 440 operator()() const 441 { 442 wstring s(20, wchar_t()); 443 s.resize(s.capacity()); 444 return s; 445 } 446 }; 447 448 typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 449 450 inline 451 wide_printf 452 get_swprintf() 453 { 454 #ifndef _LIBCPP_MSVCRT 455 return swprintf; 456 #else 457 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf); 458 #endif 459 } 460 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 461 462 template <typename S, typename V> 463 S i_to_string(V v) 464 { 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 475 } // unnamed namespace 476 477 string to_string (int val) { return i_to_string< string>(val); } 478 string to_string (long val) { return i_to_string< string>(val); } 479 string to_string (long long val) { return i_to_string< string>(val); } 480 string to_string (unsigned val) { return i_to_string< string>(val); } 481 string to_string (unsigned long val) { return i_to_string< string>(val); } 482 string to_string (unsigned long long val) { return i_to_string< string>(val); } 483 484 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 485 wstring to_wstring(int val) { return i_to_string<wstring>(val); } 486 wstring to_wstring(long val) { return i_to_string<wstring>(val); } 487 wstring to_wstring(long long val) { return i_to_string<wstring>(val); } 488 wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); } 489 wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); } 490 wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); } 491 #endif 492 493 string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } 494 string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } 495 string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); } 496 497 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 498 wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); } 499 wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); } 500 wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); } 501 #endif 502 503 _LIBCPP_END_NAMESPACE_STD 504