|
Boost-Commit : |
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))
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk