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 | |
32 | namespace boost { |
33 | namespace test_tools { |
34 | namespace 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 |
42 | template<typename FPT> |
43 | struct tolerance_manip { |
44 | explicit tolerance_manip( FPT const & tol ) : m_value( tol ) {} |
45 | |
46 | FPT m_value; |
47 | }; |
48 | |
49 | //____________________________________________________________________________// |
50 | |
51 | struct tolerance_manip_delay {}; |
52 | |
53 | template<typename FPT> |
54 | inline tolerance_manip<FPT> |
55 | operator%( 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 | |
63 | template <typename FPT> |
64 | struct 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 | |
75 | template<typename E, typename FPT> |
76 | inline assertion_evaluate_t<E> |
77 | operator<<(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 | |
87 | template<typename FPT> |
88 | unit_test::lazy_ostream & |
89 | operator<<( 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 |
92 | template<typename FPT> |
93 | std::ostream& |
94 | operator<<( std::ostream& o, tolerance_manip<FPT> const& ) { return o; } |
95 | |
96 | |
97 | //____________________________________________________________________________// |
98 | |
99 | template<typename FPT> |
100 | inline assertion_type |
101 | operator<<( 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 | */ |
115 | template<typename FPT> |
116 | inline tt_detail::tolerance_manip<FPT> |
117 | tolerance( 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 ) |
128 | template<typename FPT> |
129 | inline tt_detail::tolerance_manip<FPT> |
130 | tolerance( 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 ) |
141 | inline tt_detail::tolerance_manip_delay |
142 | tolerance() |
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 | |