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_NUMBER_COMPARE_HPP
7#define BOOST_MP_NUMBER_COMPARE_HPP
8
9#include <boost/multiprecision/traits/is_backend.hpp>
10#include <boost/multiprecision/detail/fpclassify.hpp>
11
12//
13// Comparison operators for number.
14//
15
16namespace boost { namespace multiprecision {
17
18namespace default_ops {
19
20//
21// The dispatching mechanism used here to deal with differently typed arguments
22// could be better replaced with enable_if overloads, but that breaks MSVC-12
23// under strange and hard to reproduce circumstances.
24//
25template <class B>
26inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq(const B& a, const B& b)
27{
28 return a.compare(b) == 0;
29}
30template <class T, class U>
31inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq_imp(const T& a, const U& b, const std::integral_constant<bool, true>&)
32{
33 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
34 return eval_eq(a, t.backend());
35}
36template <class T, class U>
37inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq_imp(const T& a, const U& b, const std::integral_constant<bool, false>&)
38{
39 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
40 return eval_eq(t.backend(), b);
41}
42template <class T, class U>
43inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq(const T& a, const U& b)
44{
45 using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_first_backend<T, U>::value>;
46 return eval_eq_imp(a, b, tag_type());
47}
48
49template <class B>
50inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const B& a, const B& b)
51{
52 return a.compare(b) < 0;
53}
54template <class T, class U>
55inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt_imp(const T& a, const U& b, const std::integral_constant<bool, true>&)
56{
57 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
58 return eval_lt(a, t.backend());
59}
60template <class T, class U>
61inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt_imp(const T& a, const U& b, const std::integral_constant<bool, false>&)
62{
63 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
64 return eval_lt(t.backend(), b);
65}
66template <class T, class U>
67inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const T& a, const U& b)
68{
69 using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_first_backend<T, U>::value>;
70 return eval_lt_imp(a, b, tag_type());
71}
72
73template <class B>
74inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const B& a, const B& b)
75{
76 return a.compare(b) > 0;
77}
78template <class T, class U>
79inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt_imp(const T& a, const U& b, const std::integral_constant<bool, true>&)
80{
81 typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
82 return eval_gt(a, t.backend());
83}
84template <class T, class U>
85inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt_imp(const T& a, const U& b, const std::integral_constant<bool, false>&)
86{
87 typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
88 return eval_gt(t.backend(), b);
89}
90template <class T, class U>
91inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const T& a, const U& b)
92{
93 using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_first_backend<T, U>::value>;
94 return eval_gt_imp(a, b, tag_type());
95}
96
97} // namespace default_ops
98
99namespace detail {
100
101template <class Num, class Val>
102struct is_valid_mixed_compare : public std::integral_constant<bool, false>
103{};
104
105template <class B, expression_template_option ET, class Val>
106struct is_valid_mixed_compare<number<B, ET>, Val> : public std::is_convertible<Val, number<B, ET> >
107{};
108
109template <class B, expression_template_option ET>
110struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public std::integral_constant<bool, false>
111{};
112
113template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
114struct is_valid_mixed_compare<number<B, ET>, expression<tag, Arg1, Arg2, Arg3, Arg4> >
115 : public std::is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
116{};
117
118template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
119struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
120 : public std::is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
121{};
122
123template <class Backend, expression_template_option ExpressionTemplates>
124inline constexpr typename std::enable_if<number_category<Backend>::value != number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>&)
125{
126 return false;
127}
128template <class Backend, expression_template_option ExpressionTemplates>
129inline constexpr typename std::enable_if<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a)
130{
131 using default_ops::eval_fpclassify;
132 return eval_fpclassify(a.backend()) == FP_NAN;
133}
134
135template <class Arithmetic>
136inline constexpr typename std::enable_if<number_category<Arithmetic>::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&)
137{
138 return false;
139}
140template <class Arithmetic>
141inline
142#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
143 BOOST_MP_CXX14_CONSTEXPR
144#endif
145 typename std::enable_if < number_category < Arithmetic> ::value == number_kind_floating_point, bool> ::type
146 is_unordered_value(const Arithmetic& a)
147{
148#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
149 if (BOOST_MP_IS_CONST_EVALUATED(a))
150 {
151 return a != a;
152 }
153 else
154#endif
155 {
156 return BOOST_MP_ISNAN(a);
157 }
158}
159
160template <class T, class U>
161inline constexpr bool is_unordered_comparison(const T& a, const U& b)
162{
163 return is_unordered_value(a) || is_unordered_value(b);
164}
165
166} // namespace detail
167
168template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
169inline BOOST_MP_CXX14_CONSTEXPR bool operator==(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
170{
171 using default_ops::eval_eq;
172 if (detail::is_unordered_comparison(a, b))
173 return false;
174 return eval_eq(a.backend(), b.backend());
175}
176template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
177inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type
178operator==(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
179{
180 using default_ops::eval_eq;
181 if (detail::is_unordered_comparison(a, b))
182 return false;
183 return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
184}
185template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
186inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type
187operator==(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
188{
189 using default_ops::eval_eq;
190 if (detail::is_unordered_comparison(a, b))
191 return false;
192 return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
193}
194template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
195inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
196operator==(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
197{
198 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
199 using default_ops::eval_eq;
200 result_type t(b);
201 if (detail::is_unordered_comparison(a, t))
202 return false;
203 return eval_eq(t.backend(), result_type::canonical_value(a));
204}
205template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
206inline BOOST_MP_CXX14_CONSTEXPR bool operator==(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
207{
208 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
209 using default_ops::eval_eq;
210 result_type t(b);
211 if (detail::is_unordered_comparison(a, t))
212 return false;
213 return eval_eq(t.backend(), a.backend());
214}
215template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
216inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
217operator==(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
218{
219 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
220 using default_ops::eval_eq;
221 result_type t(a);
222 if (detail::is_unordered_comparison(t, b))
223 return false;
224 return eval_eq(t.backend(), result_type::canonical_value(b));
225}
226template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates>
227inline BOOST_MP_CXX14_CONSTEXPR bool operator==(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b)
228{
229 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
230 using default_ops::eval_eq;
231 result_type t(a);
232 if (detail::is_unordered_comparison(t, b))
233 return false;
234 return eval_eq(t.backend(), b.backend());
235}
236template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
237inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
238operator==(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
239{
240 using default_ops::eval_eq;
241 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
242 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
243 if (detail::is_unordered_comparison(t, t2))
244 return false;
245 return eval_eq(t.backend(), t2.backend());
246}
247
248template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
249inline BOOST_MP_CXX14_CONSTEXPR bool operator!=(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
250{
251 using default_ops::eval_eq;
252 if (detail::is_unordered_comparison(a, b))
253 return true;
254 return !eval_eq(a.backend(), b.backend());
255}
256template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
257inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type
258operator!=(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
259{
260 using default_ops::eval_eq;
261 if (detail::is_unordered_comparison(a, b))
262 return true;
263 return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b));
264}
265template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
266inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type
267operator!=(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
268{
269 using default_ops::eval_eq;
270 if (detail::is_unordered_comparison(a, b))
271 return true;
272 return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a));
273}
274template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
275inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
276operator!=(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
277{
278 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
279 using default_ops::eval_eq;
280 result_type t(b);
281 if (detail::is_unordered_comparison(a, t))
282 return true;
283 return !eval_eq(t.backend(), result_type::canonical_value(a));
284}
285template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
286inline BOOST_MP_CXX14_CONSTEXPR bool operator!=(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
287{
288 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
289 using default_ops::eval_eq;
290 result_type t(b);
291 if (detail::is_unordered_comparison(a, t))
292 return true;
293 return !eval_eq(t.backend(), a.backend());
294}
295template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
296inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
297operator!=(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
298{
299 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
300 using default_ops::eval_eq;
301 result_type t(a);
302 if (detail::is_unordered_comparison(t, b))
303 return true;
304 return !eval_eq(t.backend(), result_type::canonical_value(b));
305}
306template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates>
307inline BOOST_MP_CXX14_CONSTEXPR bool operator!=(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b)
308{
309 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
310 using default_ops::eval_eq;
311 result_type t(a);
312 if (detail::is_unordered_comparison(t, b))
313 return true;
314 return !eval_eq(t.backend(), result_type::canonical_value(b));
315}
316template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
317inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
318operator!=(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
319{
320 using default_ops::eval_eq;
321 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
322 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
323 if (detail::is_unordered_comparison(t, t2))
324 return true;
325 return !eval_eq(t.backend(), t2.backend());
326}
327
328template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
329inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
330operator<(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
331{
332 using default_ops::eval_lt;
333 if (detail::is_unordered_comparison(a, b))
334 return false;
335 return eval_lt(a.backend(), b.backend());
336}
337template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
338inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
339operator<(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
340{
341 using default_ops::eval_lt;
342 if (detail::is_unordered_comparison(a, b))
343 return false;
344 return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
345}
346template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
347inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
348operator<(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
349{
350 using default_ops::eval_gt;
351 if (detail::is_unordered_comparison(a, b))
352 return false;
353 return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
354}
355template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
356inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
357operator<(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
358{
359 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
360 using default_ops::eval_gt;
361 result_type t(b);
362 if (detail::is_unordered_comparison(a, t))
363 return false;
364 return eval_gt(t.backend(), result_type::canonical_value(a));
365}
366template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
367inline BOOST_MP_CXX14_CONSTEXPR bool operator<(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
368{
369 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
370 using default_ops::eval_gt;
371 result_type t(b);
372 return a < t;
373}
374template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
375inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
376operator<(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
377{
378 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
379 using default_ops::eval_lt;
380 result_type t(a);
381 if (detail::is_unordered_comparison(t, b))
382 return false;
383 return eval_lt(t.backend(), result_type::canonical_value(b));
384}
385template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates>
386inline BOOST_MP_CXX14_CONSTEXPR bool operator<(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b)
387{
388 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
389 using default_ops::eval_lt;
390 result_type t(a);
391 return t < b;
392}
393template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
394inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
395operator<(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
396{
397 using default_ops::eval_lt;
398 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
399 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
400 if (detail::is_unordered_comparison(t, t2))
401 return false;
402 return eval_lt(t.backend(), t2.backend());
403}
404
405template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
406inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
407operator>(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
408{
409 using default_ops::eval_gt;
410 if (detail::is_unordered_comparison(a, b))
411 return false;
412 return eval_gt(a.backend(), b.backend());
413}
414template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
415inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
416operator>(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
417{
418 using default_ops::eval_gt;
419 if (detail::is_unordered_comparison(a, b))
420 return false;
421 return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
422}
423template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
424inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
425operator>(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
426{
427 using default_ops::eval_lt;
428 if (detail::is_unordered_comparison(a, b))
429 return false;
430 return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
431}
432template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
433inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
434operator>(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
435{
436 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
437 using default_ops::eval_lt;
438 result_type t(b);
439 return a > t;
440}
441template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
442inline BOOST_MP_CXX14_CONSTEXPR bool operator>(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
443{
444 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
445 using default_ops::eval_lt;
446 result_type t(b);
447 return a > t;
448}
449template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
450inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
451operator>(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
452{
453 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
454 using default_ops::eval_gt;
455 result_type t(a);
456 return t > b;
457}
458template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates>
459inline BOOST_MP_CXX14_CONSTEXPR bool operator>(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b)
460{
461 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
462 using default_ops::eval_gt;
463 result_type t(a);
464 return t > b;
465}
466template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
467inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
468operator>(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
469{
470 using default_ops::eval_gt;
471 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
472 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
473 return t > t2;
474}
475
476template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
477inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
478operator<=(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
479{
480 using default_ops::eval_gt;
481 if (detail::is_unordered_comparison(a, b))
482 return false;
483 return !eval_gt(a.backend(), b.backend());
484}
485template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
486inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
487operator<=(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
488{
489 using default_ops::eval_gt;
490 if (detail::is_unordered_comparison(a, b))
491 return false;
492 return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
493}
494template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
495inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
496operator<=(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
497{
498 using default_ops::eval_lt;
499 if (detail::is_unordered_comparison(a, b))
500 return false;
501 return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
502}
503template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
504inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
505operator<=(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
506{
507 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
508 using default_ops::eval_lt;
509 if (detail::is_unordered_value(a) || detail::is_unordered_value(b))
510 return false;
511 result_type t(b);
512 if (detail::is_unordered_comparison(a, t))
513 return false;
514 return !eval_lt(t.backend(), result_type::canonical_value(a));
515}
516template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
517inline BOOST_MP_CXX14_CONSTEXPR bool operator<=(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
518{
519 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
520 using default_ops::eval_lt;
521 if (detail::is_unordered_value(a) || detail::is_unordered_value(b))
522 return false;
523 result_type t(b);
524 return a <= t;
525}
526template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
527inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
528operator<=(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
529{
530 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
531 using default_ops::eval_gt;
532 result_type t(a);
533 if (detail::is_unordered_comparison(t, b))
534 return false;
535 return !eval_gt(t.backend(), result_type::canonical_value(b));
536}
537template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates>
538inline BOOST_MP_CXX14_CONSTEXPR bool operator<=(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b)
539{
540 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
541 using default_ops::eval_gt;
542 result_type t(a);
543 return t <= b;
544}
545template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
546inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
547operator<=(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
548{
549 using default_ops::eval_gt;
550 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
551 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
552 if (detail::is_unordered_comparison(t, t2))
553 return false;
554 return !eval_gt(t.backend(), t2.backend());
555}
556
557template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
558inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
559operator>=(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
560{
561 using default_ops::eval_lt;
562 if (detail::is_unordered_comparison(a, b))
563 return false;
564 return !eval_lt(a.backend(), b.backend());
565}
566template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
567inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
568operator>=(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
569{
570 using default_ops::eval_lt;
571 if (detail::is_unordered_comparison(a, b))
572 return false;
573 return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
574}
575template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
576inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type
577operator>=(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
578{
579 using default_ops::eval_gt;
580 if (detail::is_unordered_comparison(a, b))
581 return false;
582 return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
583}
584template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
585inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
586operator>=(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
587{
588 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
589 using default_ops::eval_gt;
590 result_type t(b);
591 if (detail::is_unordered_comparison(a, t))
592 return false;
593 return !eval_gt(t.backend(), result_type::canonical_value(a));
594}
595template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
596inline BOOST_MP_CXX14_CONSTEXPR bool operator>=(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
597{
598 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
599 using default_ops::eval_gt;
600 result_type t(b);
601 return a >= t;
602}
603template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
604inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
605operator>=(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
606{
607 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
608 using default_ops::eval_lt;
609 result_type t(a);
610 if (detail::is_unordered_comparison(t, b))
611 return false;
612 return !eval_lt(t.backend(), result_type::canonical_value(b));
613}
614template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates>
615inline BOOST_MP_CXX14_CONSTEXPR bool operator>=(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b)
616{
617 using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type;
618 using default_ops::eval_lt;
619 result_type t(a);
620 return t >= b;
621}
622template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
623inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
624operator>=(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
625{
626 using default_ops::eval_lt;
627 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
628 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
629 if (detail::is_unordered_comparison(t, t2))
630 return false;
631 return !eval_lt(t.backend(), t2.backend());
632}
633
634//
635// C99 comparison macros as functions:
636//
637template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
638inline BOOST_MP_CXX14_CONSTEXPR bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a > b; }
639
640template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
641inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
642 isgreater
643 BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a > b; }
644
645template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
646inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
647 isgreater
648 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a > b; }
649
650template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
651inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
652 isgreater
653 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a > b; }
654
655template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
656inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
657 isgreater
658 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a > b; }
659
660template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
661inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
662 isgreater
663 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; }
664
665template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
666inline BOOST_MP_CXX14_CONSTEXPR bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a >= b; }
667
668template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
669inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
670 isgreaterequal
671 BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a >= b; }
672
673template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
674inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
675 isgreaterequal
676 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a >= b; }
677
678template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
679inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
680 isgreaterequal
681 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a >= b; }
682
683template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
684inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
685 isgreaterequal
686 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a >= b; }
687
688template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
689inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
690 isgreaterequal
691 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; }
692
693template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
694inline BOOST_MP_CXX14_CONSTEXPR bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a <= b; }
695
696template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
697inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
698 islessequal
699 BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a <= b; }
700
701template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
702inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
703 islessequal
704 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a <= b; }
705
706template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
707inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
708 islessequal
709 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a <= b; }
710
711template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
712inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
713 islessequal
714 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a <= b; }
715
716template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
717inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
718 islessequal
719 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; }
720
721template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
722inline BOOST_MP_CXX14_CONSTEXPR bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a < b; }
723
724template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
725inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
726 isless
727 BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a < b; }
728
729template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
730inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
731 isless
732 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a < b; }
733
734template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
735inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
736 isless
737 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a < b; }
738
739template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
740inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
741 isless
742 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a < b; }
743
744template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
745inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
746 isless
747 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; }
748
749template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
750inline BOOST_MP_CXX14_CONSTEXPR bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
751{
752 if (detail::is_unordered_comparison(a, b))
753 return false;
754 return a != b;
755}
756
757template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
758inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
759 islessgreater
760 BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
761{
762 if (detail::is_unordered_comparison(a, b))
763 return false;
764 return a != b;
765}
766
767template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
768inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
769 islessgreater
770 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
771{
772 if (detail::is_unordered_comparison(a, b))
773 return false;
774 return a != b;
775}
776
777template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
778inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
779 islessgreater
780 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& bb)
781{
782 typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb);
783 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
784}
785
786template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
787inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
788 islessgreater
789 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const Arithmetic& b)
790{
791 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
792 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
793}
794
795template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
796inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
797 islessgreater
798 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& bb)
799{
800 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
801 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type b(bb);
802 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
803}
804
805template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
806inline BOOST_MP_CXX14_CONSTEXPR bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return detail::is_unordered_comparison(a, b); }
807
808template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
809inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
810 isunordered
811 BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return detail::is_unordered_comparison(a, b); }
812
813template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
814inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
815 isunordered
816 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return detail::is_unordered_comparison(a, b); }
817
818template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
819inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
820 isunordered
821 BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& bb)
822{
823 typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb);
824 return detail::is_unordered_comparison(a, b);
825}
826
827template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
828inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
829 isunordered
830 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const Arithmetic& b)
831{
832 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
833 return detail::is_unordered_comparison(a, b);
834}
835
836template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
837inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type
838 isunordered
839 BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& bb)
840{
841 typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa);
842 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type b(bb);
843 return detail::is_unordered_comparison(a, b);
844}
845
846}} // namespace boost::multiprecision
847
848#endif // BOOST_MP_NUMBER_COMPARE_HPP
849

source code of boost/libs/multiprecision/include/boost/multiprecision/detail/number_compare.hpp