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