]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/test/include/boost/test/tools/collection_comparison_op.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / test / include / boost / test / tools / collection_comparison_op.hpp
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 Collection comparison with enhanced reporting
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
13 #define BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
14
15 // Boost.Test
16 #include <boost/test/tools/assertion.hpp>
17
18 #include <boost/test/utils/is_forward_iterable.hpp>
19
20 // Boost
21 #include <boost/mpl/bool.hpp>
22 #include <boost/utility/enable_if.hpp>
23 #include <boost/type_traits/decay.hpp>
24
25 #include <boost/test/detail/suppress_warnings.hpp>
26
27 //____________________________________________________________________________//
28
29 namespace boost {
30 namespace test_tools {
31 namespace assertion {
32
33 // ************************************************************************** //
34 // ************* selectors for specialized comparizon routines ************** //
35 // ************************************************************************** //
36
37 template<typename T>
38 struct specialized_compare : public mpl::false_ {};
39
40 #define BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(Col) \
41 namespace boost { namespace test_tools { namespace assertion { \
42 template<> \
43 struct specialized_compare<Col> : public mpl::true_ {}; \
44 }}} \
45 /**/
46
47 // ************************************************************************** //
48 // ************** lexicographic_compare ************** //
49 // ************************************************************************** //
50
51 namespace op {
52
53 template <typename OP, bool can_be_equal, bool prefer_shorter,
54 typename Lhs, typename Rhs>
55 inline assertion_result
56 lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
57 {
58 assertion_result ar( true );
59
60 typename Lhs::const_iterator first1 = lhs.begin();
61 typename Rhs::const_iterator first2 = rhs.begin();
62 typename Lhs::const_iterator last1 = lhs.end();
63 typename Rhs::const_iterator last2 = rhs.end();
64 std::size_t pos = 0;
65
66 for( ; (first1 != last1) && (first2 != last2); ++first1, ++first2, ++pos ) {
67 assertion_result const& element_ar = OP::eval(*first1, *first2);
68 if( !can_be_equal && element_ar )
69 return ar; // a < b
70
71 assertion_result const& reverse_ar = OP::eval(*first2, *first1);
72 if( element_ar && !reverse_ar )
73 return ar; // a<=b and !(b<=a) => a < b => return true
74
75 if( element_ar || !reverse_ar )
76 continue; // (a<=b and b<=a) or (!(a<b) and !(b<a)) => a == b => keep looking
77
78 // !(a<=b) and b<=a => b < a => return false
79 ar = false;
80 ar.message() << "\nFailure at position " << pos << ": "
81 << tt_detail::print_helper(*first1)
82 << OP::revert()
83 << tt_detail::print_helper(*first2)
84 << ". " << element_ar.message();
85 return ar;
86 }
87
88
89 if( first1 != last1 ) {
90 if( prefer_shorter ) {
91 ar = false;
92 ar.message() << "\nFirst collection has extra trailing elements.";
93 }
94 }
95 else if( first2 != last2 ) {
96 if( !prefer_shorter ) {
97 ar = false;
98 ar.message() << "\nSecond collection has extra trailing elements.";
99 }
100 }
101 else if( !can_be_equal ) {
102 ar = false;
103 ar.message() << "\nCollections appear to be equal.";
104 }
105
106 return ar;
107 }
108
109 //____________________________________________________________________________//
110
111 // ************************************************************************** //
112 // ************** equality_compare ************** //
113 // ************************************************************************** //
114
115 template <typename OP, typename Lhs, typename Rhs>
116 inline assertion_result
117 element_compare( Lhs const& lhs, Rhs const& rhs )
118 {
119 assertion_result ar( true );
120
121 if( lhs.size() != rhs.size() ) {
122 ar = false;
123 ar.message() << "\nCollections size mismatch: " << lhs.size() << " != " << rhs.size();
124 return ar;
125 }
126
127 typename Lhs::const_iterator left = lhs.begin();
128 typename Rhs::const_iterator right = rhs.begin();
129 std::size_t pos = 0;
130
131 for( ; pos < lhs.size(); ++left, ++right, ++pos ) {
132 assertion_result const element_ar = OP::eval( *left, *right );
133 if( element_ar )
134 continue;
135
136 ar = false;
137 ar.message() << "\nMismatch at position " << pos << ": "
138 << tt_detail::print_helper(*left)
139 << OP::revert()
140 << tt_detail::print_helper(*right)
141 << ". " << element_ar.message();
142 }
143
144 return ar;
145 }
146
147 //____________________________________________________________________________//
148
149 // ************************************************************************** //
150 // ************** non_equality_compare ************** //
151 // ************************************************************************** //
152
153 template <typename OP, typename Lhs, typename Rhs>
154 inline assertion_result
155 non_equality_compare( Lhs const& lhs, Rhs const& rhs )
156 {
157 assertion_result ar( true );
158
159 if( lhs.size() != rhs.size() )
160 return ar;
161
162 typename Lhs::const_iterator left = lhs.begin();
163 typename Rhs::const_iterator right = rhs.begin();
164 typename Lhs::const_iterator end = lhs.end();
165
166 for( ; left != end; ++left, ++right ) {
167 if( OP::eval( *left, *right ) )
168 return ar;
169 }
170
171 ar = false;
172 ar.message() << "\nCollections appear to be equal";
173
174 return ar;
175 }
176
177 //____________________________________________________________________________//
178
179 // ************************************************************************** //
180 // ************** cctraits ************** //
181 // ************************************************************************** //
182 // set of collection comparison traits per comparison OP
183
184 template<typename OP>
185 struct cctraits;
186
187 template<typename Lhs, typename Rhs>
188 struct cctraits<op::EQ<Lhs, Rhs> > {
189 typedef specialized_compare<Lhs> is_specialized;
190 };
191
192 template<typename Lhs, typename Rhs>
193 struct cctraits<op::NE<Lhs, Rhs> > {
194 typedef specialized_compare<Lhs> is_specialized;
195 };
196
197 template<typename Lhs, typename Rhs>
198 struct cctraits<op::LT<Lhs, Rhs> > {
199 static const bool can_be_equal = false;
200 static const bool prefer_short = true;
201
202 typedef specialized_compare<Lhs> is_specialized;
203 };
204
205 template<typename Lhs, typename Rhs>
206 struct cctraits<op::LE<Lhs, Rhs> > {
207 static const bool can_be_equal = true;
208 static const bool prefer_short = true;
209
210 typedef specialized_compare<Lhs> is_specialized;
211 };
212
213 template<typename Lhs, typename Rhs>
214 struct cctraits<op::GT<Lhs, Rhs> > {
215 static const bool can_be_equal = false;
216 static const bool prefer_short = false;
217
218 typedef specialized_compare<Lhs> is_specialized;
219 };
220
221 template<typename Lhs, typename Rhs>
222 struct cctraits<op::GE<Lhs, Rhs> > {
223 static const bool can_be_equal = true;
224 static const bool prefer_short = false;
225
226 typedef specialized_compare<Lhs> is_specialized;
227 };
228
229 // ************************************************************************** //
230 // ************** compare_collections ************** //
231 // ************************************************************************** //
232 // Overloaded set of functions dispatching to specific implementation of comparison
233
234 template <typename Lhs, typename Rhs, typename L, typename R>
235 inline assertion_result
236 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::EQ<L, R> >*, mpl::true_ )
237 {
238 return assertion::op::element_compare<op::EQ<L, R> >( lhs, rhs );
239 }
240
241 //____________________________________________________________________________//
242
243 template <typename Lhs, typename Rhs, typename L, typename R>
244 inline assertion_result
245 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::EQ<L, R> >*, mpl::false_ )
246 {
247 return lhs == rhs;
248 }
249
250 //____________________________________________________________________________//
251
252 template <typename Lhs, typename Rhs, typename L, typename R>
253 inline assertion_result
254 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::NE<L, R> >*, mpl::true_ )
255 {
256 return assertion::op::non_equality_compare<op::NE<L, R> >( lhs, rhs );
257 }
258
259 //____________________________________________________________________________//
260
261 template <typename Lhs, typename Rhs, typename L, typename R>
262 inline assertion_result
263 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::NE<L, R> >*, mpl::false_ )
264 {
265 return lhs != rhs;
266 }
267
268 //____________________________________________________________________________//
269
270 template <typename OP, typename Lhs, typename Rhs>
271 inline assertion_result
272 lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
273 {
274 return assertion::op::lexicographic_compare<OP, cctraits<OP>::can_be_equal, cctraits<OP>::prefer_short>( lhs, rhs );
275 }
276
277 //____________________________________________________________________________//
278
279 template <typename Lhs, typename Rhs, typename OP>
280 inline assertion_result
281 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<OP>*, mpl::true_ )
282 {
283 return lexicographic_compare<OP>( lhs, rhs );
284 }
285
286 //____________________________________________________________________________//
287
288 template <typename Lhs, typename Rhs, typename L, typename R>
289 inline assertion_result
290 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LT<L, R> >*, mpl::false_ )
291 {
292 return lhs < rhs;
293 }
294
295 //____________________________________________________________________________//
296
297 template <typename Lhs, typename Rhs, typename L, typename R>
298 inline assertion_result
299 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LE<L, R> >*, mpl::false_ )
300 {
301 return lhs <= rhs;
302 }
303
304 //____________________________________________________________________________//
305
306 template <typename Lhs, typename Rhs, typename L, typename R>
307 inline assertion_result
308 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GT<L, R> >*, mpl::false_ )
309 {
310 return lhs > rhs;
311 }
312
313 //____________________________________________________________________________//
314
315 template <typename Lhs, typename Rhs, typename L, typename R>
316 inline assertion_result
317 compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >*, mpl::false_ )
318 {
319 return lhs >= rhs;
320 }
321
322 //____________________________________________________________________________//
323
324 // ************************************************************************** //
325 // ********* specialization of comparison operators for collections ********* //
326 // ************************************************************************** //
327
328 #define DEFINE_COLLECTION_COMPARISON( oper, name, rev ) \
329 template<typename Lhs,typename Rhs> \
330 struct name<Lhs,Rhs,typename boost::enable_if_c< \
331 unit_test::is_forward_iterable<Lhs>::value && \
332 unit_test::is_forward_iterable<Rhs>::value>::type> { \
333 public: \
334 typedef assertion_result result_type; \
335 \
336 typedef name<Lhs, Rhs> OP; \
337 typedef typename \
338 mpl::if_c<is_same<typename decay<Lhs>::type, \
339 typename decay<Rhs>::type>::value, \
340 typename cctraits<OP>::is_specialized, \
341 mpl::false_>::type is_specialized; \
342 \
343 typedef name<typename Lhs::value_type, \
344 typename Rhs::value_type> elem_op; \
345 \
346 static assertion_result \
347 eval( Lhs const& lhs, Rhs const& rhs) \
348 { \
349 return assertion::op::compare_collections( lhs, rhs, \
350 (boost::type<elem_op>*)0, \
351 is_specialized() ); \
352 } \
353 \
354 template<typename PrevExprType> \
355 static void \
356 report( std::ostream&, \
357 PrevExprType const&, \
358 Rhs const& ) {} \
359 \
360 static char const* revert() \
361 { return " " #rev " "; } \
362 \
363 }; \
364 /**/
365
366 BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_COLLECTION_COMPARISON )
367 #undef DEFINE_COLLECTION_COMPARISON
368
369 //____________________________________________________________________________//
370
371 } // namespace op
372 } // namespace assertion
373 } // namespace test_tools
374 } // namespace boost
375
376 #include <boost/test/detail/enable_warnings.hpp>
377
378 #endif // BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER