Merge from trunk: r72184 (a lot of optimizations, new tests, fix inspection warnings).

[SVN r72185]
This commit is contained in:
Antony Polukhin committed 2011-05-26 16:27:53 +00:00
1 parent 701d5f0bf0
commit a385c3ec99
4 files changed
+702 -44

No files matched your search

+149 -14
View File
@@ -2,8 +2,9 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Terje Slettebø and Kevlin Henney, 2005.
// Copyright Terje Sletteb and Kevlin Henney, 2005.
// Copyright Alexander Nasonov, 2006.
// Copyright Antony Polukhin, 2011.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -32,6 +33,7 @@
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/type_traits/integral_promotion.hpp>
#include <string>
#include <memory>
@@ -84,6 +86,9 @@ void test_conversion_from_to_uintmax_t();
void test_conversion_from_to_longlong();
void test_conversion_from_to_ulonglong();
#endif
void test_conversion_from_to_float();
void test_conversion_from_to_double();
void test_conversion_from_to_long_double();
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
void test_traits();
void test_wtraits();
@@ -122,6 +127,9 @@ 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_ulonglong));
#endif
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_float));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_double));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long_double));
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
suite->add(BOOST_TEST_CASE(&test_traits));
suite->add(BOOST_TEST_CASE(&test_wtraits));
@@ -229,10 +237,24 @@ void test_conversion_to_bool()
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
BOOST_CHECK_THROW(lexical_cast<bool>(1.0001L), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(2), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(2u), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(-1), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(-2), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
BOOST_CHECK(lexical_cast<bool>("+1") == true );
BOOST_CHECK(lexical_cast<bool>("+0") == false );
BOOST_CHECK(lexical_cast<bool>("-0") == false );
BOOST_CHECK_THROW(lexical_cast<bool>("--0"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-+-0"), bad_lexical_cast);
}
void test_conversion_to_string()
@@ -447,6 +469,24 @@ void test_conversion_from_integral_to_char(CharT zero)
BOOST_CHECK_THROW(lexical_cast<CharT>(t), bad_lexical_cast);
}
template<class T, class CharT>
void test_conversion_from_char_to_integral(CharT zero)
{
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 0)) == static_cast<T>(0) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 1)) == static_cast<T>(1) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 2)) == static_cast<T>(2) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 3)) == static_cast<T>(3) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 4)) == static_cast<T>(4) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 5)) == static_cast<T>(5) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 6)) == static_cast<T>(6) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 7)) == static_cast<T>(7) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 8)) == static_cast<T>(8) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 9)) == static_cast<T>(9) );
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
}
template<class T>
void test_conversion_from_integral_to_integral()
{
@@ -540,25 +580,46 @@ void test_conversion_from_string_to_integral(CharT)
BOOST_CHECK_EQUAL(lexical_cast<T>(s), min_val);
if(limits::is_signed)
{
#if defined(BOOST_MSVC) && BOOST_MSVC == 1400
// VC++ 8.0 bug, see libs/conversion/test/lexical_cast_vc8_bug_test.cpp
if(sizeof(T) < sizeof(boost::intmax_t))
#endif
{
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
}
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
}
s = to_str<CharT>(max_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(s), max_val);
#if defined(BOOST_MSVC) && BOOST_MSVC == 1400
// VC++ 8.0 bug, see libs/conversion/test/lexical_cast_vc8_bug_test.cpp
if(sizeof(T) != sizeof(boost::intmax_t))
#endif
{
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
s = to_str<CharT>(max_val);
for (int i =1; i <=10; ++i) {
s[s.size()-1] += 1;
BOOST_CHECK_THROW(lexical_cast<T>( s ), bad_lexical_cast);
}
s = to_str<CharT>(max_val);
std::locale loc;
typedef std::numpunct<char> numpunct;
if ( BOOST_USE_FACET(numpunct, loc).grouping().empty() ) {
// Following tests work well for locale C
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+s), max_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
}
for (int i =1; i <=256; ++i) {
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
}
typedef BOOST_DEDUCED_TYPENAME boost::integral_promotion<T>::type promoted;
if ( !(boost::is_same<T, promoted>::value) )
{
promoted prom = max_val;
s = to_str<CharT>(max_val);
for (int i =1; i <=256; ++i) {
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(prom+i) ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
}
}
}
if(limits::digits <= 16 && lcast_test_small_integral_types_completely)
@@ -603,6 +664,18 @@ void test_conversion_from_string_to_integral(CharT)
template<class T>
void test_conversion_from_to_integral_for_locale()
{
std::locale current_locale;
typedef std::numpunct<char> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, current_locale);
if ( !np.grouping().empty() )
{
BOOST_CHECK_THROW(
lexical_cast<T>( std::string("100") + np.thousands_sep() + np.thousands_sep() + "0" )
, bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
}
test_conversion_from_integral_to_integral<T>();
test_conversion_from_integral_to_string<T>('0');
test_conversion_from_string_to_integral<T>('0');
@@ -625,13 +698,38 @@ void test_conversion_from_to_integral()
signed char const szero = '0';
unsigned char const uzero = '0';
test_conversion_from_integral_to_char<T>(zero);
test_conversion_from_char_to_integral<T>(zero);
test_conversion_from_integral_to_char<T>(szero);
test_conversion_from_char_to_integral<T>(szero);
test_conversion_from_integral_to_char<T>(uzero);
test_conversion_from_char_to_integral<T>(uzero);
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
wchar_t const wzero = L'0';
test_conversion_from_integral_to_char<T>(wzero);
test_conversion_from_char_to_integral<T>(wzero);
#endif
BOOST_CHECK(lexical_cast<T>("-1") == static_cast<T>(-1));
BOOST_CHECK(lexical_cast<T>("-9") == static_cast<T>(-9));
BOOST_CHECK(lexical_cast<T>(-1) == static_cast<T>(-1));
BOOST_CHECK(lexical_cast<T>(-9) == static_cast<T>(-9));
BOOST_CHECK_THROW(lexical_cast<T>("-1.0"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("-9.0"), bad_lexical_cast);
BOOST_CHECK(lexical_cast<T>(-1.0) == static_cast<T>(-1));
BOOST_CHECK(lexical_cast<T>(-9.0) == static_cast<T>(-9));
BOOST_CHECK(lexical_cast<T>(static_cast<T>(1)) == static_cast<T>(1));
BOOST_CHECK(lexical_cast<T>(static_cast<T>(9)) == static_cast<T>(9));
BOOST_CHECK_THROW(lexical_cast<T>(1.1f), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.1), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.1L), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.0001f), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.0001), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.0001L), bad_lexical_cast);
BOOST_CHECK(lexical_cast<T>("+1") == static_cast<T>(1) );
BOOST_CHECK(lexical_cast<T>("+9") == static_cast<T>(9) );
// test_conversion_from_to_integral_for_locale
typedef std::numpunct<char> numpunct;
@@ -665,6 +763,30 @@ void test_conversion_from_to_integral()
BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested");
}
template<class T>
void test_conversion_from_to_float()
{
char const zero = '0';
signed char const szero = '0';
unsigned char const uzero = '0';
test_conversion_from_integral_to_char<T>(zero);
test_conversion_from_char_to_integral<T>(zero);
test_conversion_from_integral_to_char<T>(szero);
test_conversion_from_char_to_integral<T>(szero);
test_conversion_from_integral_to_char<T>(uzero);
test_conversion_from_char_to_integral<T>(uzero);
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
wchar_t const wzero = L'0';
test_conversion_from_integral_to_char<T>(wzero);
test_conversion_from_char_to_integral<T>(wzero);
#endif
test_conversion_from_integral_to_integral<T>();
BOOST_CHECK_CLOSE(lexical_cast<T>("+1"), 1, std::numeric_limits<T>::epsilon() );
BOOST_CHECK_CLOSE(lexical_cast<T>("+9"), 9, std::numeric_limits<T>::epsilon()*9 );
}
void test_conversion_from_to_short()
{
test_conversion_from_to_integral<short>();
@@ -705,6 +827,19 @@ void test_conversion_from_to_uintmax_t()
test_conversion_from_to_integral<boost::uintmax_t>();
}
void test_conversion_from_to_float()
{
test_conversion_from_to_float<float>();
}
void test_conversion_from_to_double()
{
test_conversion_from_to_float<double>();
}
void test_conversion_from_to_long_double()
{
test_conversion_from_to_float<long double>();
}
#if defined(BOOST_HAS_LONG_LONG)
void test_conversion_from_to_longlong()
@@ -717,7 +852,7 @@ void test_conversion_from_to_ulonglong()
test_conversion_from_to_integral<boost::ulong_long_type>();
}
#elif defined(LCAST_TEST_LONGLONG)
#elif defined(BOOST_HAS_MS_INT64)
void test_conversion_from_to_longlong()
{