77// ===----------------------------------------------------------------------===//
88
99#include " string"
10+ #include " charconv"
1011#include " cstdlib"
1112#include " cwchar"
1213#include " cerrno"
1314#include " limits"
1415#include " stdexcept"
1516#include < stdio.h>
17+ #include " __debug"
1618
1719_LIBCPP_BEGIN_NAMESPACE_STD
1820
@@ -171,7 +173,7 @@ as_integer( const string& func, const wstring& s, size_t* idx, int base )
171173
172174// as_float
173175
174- template <typename V, typename S, typename F>
176+ template <typename V, typename S, typename F>
175177inline
176178V
177179as_float_helper (const string& func, const S& str, size_t * idx, F f )
@@ -375,11 +377,11 @@ as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
375377 return s;
376378}
377379
378- template <class S , class V , bool = is_floating_point<V>::value >
380+ template <class S >
379381struct initial_string ;
380382
381- template <class V , bool b >
382- struct initial_string <string, V, b >
383+ template <>
384+ struct initial_string <string>
383385{
384386 string
385387 operator ()() const
@@ -390,23 +392,8 @@ struct initial_string<string, V, b>
390392 }
391393};
392394
393- template <class V >
394- struct initial_string <wstring, V, false >
395- {
396- wstring
397- operator ()() const
398- {
399- const size_t n = (numeric_limits<unsigned long long >::digits / 3 )
400- + ((numeric_limits<unsigned long long >::digits % 3 ) != 0 )
401- + 1 ;
402- wstring s (n, wchar_t ());
403- s.resize (s.capacity ());
404- return s;
405- }
406- };
407-
408- template <class V >
409- struct initial_string <wstring, V, true >
395+ template <>
396+ struct initial_string <wstring>
410397{
411398 wstring
412399 operator ()() const
@@ -430,95 +417,42 @@ get_swprintf()
430417#endif
431418}
432419
433- } // unnamed namespace
434-
435- string to_string (int val)
436- {
437- return as_string (snprintf, initial_string<string, int >()(), " %d" , val);
438- }
439-
440- string to_string (unsigned val)
420+ template <typename S, typename V>
421+ S i_to_string (const V v)
441422{
442- return as_string (snprintf, initial_string<string, unsigned >()(), " %u" , val);
423+ // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
424+ // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
425+ // so we need +1 here.
426+ constexpr size_t bufsize = numeric_limits<V>::digits10 + 2 ; // +1 for minus, +1 for digits10
427+ char buf[bufsize];
428+ const auto res = to_chars (buf, buf + bufsize, v);
429+ _LIBCPP_ASSERT (res.ec == errc (), " bufsize must be large enough to accomodate the value" );
430+ return S (buf, res.ptr );
443431}
444432
445- string to_string (long val)
446- {
447- return as_string (snprintf, initial_string<string, long >()(), " %ld" , val);
448- }
449-
450- string to_string (unsigned long val)
451- {
452- return as_string (snprintf, initial_string<string, unsigned long >()(), " %lu" , val);
453- }
454-
455- string to_string (long long val)
456- {
457- return as_string (snprintf, initial_string<string, long long >()(), " %lld" , val);
458- }
459-
460- string to_string (unsigned long long val)
461- {
462- return as_string (snprintf, initial_string<string, unsigned long long >()(), " %llu" , val);
463- }
464-
465- string to_string (float val)
466- {
467- return as_string (snprintf, initial_string<string, float >()(), " %f" , val);
468- }
469-
470- string to_string (double val)
471- {
472- return as_string (snprintf, initial_string<string, double >()(), " %f" , val);
473- }
474-
475- string to_string (long double val)
476- {
477- return as_string (snprintf, initial_string<string, long double >()(), " %Lf" , val);
478- }
479-
480- wstring to_wstring (int val)
481- {
482- return as_string (get_swprintf (), initial_string<wstring, int >()(), L" %d" , val);
483- }
484-
485- wstring to_wstring (unsigned val)
486- {
487- return as_string (get_swprintf (), initial_string<wstring, unsigned >()(), L" %u" , val);
488- }
489-
490- wstring to_wstring (long val)
491- {
492- return as_string (get_swprintf (), initial_string<wstring, long >()(), L" %ld" , val);
493- }
433+ } // unnamed namespace
494434
495- wstring to_wstring (unsigned long val)
496- {
497- return as_string (get_swprintf (), initial_string<wstring, unsigned long >()(), L" %lu" , val);
498- }
435+ string to_string (int val) { return i_to_string< string>(val); }
436+ string to_string (long val) { return i_to_string< string>(val); }
437+ string to_string (long long val) { return i_to_string< string>(val); }
438+ string to_string (unsigned val) { return i_to_string< string>(val); }
439+ string to_string (unsigned long val) { return i_to_string< string>(val); }
440+ string to_string (unsigned long long val) { return i_to_string< string>(val); }
499441
500- wstring to_wstring (long long val)
501- {
502- return as_string (get_swprintf (), initial_string<wstring, long long >()(), L" %lld" , val);
503- }
442+ wstring to_wstring (int val) { return i_to_string<wstring>(val); }
443+ wstring to_wstring (long val) { return i_to_string<wstring>(val); }
444+ wstring to_wstring (long long val) { return i_to_string<wstring>(val); }
445+ wstring to_wstring (unsigned val) { return i_to_string<wstring>(val); }
446+ wstring to_wstring (unsigned long val) { return i_to_string<wstring>(val); }
447+ wstring to_wstring (unsigned long long val) { return i_to_string<wstring>(val); }
504448
505- wstring to_wstring (unsigned long long val)
506- {
507- return as_string (get_swprintf (), initial_string<wstring, unsigned long long >()(), L" %llu" , val);
508- }
509449
510- wstring to_wstring (float val)
511- {
512- return as_string (get_swprintf (), initial_string<wstring, float >()(), L" %f" , val);
513- }
450+ string to_string (float val) { return as_string (snprintf, initial_string< string>()(), " %f" , val); }
451+ string to_string (double val) { return as_string (snprintf, initial_string< string>()(), " %f" , val); }
452+ string to_string (long double val) { return as_string (snprintf, initial_string< string>()(), " %Lf" , val); }
514453
515- wstring to_wstring (double val)
516- {
517- return as_string (get_swprintf (), initial_string<wstring, double >()(), L" %f" , val);
518- }
454+ wstring to_wstring (float val) { return as_string (get_swprintf (), initial_string<wstring>()(), L" %f" , val); }
455+ wstring to_wstring (double val) { return as_string (get_swprintf (), initial_string<wstring>()(), L" %f" , val); }
456+ wstring to_wstring (long double val) { return as_string (get_swprintf (), initial_string<wstring>()(), L" %Lf" , val); }
519457
520- wstring to_wstring (long double val)
521- {
522- return as_string (get_swprintf (), initial_string<wstring, long double >()(), L" %Lf" , val);
523- }
524458_LIBCPP_END_NAMESPACE_STD
0 commit comments