$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73323 - trunk/boost
From: antoshkka_at_[hidden]
Date: 2011-07-24 05:42:09
Author: apolukhin
Date: 2011-07-24 05:42:06 EDT (Sun, 24 Jul 2011)
New Revision: 73323
URL: http://svn.boost.org/trac/boost/changeset/73323
Log:
Fixes #5732.
* fixes performance regression, that was added by previous commit
* fixes float types preformance regression for old compilers
Text files modified: 
   trunk/boost/lexical_cast.hpp |   108 +++++++++++++++++++++++++++------------ 
   1 files changed, 73 insertions(+), 35 deletions(-)
Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp	(original)
+++ trunk/boost/lexical_cast.hpp	2011-07-24 05:42:06 EDT (Sun, 24 Jul 2011)
@@ -25,6 +25,7 @@
 #include <istream>
 #include <string>
 #include <cstring>
+#include <cstdio>
 #include <typeinfo>
 #include <exception>
 #include <cmath>
@@ -35,6 +36,7 @@
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
 #include <boost/numeric/conversion/cast.hpp>
 #include <boost/type_traits/ice.hpp>
 #include <boost/type_traits/make_unsigned.hpp>
@@ -1003,6 +1005,7 @@
         // String representation of Source has an upper limit.
         template< class CharT // a result of widest_char transformation
                 , class Traits // usually char_traits<CharT>
+                , bool RequiresStringbuffer
                 >
         class lexical_stream_limited_src
         {
@@ -1015,25 +1018,23 @@
 #else
             typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT > local_stringbuffer_t;
 #endif
+            typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
+                RequiresStringbuffer,
+                local_stringbuffer_t,
+                char
+            >::type deduced_stringbuffer_t;
+
             // A string representation of Source is written to [start, finish).
-            // Currently, it is assumed that [start, finish) is big enough
-            // to hold a string representation of any Source value.
             CharT* start;
             CharT* finish;
-            local_stringbuffer_t *stringbuf;
+            deduced_stringbuffer_t stringbuffer;
 
         public:
             lexical_stream_limited_src(CharT* sta, CharT* fin)
               : start(sta)
               , finish(fin)
-              , stringbuf(NULL)
             {}
 
-            ~lexical_stream_limited_src()
-            {
-                if (stringbuf) delete stringbuf;
-            }
-
         private:
             // Undefined:
             lexical_stream_limited_src(lexical_stream_limited_src const&);
@@ -1078,7 +1079,7 @@
             bool shl_char_array(T const* str)
             {
                 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
-                    "boost::lexical_cast does not support conversions from whar_t to char types."
+                    "boost::lexical_cast does not support conversions from wchar_t to char types."
                     "Use boost::locale instead" );
                 return shl_input_streamable(str);
             }
@@ -1087,15 +1088,10 @@
             template<typename InputStreamable>
             bool shl_input_streamable(InputStreamable& input)
             {
-                /* No one will call this function twice,
-                 * so we do not need `if (!stringbuf)' */
-                stringbuf = new local_stringbuffer_t();
-
-                std::basic_ostream<CharT> stream(stringbuf);
-                lcast_set_precision(stream, static_cast<InputStreamable*>(0));
+                std::basic_ostream<CharT> stream(&stringbuffer);
                 bool const result = !(stream << input).fail();
-                start = stringbuf->pbase();
-                finish = stringbuf->pptr();
+                start = stringbuffer.pbase();
+                finish = stringbuffer.pptr();
                 return result;
             }
 
@@ -1112,18 +1108,44 @@
                 return true;
             }
 
-#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
             template <class T>
-            bool shl_float_types(T val)
-            {
-                if (put_inf_nan(start, finish, val)) return true;
-                local_streambuffer_t bb;
-                bb.setp(start, finish);
-                std::basic_ostream<CharT> stream(&bb);
-                lcast_set_precision(stream, &val);
-                bool const result = !(stream << val).fail();
-                finish = bb.pptr();
-                return result;
+            bool shl_float(float val,T* out)
+            {   using namespace std;
+                finish = start + sprintf(out,"%.*g", static_cast<int>(boost::detail::lcast_get_precision<float >()), val );
+                return finish > start;
+            }
+
+            template <class T>
+            bool shl_double(double val,T* out)
+            {   using namespace std;
+                finish = start + sprintf(out,"%.*lg", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
+                return finish > start;
+            }
+
+            template <class T>
+            bool shl_long_double(long double val,T* out)
+            {   using namespace std;
+                finish = start + sprintf(out,"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
+                return finish > start;
+            }
+
+#ifndef BOOST_LCAST_NO_WCHAR_T
+            bool shl_float(float val,wchar_t* out)
+            {   using namespace std;
+                finish = start + swprintf(out,finish-start,L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<float >()), val );
+                return finish > start;
+            }
+
+            bool shl_double(double val,wchar_t* out)
+            {   using namespace std;
+                finish = start + swprintf(out,finish-start,L"%.*lg", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
+                return finish > start;
+            }
+
+            bool shl_long_double(long double val,wchar_t* out)
+            {   using namespace std;
+                finish = start + swprintf(out,finish-start,L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
+                return finish > start;
             }
 #endif
 
@@ -1171,11 +1193,9 @@
             bool operator<<(unsigned __int64 n)         { start = lcast_put_unsigned<Traits>(n, finish); return true; }
             bool operator<<(         __int64 n)         { return shl_signed(n); }
 #endif
-#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
-            bool operator<<(float val)                  { return shl_float_types(val); }
-            bool operator<<(double val)                 { return shl_float_types(val); }
-            bool operator<<(long double val)            { return shl_float_types(val); }
-#endif // BOOST_LCAST_NO_COMPILE_TIME_PRECISION
+            bool operator<<(float val)                  { return shl_float(val,start); }
+            bool operator<<(double val)                 { return shl_double(val,start); }
+            bool operator<<(long double val)            { return shl_long_double(val,start); }
 
             template<class InStreamable>
             bool operator<<(const InStreamable& input)  { return shl_input_streamable(input); }
@@ -1586,7 +1606,25 @@
                 typedef BOOST_DEDUCED_TYPENAME
                     deduce_char_traits<char_type,Target,Source>::type traits;
 
-                detail::lexical_stream_limited_src<char_type,traits> interpreter(buf, buf + src_len);
+                typedef BOOST_DEDUCED_TYPENAME remove_pointer<src >::type removed_ptr_t;
+                const bool requires_stringbuf =
+                        !(
+                             ::boost::type_traits::ice_or<
+                                 is_stdstring<src >::value,
+                                 is_arithmetic<src >::value,
+                                 ::boost::type_traits::ice_and<
+                                     is_pointer<src >::value,
+                                     is_char_or_wchar<removed_ptr_t >::value,
+                                     ::boost::type_traits::ice_eq<
+                                        sizeof(char_type),
+                                        sizeof(removed_ptr_t)
+                                     >::value
+                                 >::value
+                             >::value
+                        );
+
+                detail::lexical_stream_limited_src<char_type,traits, requires_stringbuf >
+                        interpreter(buf, buf + src_len);
 
                 Target result;
                 if(!(interpreter << arg && interpreter >> result))