diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index c954310..5b43501 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -631,12 +631,11 @@ namespace boost { { template inline - BOOST_DEDUCED_TYPENAME boost::make_unsigned::type lcast_to_unsigned(const T value) BOOST_NOEXCEPT - { + BOOST_DEDUCED_TYPENAME boost::make_unsigned::type lcast_to_unsigned(const T value) BOOST_NOEXCEPT { typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned::type result_type; - return static_cast( - value < 0 ? 0u - static_cast(value) : value - ); + return value < 0 + ? static_cast(0u - static_cast(value)) + : static_cast(value); } } @@ -1063,9 +1062,6 @@ namespace boost { CharT const plus = lcast_char_constants::plus; CharT const capital_e = lcast_char_constants::capital_e; CharT const lowercase_e = lcast_char_constants::lowercase_e; - - typedef BOOST_DEDUCED_TYPENAME Traits::int_type int_type; - int_type const zero = Traits::to_int_type(czero); /* Getting the plus/minus sign */ bool const has_minus = Traits::eq(*begin, minus); @@ -1106,7 +1102,7 @@ namespace boost { if (found_decimal) { /* We allow no thousand_separators after decimal point */ - const mantissa_type tmp_sub_value = static_cast(*begin - zero); + const mantissa_type tmp_sub_value = static_cast(*begin - czero); if (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) break; if ( *begin < czero || *begin >= czero + 10 ) return false; if ( is_mantissa_full @@ -1128,7 +1124,7 @@ namespace boost { /* Checking for mantissa overflow. If overflow will * occur, them we only increase multiplyer */ - const mantissa_type tmp_sub_value = static_cast(*begin - zero); + const mantissa_type tmp_sub_value = static_cast(*begin - czero); if( is_mantissa_full || ((std::numeric_limits::max)() - tmp_sub_value) / 10u < mantissa ) @@ -1224,7 +1220,7 @@ namespace boost { pow_of_10_t exp_pow_of_10 = 0; while (begin != end) { - pow_of_10_t const sub_value = *begin - zero; + pow_of_10_t const sub_value = *begin - czero; if ( *begin < czero || *begin >= czero + 10 || ((std::numeric_limits::max)() - sub_value) / 10 < exp_pow_of_10) @@ -1733,7 +1729,7 @@ namespace boost { } else { utype const comp_val = static_cast((std::numeric_limits::max)()); succeed = succeed && out_tmp<=comp_val; - output = out_tmp; + output = static_cast(out_tmp); } return succeed; } @@ -1804,7 +1800,7 @@ namespace boost { template bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT { using namespace std; - const std::size_t size = finish - start; + const std::size_t size = static_cast(finish - start); if (size > N - 1) { // `-1` because we need to store \0 at the end return false; } diff --git a/test.hpp b/test.hpp deleted file mode 100644 index 4c7eecb..0000000 --- a/test.hpp +++ /dev/null @@ -1,308 +0,0 @@ -// what: simple unit test framework -// who: developed by Kevlin Henney -// when: November 2000 -// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91 -// -// ChangeLog: -// 20 Jan 2001 - Fixed a warning for MSVC (Dave Abrahams) - -#ifndef TEST_INCLUDED -#define TEST_INCLUDED - -#include -#include -#include // for out-of-the-box g++ -#include - -namespace test // test tuple comprises name and nullary function (object) -{ - template - struct test - { - string_type name; - function_type action; - - static test make(string_type name, function_type action) - { - test result; // MSVC aggreggate initializer bugs - result.name = name; - result.action = action; - return result; - } - }; -} - -namespace test // failure exception used to indicate checked test failures -{ - class failure : public std::exception - { - public: // struction (default cases are OK) - - failure(const std::string & why) - : reason(why) - { - } - - // std::~string has no exception-specification (could throw anything), - // but we need to be compatible with std::~exception's empty one - // see std::15.4p13 and std::15.4p3 - ~failure() throw() - { - } - - public: // usage - - virtual const char * what() const throw() - { - return reason.c_str(); - } - - private: // representation - - std::string reason; - - }; -} - -namespace test // not_implemented exception used to mark unimplemented tests -{ - class not_implemented : public std::exception - { - public: // usage (default ctor and dtor are OK) - - virtual const char * what() const throw() - { - return "not implemented"; - } - - }; -} - -namespace test // test utilities -{ - inline void check(bool condition, const std::string & description) - { - if(!condition) - { - throw failure(description); - } - } - - inline void check_true(bool value, const std::string & description) - { - check(value, "expected true: " + description); - } - - inline void check_false(bool value, const std::string & description) - { - check(!value, "expected false: " + description); - } - - template - void check_equal( - const lhs_type & lhs, const rhs_type & rhs, - const std::string & description) - { - check(lhs == rhs, "expected equal values: " + description); - } - - template - void check_unequal( - const lhs_type & lhs, const rhs_type & rhs, - const std::string & description) - { - check(lhs != rhs, "expected unequal values: " + description); - } - - inline void check_null(const void* ptr, const std::string & description) - { - check(!ptr, "expected null pointer: " + description); - } - - inline void check_non_null(const void* ptr, const std::string & description) - { - check(ptr != 0, "expected non-null pointer: " + description); - } -} - -#define TEST_CHECK_THROW(expression, exception, description) \ - try \ - { \ - expression; \ - throw ::test::failure(description); \ - } \ - catch(exception &) \ - { \ - } - -namespace test // memory tracking (enabled if test new and delete linked in) -{ - class allocations - { - public: // singleton access - - static allocations & instance() - { - static allocations singleton; - return singleton; - } - - public: // logging - - void clear() - { - alloc_count = dealloc_count = 0; - } - - void allocation() - { - ++alloc_count; - } - - void deallocation() - { - ++dealloc_count; - } - - public: // reporting - - unsigned long allocated() const - { - return alloc_count; - } - - unsigned long deallocated() const - { - return dealloc_count; - } - - bool balanced() const - { - return alloc_count == dealloc_count; - } - - private: // structors (default dtor is fine) - - allocations() - : alloc_count(0), dealloc_count(0) - { - } - - private: // prevention - - allocations(const allocations &); - allocations & operator=(const allocations &); - - private: // state - - unsigned long alloc_count, dealloc_count; - - }; -} - -namespace test // tester is the driver class for a sequence of tests -{ - template - class tester - { - public: // structors (default destructor is OK) - - tester(test_iterator first_test, test_iterator after_last_test) - : begin(first_test), end(after_last_test) - { - } - - public: // usage - - bool operator()(); // returns true if all tests passed - - private: // representation - - test_iterator begin, end; - - private: // prevention - - tester(const tester &); - tester &operator=(const tester &); - - }; - - template - bool tester::operator()() - { - using namespace std; - - unsigned long passed = 0, failed = 0, unimplemented = 0; - - for(test_iterator current = begin; current != end; ++current) - { - cerr << "[" << current->name << "] " << flush; - string result = "passed"; // optimistic - - try - { - allocations::instance().clear(); - current->action(); - - if(!allocations::instance().balanced()) - { - unsigned long allocated = allocations::instance().allocated(); - unsigned long deallocated = allocations::instance().deallocated(); - ostrstream report; - report << "new/delete (" - << allocated << " allocated, " - << deallocated << " deallocated)" - << ends; - const char * text = report.str(); - report.freeze(false); - throw failure(text); - } - - ++passed; - } - catch(const failure & caught) - { - (result = "failed: ") += caught.what(); - ++failed; - } - catch(const not_implemented &) - { - result = "not implemented"; - ++unimplemented; - } - catch(const exception & caught) - { - (result = "exception: ") += caught.what(); - ++failed; - } - catch(...) - { - result = "failed with unknown exception"; - ++failed; - } - - cerr << result << endl; - } - - cerr << passed + failed << " tests: " - << passed << " passed, " - << failed << " failed"; - - if(unimplemented) - { - cerr << " (" << unimplemented << " not implemented)"; - } - - cerr << endl; - - return failed == 0; - } -} - -#endif - -// Copyright Kevlin Henney, 2000. All rights reserved. -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bd17204..1ac10ae 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -30,9 +30,9 @@ feature.compose on : /Zc:wchar_t- ; test-suite conversion : [ run implicit_cast.cpp ] [ compile-fail implicit_cast_fail.cpp ] - [ run ../cast_test.cpp ] - [ run ../numeric_cast_test.cpp ] - [ run ../lexical_cast_test.cpp ] + [ run cast_test.cpp ] + [ run numeric_cast_test.cpp ] + [ run lexical_cast_test.cpp ] [ run lexical_cast_loopback_test.cpp ] [ run lexical_cast_abstract_test.cpp ] [ run lexical_cast_noncopyable_test.cpp ] diff --git a/cast_test.cpp b/test/cast_test.cpp similarity index 100% rename from cast_test.cpp rename to test/cast_test.cpp diff --git a/test/lexical_cast_empty_input_test.cpp b/test/lexical_cast_empty_input_test.cpp old mode 100755 new mode 100644 diff --git a/test/lexical_cast_float_types_test.cpp b/test/lexical_cast_float_types_test.cpp old mode 100755 new mode 100644 diff --git a/test/lexical_cast_inf_nan_test.cpp b/test/lexical_cast_inf_nan_test.cpp old mode 100755 new mode 100644 diff --git a/test/lexical_cast_integral_types_test.cpp b/test/lexical_cast_integral_types_test.cpp index 4755071..551a349 100644 --- a/test/lexical_cast_integral_types_test.cpp +++ b/test/lexical_cast_integral_types_test.cpp @@ -367,10 +367,36 @@ void test_conversion_from_to_integral_for_locale() BOOST_CHECK( lexical_cast("30000") == static_cast(30000) ); } + test_conversion_from_integral_to_integral(); + + // This is a part of test_conversion_from_integral_to_string('0') method, + // but with BOOST_CHECK_EQUAL instead of BOOST_CHECK. It is required to see + // what is produced by the to_str(t) method in situations when result + // is different. BOOST_CHECK does not work with wchar_t. + typedef std::numeric_limits limits; + T t = (limits::min)(); + BOOST_CHECK_EQUAL(lexical_cast(t), to_str(t)); + test_conversion_from_integral_to_string('0'); test_conversion_from_string_to_integral('0'); #if !defined(BOOST_LCAST_NO_WCHAR_T) + if (lexical_cast(t) != to_str(t)) { + // Something went wrong, and now we are attempting to find and print the + // difference. + std::wstring wstr = to_str(t); + std::string lcast_str = lexical_cast(t); + std::string str; + str.reserve(wstr.size()); + for (std::size_t i = 0; i < wstr.size(); ++i) { + str.push_back(static_cast(wstr[i])); + } + + BOOST_CHECK_EQUAL(lcast_str.length(), lexical_cast(t).length()); + BOOST_CHECK_EQUAL(to_str(t), str); + BOOST_CHECK_EQUAL(lcast_str, str); + } + test_conversion_from_integral_to_string(L'0'); test_conversion_from_string_to_integral(L'0'); #endif diff --git a/test/lexical_cast_no_exceptions_test.cpp b/test/lexical_cast_no_exceptions_test.cpp old mode 100755 new mode 100644 diff --git a/test/lexical_cast_no_locale_test.cpp b/test/lexical_cast_no_locale_test.cpp old mode 100755 new mode 100644 diff --git a/test/lexical_cast_pointers_test.cpp b/test/lexical_cast_pointers_test.cpp old mode 100755 new mode 100644 diff --git a/lexical_cast_test.cpp b/test/lexical_cast_test.cpp similarity index 100% rename from lexical_cast_test.cpp rename to test/lexical_cast_test.cpp diff --git a/test/lexical_cast_typedefed_wchar_test.cpp b/test/lexical_cast_typedefed_wchar_test.cpp old mode 100755 new mode 100644 diff --git a/test/lexical_cast_typedefed_wchar_test_runtime.cpp b/test/lexical_cast_typedefed_wchar_test_runtime.cpp old mode 100755 new mode 100644 diff --git a/numeric_cast_test.cpp b/test/numeric_cast_test.cpp similarity index 100% rename from numeric_cast_test.cpp rename to test/numeric_cast_test.cpp