]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/include/boost/multiprecision/detail/number_compare.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / multiprecision / include / boost / multiprecision / detail / number_compare.hpp
CommitLineData
7c673cae
FG
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
15namespace boost{ namespace multiprecision{
16
17namespace 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//
24template <class B>
25inline bool eval_eq(const B& a, const B& b)
26{
27 return a.compare(b) == 0;
28}
29template <class T, class U>
30inline 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}
35template <class T, class U>
36inline 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}
41template <class T, class U>
42inline 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
48template <class B>
49inline bool eval_lt(const B& a, const B& b)
50{
51 return a.compare(b) < 0;
52}
53template <class T, class U>
54inline 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}
59template <class T, class U>
60inline 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}
65template <class T, class U>
66inline 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
72template <class B>
73inline bool eval_gt(const B& a, const B& b)
74{
75 return a.compare(b) > 0;
76}
77template <class T, class U>
78inline 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}
83template <class T, class U>
84inline 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}
89template <class T, class U>
90inline 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
98namespace detail{
99
100template <class Num, class Val>
101struct is_valid_mixed_compare : public mpl::false_ {};
102
103template <class B, expression_template_option ET, class Val>
104struct is_valid_mixed_compare<number<B, ET>, Val> : public is_convertible<Val, number<B, ET> > {};
105
106template <class B, expression_template_option ET>
107struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public mpl::false_ {};
108
109template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
110struct 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
113template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
114struct 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
117template <class Backend, expression_template_option ExpressionTemplates>
118inline 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}
122template <class Backend, expression_template_option ExpressionTemplates>
123inline
124#if !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
125BOOST_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
133template <class Arithmetic>
134inline 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}
138template <class Arithmetic>
139inline 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
144template <class T, class U>
145inline 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
152template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
153inline 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}
159template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
160inline 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}
167template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
168inline 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}
175template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
176inline 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}
185template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
186inline 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}
195template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
196inline 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
206template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
207inline 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}
213template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
214inline 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}
221template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
222inline 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}
229template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
230inline 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}
239template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
240inline 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}
249template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
250inline 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
260template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
261inline 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}
267template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
268inline 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}
275template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
276inline 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}
283template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
284inline 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}
293template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
294inline 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}
303template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
304inline 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
314template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
315inline 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}
321template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
322inline 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}
329template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
330inline 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}
337template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
338inline 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}
347template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
348inline 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}
357template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
358inline 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
368template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
369inline 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}
375template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
376inline 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}
383template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
384inline 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}
391template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
392inline 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}
403template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
404inline 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}
413template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
414inline 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
424template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
425inline 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}
431template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
432inline 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}
439template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
440inline 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}
447template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
448inline 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}
457template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
458inline 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}
467template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
468inline 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//
481template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
482inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a > b; }
483
484template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
485inline 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
488template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
489inline 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
492template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
493inline 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
496template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
497inline 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
500template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
501inline 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
504template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
505inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a >= b; }
506
507template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
508inline 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
511template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
512inline 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
515template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
516inline 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
519template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
520inline 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
523template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
524inline 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
527template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
528inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a <= b; }
529
530template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
531inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
532islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a <= b; }
533
534template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
535inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
536islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a <= b; }
537
538template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
539inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
540islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a <= b; }
541
542template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
543inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
544islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a <= b; }
545
546template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
547inline 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
548islessequal 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
550template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
551inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a < b; }
552
553template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
554inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
555isless BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a < b; }
556
557template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
558inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
559isless BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a < b; }
560
561template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
562inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
563isless BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a < b; }
564
565template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
566inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
567isless BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a < b; }
568
569template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
570inline 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
571isless 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
573template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
574inline 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
580template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
581inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
582islessgreater 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
588template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
589inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
590islessgreater 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
596template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
597inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
598islessgreater 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
604template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
605inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
606islessgreater 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
612template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
613inline 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
614islessgreater 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
621template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
622inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return detail::is_unordered_comparison(a, b); }
623
624template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
625inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
626isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return detail::is_unordered_comparison(a, b); }
627
628template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
629inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
630isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return detail::is_unordered_comparison(a, b); }
631
632template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
633inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
634isunordered 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
640template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
641inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
642isunordered 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
648template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
649inline 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
650isunordered 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