| // Copyright (C) 2000 Stephen Cleary |
| // |
| // 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) |
| // |
| // See http://www.boost.org for updates, documentation, and revision history. |
| |
| #ifndef BOOST_POOL_CT_GCD_LCM_HPP |
| #define BOOST_POOL_CT_GCD_LCM_HPP |
| |
| #include <boost/static_assert.hpp> |
| #include <boost/type_traits/ice.hpp> |
| |
| namespace boost { |
| |
| namespace details { |
| namespace pool { |
| |
| // Compile-time calculation of greatest common divisor and least common multiple |
| |
| // |
| // ct_gcd is a compile-time algorithm that calculates the greatest common |
| // divisor of two unsigned integers, using Euclid's algorithm. |
| // |
| // assumes: A != 0 && B != 0 |
| // |
| |
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
| |
| namespace details { |
| template <unsigned A, unsigned B, bool Bis0> |
| struct ct_gcd_helper; |
| template <unsigned A, unsigned B> |
| struct ct_gcd_helper<A, B, false> |
| { |
| BOOST_STATIC_CONSTANT(unsigned, A_mod_B_ = A % B); |
| BOOST_STATIC_CONSTANT(unsigned, value = |
| (::boost::details::pool::details::ct_gcd_helper< |
| B, static_cast<unsigned>(A_mod_B_), |
| ::boost::type_traits::ice_eq<A_mod_B_, 0>::value |
| >::value) ); |
| }; |
| template <unsigned A, unsigned B> |
| struct ct_gcd_helper<A, B, true> |
| { |
| BOOST_STATIC_CONSTANT(unsigned, value = A); |
| }; |
| } // namespace details |
| |
| template <unsigned A, unsigned B> |
| struct ct_gcd |
| { |
| BOOST_STATIC_ASSERT(A != 0 && B != 0); |
| BOOST_STATIC_CONSTANT(unsigned, value = |
| (::boost::details::pool::details::ct_gcd_helper<A, B, false>::value) ); |
| }; |
| |
| #else |
| |
| // Thanks to Peter Dimov for providing this workaround! |
| namespace details { |
| template<unsigned A> struct ct_gcd2 |
| { |
| template<unsigned B> |
| struct helper |
| { |
| BOOST_STATIC_CONSTANT(unsigned, value = ct_gcd2<B>::helper<A % B>::value); |
| }; |
| template<> |
| struct helper<0> |
| { |
| BOOST_STATIC_CONSTANT(unsigned, value = A); |
| }; |
| }; |
| } // namespace details |
| |
| template<unsigned A, unsigned B> struct ct_gcd |
| { |
| BOOST_STATIC_ASSERT(A != 0 && B != 0); |
| enum { value = details::ct_gcd2<A>::helper<B>::value }; |
| }; |
| |
| #endif |
| |
| // |
| // ct_lcm is a compile-time algorithm that calculates the least common |
| // multiple of two unsigned integers. |
| // |
| // assumes: A != 0 && B != 0 |
| // |
| template <unsigned A, unsigned B> |
| struct ct_lcm |
| { |
| BOOST_STATIC_CONSTANT(unsigned, value = |
| (A / ::boost::details::pool::ct_gcd<A, B>::value * B) ); |
| }; |
| |
| } // namespace pool |
| } // namespace details |
| |
| } // namespace boost |
| |
| #endif |