Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext
Enabling tolerance for user-defined types

The Unit Test Framework recognizes that a given type T is suitable for tolerance-based comparisons using the expression boost::math::fpc::tolerance_based<T>::value. This meta-function already returns true for built-in floating-point types as well as any other types that match the following compile-time expression:

boost::is_floating_point<T>::value ||
    ( std::numeric_limits<T>::is_specialized &&
     !std::numeric_limits<T>::is_integer &&
     !std::numeric_limits<T>::is_exact)

If you require your type to also participate in tolerance-based comparisons, regardless of the above expression, you can just specialize boost::math::fpc::tolerance_based for your type directly, and derive it from boost::true_type. Your type does not even have to be a floating-point type provided that it models concept ToleranceCompatible.

Example: adapting user-defined types for tolerance-based comparison

Code

#define BOOST_TEST_MODULE tolerance_04
#include <boost/test/included/unit_test.hpp>
#include <boost/rational.hpp>
namespace utf = boost::unit_test;
namespace tt = boost::test_tools;

namespace boost { namespace math { namespace fpc {

  template <typename I>
  struct tolerance_based< rational<I> > : boost::true_type{};

} } }

typedef boost::rational<int> ratio;

BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(ratio(1, 1000)))
{
  ratio x (1002, 100); // 10.02
  ratio y (1001, 100); // 10.01
  ratio z (1000, 100); // 10.00

  BOOST_TEST(x == y);  // irrelevant diff by default
  BOOST_TEST(x == y, tt::tolerance(ratio(1, 2000)));

  BOOST_TEST(x != z);  // relevant diff by default
  BOOST_TEST(x != z, tt::tolerance(ratio(2, 1000)));
}

Output

> tolerance_04
Running 1 test case...
test.cpp(23): error: in "test1": check x == y has failed [501/50 != 1001/100]. Relative difference exceeds tolerance [1/1001 > 1/2000]
test.cpp(26): error: in "test1": check x != z has failed [501/50 == 10/1]. Relative difference is within tolerance [1/501 < 1/500]

*** 2 failures are detected in the test module "tolerance_04"

Concept ToleranceCompatible

Refinement of

MoveConstructible, EqualityComparable, LessThanComparable

Notation

T

A type that is a model of ToleranceCompatible

x, y

objects of type T

i, j

objects of type int

Valid expressions

Name

Expression

Return type

Conversion from int

T j = i;

Addition

x + y

T

Subtraction

x - y

T

Negation

-x

T

Multiplication

x * y
x * i

T

Division

x / y
x / i

T

Mixed equality

x == i
x != i

bool

Mixed ordering

x < i
x > i
x <= i
x >= i

bool

Invariants

T and int consistency

(x == T(i)) == (x == i)
(x != T(i)) == (x != i)
(x < T(i)) == (x < i)
(x > T(i)) == (x > i)
(x / T(i)) == (x / i)
(x * T(i)) == (x * i)


PrevUpHomeNext