diff --git a/include/boost/test/tools/assertion.hpp b/include/boost/test/tools/assertion.hpp index 8e4d85e0..e8e71650 100644 --- a/include/boost/test/tools/assertion.hpp +++ b/include/boost/test/tools/assertion.hpp @@ -24,11 +24,11 @@ #include // Boost +#include // for numeric::conversion_traits #include #include #include #include -#include // STL #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES @@ -323,7 +323,7 @@ struct compare_fpv,FPT> { compare( Lhs const& lhs, Rhs const& rhs ) { fpc::close_at_tolerance P( fpc_tolerance(), fpc::FPC_STRONG ); - + assertion_result ar( !P( lhs, rhs ) ); if( !ar ) ar.message() << "Relative difference is within tolerance [" @@ -350,8 +350,8 @@ struct compare_fpv,FPT> { #define DEFINE_FPV_COMPARISON( oper, name, rev ) \ template \ struct name::value && \ - is_floating_point::value>::type> { \ + fpc::tolerance_based::value && \ + fpc::tolerance_based::value>::type> { \ typedef typename numeric::conversion_traits::supertype FPT; \ typedef name OP; \ diff --git a/include/boost/test/tools/detail/tolerance_manip.hpp b/include/boost/test/tools/detail/tolerance_manip.hpp index 0ea06e1b..63a3eb8a 100644 --- a/include/boost/test/tools/detail/tolerance_manip.hpp +++ b/include/boost/test/tools/detail/tolerance_manip.hpp @@ -21,9 +21,6 @@ #include -// Boost -#include - #include //____________________________________________________________________________// @@ -51,7 +48,7 @@ template inline tolerance_manip operator%( FPT v, tolerance_manip_delay const& ) { - BOOST_STATIC_ASSERT( is_floating_point::value ); + BOOST_STATIC_ASSERT( fpc::tolerance_based::value ); return tolerance_manip( v * static_cast(0.01) ); } @@ -87,7 +84,7 @@ template inline tt_detail::tolerance_manip tolerance( FPT v ) { - BOOST_STATIC_ASSERT( is_floating_point::value ); + BOOST_STATIC_ASSERT( fpc::tolerance_based::value ); return tt_detail::tolerance_manip( v ); } @@ -98,7 +95,7 @@ template inline tt_detail::tolerance_manip tolerance( fpc::percent_tolerance_t v ) { - BOOST_STATIC_ASSERT( is_floating_point::value ); + BOOST_STATIC_ASSERT( fpc::tolerance_based::value ); return tt_detail::tolerance_manip( v.m_value * static_cast(0.01) ); } diff --git a/include/boost/test/tools/floating_point_comparison.hpp b/include/boost/test/tools/floating_point_comparison.hpp index 70c21030..a13f83a2 100644 --- a/include/boost/test/tools/floating_point_comparison.hpp +++ b/include/boost/test/tools/floating_point_comparison.hpp @@ -18,9 +18,9 @@ // Boost #include // for std::numeric_limits -#include // for numeric::conversion_traits #include #include +#include // STL #include @@ -33,6 +33,17 @@ namespace boost { namespace math { namespace fpc { +// ************************************************************************** // +// ************** fpc::tolerance_based ************** // +// ************************************************************************** // + +template +struct tolerance_based : mpl::bool_< + is_floating_point::value || + std::numeric_limits::is_specialized && + !std::numeric_limits::is_integer && + !std::numeric_limits::is_exact> {}; + // ************************************************************************** // // ************** fpc::strength ************** // // ************************************************************************** // @@ -42,6 +53,37 @@ enum strength { FPC_WEAK // "Close enough" - equation 2' in docs. }; + +// ************************************************************************** // +// ************** tolerance presentation types ************** // +// ************************************************************************** // + +template +struct percent_tolerance_t { + explicit percent_tolerance_t( FPT v ) : m_value( v ) {} + + FPT m_value; +}; + +//____________________________________________________________________________// + +template +inline std::ostream& operator<<( std::ostream& out, percent_tolerance_t t ) +{ + return out << t.m_value; +} + +//____________________________________________________________________________// + +template +inline percent_tolerance_t +percent_tolerance( FPT v ) +{ + return percent_tolerance_t( v ); +} + +//____________________________________________________________________________// + // ************************************************************************** // // ************** details ************** // // ************************************************************************** // @@ -95,71 +137,26 @@ safe_fpt_division( FPT f1, FPT f2 ) //____________________________________________________________________________// +template +inline FPT +fraction_tolerance( ToleranceType tolerance ) +{ + return static_cast(tolerance); +} + +//____________________________________________________________________________// + +template +inline FPT2 +fraction_tolerance( percent_tolerance_t tolerance ) +{ + return static_cast(tolerance.m_value)*static_cast(0.01); +} + +//____________________________________________________________________________// + } // namespace fpc_detail -// ************************************************************************** // -// ************** tolerance presentation types ************** // -// ************************************************************************** // - -template -struct tolerance_traits { - template - static ToleranceType actual_tolerance( FPT fraction_tolerance ) - { - return static_cast( fraction_tolerance ); - } - template - static FPT fraction_tolerance( ToleranceType tolerance ) - { - return static_cast(tolerance); - } -}; - -//____________________________________________________________________________// - -template -struct percent_tolerance_t { - explicit percent_tolerance_t( FPT v ) : m_value( v ) {} - - FPT m_value; -}; - -//____________________________________________________________________________// - -template -struct tolerance_traits > { - template - static percent_tolerance_t actual_tolerance( FPT2 fraction_tolerance ) - { - return percent_tolerance_t( fraction_tolerance * static_cast(100.) ); - } - - template - static FPT2 fraction_tolerance( percent_tolerance_t tolerance ) - { - return static_cast(tolerance.m_value)*static_cast(0.01); - } -}; - -//____________________________________________________________________________// - -template -inline std::ostream& operator<<( std::ostream& out, percent_tolerance_t t ) -{ - return out << t.m_value; -} - -//____________________________________________________________________________// - -template -inline percent_tolerance_t -percent_tolerance( FPT v ) -{ - return percent_tolerance_t( v ); -} - -//____________________________________________________________________________// - // ************************************************************************** // // ************** close_at_tolerance ************** // // ************************************************************************** // @@ -173,7 +170,7 @@ public: // Constructor template explicit close_at_tolerance( ToleranceType tolerance, fpc::strength fpc_strength = FPC_STRONG ) - : m_fraction_tolerance( tolerance_traits::template fraction_tolerance( tolerance ) ) + : m_fraction_tolerance( fpc_detail::fraction_tolerance( tolerance ) ) , m_strength( fpc_strength ) , m_failed_fraction() { @@ -191,7 +188,7 @@ public: FPT diff = fpc_detail::fpt_abs( left - right ); FPT fraction_of_right = fpc_detail::safe_fpt_division( diff, fpc_detail::fpt_abs( right ) ); FPT fraction_of_left = fpc_detail::safe_fpt_division( diff, fpc_detail::fpt_abs( left ) ); - + bool res( m_strength == FPC_STRONG ? (fraction_of_right <= m_fraction_tolerance && fraction_of_left <= m_fraction_tolerance) : (fraction_of_right <= m_fraction_tolerance || fraction_of_left <= m_fraction_tolerance) ); diff --git a/include/boost/test/tools/old/impl.hpp b/include/boost/test/tools/old/impl.hpp index d5864a99..368e50e2 100644 --- a/include/boost/test/tools/old/impl.hpp +++ b/include/boost/test/tools/old/impl.hpp @@ -25,6 +25,7 @@ // Boost #include +#include // for numeric::conversion_traits #include #include