]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multiprecision/include/boost/multiprecision/detail/number_compare.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / multiprecision / include / boost / multiprecision / detail / number_compare.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright 2012 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_MP_COMPARE_HPP
7 #define BOOST_MP_COMPARE_HPP
8
9 #include <boost/multiprecision/traits/is_backend.hpp>
10
11 //
12 // Comparison operators for number.
13 //
14
15 namespace boost{ namespace multiprecision{
16
17 namespace default_ops{
18
19 //
20 // The dispatching mechanism used here to deal with differently typed arguments
21 // could be better replaced with enable_if overloads, but that breaks MSVC-12
22 // under strange and hard to reproduce circumstances.
23 //
24 template <class B>
25 inline bool eval_eq(const B& a, const B& b)
26 {
27 return a.compare(b) == 0;
28 }
29 template <class T, class U>
30 inline bool eval_eq_imp(const T& a, const U& b, const mpl::true_&)
31 {
32 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
33 return eval_eq(a, t.backend());
34 }
35 template <class T, class U>
36 inline bool eval_eq_imp(const T& a, const U& b, const mpl::false_&)
37 {
38 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
39 return eval_eq(t.backend(), b);
40 }
41 template <class T, class U>
42 inline bool eval_eq(const T& a, const U& b)
43 {
44 typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
45 return eval_eq_imp(a, b, tag_type());
46 }
47
48 template <class B>
49 inline bool eval_lt(const B& a, const B& b)
50 {
51 return a.compare(b) < 0;
52 }
53 template <class T, class U>
54 inline bool eval_lt_imp(const T& a, const U& b, const mpl::true_&)
55 {
56 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
57 return eval_lt(a, t.backend());
58 }
59 template <class T, class U>
60 inline bool eval_lt_imp(const T& a, const U& b, const mpl::false_&)
61 {
62 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
63 return eval_lt(t.backend(), b);
64 }
65 template <class T, class U>
66 inline bool eval_lt(const T& a, const U& b)
67 {
68 typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
69 return eval_lt_imp(a, b, tag_type());
70 }
71
72 template <class B>
73 inline bool eval_gt(const B& a, const B& b)
74 {
75 return a.compare(b) > 0;
76 }
77 template <class T, class U>
78 inline bool eval_gt_imp(const T& a, const U& b, const mpl::true_&)
79 {
80 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
81 return eval_gt(a, t.backend());
82 }
83 template <class T, class U>
84 inline bool eval_gt_imp(const T& a, const U& b, const mpl::false_&)
85 {
86 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
87 return eval_gt(t.backend(), b);
88 }
89 template <class T, class U>
90 inline bool eval_gt(const T& a, const U& b)
91 {
92 typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
93 return eval_gt_imp(a, b, tag_type());
94 }
95
96 } // namespace default_ops
97
98 namespace detail{
99
100 template <class Num, class Val>
101 struct is_valid_mixed_compare : public mpl::false_ {};
102
103 template <class B, expression_template_option ET, class Val>
104 struct is_valid_mixed_compare<number<B, ET>, Val> : public is_convertible<Val, number<B, ET> > {};
105
106 template <class B, expression_template_option ET>
107 struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public mpl::false_ {};
108
109 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
110 struct is_valid_mixed_compare<number<B, ET>, expression<tag, Arg1, Arg2, Arg3, Arg4> >
111 : public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {};
112
113 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
114 struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
115 : public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {};
116
117 template <class Backend, expression_template_option ExpressionTemplates>
118 inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value != number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>&)
119 {
120 return false;
121 }
122 template <class Backend, expression_template_option ExpressionTemplates>
123 inline
124 #if !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
125 BOOST_CONSTEXPR
126 #endif
127 typename boost::enable_if_c<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a)
128 {
129 using default_ops::eval_fpclassify;
130 return eval_fpclassify(a.backend()) == FP_NAN;
131 }
132
133 template <class Arithmetic>
134 inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&)
135 {
136 return false;
137 }
138 template <class Arithmetic>
139 inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value == number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic& a)
140 {
141 return (boost::math::isnan)(a);
142 }
143
144 template <class T, class U>
145 inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b)
146 {
147 return is_unordered_value(a) || is_unordered_value(b);
148 }
149
150 }
151
152 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
153 inline bool operator == (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
154 {
155 using default_ops::eval_eq;
156 if(detail::is_unordered_comparison(a, b)) return false;
157 return eval_eq(a.backend(), b.backend());
158 }
159 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
160 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
161 operator == (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
162 {
163 using default_ops::eval_eq;
164 if(detail::is_unordered_comparison(a, b)) return false;
165 return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
166 }
167 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
168 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
169 operator == (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
170 {
171 using default_ops::eval_eq;
172 if(detail::is_unordered_comparison(a, b)) return false;
173 return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
174 }
175 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
176 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
177 operator == (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
178 {
179 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
180 using default_ops::eval_eq;
181 result_type t(b);
182 if(detail::is_unordered_comparison(a, t)) return false;
183 return eval_eq(t.backend(), result_type::canonical_value(a));
184 }
185 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
186 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
187 operator == (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
188 {
189 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
190 using default_ops::eval_eq;
191 result_type t(a);
192 if(detail::is_unordered_comparison(t, b)) return false;
193 return eval_eq(t.backend(), result_type::canonical_value(b));
194 }
195 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
196 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
197 operator == (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
198 {
199 using default_ops::eval_eq;
200 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
201 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
202 if(detail::is_unordered_comparison(t, t2)) return false;
203 return eval_eq(t.backend(), t2.backend());
204 }
205
206 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
207 inline bool operator != (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
208 {
209 using default_ops::eval_eq;
210 if(detail::is_unordered_comparison(a, b)) return true;
211 return !eval_eq(a.backend(), b.backend());
212 }
213 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
214 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
215 operator != (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
216 {
217 using default_ops::eval_eq;
218 if(detail::is_unordered_comparison(a, b)) return true;
219 return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b));
220 }
221 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
222 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
223 operator != (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
224 {
225 using default_ops::eval_eq;
226 if(detail::is_unordered_comparison(a, b)) return true;
227 return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a));
228 }
229 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
230 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
231 operator != (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
232 {
233 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
234 using default_ops::eval_eq;
235 result_type t(b);
236 if(detail::is_unordered_comparison(a, t)) return true;
237 return !eval_eq(t.backend(), result_type::canonical_value(a));
238 }
239 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
240 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
241 operator != (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
242 {
243 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
244 using default_ops::eval_eq;
245 result_type t(a);
246 if(detail::is_unordered_comparison(t, b)) return true;
247 return !eval_eq(t.backend(), result_type::canonical_value(b));
248 }
249 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
250 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
251 operator != (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
252 {
253 using default_ops::eval_eq;
254 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
255 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
256 if(detail::is_unordered_comparison(t, t2)) return true;
257 return !eval_eq(t.backend(), t2.backend());
258 }
259
260 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
261 inline bool operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
262 {
263 using default_ops::eval_lt;
264 if(detail::is_unordered_comparison(a, b)) return false;
265 return eval_lt(a.backend(), b.backend());
266 }
267 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
268 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
269 operator < (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
270 {
271 using default_ops::eval_lt;
272 if(detail::is_unordered_comparison(a, b)) return false;
273 return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
274 }
275 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
276 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
277 operator < (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
278 {
279 using default_ops::eval_gt;
280 if(detail::is_unordered_comparison(a, b)) return false;
281 return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
282 }
283 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
284 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
285 operator < (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
286 {
287 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
288 using default_ops::eval_gt;
289 result_type t(b);
290 if(detail::is_unordered_comparison(a, t)) return false;
291 return eval_gt(t.backend(), result_type::canonical_value(a));
292 }
293 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
294 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
295 operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
296 {
297 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
298 using default_ops::eval_lt;
299 result_type t(a);
300 if(detail::is_unordered_comparison(t, b)) return false;
301 return eval_lt(t.backend(), result_type::canonical_value(b));
302 }
303 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
304 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
305 operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
306 {
307 using default_ops::eval_lt;
308 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
309 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
310 if(detail::is_unordered_comparison(t, t2)) return false;
311 return eval_lt(t.backend(), t2.backend());
312 }
313
314 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
315 inline bool operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
316 {
317 using default_ops::eval_gt;
318 if(detail::is_unordered_comparison(a, b)) return false;
319 return eval_gt(a.backend(), b.backend());
320 }
321 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
322 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
323 operator > (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
324 {
325 using default_ops::eval_gt;
326 if(detail::is_unordered_comparison(a, b)) return false;
327 return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
328 }
329 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
330 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
331 operator > (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
332 {
333 using default_ops::eval_lt;
334 if(detail::is_unordered_comparison(a, b)) return false;
335 return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
336 }
337 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
338 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
339 operator > (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
340 {
341 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
342 using default_ops::eval_lt;
343 result_type t(b);
344 if(detail::is_unordered_comparison(a, t)) return false;
345 return a > t;
346 }
347 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
348 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
349 operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
350 {
351 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
352 using default_ops::eval_gt;
353 result_type t(a);
354 if(detail::is_unordered_comparison(t, b)) return false;
355 return t > b;
356 }
357 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
358 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
359 operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
360 {
361 using default_ops::eval_gt;
362 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
363 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
364 if(detail::is_unordered_comparison(t, t2)) return false;
365 return t > t2;
366 }
367
368 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
369 inline bool operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
370 {
371 using default_ops::eval_gt;
372 if(detail::is_unordered_comparison(a, b)) return false;
373 return !eval_gt(a.backend(), b.backend());
374 }
375 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
376 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
377 operator <= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
378 {
379 using default_ops::eval_gt;
380 if(detail::is_unordered_comparison(a, b)) return false;
381 return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
382 }
383 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
384 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
385 operator <= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
386 {
387 using default_ops::eval_lt;
388 if(detail::is_unordered_comparison(a, b)) return false;
389 return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
390 }
391 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
392 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
393 operator <= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
394 {
395 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
396 using default_ops::eval_lt;
397 if(detail::is_unordered_value(a) || detail::is_unordered_value(b))
398 return false;
399 result_type t(b);
400 if(detail::is_unordered_comparison(a, t)) return false;
401 return !eval_lt(t.backend(), result_type::canonical_value(a));
402 }
403 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
404 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
405 operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
406 {
407 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
408 using default_ops::eval_gt;
409 result_type t(a);
410 if(detail::is_unordered_comparison(t, b)) return false;
411 return !eval_gt(t.backend(), result_type::canonical_value(b));
412 }
413 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
414 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
415 operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
416 {
417 using default_ops::eval_gt;
418 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
419 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
420 if(detail::is_unordered_comparison(t, t2)) return false;
421 return !eval_gt(t.backend(), t2.backend());
422 }
423
424 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
425 inline bool operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
426 {
427 using default_ops::eval_lt;
428 if(detail::is_unordered_comparison(a, b)) return false;
429 return !eval_lt(a.backend(), b.backend());
430 }
431 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
432 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
433 operator >= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
434 {
435 using default_ops::eval_lt;
436 if(detail::is_unordered_comparison(a, b)) return false;
437 return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
438 }
439 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
440 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
441 operator >= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
442 {
443 using default_ops::eval_gt;
444 if(detail::is_unordered_comparison(a, b)) return false;
445 return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
446 }
447 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
448 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
449 operator >= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
450 {
451 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
452 using default_ops::eval_gt;
453 result_type t(b);
454 if(detail::is_unordered_comparison(a, t)) return false;
455 return !eval_gt(t.backend(), result_type::canonical_value(a));
456 }
457 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
458 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
459 operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
460 {
461 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
462 using default_ops::eval_lt;
463 result_type t(a);
464 if(detail::is_unordered_comparison(t, b)) return false;
465 return !eval_lt(t.backend(), result_type::canonical_value(b));
466 }
467 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
468 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
469 operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
470 {
471 using default_ops::eval_lt;
472 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
473 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
474 if(detail::is_unordered_comparison(t, t2)) return false;
475 return !eval_lt(t.backend(), t2.backend());
476 }
477
478 //
479 // C99 comparison macros as functions:
480 //
481 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
482 inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a > b; }
483
484 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
485 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
486 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a > b; }
487
488 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
489 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
490 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a > b; }
491
492 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
493 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
494 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a > b; }
495
496 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
497 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
498 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a > b; }
499
500 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
501 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
502 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a > b; }
503
504 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
505 inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a >= b; }
506
507 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
508 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
509 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a >= b; }
510
511 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
512 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
513 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a >= b; }
514
515 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
516 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
517 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a >= b; }
518
519 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
520 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
521 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a >= b; }
522
523 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
524 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
525 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a >= b; }
526
527 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
528 inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a <= b; }
529
530 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
531 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
532 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a <= b; }
533
534 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
535 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
536 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a <= b; }
537
538 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
539 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
540 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a <= b; }
541
542 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
543 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
544 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a <= b; }
545
546 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
547 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
548 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a <= b; }
549
550 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
551 inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a < b; }
552
553 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
554 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
555 isless BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a < b; }
556
557 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
558 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
559 isless BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a < b; }
560
561 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
562 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
563 isless BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a < b; }
564
565 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
566 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
567 isless BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a < b; }
568
569 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
570 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
571 isless BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a < b; }
572
573 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
574 inline bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
575 {
576 if(detail::is_unordered_comparison(a, b)) return false;
577 return a != b;
578 }
579
580 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
581 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
582 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
583 {
584 if(detail::is_unordered_comparison(a, b)) return false;
585 return a != b;
586 }
587
588 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
589 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
590 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
591 {
592 if(detail::is_unordered_comparison(a, b)) return false;
593 return a != b;
594 }
595
596 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
597 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
598 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& bb)
599 {
600 typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb);
601 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
602 }
603
604 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
605 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
606 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const Arithmetic& b)
607 {
608 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
609 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
610 }
611
612 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
613 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
614 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& bb)
615 {
616 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
617 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type b(bb);
618 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
619 }
620
621 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
622 inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return detail::is_unordered_comparison(a, b); }
623
624 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
625 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
626 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return detail::is_unordered_comparison(a, b); }
627
628 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
629 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
630 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return detail::is_unordered_comparison(a, b); }
631
632 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
633 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
634 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& bb)
635 {
636 typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb);
637 return detail::is_unordered_comparison(a, b);
638 }
639
640 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
641 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
642 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const Arithmetic& b)
643 {
644 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
645 return detail::is_unordered_comparison(a, b);
646 }
647
648 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
649 inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
650 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& bb)
651 {
652 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
653 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type b(bb);
654 return detail::is_unordered_comparison(a, b);
655 }
656
657 }} // namespaces
658
659 #endif // BOOST_MP_COMPARE_HPP
660