// Copyright John Maddock 2011. // Use, modification and distribution are subject to 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) #ifdef _MSC_VER #define _SCL_SECURE_NO_WARNINGS #endif #if !defined(TEST_MPQ) && !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) #define TEST_MPQ #define TEST_TOMMATH #define TEST_CPP_INT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") #endif #ifdef __GNUC__ #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!" #endif #endif #if defined(TEST_MPQ) #include #endif #if defined(TEST_TOMMATH) #include #endif #ifdef TEST_CPP_INT #include #endif #include #include #include #include #include "test.hpp" #include #include template T generate_random() { typedef typename boost::multiprecision::component_type::type int_type; static boost::random::uniform_int_distribution ui(0, 20); static boost::random::mt19937 gen; int_type val = int_type(gen()); unsigned lim = ui(gen); for (unsigned i = 0; i < lim; ++i) { val *= (gen.max)(); val += gen(); } int_type denom = int_type(gen()); lim = ui(gen); for (unsigned i = 0; i < lim; ++i) { denom *= (gen.max)(); denom += gen(); } return T(val, denom); } template void do_round_trip(const T& val, std::ios_base::fmtflags f, const boost::mpl::true_&) { std::stringstream ss; #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS ss << std::setprecision(std::numeric_limits::max_digits10); #else ss << std::setprecision(std::numeric_limits::digits10 + 5); #endif ss.flags(f); ss << val; T new_val = static_cast(ss.str()); BOOST_CHECK_EQUAL(new_val, val); new_val = static_cast(val.str(0, f)); BOOST_CHECK_EQUAL(new_val, val); } template void do_round_trip(const T& val, std::ios_base::fmtflags f, const boost::mpl::false_&) { std::stringstream ss; ss << std::setprecision(std::numeric_limits::digits10 + 4); ss.flags(f); ss << val; T new_val; ss >> new_val; BOOST_CHECK_EQUAL(new_val, val); } template struct is_number : public boost::mpl::false_ {}; template struct is_number > : public boost::mpl::true_ {}; template void do_round_trip(const T& val, std::ios_base::fmtflags f) { do_round_trip(val, f, is_number()); } template void do_round_trip(const T& val) { do_round_trip(val, std::ios_base::fmtflags(0)); if (val >= 0) { do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase | std::ios_base::hex)); do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase | std::ios_base::oct)); } } template void test_round_trip() { for (unsigned i = 0; i < 1000; ++i) { T val = generate_random(); do_round_trip(val); do_round_trip(T(-val)); } } int main() { #ifdef TEST_MPQ test_round_trip(); test_round_trip >(); test_round_trip > >(); #endif #ifdef TEST_TOMMATH test_round_trip >(); test_round_trip(); #endif #ifdef TEST_CPP_INT test_round_trip >(); test_round_trip(); #endif return boost::report_errors(); }