mirror of
https://github.com/boostorg/test.git
synced 2026-01-24 18:32:30 +00:00
introduce fpc::tolerance_based to be used instead of if_floating_point. This should allow us to extend tolerance based comparisons t omore types
This commit is contained in:
@@ -24,11 +24,11 @@
|
||||
#include <boost/test/tools/fpc_tolerance.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
// STL
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
@@ -323,7 +323,7 @@ struct compare_fpv<op::NE<Lhs,Rhs>,FPT> {
|
||||
compare( Lhs const& lhs, Rhs const& rhs )
|
||||
{
|
||||
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), 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<op::NE<Lhs,Rhs>,FPT> {
|
||||
#define DEFINE_FPV_COMPARISON( oper, name, rev ) \
|
||||
template<typename Lhs,typename Rhs> \
|
||||
struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
is_floating_point<Lhs>::value && \
|
||||
is_floating_point<Rhs>::value>::type> { \
|
||||
fpc::tolerance_based<Lhs>::value && \
|
||||
fpc::tolerance_based<Rhs>::value>::type> { \
|
||||
typedef typename numeric::conversion_traits<Lhs,Rhs \
|
||||
>::supertype FPT; \
|
||||
typedef name<Lhs,Rhs> OP; \
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
|
||||
#include <boost/test/tools/fpc_tolerance.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -51,7 +48,7 @@ template<typename FPT>
|
||||
inline tolerance_manip<FPT>
|
||||
operator%( FPT v, tolerance_manip_delay const& )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_floating_point<FPT>::value );
|
||||
BOOST_STATIC_ASSERT( fpc::tolerance_based<FPT>::value );
|
||||
|
||||
return tolerance_manip<FPT>( v * static_cast<FPT>(0.01) );
|
||||
}
|
||||
@@ -87,7 +84,7 @@ template<typename FPT>
|
||||
inline tt_detail::tolerance_manip<FPT>
|
||||
tolerance( FPT v )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_floating_point<FPT>::value );
|
||||
BOOST_STATIC_ASSERT( fpc::tolerance_based<FPT>::value );
|
||||
|
||||
return tt_detail::tolerance_manip<FPT>( v );
|
||||
}
|
||||
@@ -98,7 +95,7 @@ template<typename FPT>
|
||||
inline tt_detail::tolerance_manip<FPT>
|
||||
tolerance( fpc::percent_tolerance_t<FPT> v )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_floating_point<FPT>::value );
|
||||
BOOST_STATIC_ASSERT( fpc::tolerance_based<FPT>::value );
|
||||
|
||||
return tt_detail::tolerance_manip<FPT>( v.m_value * static_cast<FPT>(0.01) );
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
// Boost
|
||||
#include <boost/limits.hpp> // for std::numeric_limits
|
||||
#include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
// STL
|
||||
#include <iosfwd>
|
||||
@@ -33,6 +33,17 @@ namespace boost {
|
||||
namespace math {
|
||||
namespace fpc {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** fpc::tolerance_based ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename T>
|
||||
struct tolerance_based : mpl::bool_<
|
||||
is_floating_point<T>::value ||
|
||||
std::numeric_limits<T>::is_specialized &&
|
||||
!std::numeric_limits<T>::is_integer &&
|
||||
!std::numeric_limits<T>::is_exact> {};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** fpc::strength ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -42,6 +53,37 @@ enum strength {
|
||||
FPC_WEAK // "Close enough" - equation 2' in docs.
|
||||
};
|
||||
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** tolerance presentation types ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename FPT>
|
||||
struct percent_tolerance_t {
|
||||
explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
|
||||
|
||||
FPT m_value;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
inline std::ostream& operator<<( std::ostream& out, percent_tolerance_t<FPT> t )
|
||||
{
|
||||
return out << t.m_value;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
inline percent_tolerance_t<FPT>
|
||||
percent_tolerance( FPT v )
|
||||
{
|
||||
return percent_tolerance_t<FPT>( v );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** details ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -95,71 +137,26 @@ safe_fpt_division( FPT f1, FPT f2 )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT, typename ToleranceType>
|
||||
inline FPT
|
||||
fraction_tolerance( ToleranceType tolerance )
|
||||
{
|
||||
return static_cast<FPT>(tolerance);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT2, typename FPT>
|
||||
inline FPT2
|
||||
fraction_tolerance( percent_tolerance_t<FPT> tolerance )
|
||||
{
|
||||
return static_cast<FPT2>(tolerance.m_value)*static_cast<FPT2>(0.01);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace fpc_detail
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** tolerance presentation types ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename ToleranceType>
|
||||
struct tolerance_traits {
|
||||
template<typename FPT>
|
||||
static ToleranceType actual_tolerance( FPT fraction_tolerance )
|
||||
{
|
||||
return static_cast<ToleranceType>( fraction_tolerance );
|
||||
}
|
||||
template<typename FPT>
|
||||
static FPT fraction_tolerance( ToleranceType tolerance )
|
||||
{
|
||||
return static_cast<FPT>(tolerance);
|
||||
}
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
struct percent_tolerance_t {
|
||||
explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
|
||||
|
||||
FPT m_value;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
struct tolerance_traits<percent_tolerance_t<FPT> > {
|
||||
template<typename FPT2>
|
||||
static percent_tolerance_t<FPT> actual_tolerance( FPT2 fraction_tolerance )
|
||||
{
|
||||
return percent_tolerance_t<FPT>( fraction_tolerance * static_cast<FPT2>(100.) );
|
||||
}
|
||||
|
||||
template<typename FPT2>
|
||||
static FPT2 fraction_tolerance( percent_tolerance_t<FPT> tolerance )
|
||||
{
|
||||
return static_cast<FPT2>(tolerance.m_value)*static_cast<FPT2>(0.01);
|
||||
}
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
inline std::ostream& operator<<( std::ostream& out, percent_tolerance_t<FPT> t )
|
||||
{
|
||||
return out << t.m_value;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
inline percent_tolerance_t<FPT>
|
||||
percent_tolerance( FPT v )
|
||||
{
|
||||
return percent_tolerance_t<FPT>( v );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** close_at_tolerance ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -173,7 +170,7 @@ public:
|
||||
// Constructor
|
||||
template<typename ToleranceType>
|
||||
explicit close_at_tolerance( ToleranceType tolerance, fpc::strength fpc_strength = FPC_STRONG )
|
||||
: m_fraction_tolerance( tolerance_traits<ToleranceType>::template fraction_tolerance<FPT>( tolerance ) )
|
||||
: m_fraction_tolerance( fpc_detail::fraction_tolerance<FPT>( tolerance ) )
|
||||
, m_strength( fpc_strength )
|
||||
, m_failed_fraction()
|
||||
{
|
||||
@@ -191,7 +188,7 @@ public:
|
||||
FPT diff = fpc_detail::fpt_abs<FPT>( 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) );
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
// Boost
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
|
||||
Reference in New Issue
Block a user