forked from boostorg/conversion
More strict tests, less workarounds, bugfixes (refs #7814)
[SVN r82227]
This commit is contained in:
@@ -767,26 +767,15 @@ namespace boost {
|
|||||||
|
|
||||||
namespace detail // lcast_to_unsigned
|
namespace detail // lcast_to_unsigned
|
||||||
{
|
{
|
||||||
#if (defined _MSC_VER)
|
|
||||||
# pragma warning( push )
|
|
||||||
// C4146: unary minus operator applied to unsigned type, result still unsigned
|
|
||||||
# pragma warning( disable : 4146 )
|
|
||||||
#elif defined( __BORLANDC__ )
|
|
||||||
# pragma option push -w-8041
|
|
||||||
#endif
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline
|
||||||
BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
|
BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME make_unsigned<T>::type result_type;
|
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
|
||||||
const result_type uvalue = static_cast<result_type>(value);
|
return static_cast<result_type>(
|
||||||
return value < 0 ? -uvalue : uvalue;
|
value < 0 ? 0u - static_cast<result_type>(value) : value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#if (defined _MSC_VER)
|
|
||||||
# pragma warning( pop )
|
|
||||||
#elif defined( __BORLANDC__ )
|
|
||||||
# pragma option pop
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail // lcast_put_unsigned
|
namespace detail // lcast_put_unsigned
|
||||||
@@ -1825,19 +1814,11 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
|
bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
|
||||||
#if (defined _MSC_VER)
|
|
||||||
# pragma warning( push )
|
if (has_minus) {
|
||||||
// C4146: unary minus operator applied to unsigned type, result still unsigned
|
output = static_cast<Type>(0u - output);
|
||||||
# pragma warning( disable : 4146 )
|
}
|
||||||
#elif defined( __BORLANDC__ )
|
|
||||||
# pragma option push -w-8041
|
|
||||||
#endif
|
|
||||||
if (has_minus) output = static_cast<Type>(-output);
|
|
||||||
#if (defined _MSC_VER)
|
|
||||||
# pragma warning( pop )
|
|
||||||
#elif defined( __BORLANDC__ )
|
|
||||||
# pragma option pop
|
|
||||||
#endif
|
|
||||||
return succeed;
|
return succeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1863,21 +1844,9 @@ namespace boost {
|
|||||||
|
|
||||||
bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
|
bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
|
||||||
if (has_minus) {
|
if (has_minus) {
|
||||||
#if (defined _MSC_VER)
|
utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
|
||||||
# pragma warning( push )
|
|
||||||
// C4146: unary minus operator applied to unsigned type, result still unsigned
|
|
||||||
# pragma warning( disable : 4146 )
|
|
||||||
#elif defined( __BORLANDC__ )
|
|
||||||
# pragma option push -w-8041
|
|
||||||
#endif
|
|
||||||
utype const comp_val = static_cast<utype>(-(std::numeric_limits<Type>::min)());
|
|
||||||
succeed = succeed && out_tmp<=comp_val;
|
succeed = succeed && out_tmp<=comp_val;
|
||||||
output = -out_tmp;
|
output = static_cast<Type>(0u - out_tmp);
|
||||||
#if (defined _MSC_VER)
|
|
||||||
# pragma warning( pop )
|
|
||||||
#elif defined( __BORLANDC__ )
|
|
||||||
# pragma option pop
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
|
utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
|
||||||
succeed = succeed && out_tmp<=comp_val;
|
succeed = succeed && out_tmp<=comp_val;
|
||||||
@@ -2295,11 +2264,14 @@ namespace boost {
|
|||||||
|
|
||||||
static source_type nearbyint ( argument_type s )
|
static source_type nearbyint ( argument_type s )
|
||||||
{
|
{
|
||||||
const source_type orig_div_round = s / Rounder::nearbyint(s);
|
const source_type near_int = Rounder::nearbyint(s);
|
||||||
const source_type eps = std::numeric_limits<source_type>::epsilon();
|
if (near_int) {
|
||||||
|
const source_type orig_div_round = s / near_int;
|
||||||
|
const source_type eps = std::numeric_limits<source_type>::epsilon();
|
||||||
|
|
||||||
if ((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps)
|
if ((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps)
|
||||||
BOOST_LCAST_THROW_BAD_CAST(Source, Target);
|
BOOST_LCAST_THROW_BAD_CAST(Source, Target);
|
||||||
|
}
|
||||||
|
|
||||||
return s ;
|
return s ;
|
||||||
}
|
}
|
||||||
@@ -2337,16 +2309,22 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
static inline Target lexical_cast_impl(const Source &arg)
|
static inline Target lexical_cast_impl(const Source &arg)
|
||||||
{
|
{
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if_c<
|
||||||
|
boost::is_float<Source>::value,
|
||||||
|
boost::mpl::identity<Source>,
|
||||||
|
boost::make_unsigned<Source>
|
||||||
|
>::type usource_t;
|
||||||
|
|
||||||
typedef boost::numeric::converter<
|
typedef boost::numeric::converter<
|
||||||
Target,
|
Target,
|
||||||
Source,
|
usource_t,
|
||||||
boost::numeric::conversion_traits<Target,Source>,
|
boost::numeric::conversion_traits<Target,usource_t>,
|
||||||
nothrow_overflow_handler<Source, Target>,
|
nothrow_overflow_handler<usource_t, Target>,
|
||||||
detect_precision_loss<Source, Target>
|
detect_precision_loss<usource_t, Target>
|
||||||
> converter_t;
|
> converter_t;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
arg < 0 ? -converter_t::convert(-arg) : converter_t::convert(arg)
|
arg < 0 ? 0u - converter_t::convert(0u - arg) : converter_t::convert(arg)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -12,7 +12,9 @@ project
|
|||||||
: requirements
|
: requirements
|
||||||
<library>/boost/test//boost_unit_test_framework
|
<library>/boost/test//boost_unit_test_framework
|
||||||
<link>static
|
<link>static
|
||||||
<toolset>gcc-4.8:<define>BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
|
<toolset>gcc-4.7:<cxxflags>-ftrapv
|
||||||
|
<toolset>gcc-4.6:<cxxflags>-ftrapv
|
||||||
|
<toolset>clang:<cxxflags>-ftrapv
|
||||||
;
|
;
|
||||||
|
|
||||||
# Thanks to Steven Watanabe for helping with <nowchar> feature
|
# Thanks to Steven Watanabe for helping with <nowchar> feature
|
||||||
@@ -40,11 +42,13 @@ test-suite conversion
|
|||||||
[ run lexical_cast_typedefed_wchar_test_runtime.cpp : : : <toolset>msvc:<nowchar>on <toolset>msvc,<stdlib>stlport:<build>no ]
|
[ run lexical_cast_typedefed_wchar_test_runtime.cpp : : : <toolset>msvc:<nowchar>on <toolset>msvc,<stdlib>stlport:<build>no ]
|
||||||
[ run lexical_cast_no_locale_test.cpp : : : <define>BOOST_NO_STD_LOCALE <define>BOOST_LEXICAL_CAST_ASSUME_C_LOCALE ]
|
[ run lexical_cast_no_locale_test.cpp : : : <define>BOOST_NO_STD_LOCALE <define>BOOST_LEXICAL_CAST_ASSUME_C_LOCALE ]
|
||||||
[ run lexical_cast_no_exceptions_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
|
[ run lexical_cast_no_exceptions_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
|
||||||
<toolset>gcc-4.3:<cflags>-fno-exceptions
|
<toolset>gcc-4.3:<cxxflags>-fno-exceptions
|
||||||
<toolset>gcc-4.4:<cflags>-fno-exceptions
|
<toolset>gcc-4.4:<cxxflags>-fno-exceptions
|
||||||
<toolset>gcc-4.5:<cflags>-fno-exceptions
|
<toolset>gcc-4.5:<cxxflags>-fno-exceptions
|
||||||
<toolset>gcc-4.6:<cflags>-fno-exceptions
|
<toolset>gcc-4.6:<cxxflags>-fno-exceptions
|
||||||
<toolset>gcc-4.7:<cflags>-fno-exceptions
|
<toolset>gcc-4.7:<cxxflags>-fno-exceptions
|
||||||
|
<toolset>gcc-4.8:<cxxflags>-fno-exceptions
|
||||||
|
<toolset>clang:<cxxflags>-fno-exceptions
|
||||||
]
|
]
|
||||||
[ run lexical_cast_iterator_range_test.cpp ]
|
[ run lexical_cast_iterator_range_test.cpp ]
|
||||||
[ run lexical_cast_arrays_test.cpp ]
|
[ run lexical_cast_arrays_test.cpp ]
|
||||||
|
@@ -68,6 +68,7 @@ void test_conversion_from_to_uintmax_t();
|
|||||||
void test_conversion_from_to_longlong();
|
void test_conversion_from_to_longlong();
|
||||||
void test_conversion_from_to_ulonglong();
|
void test_conversion_from_to_ulonglong();
|
||||||
#endif
|
#endif
|
||||||
|
void test_integral_conversions_on_min_max();
|
||||||
|
|
||||||
|
|
||||||
unit_test::test_suite *init_unit_test_suite(int, char *[])
|
unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||||
@@ -87,6 +88,7 @@ unit_test::test_suite *init_unit_test_suite(int, char *[])
|
|||||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong));
|
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong));
|
||||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong));
|
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong));
|
||||||
#endif
|
#endif
|
||||||
|
suite->add(BOOST_TEST_CASE(&test_integral_conversions_on_min_max));
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
@@ -230,7 +232,7 @@ void test_conversion_from_integral_to_string(CharT)
|
|||||||
|
|
||||||
// Test values around 100, 1000, 10000, ...
|
// Test values around 100, 1000, 10000, ...
|
||||||
T ten_power = 100;
|
T ten_power = 100;
|
||||||
for(int e = 2; e <= limits::digits10; ++e, ten_power *= 10)
|
for(int e = 2; e < limits::digits10; ++e, ten_power *= 10)
|
||||||
{
|
{
|
||||||
// ten_power + 100 probably never overflows
|
// ten_power + 100 probably never overflows
|
||||||
for(t = ten_power - 100; t != ten_power + 100; ++t)
|
for(t = ten_power - 100; t != ten_power + 100; ++t)
|
||||||
@@ -327,7 +329,7 @@ void test_conversion_from_string_to_integral(CharT)
|
|||||||
|
|
||||||
// Test values around 100, 1000, 10000, ...
|
// Test values around 100, 1000, 10000, ...
|
||||||
T ten_power = 100;
|
T ten_power = 100;
|
||||||
for(int e = 2; e <= limits::digits10; ++e, ten_power *= 10)
|
for(int e = 2; e < limits::digits10; ++e, ten_power *= 10)
|
||||||
{
|
{
|
||||||
// ten_power + 100 probably never overflows
|
// ten_power + 100 probably never overflows
|
||||||
for(t = ten_power - 100; t != ten_power + 100; ++t)
|
for(t = ten_power - 100; t != ten_power + 100; ++t)
|
||||||
@@ -534,6 +536,19 @@ void test_conversion_from_to_ulonglong()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void test_integral_conversions_on_min_max()
|
||||||
|
{
|
||||||
|
typedef std::numeric_limits<int> int_limits;
|
||||||
|
typedef std::numeric_limits<unsigned int> uint_limits;
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((uint_limits::max)()), (uint_limits::max)());
|
||||||
|
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((uint_limits::min)()), (uint_limits::min)());
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(lexical_cast<int>((int_limits::max)()), (int_limits::max)());
|
||||||
|
BOOST_CHECK_EQUAL(lexical_cast<int>((uint_limits::min)()), static_cast<int>((uint_limits::min)()));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((int_limits::max)()), static_cast<unsigned int>((int_limits::max)()));
|
||||||
|
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((int_limits::min)()), static_cast<unsigned int>((int_limits::min)()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user