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)
6 #ifndef BOOST_MP_COMPARE_HPP
7 #define BOOST_MP_COMPARE_HPP
9 #include <boost/multiprecision/traits/is_backend.hpp>
12 // Comparison operators for number.
15 namespace boost{ namespace multiprecision{
17 namespace default_ops{
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.
25 inline bool eval_eq(const B& a, const B& b)
27 return a.compare(b) == 0;
29 template <class T, class U>
30 inline bool eval_eq_imp(const T& a, const U& b, const mpl::true_&)
32 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
33 return eval_eq(a, t.backend());
35 template <class T, class U>
36 inline bool eval_eq_imp(const T& a, const U& b, const mpl::false_&)
38 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
39 return eval_eq(t.backend(), b);
41 template <class T, class U>
42 inline bool eval_eq(const T& a, const U& b)
44 typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
45 return eval_eq_imp(a, b, tag_type());
49 inline bool eval_lt(const B& a, const B& b)
51 return a.compare(b) < 0;
53 template <class T, class U>
54 inline bool eval_lt_imp(const T& a, const U& b, const mpl::true_&)
56 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
57 return eval_lt(a, t.backend());
59 template <class T, class U>
60 inline bool eval_lt_imp(const T& a, const U& b, const mpl::false_&)
62 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
63 return eval_lt(t.backend(), b);
65 template <class T, class U>
66 inline bool eval_lt(const T& a, const U& b)
68 typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
69 return eval_lt_imp(a, b, tag_type());
73 inline bool eval_gt(const B& a, const B& b)
75 return a.compare(b) > 0;
77 template <class T, class U>
78 inline bool eval_gt_imp(const T& a, const U& b, const mpl::true_&)
80 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
81 return eval_gt(a, t.backend());
83 template <class T, class U>
84 inline bool eval_gt_imp(const T& a, const U& b, const mpl::false_&)
86 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
87 return eval_gt(t.backend(), b);
89 template <class T, class U>
90 inline bool eval_gt(const T& a, const U& b)
92 typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
93 return eval_gt_imp(a, b, tag_type());
96 } // namespace default_ops
100 template <class Num, class Val>
101 struct is_valid_mixed_compare : public mpl::false_ {};
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> > {};
106 template <class B, expression_template_option ET>
107 struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public mpl::false_ {};
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> {};
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> {};
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>&)
122 template <class Backend, expression_template_option ExpressionTemplates>
124 #if !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
127 typename boost::enable_if_c<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a)
129 using default_ops::eval_fpclassify;
130 return eval_fpclassify(a.backend()) == FP_NAN;
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&)
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)
141 return (boost::math::isnan)(a);
144 template <class T, class U>
145 inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b)
147 return is_unordered_value(a) || is_unordered_value(b);
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)
155 using default_ops::eval_eq;
156 if(detail::is_unordered_comparison(a, b)) return false;
157 return eval_eq(a.backend(), b.backend());
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)
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));
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)
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));
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)
179 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
180 using default_ops::eval_eq;
182 if(detail::is_unordered_comparison(a, t)) return false;
183 return eval_eq(t.backend(), result_type::canonical_value(a));
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)
189 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
190 using default_ops::eval_eq;
192 if(detail::is_unordered_comparison(t, b)) return false;
193 return eval_eq(t.backend(), result_type::canonical_value(b));
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)
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());
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)
209 using default_ops::eval_eq;
210 if(detail::is_unordered_comparison(a, b)) return true;
211 return !eval_eq(a.backend(), b.backend());
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)
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));
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)
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));
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)
233 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
234 using default_ops::eval_eq;
236 if(detail::is_unordered_comparison(a, t)) return true;
237 return !eval_eq(t.backend(), result_type::canonical_value(a));
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)
243 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
244 using default_ops::eval_eq;
246 if(detail::is_unordered_comparison(t, b)) return true;
247 return !eval_eq(t.backend(), result_type::canonical_value(b));
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)
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());
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)
263 using default_ops::eval_lt;
264 if(detail::is_unordered_comparison(a, b)) return false;
265 return eval_lt(a.backend(), b.backend());
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)
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));
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)
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));
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)
287 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
288 using default_ops::eval_gt;
290 if(detail::is_unordered_comparison(a, t)) return false;
291 return eval_gt(t.backend(), result_type::canonical_value(a));
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)
297 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
298 using default_ops::eval_lt;
300 if(detail::is_unordered_comparison(t, b)) return false;
301 return eval_lt(t.backend(), result_type::canonical_value(b));
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)
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());
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)
317 using default_ops::eval_gt;
318 if(detail::is_unordered_comparison(a, b)) return false;
319 return eval_gt(a.backend(), b.backend());
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)
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));
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)
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));
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)
341 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
342 using default_ops::eval_lt;
344 if(detail::is_unordered_comparison(a, t)) return false;
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)
351 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
352 using default_ops::eval_gt;
354 if(detail::is_unordered_comparison(t, b)) return false;
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)
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;
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)
371 using default_ops::eval_gt;
372 if(detail::is_unordered_comparison(a, b)) return false;
373 return !eval_gt(a.backend(), b.backend());
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)
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));
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)
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));
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)
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))
400 if(detail::is_unordered_comparison(a, t)) return false;
401 return !eval_lt(t.backend(), result_type::canonical_value(a));
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)
407 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
408 using default_ops::eval_gt;
410 if(detail::is_unordered_comparison(t, b)) return false;
411 return !eval_gt(t.backend(), result_type::canonical_value(b));
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)
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());
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)
427 using default_ops::eval_lt;
428 if(detail::is_unordered_comparison(a, b)) return false;
429 return !eval_lt(a.backend(), b.backend());
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)
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));
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)
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));
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)
451 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
452 using default_ops::eval_gt;
454 if(detail::is_unordered_comparison(a, t)) return false;
455 return !eval_gt(t.backend(), result_type::canonical_value(a));
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)
461 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
462 using default_ops::eval_lt;
464 if(detail::is_unordered_comparison(t, b)) return false;
465 return !eval_lt(t.backend(), result_type::canonical_value(b));
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)
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());
479 // C99 comparison macros as functions:
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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)
576 if(detail::is_unordered_comparison(a, b)) return false;
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)
584 if(detail::is_unordered_comparison(a, b)) return false;
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)
592 if(detail::is_unordered_comparison(a, b)) return false;
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)
600 typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb);
601 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
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)
608 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
609 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
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)
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);
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); }
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); }
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); }
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)
636 typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb);
637 return detail::is_unordered_comparison(a, b);
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)
644 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
645 return detail::is_unordered_comparison(a, b);
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)
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);
659 #endif // BOOST_MP_COMPARE_HPP