liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//  (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/utils/lazy_ostream.hpp>
#include <boost/test/tools/fpc_tolerance.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>
 
#include <ostream>
 
#include <boost/test/detail/suppress_warnings.hpp>
 
//____________________________________________________________________________//
 
namespace boost {
namespace test_tools {
namespace tt_detail {
 
// ************************************************************************** //
// **************           fpc tolerance manipulator          ************** //
// ************************************************************************** //
 
//! Tolerance manipulator, not to be used directly
//! This is not a terminal of the expression
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 FPT>
struct tolerance_evaluation_context: assertion_evaluation_context {
    tolerance_evaluation_context(FPT tol)
    : assertion_evaluation_context( true ) // has report
    , m_tolerance_context(tol)
    {}
 
    local_fpc_tolerance<FPT> m_tolerance_context;
};
 
//____________________________________________________________________________//
 
template<typename E, typename FPT>
inline assertion_evaluate_t<E>
operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
{
    return ae.stack_context(
      typename assertion_evaluate_t<E>::context_holder(
        new tolerance_evaluation_context<FPT>( tol.m_value ))
    );
}
 
//____________________________________________________________________________//
 
template<typename FPT>
unit_test::lazy_ostream &
operator<<( unit_test::lazy_ostream &o, tolerance_manip<FPT> const& )   { return o; }
 
// needed for the lazy evaluation in lazy_ostream as for commutativity with other arguments
template<typename FPT>
std::ostream& 
operator<<( std::ostream& o, tolerance_manip<FPT> const& )              { return o; }
 
 
//____________________________________________________________________________//
 
template<typename FPT>
inline assertion_type
operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& ) {
    return assertion_type(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