/////////////////////////////////////////////////////////////////////////////// // Copyright 2012 John Maddock. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_MP_COMPARE_HPP #define BOOST_MP_COMPARE_HPP // // Comparison operators for number. // namespace boost{ namespace multiprecision{ namespace default_ops{ template inline bool eval_eq(const B& a, const B& b) { return a.compare(b) == 0; } // // For the default version which compares to some arbitrary type convertible to // our number type, we don't know what value the ExpressionTemplates parameter to // class number should be. We generally prefer ExpressionTemplates to be enabled // in case type A is itself an expression template, but we need to test both options // with is_convertible in case A has an implicit conversion operator to number. // This is the case with many uBlas types for example. // template inline bool eval_eq(const B& a, const A& b) { typedef typename mpl::if_c< is_convertible >::value, number, number >::type mp_type; mp_type t(b); return eval_eq(a, t.backend()); } template inline bool eval_lt(const B& a, const B& b) { return a.compare(b) < 0; } template inline bool eval_lt(const B& a, const A& b) { typedef typename mpl::if_c< is_convertible >::value, number, number >::type mp_type; mp_type t(b); return eval_lt(a, t.backend()); } template inline bool eval_gt(const B& a, const B& b) { return a.compare(b) > 0; } template inline bool eval_gt(const B& a, const A& b) { typedef typename mpl::if_c< is_convertible >::value, number, number >::type mp_type; mp_type t(b); return eval_gt(a, t.backend()); } } // namespace default_ops namespace detail{ template struct is_valid_mixed_compare : public mpl::false_ {}; template struct is_valid_mixed_compare, Val> : public is_convertible > {}; template struct is_valid_mixed_compare, number > : public mpl::false_ {}; template struct is_valid_mixed_compare, expression > : public mpl::bool_, number >::value> {}; template struct is_valid_mixed_compare, number > : public mpl::bool_, number >::value> {}; } template inline bool operator == (const number& a, const number& b) { using default_ops::eval_eq; return eval_eq(a.backend(), b.backend()); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator == (const number& a, const Arithmetic& b) { using default_ops::eval_eq; return eval_eq(a.backend(), number::canonical_value(b)); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator == (const Arithmetic& a, const number& b) { using default_ops::eval_eq; return eval_eq(b.backend(), number::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator == (const Arithmetic& a, const detail::expression& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_eq; result_type t(b); return eval_eq(t.backend(), result_type::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator == (const detail::expression& a, const Arithmetic& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_eq; result_type t(a); return eval_eq(t.backend(), result_type::canonical_value(b)); } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type operator == (const detail::expression& a, const detail::expression& b) { using default_ops::eval_eq; typename detail::expression::result_type t(a); typename detail::expression::result_type t2(b); return eval_eq(t.backend(), t2.backend()); } template inline bool operator != (const number& a, const number& b) { using default_ops::eval_eq; return !eval_eq(a.backend(), b.backend()); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator != (const number& a, const Arithmetic& b) { using default_ops::eval_eq; return !eval_eq(a.backend(), number::canonical_value(b)); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator != (const Arithmetic& a, const number& b) { using default_ops::eval_eq; return !eval_eq(b.backend(), number::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator != (const Arithmetic& a, const detail::expression& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_eq; result_type t(b); return !eval_eq(t.backend(), result_type::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator != (const detail::expression& a, const Arithmetic& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_eq; result_type t(a); return !eval_eq(t.backend(), result_type::canonical_value(b)); } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type operator != (const detail::expression& a, const detail::expression& b) { using default_ops::eval_eq; typename detail::expression::result_type t(a); typename detail::expression::result_type t2(b); return !eval_eq(t.backend(), t2.backend()); } template inline bool operator < (const number& a, const number& b) { using default_ops::eval_lt; return eval_lt(a.backend(), b.backend()); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator < (const number& a, const Arithmetic& b) { using default_ops::eval_lt; return eval_lt(a.backend(), number::canonical_value(b)); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator < (const Arithmetic& a, const number& b) { using default_ops::eval_gt; return eval_gt(b.backend(), number::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator < (const Arithmetic& a, const detail::expression& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_gt; result_type t(b); return eval_gt(t.backend(), result_type::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator < (const detail::expression& a, const Arithmetic& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_lt; result_type t(a); return eval_lt(t.backend(), result_type::canonical_value(b)); } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type operator < (const detail::expression& a, const detail::expression& b) { using default_ops::eval_lt; typename detail::expression::result_type t(a); typename detail::expression::result_type t2(b); return eval_lt(t.backend(), t2.backend()); } template inline bool operator > (const number& a, const number& b) { using default_ops::eval_gt; return eval_gt(a.backend(), b.backend()); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator > (const number& a, const Arithmetic& b) { using default_ops::eval_gt; return eval_gt(a.backend(), number::canonical_value(b)); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator > (const Arithmetic& a, const number& b) { using default_ops::eval_lt; return eval_lt(b.backend(), number::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator > (const Arithmetic& a, const detail::expression& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_lt; result_type t(b); return eval_lt(t.backend(), result_type::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator > (const detail::expression& a, const Arithmetic& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_gt; result_type t(a); return eval_gt(t.backend(), result_type::canonical_value(b)); } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type operator > (const detail::expression& a, const detail::expression& b) { using default_ops::eval_gt; typename detail::expression::result_type t(a); typename detail::expression::result_type t2(b); return eval_gt(t.backend(), t2.backend()); } template inline bool operator <= (const number& a, const number& b) { using default_ops::eval_gt; return !eval_gt(a.backend(), b.backend()); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator <= (const number& a, const Arithmetic& b) { using default_ops::eval_gt; return !eval_gt(a.backend(), number::canonical_value(b)); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator <= (const Arithmetic& a, const number& b) { using default_ops::eval_lt; return !eval_lt(b.backend(), number::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator <= (const Arithmetic& a, const detail::expression& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_lt; result_type t(b); return !eval_lt(t.backend(), result_type::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator <= (const detail::expression& a, const Arithmetic& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_gt; result_type t(a); return !eval_gt(t.backend(), result_type::canonical_value(b)); } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type operator <= (const detail::expression& a, const detail::expression& b) { using default_ops::eval_gt; typename detail::expression::result_type t(a); typename detail::expression::result_type t2(b); return !eval_gt(t.backend(), t2.backend()); } template inline bool operator >= (const number& a, const number& b) { using default_ops::eval_lt; return !eval_lt(a.backend(), b.backend()); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator >= (const number& a, const Arithmetic& b) { using default_ops::eval_lt; return !eval_lt(a.backend(), number::canonical_value(b)); } template inline typename enable_if_c, Arithmetic>::value, bool>::type operator >= (const Arithmetic& a, const number& b) { using default_ops::eval_gt; return !eval_gt(b.backend(), number::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator >= (const Arithmetic& a, const detail::expression& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_gt; result_type t(b); return !eval_gt(t.backend(), result_type::canonical_value(a)); } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type operator >= (const detail::expression& a, const Arithmetic& b) { typedef typename detail::expression::result_type result_type; using default_ops::eval_lt; result_type t(a); return !eval_lt(t.backend(), result_type::canonical_value(b)); } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type operator >= (const detail::expression& a, const detail::expression& b) { using default_ops::eval_lt; typename detail::expression::result_type t(a); typename detail::expression::result_type t2(b); return !eval_lt(t.backend(), t2.backend()); } }} // namespaces #endif // BOOST_MP_COMPARE_HPP