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