forked from boostorg/conversion
Fixes #5732.
* fixes performance regression, that was added by previous commit * fixes float types preformance regression for old compilers [SVN r73323]
This commit is contained in:
@@ -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))
|
||||||
|
Reference in New Issue
Block a user