Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/multiprecision/cpp_int/comparison.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/multiprecision/cpp_int/comparison.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,408 @@ +/////////////////////////////////////////////////////////////// +// 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_ +// +// Comparison operators for cpp_int_backend: +// +#ifndef BOOST_MP_CPP_INT_COMPARISON_HPP +#define BOOST_MP_CPP_INT_COMPARISON_HPP + +#include <boost/type_traits/make_unsigned.hpp> + +namespace boost{ namespace multiprecision{ namespace backends{ + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4018 4389 4996) +#endif + +// +// Start with non-trivial cpp_int's: +// +template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, + bool + >::type + eval_eq(const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a, const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b) BOOST_NOEXCEPT +{ +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600) + return (a.sign() == b.sign()) + && (a.size() == b.size()) + && std::equal(a.limbs(), a.limbs() + a.size(), + stdext::checked_array_iterator<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::const_limb_pointer>(b.limbs(), b.size())); +#else + return (a.sign() == b.sign()) + && (a.size() == b.size()) + && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs()); +#endif +} +template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value + && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value, + bool + >::type + eval_eq(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) BOOST_NOEXCEPT +{ +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600) + return (a.sign() == b.sign()) + && (a.size() == b.size()) + && std::equal(a.limbs(), a.limbs() + a.size(), stdext::checked_array_iterator<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer>(b.limbs(), b.size())); +#else + return (a.sign() == b.sign()) + && (a.size() == b.size()) + && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs()); +#endif +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT +{ + return (a.sign() == false) + && (a.size() == 1) + && (*a.limbs() == b); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT +{ + BOOST_MP_USING_ABS + return (a.sign() == (b < 0)) + && (a.size() == 1) + && (*a.limbs() == static_cast<limb_type>(abs(b))); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT +{ + return (a.size() == 1) + && (*a.limbs() == b); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT +{ + return (b < 0) ? eval_eq(a, cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>(b)) : eval_eq(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison +} + +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT +{ + if(a.sign()) + return true; + if(a.size() > 1) + return false; + return *a.limbs() < b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +inline typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT +{ + BOOST_MP_USING_ABS + if((b == 0) || (a.sign() != (b < 0))) + return a.sign(); + if(a.sign()) + { + if(a.size() > 1) + return true; + return *a.limbs() > static_cast<limb_type>(abs(b)); + } + else + { + if(a.size() > 1) + return false; + return *a.limbs() < static_cast<limb_type>(b); + } +} + +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT +{ + if(a.size() > 1) + return false; + return *a.limbs() < b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT +{ + return (b < 0) ? a.compare(b) < 0 : eval_lt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison +} + +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT +{ + if(a.sign()) + return false; + if(a.size() > 1) + return true; + return *a.limbs() > b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +inline typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT +{ + BOOST_MP_USING_ABS + if(b == 0) + return !a.sign() && ((a.size() > 1) || *a.limbs()); + if(a.sign() != (b < 0)) + return !a.sign(); + if(a.sign()) + { + if(a.size() > 1) + return false; + return *a.limbs() < static_cast<limb_type>(abs(b)); + } + else + { + if(a.size() > 1) + return true; + return *a.limbs() > static_cast<limb_type>(b); + } +} + +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT +{ + if(a.size() > 1) + return true; + return *a.limbs() > b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator> +BOOST_MP_FORCEINLINE typename enable_if_c< + !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT +{ + return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison. +} +// +// And again for trivial cpp_ints: +// +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT +{ + return (a.sign() == b.sign()) && (*a.limbs() == *b.limbs()); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT +{ + return *a.limbs() == *b.limbs(); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT +{ + return !a.sign() && (*a.limbs() == b); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT +{ + BOOST_MP_USING_ABS + typedef typename make_unsigned<S>::type ui_type; + return (a.sign() == (b < 0)) && (*a.limbs() == static_cast<ui_type>(abs(b))); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT +{ + return *a.limbs() == b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT +{ + typedef typename make_unsigned<S>::type ui_type; + if(b < 0) + { + cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b); + return *a.limbs() == *t.limbs(); + } + else + { + return *a.limbs() == static_cast<ui_type>(b); + } +} + +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT +{ + if(a.sign() != b.sign()) + return a.sign(); + return a.sign() ? *a.limbs() > *b.limbs() : *a.limbs() < *b.limbs(); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT +{ + return *a.limbs() < *b.limbs(); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT +{ + if(a.sign()) + return true; + return *a.limbs() < b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT +{ + BOOST_MP_USING_ABS + typedef typename make_unsigned<S>::type ui_type; + if(a.sign() != (b < 0)) + return a.sign(); + return a.sign() ? (*a.limbs() > static_cast<ui_type>(abs(b))) : (*a.limbs() < static_cast<ui_type>(abs(b))); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT +{ + return *a.limbs() < b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT +{ + typedef typename make_unsigned<S>::type ui_type; + if(b < 0) + { + cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b); + return *a.limbs() < *t.limbs(); + } + else + { + return *a.limbs() < static_cast<ui_type>(b); + } +} + +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT +{ + if(a.sign() != b.sign()) + return !a.sign(); + return a.sign() ? *a.limbs() < *b.limbs() : *a.limbs() > *b.limbs(); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT +{ + return *a.limbs() > *b.limbs(); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT +{ + if(a.sign()) + return false; + return *a.limbs() > b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT +{ + BOOST_MP_USING_ABS + typedef typename make_unsigned<S>::type ui_type; + if(a.sign() != (b < 0)) + return !a.sign(); + return a.sign() ? (*a.limbs() < static_cast<ui_type>(abs(b))) : (*a.limbs() > static_cast<ui_type>(abs(b))); +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT +{ + return *a.limbs() > b; +} +template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S> +BOOST_MP_FORCEINLINE typename enable_if_c< + is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, + bool + >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT +{ + typedef typename make_unsigned<S>::type ui_type; + if(b < 0) + { + cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b); + return *a.limbs() > *t.limbs(); + } + else + { + return *a.limbs() > static_cast<ui_type>(b); + } +} + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +}}} // namespaces + +#endif