1// (C) Copyright Gennadiy Rozental 2001.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5
6// See http://www.boost.org/libs/test for the library home page.
7//
8//! @file
9//! @brief Floating point comparison tolerance manipulators
10//!
11//! This file defines several manipulators for floating point comparison. These
12//! manipulators are intended to be used with BOOST_TEST.
13// ***************************************************************************
14
15#ifndef BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
16#define BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
17
18// Boost Test
19#include <boost/test/tools/detail/fwd.hpp>
20#include <boost/test/tools/detail/indirections.hpp>
21
22#include <boost/test/utils/lazy_ostream.hpp>
23#include <boost/test/tools/fpc_tolerance.hpp>
24#include <boost/test/tools/floating_point_comparison.hpp>
25
26#include <ostream>
27
28#include <boost/test/detail/suppress_warnings.hpp>
29
30//____________________________________________________________________________//
31
32namespace boost {
33namespace test_tools {
34namespace tt_detail {
35
36// ************************************************************************** //
37// ************** fpc tolerance manipulator ************** //
38// ************************************************************************** //
39
40//! Tolerance manipulator, not to be used directly
41//! This is not a terminal of the expression
42template<typename FPT>
43struct tolerance_manip {
44 explicit tolerance_manip( FPT const & tol ) : m_value( tol ) {}
45
46 FPT m_value;
47};
48
49//____________________________________________________________________________//
50
51struct tolerance_manip_delay {};
52
53template<typename FPT>
54inline tolerance_manip<FPT>
55operator%( FPT v, tolerance_manip_delay const& )
56{
57 BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
58 "tolerance should be specified using a floating points type" );
59
60 return tolerance_manip<FPT>( FPT(v / 100) );
61}
62
63template <typename FPT>
64struct tolerance_evaluation_context: assertion_evaluation_context {
65 tolerance_evaluation_context(FPT tol)
66 : assertion_evaluation_context( true ) // has report
67 , m_tolerance_context(tol)
68 {}
69
70 local_fpc_tolerance<FPT> m_tolerance_context;
71};
72
73//____________________________________________________________________________//
74
75template<typename E, typename FPT>
76inline assertion_evaluate_t<E>
77operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
78{
79 return ae.stack_context(
80 typename assertion_evaluate_t<E>::context_holder(
81 new tolerance_evaluation_context<FPT>( tol.m_value ))
82 );
83}
84
85//____________________________________________________________________________//
86
87template<typename FPT>
88unit_test::lazy_ostream &
89operator<<( unit_test::lazy_ostream &o, tolerance_manip<FPT> const& ) { return o; }
90
91// needed for the lazy evaluation in lazy_ostream as for commutativity with other arguments
92template<typename FPT>
93std::ostream&
94operator<<( std::ostream& o, tolerance_manip<FPT> const& ) { return o; }
95
96
97//____________________________________________________________________________//
98
99template<typename FPT>
100inline assertion_type
101operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& ) {
102 return assertion_type(CHECK_BUILT_ASSERTION);
103}
104
105//____________________________________________________________________________//
106
107} // namespace tt_detail
108
109
110/*! Tolerance manipulator
111 *
112 * These functions return a manipulator that can be used in conjunction with BOOST_TEST
113 * in order to specify the tolerance with which floating point comparisons are made.
114 */
115template<typename FPT>
116inline tt_detail::tolerance_manip<FPT>
117tolerance( FPT v )
118{
119 BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
120 "tolerance only for floating points" );
121
122 return tt_detail::tolerance_manip<FPT>( v );
123}
124
125//____________________________________________________________________________//
126
127//! @overload tolerance( FPT v )
128template<typename FPT>
129inline tt_detail::tolerance_manip<FPT>
130tolerance( fpc::percent_tolerance_t<FPT> v )
131{
132 BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
133 "tolerance only for floating points" );
134
135 return tt_detail::tolerance_manip<FPT>( static_cast<FPT>(v.m_value / 100) );
136}
137
138//____________________________________________________________________________//
139
140//! @overload tolerance( FPT v )
141inline tt_detail::tolerance_manip_delay
142tolerance()
143{
144 return tt_detail::tolerance_manip_delay();
145}
146
147//____________________________________________________________________________//
148
149} // namespace test_tools
150} // namespace boost
151
152#include <boost/test/detail/enable_warnings.hpp>
153
154#endif // BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
155

source code of include/boost/test/tools/detail/tolerance_manip.hpp