[libcxx-commits] [libcxx] r362680 - Revert "Speedup to_string and to_wstring for integers using stack buffer and SSO."

Vlad Tsyrklevich via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jun 6 00:51:39 PDT 2019


Author: vlad.tsyrklevich
Date: Thu Jun  6 00:51:39 2019
New Revision: 362680

URL: http://llvm.org/viewvc/llvm-project?rev=362680&view=rev
Log:
Revert "Speedup to_string and to_wstring for integers using stack buffer and SSO."

This reverts commit 7ce7110e6d964778141c0866488e154b1ce73d69, it was
causing sanitizer bot failures due to changing behavior of
std::to_string(). See https://reviews.llvm.org/D59178#1532023

Modified:
    libcxx/trunk/src/string.cpp

Modified: libcxx/trunk/src/string.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/string.cpp?rev=362680&r1=362679&r2=362680&view=diff
==============================================================================
--- libcxx/trunk/src/string.cpp (original)
+++ libcxx/trunk/src/string.cpp Thu Jun  6 00:51:39 2019
@@ -7,14 +7,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "string"
-#include "charconv"
 #include "cstdlib"
 #include "cwchar"
 #include "cerrno"
 #include "limits"
 #include "stdexcept"
 #include <stdio.h>
-#include "__debug"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -173,7 +171,7 @@ as_integer( const string& func, const ws
 
 // as_float
 
-template<typename V, typename S, typename F>
+template<typename V, typename S, typename F> 
 inline
 V
 as_float_helper(const string& func, const S& str, size_t* idx, F f )
@@ -377,11 +375,11 @@ as_string(P sprintf_like, S s, const typ
     return s;
 }
 
-template <class S>
+template <class S, class V, bool = is_floating_point<V>::value>
 struct initial_string;
 
-template <>
-struct initial_string<string>
+template <class V, bool b>
+struct initial_string<string, V, b>
 {
     string
     operator()() const
@@ -392,8 +390,23 @@ struct initial_string<string>
     }
 };
 
-template <>
-struct initial_string<wstring>
+template <class V>
+struct initial_string<wstring, V, false>
+{
+    wstring
+    operator()() const
+    {
+        const size_t n = (numeric_limits<unsigned long long>::digits / 3)
+          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
+          + 1;
+        wstring s(n, wchar_t());
+        s.resize(s.capacity());
+        return s;
+    }
+};
+
+template <class V>
+struct initial_string<wstring, V, true>
 {
     wstring
     operator()() const
@@ -417,42 +430,95 @@ get_swprintf()
 #endif
 }
 
-template <typename S, typename V>
-S i_to_string(const V v)
+}  // unnamed namespace
+
+string to_string(int val)
 {
-//  numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
-//  For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
-//  so we need +1 here.
-    constexpr size_t bufsize = numeric_limits<V>::digits10 + 2;  // +1 for minus, +1 for digits10
-    char buf[bufsize];
-    const auto res = to_chars(buf, buf + bufsize, v);
-    _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
-    return S(buf, res.ptr);
+    return as_string(snprintf, initial_string<string, int>()(), "%d", val);
 }
 
-}  // unnamed namespace
+string to_string(unsigned val)
+{
+    return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
+}
 
-string  to_string (int val)                { return i_to_string< string>(val); }
-string  to_string (long val)               { return i_to_string< string>(val); }
-string  to_string (long long val)          { return i_to_string< string>(val); }
-string  to_string (unsigned val)           { return i_to_string< string>(val); }
-string  to_string (unsigned long val)      { return i_to_string< string>(val); }
-string  to_string (unsigned long long val) { return i_to_string< string>(val); }
-
-wstring to_wstring(int val)                { return i_to_string<wstring>(val); }
-wstring to_wstring(long val)               { return i_to_string<wstring>(val); }
-wstring to_wstring(long long val)          { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned val)           { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned long val)      { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
-
-
-string  to_string (float val)       { return as_string(snprintf,       initial_string< string>()(),   "%f", val); }
-string  to_string (double val)      { return as_string(snprintf,       initial_string< string>()(),   "%f", val); }
-string  to_string (long double val) { return as_string(snprintf,       initial_string< string>()(),  "%Lf", val); }
-
-wstring to_wstring(float val)       { return as_string(get_swprintf(), initial_string<wstring>()(),  L"%f", val); }
-wstring to_wstring(double val)      { return as_string(get_swprintf(), initial_string<wstring>()(),  L"%f", val); }
-wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); }
+string to_string(long val)
+{
+    return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
+}
+
+string to_string(unsigned long val)
+{
+    return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
+}
 
+string to_string(long long val)
+{
+    return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
+}
+
+string to_string(unsigned long long val)
+{
+    return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
+}
+
+string to_string(float val)
+{
+    return as_string(snprintf, initial_string<string, float>()(), "%f", val);
+}
+
+string to_string(double val)
+{
+    return as_string(snprintf, initial_string<string, double>()(), "%f", val);
+}
+
+string to_string(long double val)
+{
+    return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
+}
+
+wstring to_wstring(int val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
+}
+
+wstring to_wstring(unsigned val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
+}
+
+wstring to_wstring(long val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
+}
+
+wstring to_wstring(unsigned long val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
+}
+
+wstring to_wstring(long long val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
+}
+
+wstring to_wstring(unsigned long long val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
+}
+
+wstring to_wstring(float val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
+}
+
+wstring to_wstring(double val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
+}
+
+wstring to_wstring(long double val)
+{
+    return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
+}
 _LIBCPP_END_NAMESPACE_STD




More information about the libcxx-commits mailing list