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