* fixes performance regression, that was added by previous commit
* fixes float types preformance regression for old compilers

[SVN r73323]
This commit is contained in:
Antony Polukhin
2011-07-24 09:42:06 +00:00
parent 8a756eae7b
commit fd264b0583

View File

@@ -25,6 +25,7 @@
#include <istream> #include <istream>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <cstdio>
#include <typeinfo> #include <typeinfo>
#include <exception> #include <exception>
#include <cmath> #include <cmath>
@@ -35,6 +36,7 @@
#include <boost/type_traits/is_pointer.hpp> #include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_arithmetic.hpp> #include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/ice.hpp> #include <boost/type_traits/ice.hpp>
#include <boost/type_traits/make_unsigned.hpp> #include <boost/type_traits/make_unsigned.hpp>
@@ -1003,6 +1005,7 @@ namespace boost
// String representation of Source has an upper limit. // String representation of Source has an upper limit.
template< class CharT // a result of widest_char transformation template< class CharT // a result of widest_char transformation
, class Traits // usually char_traits<CharT> , class Traits // usually char_traits<CharT>
, bool RequiresStringbuffer
> >
class lexical_stream_limited_src class lexical_stream_limited_src
{ {
@@ -1015,25 +1018,23 @@ namespace boost
#else #else
typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT > local_stringbuffer_t; typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT > local_stringbuffer_t;
#endif #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). // 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* start;
CharT* finish; CharT* finish;
local_stringbuffer_t *stringbuf; deduced_stringbuffer_t stringbuffer;
public: public:
lexical_stream_limited_src(CharT* sta, CharT* fin) lexical_stream_limited_src(CharT* sta, CharT* fin)
: start(sta) : start(sta)
, finish(fin) , finish(fin)
, stringbuf(NULL)
{} {}
~lexical_stream_limited_src()
{
if (stringbuf) delete stringbuf;
}
private: private:
// Undefined: // Undefined:
lexical_stream_limited_src(lexical_stream_limited_src const&); lexical_stream_limited_src(lexical_stream_limited_src const&);
@@ -1078,7 +1079,7 @@ namespace boost
bool shl_char_array(T const* str) bool shl_char_array(T const* str)
{ {
BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)), 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" ); "Use boost::locale instead" );
return shl_input_streamable(str); return shl_input_streamable(str);
} }
@@ -1087,15 +1088,10 @@ namespace boost
template<typename InputStreamable> template<typename InputStreamable>
bool shl_input_streamable(InputStreamable& input) bool shl_input_streamable(InputStreamable& input)
{ {
/* No one will call this function twice, std::basic_ostream<CharT> stream(&stringbuffer);
* 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));
bool const result = !(stream << input).fail(); bool const result = !(stream << input).fail();
start = stringbuf->pbase(); start = stringbuffer.pbase();
finish = stringbuf->pptr(); finish = stringbuffer.pptr();
return result; return result;
} }
@@ -1112,18 +1108,44 @@ namespace boost
return true; return true;
} }
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
template <class T> template <class T>
bool shl_float_types(T val) bool shl_float(float val,T* out)
{ { using namespace std;
if (put_inf_nan(start, finish, val)) return true; finish = start + sprintf(out,"%.*g", static_cast<int>(boost::detail::lcast_get_precision<float >()), val );
local_streambuffer_t bb; return finish > start;
bb.setp(start, finish); }
std::basic_ostream<CharT> stream(&bb);
lcast_set_precision(stream, &val); template <class T>
bool const result = !(stream << val).fail(); bool shl_double(double val,T* out)
finish = bb.pptr(); { using namespace std;
return result; 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 #endif
@@ -1171,11 +1193,9 @@ namespace boost
bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned<Traits>(n, finish); return true; } bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
bool operator<<( __int64 n) { return shl_signed(n); } bool operator<<( __int64 n) { return shl_signed(n); }
#endif #endif
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION bool operator<<(float val) { return shl_float(val,start); }
bool operator<<(float val) { return shl_float_types(val); } bool operator<<(double val) { return shl_double(val,start); }
bool operator<<(double val) { return shl_float_types(val); } bool operator<<(long double val) { return shl_long_double(val,start); }
bool operator<<(long double val) { return shl_float_types(val); }
#endif // BOOST_LCAST_NO_COMPILE_TIME_PRECISION
template<class InStreamable> template<class InStreamable>
bool operator<<(const InStreamable& input) { return shl_input_streamable(input); } bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
@@ -1586,7 +1606,25 @@ namespace boost
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME
deduce_char_traits<char_type,Target,Source>::type traits; 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; Target result;
if(!(interpreter << arg && interpreter >> result)) if(!(interpreter << arg && interpreter >> result))