Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // Copyright 2012 John Maddock. Distributed under the Boost
|
Chris@16
|
3 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef BOOST_MP_COMPARE_HPP
|
Chris@16
|
7 #define BOOST_MP_COMPARE_HPP
|
Chris@16
|
8
|
Chris@16
|
9 //
|
Chris@16
|
10 // Comparison operators for number.
|
Chris@16
|
11 //
|
Chris@16
|
12
|
Chris@16
|
13 namespace boost{ namespace multiprecision{
|
Chris@16
|
14
|
Chris@16
|
15 namespace default_ops{
|
Chris@16
|
16
|
Chris@16
|
17 template <class B>
|
Chris@16
|
18 inline bool eval_eq(const B& a, const B& b)
|
Chris@16
|
19 {
|
Chris@16
|
20 return a.compare(b) == 0;
|
Chris@16
|
21 }
|
Chris@16
|
22 //
|
Chris@16
|
23 // For the default version which compares to some arbitrary type convertible to
|
Chris@16
|
24 // our number type, we don't know what value the ExpressionTemplates parameter to
|
Chris@16
|
25 // class number should be. We generally prefer ExpressionTemplates to be enabled
|
Chris@16
|
26 // in case type A is itself an expression template, but we need to test both options
|
Chris@16
|
27 // with is_convertible in case A has an implicit conversion operator to number<B,something>.
|
Chris@16
|
28 // This is the case with many uBlas types for example.
|
Chris@16
|
29 //
|
Chris@16
|
30 template <class B, class A>
|
Chris@16
|
31 inline bool eval_eq(const B& a, const A& b)
|
Chris@16
|
32 {
|
Chris@16
|
33 typedef typename mpl::if_c<
|
Chris@16
|
34 is_convertible<A, number<B, et_on> >::value,
|
Chris@16
|
35 number<B, et_on>,
|
Chris@16
|
36 number<B, et_off> >::type mp_type;
|
Chris@16
|
37 mp_type t(b);
|
Chris@16
|
38 return eval_eq(a, t.backend());
|
Chris@16
|
39 }
|
Chris@16
|
40
|
Chris@16
|
41 template <class B>
|
Chris@16
|
42 inline bool eval_lt(const B& a, const B& b)
|
Chris@16
|
43 {
|
Chris@16
|
44 return a.compare(b) < 0;
|
Chris@16
|
45 }
|
Chris@16
|
46 template <class B, class A>
|
Chris@16
|
47 inline bool eval_lt(const B& a, const A& b)
|
Chris@16
|
48 {
|
Chris@16
|
49 typedef typename mpl::if_c<
|
Chris@16
|
50 is_convertible<A, number<B, et_on> >::value,
|
Chris@16
|
51 number<B, et_on>,
|
Chris@16
|
52 number<B, et_off> >::type mp_type;
|
Chris@16
|
53 mp_type t(b);
|
Chris@16
|
54 return eval_lt(a, t.backend());
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 template <class B>
|
Chris@16
|
58 inline bool eval_gt(const B& a, const B& b)
|
Chris@16
|
59 {
|
Chris@16
|
60 return a.compare(b) > 0;
|
Chris@16
|
61 }
|
Chris@16
|
62 template <class B, class A>
|
Chris@16
|
63 inline bool eval_gt(const B& a, const A& b)
|
Chris@16
|
64 {
|
Chris@16
|
65 typedef typename mpl::if_c<
|
Chris@16
|
66 is_convertible<A, number<B, et_on> >::value,
|
Chris@16
|
67 number<B, et_on>,
|
Chris@16
|
68 number<B, et_off> >::type mp_type;
|
Chris@16
|
69 mp_type t(b);
|
Chris@16
|
70 return eval_gt(a, t.backend());
|
Chris@16
|
71 }
|
Chris@16
|
72
|
Chris@16
|
73 } // namespace default_ops
|
Chris@16
|
74
|
Chris@16
|
75 namespace detail{
|
Chris@16
|
76
|
Chris@16
|
77 template <class Num, class Val>
|
Chris@16
|
78 struct is_valid_mixed_compare : public mpl::false_ {};
|
Chris@16
|
79
|
Chris@16
|
80 template <class B, expression_template_option ET, class Val>
|
Chris@16
|
81 struct is_valid_mixed_compare<number<B, ET>, Val> : public is_convertible<Val, number<B, ET> > {};
|
Chris@16
|
82
|
Chris@16
|
83 template <class B, expression_template_option ET>
|
Chris@16
|
84 struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public mpl::false_ {};
|
Chris@16
|
85
|
Chris@16
|
86 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
|
Chris@16
|
87 struct is_valid_mixed_compare<number<B, ET>, expression<tag, Arg1, Arg2, Arg3, Arg4> >
|
Chris@16
|
88 : public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {};
|
Chris@16
|
89
|
Chris@16
|
90 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
|
Chris@16
|
91 struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
|
Chris@16
|
92 : public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {};
|
Chris@16
|
93
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@101
|
96 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
Chris@101
|
97 inline bool operator == (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
Chris@16
|
98 {
|
Chris@16
|
99 using default_ops::eval_eq;
|
Chris@16
|
100 return eval_eq(a.backend(), b.backend());
|
Chris@16
|
101 }
|
Chris@16
|
102 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
Chris@16
|
103 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
104 operator == (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
Chris@16
|
105 {
|
Chris@16
|
106 using default_ops::eval_eq;
|
Chris@16
|
107 return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
Chris@16
|
108 }
|
Chris@16
|
109 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
Chris@16
|
110 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
111 operator == (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
Chris@16
|
112 {
|
Chris@16
|
113 using default_ops::eval_eq;
|
Chris@16
|
114 return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
Chris@16
|
115 }
|
Chris@16
|
116 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
Chris@16
|
117 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
118 operator == (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
Chris@16
|
119 {
|
Chris@16
|
120 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
121 using default_ops::eval_eq;
|
Chris@16
|
122 result_type t(b);
|
Chris@16
|
123 return eval_eq(t.backend(), result_type::canonical_value(a));
|
Chris@16
|
124 }
|
Chris@16
|
125 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
Chris@16
|
126 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
127 operator == (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
Chris@16
|
128 {
|
Chris@16
|
129 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
130 using default_ops::eval_eq;
|
Chris@16
|
131 result_type t(a);
|
Chris@16
|
132 return eval_eq(t.backend(), result_type::canonical_value(b));
|
Chris@16
|
133 }
|
Chris@16
|
134 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
Chris@16
|
135 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
|
Chris@16
|
136 operator == (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
Chris@16
|
137 {
|
Chris@16
|
138 using default_ops::eval_eq;
|
Chris@16
|
139 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
|
Chris@16
|
140 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
|
Chris@16
|
141 return eval_eq(t.backend(), t2.backend());
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@101
|
144 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
Chris@101
|
145 inline bool operator != (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
Chris@16
|
146 {
|
Chris@16
|
147 using default_ops::eval_eq;
|
Chris@16
|
148 return !eval_eq(a.backend(), b.backend());
|
Chris@16
|
149 }
|
Chris@16
|
150 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
Chris@16
|
151 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
152 operator != (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
Chris@16
|
153 {
|
Chris@16
|
154 using default_ops::eval_eq;
|
Chris@16
|
155 return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b));
|
Chris@16
|
156 }
|
Chris@16
|
157 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
Chris@16
|
158 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
159 operator != (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
Chris@16
|
160 {
|
Chris@16
|
161 using default_ops::eval_eq;
|
Chris@16
|
162 return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a));
|
Chris@16
|
163 }
|
Chris@16
|
164 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
Chris@16
|
165 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
166 operator != (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
Chris@16
|
167 {
|
Chris@16
|
168 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
169 using default_ops::eval_eq;
|
Chris@16
|
170 result_type t(b);
|
Chris@16
|
171 return !eval_eq(t.backend(), result_type::canonical_value(a));
|
Chris@16
|
172 }
|
Chris@16
|
173 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
Chris@16
|
174 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
175 operator != (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
Chris@16
|
176 {
|
Chris@16
|
177 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
178 using default_ops::eval_eq;
|
Chris@16
|
179 result_type t(a);
|
Chris@16
|
180 return !eval_eq(t.backend(), result_type::canonical_value(b));
|
Chris@16
|
181 }
|
Chris@16
|
182 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
Chris@16
|
183 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
|
Chris@16
|
184 operator != (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
Chris@16
|
185 {
|
Chris@16
|
186 using default_ops::eval_eq;
|
Chris@16
|
187 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
|
Chris@16
|
188 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
|
Chris@16
|
189 return !eval_eq(t.backend(), t2.backend());
|
Chris@16
|
190 }
|
Chris@16
|
191
|
Chris@101
|
192 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
Chris@101
|
193 inline bool operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
Chris@16
|
194 {
|
Chris@16
|
195 using default_ops::eval_lt;
|
Chris@16
|
196 return eval_lt(a.backend(), b.backend());
|
Chris@16
|
197 }
|
Chris@16
|
198 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
Chris@16
|
199 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
200 operator < (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
Chris@16
|
201 {
|
Chris@16
|
202 using default_ops::eval_lt;
|
Chris@16
|
203 return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
Chris@16
|
204 }
|
Chris@16
|
205 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
Chris@16
|
206 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
207 operator < (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
Chris@16
|
208 {
|
Chris@16
|
209 using default_ops::eval_gt;
|
Chris@16
|
210 return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
Chris@16
|
211 }
|
Chris@16
|
212 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
Chris@16
|
213 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
214 operator < (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
Chris@16
|
215 {
|
Chris@16
|
216 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
217 using default_ops::eval_gt;
|
Chris@16
|
218 result_type t(b);
|
Chris@16
|
219 return eval_gt(t.backend(), result_type::canonical_value(a));
|
Chris@16
|
220 }
|
Chris@16
|
221 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
Chris@16
|
222 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
223 operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
Chris@16
|
224 {
|
Chris@16
|
225 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
226 using default_ops::eval_lt;
|
Chris@16
|
227 result_type t(a);
|
Chris@16
|
228 return eval_lt(t.backend(), result_type::canonical_value(b));
|
Chris@16
|
229 }
|
Chris@16
|
230 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
Chris@16
|
231 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
|
Chris@16
|
232 operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
Chris@16
|
233 {
|
Chris@16
|
234 using default_ops::eval_lt;
|
Chris@16
|
235 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
|
Chris@16
|
236 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
|
Chris@16
|
237 return eval_lt(t.backend(), t2.backend());
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@101
|
240 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
Chris@101
|
241 inline bool operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
Chris@16
|
242 {
|
Chris@16
|
243 using default_ops::eval_gt;
|
Chris@16
|
244 return eval_gt(a.backend(), b.backend());
|
Chris@16
|
245 }
|
Chris@16
|
246 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
Chris@16
|
247 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
248 operator > (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
Chris@16
|
249 {
|
Chris@16
|
250 using default_ops::eval_gt;
|
Chris@16
|
251 return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
Chris@16
|
252 }
|
Chris@16
|
253 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
Chris@16
|
254 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
255 operator > (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
Chris@16
|
256 {
|
Chris@16
|
257 using default_ops::eval_lt;
|
Chris@16
|
258 return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
Chris@16
|
259 }
|
Chris@16
|
260 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
Chris@16
|
261 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
262 operator > (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
Chris@16
|
263 {
|
Chris@16
|
264 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
265 using default_ops::eval_lt;
|
Chris@16
|
266 result_type t(b);
|
Chris@16
|
267 return eval_lt(t.backend(), result_type::canonical_value(a));
|
Chris@16
|
268 }
|
Chris@16
|
269 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
Chris@16
|
270 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
271 operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
Chris@16
|
272 {
|
Chris@16
|
273 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
274 using default_ops::eval_gt;
|
Chris@16
|
275 result_type t(a);
|
Chris@16
|
276 return eval_gt(t.backend(), result_type::canonical_value(b));
|
Chris@16
|
277 }
|
Chris@16
|
278 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
Chris@16
|
279 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
|
Chris@16
|
280 operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
Chris@16
|
281 {
|
Chris@16
|
282 using default_ops::eval_gt;
|
Chris@16
|
283 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
|
Chris@16
|
284 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
|
Chris@16
|
285 return eval_gt(t.backend(), t2.backend());
|
Chris@16
|
286 }
|
Chris@16
|
287
|
Chris@101
|
288 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
Chris@101
|
289 inline bool operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
Chris@16
|
290 {
|
Chris@16
|
291 using default_ops::eval_gt;
|
Chris@16
|
292 return !eval_gt(a.backend(), b.backend());
|
Chris@16
|
293 }
|
Chris@16
|
294 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
Chris@16
|
295 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
296 operator <= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
Chris@16
|
297 {
|
Chris@16
|
298 using default_ops::eval_gt;
|
Chris@16
|
299 return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
Chris@16
|
300 }
|
Chris@16
|
301 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
Chris@16
|
302 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
303 operator <= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
Chris@16
|
304 {
|
Chris@16
|
305 using default_ops::eval_lt;
|
Chris@16
|
306 return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
Chris@16
|
307 }
|
Chris@16
|
308 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
Chris@16
|
309 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
310 operator <= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
Chris@16
|
311 {
|
Chris@16
|
312 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
313 using default_ops::eval_lt;
|
Chris@16
|
314 result_type t(b);
|
Chris@16
|
315 return !eval_lt(t.backend(), result_type::canonical_value(a));
|
Chris@16
|
316 }
|
Chris@16
|
317 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
Chris@16
|
318 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
319 operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
Chris@16
|
320 {
|
Chris@16
|
321 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
322 using default_ops::eval_gt;
|
Chris@16
|
323 result_type t(a);
|
Chris@16
|
324 return !eval_gt(t.backend(), result_type::canonical_value(b));
|
Chris@16
|
325 }
|
Chris@16
|
326 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
Chris@16
|
327 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
|
Chris@16
|
328 operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
Chris@16
|
329 {
|
Chris@16
|
330 using default_ops::eval_gt;
|
Chris@16
|
331 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
|
Chris@16
|
332 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
|
Chris@16
|
333 return !eval_gt(t.backend(), t2.backend());
|
Chris@16
|
334 }
|
Chris@16
|
335
|
Chris@101
|
336 template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
Chris@101
|
337 inline bool operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
Chris@16
|
338 {
|
Chris@16
|
339 using default_ops::eval_lt;
|
Chris@16
|
340 return !eval_lt(a.backend(), b.backend());
|
Chris@16
|
341 }
|
Chris@16
|
342 template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
Chris@16
|
343 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
344 operator >= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
Chris@16
|
345 {
|
Chris@16
|
346 using default_ops::eval_lt;
|
Chris@16
|
347 return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
Chris@16
|
348 }
|
Chris@16
|
349 template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
Chris@16
|
350 inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
Chris@16
|
351 operator >= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
Chris@16
|
352 {
|
Chris@16
|
353 using default_ops::eval_gt;
|
Chris@16
|
354 return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
Chris@16
|
355 }
|
Chris@16
|
356 template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
Chris@16
|
357 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
358 operator >= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
Chris@16
|
359 {
|
Chris@16
|
360 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
361 using default_ops::eval_gt;
|
Chris@16
|
362 result_type t(b);
|
Chris@16
|
363 return !eval_gt(t.backend(), result_type::canonical_value(a));
|
Chris@16
|
364 }
|
Chris@16
|
365 template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
Chris@16
|
366 inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
Chris@16
|
367 operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
Chris@16
|
368 {
|
Chris@16
|
369 typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
Chris@16
|
370 using default_ops::eval_lt;
|
Chris@16
|
371 result_type t(a);
|
Chris@16
|
372 return !eval_lt(t.backend(), result_type::canonical_value(b));
|
Chris@16
|
373 }
|
Chris@16
|
374 template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
Chris@16
|
375 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
|
Chris@16
|
376 operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
Chris@16
|
377 {
|
Chris@16
|
378 using default_ops::eval_lt;
|
Chris@16
|
379 typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
|
Chris@16
|
380 typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
|
Chris@16
|
381 return !eval_lt(t.backend(), t2.backend());
|
Chris@16
|
382 }
|
Chris@16
|
383
|
Chris@16
|
384
|
Chris@16
|
385 }} // namespaces
|
Chris@16
|
386
|
Chris@16
|
387 #endif // BOOST_MP_COMPARE_HPP
|
Chris@16
|
388
|