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