summaryrefslogtreecommitdiff
path: root/boost/test/tools/detail/tolerance_manip.hpp
blob: e07b0435913588bd28f0f90237190edf58c1474c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//  (C) Copyright Gennadiy Rozental 2001.
//  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)

//  See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! @brief Floating point comparison tolerance manipulators
//! 
//! This file defines several manipulators for floating point comparison. These
//! manipulators are intended to be used with BOOST_TEST.
// ***************************************************************************

#ifndef BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
#define BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER

// Boost Test
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/indirections.hpp>

#include <boost/test/tools/fpc_tolerance.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace test_tools {
namespace tt_detail {

// ************************************************************************** //
// **************           fpc tolerance manipulator          ************** //
// ************************************************************************** //

template<typename FPT>
struct tolerance_manip {
    explicit tolerance_manip( FPT const & tol ) : m_value( tol ) {}

    FPT m_value;
};

//____________________________________________________________________________//

struct tolerance_manip_delay {};

template<typename FPT>
inline tolerance_manip<FPT>
operator%( FPT v, tolerance_manip_delay const& )
{
    BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value), 
                             "tolerance should be specified using a floating points type" );

    return tolerance_manip<FPT>( FPT(v / 100) );
}

//____________________________________________________________________________//

template<typename E, typename FPT>
inline assertion_result
operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
{
    local_fpc_tolerance<FPT> lt( tol.m_value );

    return ae.m_e.evaluate();
}

//____________________________________________________________________________//

template<typename FPT>
inline int
operator<<( unit_test::lazy_ostream const&, tolerance_manip<FPT> const& )   { return 0; }

//____________________________________________________________________________//

template<typename FPT>
inline check_type
operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& )         { return CHECK_BUILT_ASSERTION; }

//____________________________________________________________________________//

} // namespace tt_detail


/*! Tolerance manipulator
 *
 * These functions return a manipulator that can be used in conjunction with BOOST_TEST
 * in order to specify the tolerance with which floating point comparisons are made.
 */
template<typename FPT>
inline tt_detail::tolerance_manip<FPT>
tolerance( FPT v )
{
    BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value), 
                             "tolerance only for floating points" );

    return tt_detail::tolerance_manip<FPT>( v );
}

//____________________________________________________________________________//

//! @overload tolerance( FPT v )
template<typename FPT>
inline tt_detail::tolerance_manip<FPT>
tolerance( fpc::percent_tolerance_t<FPT> v )
{
    BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value), 
                             "tolerance only for floating points" );

    return tt_detail::tolerance_manip<FPT>( static_cast<FPT>(v.m_value / 100) );
}

//____________________________________________________________________________//

//! @overload tolerance( FPT v )
inline tt_detail::tolerance_manip_delay
tolerance()
{
    return tt_detail::tolerance_manip_delay();
}

//____________________________________________________________________________//

} // namespace test_tools
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER