Removed duplicate tests.
Unified behaviour for float conversions on different compillers

[SVN r72972]
This commit is contained in:
Antony Polukhin
2011-07-08 17:23:31 +00:00
parent fff0066392
commit 27a7fac22e
2 changed files with 42 additions and 20 deletions

View File

@@ -1338,15 +1338,39 @@ namespace boost
return lcast_ret_float<Traits>(output,start,finish);
}
#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
private:
// we need workaround
bool no_long_double_80bit_realization_workaround(double& output, int) {
return convert_using_base_class(output);
// Not optimised converter
template <class T>
bool float_types_converter_internal(T& output, int /*tag*/) {
bool return_value = convert_using_base_class(output);
/* Some compilers and libraries successfully
* parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
* We are trying to provide a unified behaviour,
* so we just forbid such conversions (as some
* of the most popular compilers/libraries do)
* */
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
CharT const capital_e = lcast_char_constants<CharT>::capital_e;
CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
if ( return_value &&
(
output > (std::numeric_limits<T>::max)() // +inf
|| output < -(std::numeric_limits<T>::max)() // -inf
|| output != output // NaN
|| *(finish-1) == lowercase_e // 1.0e
|| *(finish-1) == capital_e // 1.0E
|| *(finish-1) == minus // 1.0e- or 1.0E-
|| *(finish-1) == plus // 1.0e+ or 1.0E+
)
) return false;
return return_value;
}
// we do not need a workaround
bool no_long_double_80bit_realization_workaround(double& output,char) {
// Optimised converter
bool float_types_converter_internal(double& output,char /*tag*/) {
return lcast_ret_float<Traits>(output,start,finish);
}
public:
@@ -1360,14 +1384,23 @@ namespace boost
* double, because it will give a big precision loss.
* */
boost::mpl::if_c<
#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
::boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
#else
0
#endif
int,
char
>::type dummy = 0;
>::type tag = 0;
return no_long_double_80bit_realization_workaround(output, dummy);
return float_types_converter_internal(output, tag);
}
bool operator>>(long double& output)
{
int tag = 0;
return float_types_converter_internal(output, tag);
}
#endif
// Generic istream-based algorithm.
// lcast_streambuf_for_target<InputStreamable>::value is true.

View File

@@ -921,17 +921,6 @@ void test_char_types_conversions()
BOOST_CHECK(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
BOOST_CHECK(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
// Following tests depend on realization of std::locale.
// All we need to know, is that this functions must compile
BOOST_CHECK(boost::lexical_cast<wchar_t>(c_arr[0]) == wc_arr[0]);
BOOST_CHECK(boost::lexical_cast<std::wstring>(c_arr) == std::wstring(wc_arr));
BOOST_CHECK(boost::lexical_cast<std::wstring>(sc_arr) != std::wstring(wc_arr) );
BOOST_CHECK(boost::lexical_cast<std::wstring>(uc_arr) != std::wstring(wc_arr) );
BOOST_CHECK_THROW(boost::lexical_cast<wchar_t>(uc_arr[0]), bad_lexical_cast);
BOOST_CHECK_THROW(boost::lexical_cast<wchar_t>(sc_arr[0]), bad_lexical_cast);
#endif
}