2002-07-02 07:51:48 +00:00
|
|
|
// Boost common_factor_ct.hpp header file ----------------------------------//
|
|
|
|
|
2004-09-28 12:55:45 +00:00
|
|
|
// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002.
|
|
|
|
// 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)
|
2002-07-02 07:51:48 +00:00
|
|
|
|
|
|
|
// See http://www.boost.org for updates, documentation, and revision history.
|
|
|
|
|
|
|
|
#ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP
|
|
|
|
#define BOOST_MATH_COMMON_FACTOR_CT_HPP
|
|
|
|
|
|
|
|
#include <boost/math_fwd.hpp> // self include
|
|
|
|
|
|
|
|
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
|
|
|
|
|
|
|
|
|
|
|
|
namespace boost
|
|
|
|
{
|
|
|
|
namespace math
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// Implementation details --------------------------------------------------//
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
|
|
// Build GCD with Euclid's recursive algorithm
|
|
|
|
template < unsigned long Value1, unsigned long Value2 >
|
|
|
|
struct static_gcd_helper_t
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 );
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 );
|
|
|
|
|
|
|
|
#ifndef __BORLANDC__
|
2002-10-01 13:31:42 +00:00
|
|
|
#define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast<unsigned long>(Value)
|
2002-07-02 07:51:48 +00:00
|
|
|
#else
|
|
|
|
typedef static_gcd_helper_t self_type;
|
|
|
|
#define BOOST_DETAIL_GCD_HELPER_VAL(Value) (self_type:: Value )
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1),
|
|
|
|
BOOST_DETAIL_GCD_HELPER_VAL(new_value2) > next_step_type;
|
|
|
|
|
|
|
|
#undef BOOST_DETAIL_GCD_HELPER_VAL
|
|
|
|
|
|
|
|
public:
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = next_step_type::value );
|
|
|
|
};
|
|
|
|
|
|
|
|
// Non-recursive case
|
|
|
|
template < unsigned long Value1 >
|
|
|
|
struct static_gcd_helper_t< Value1, 0UL >
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = Value1 );
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
// Use inner class template workaround from Peter Dimov
|
|
|
|
template < unsigned long Value1 >
|
|
|
|
struct static_gcd_helper2_t
|
|
|
|
{
|
|
|
|
template < unsigned long Value2 >
|
|
|
|
struct helper
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value
|
2005-02-07 14:34:32 +00:00
|
|
|
= static_gcd_helper2_t<Value2>::BOOST_NESTED_TEMPLATE
|
|
|
|
helper<Value1 % Value2>::value );
|
2002-07-02 07:51:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template < >
|
|
|
|
struct helper< 0UL >
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = Value1 );
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Special case
|
|
|
|
template < >
|
|
|
|
struct static_gcd_helper2_t< 0UL >
|
|
|
|
{
|
|
|
|
template < unsigned long Value2 >
|
|
|
|
struct helper
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = Value2 );
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Build the GCD from the above template(s)
|
|
|
|
template < unsigned long Value1, unsigned long Value2 >
|
|
|
|
struct static_gcd_helper_t
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value
|
|
|
|
= static_gcd_helper2_t<Value1>::BOOST_NESTED_TEMPLATE
|
|
|
|
helper<Value2>::value );
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
|
|
// Build the LCM from the GCD
|
|
|
|
template < unsigned long Value1, unsigned long Value2 >
|
|
|
|
struct static_lcm_helper_t
|
|
|
|
{
|
|
|
|
typedef static_gcd_helper_t<Value1, Value2> gcd_type;
|
|
|
|
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value
|
|
|
|
* Value2 );
|
|
|
|
};
|
|
|
|
|
|
|
|
// Special case for zero-GCD values
|
|
|
|
template < >
|
|
|
|
struct static_lcm_helper_t< 0UL, 0UL >
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = 0UL );
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
// Adapt GCD's inner class template workaround for LCM
|
|
|
|
template < unsigned long Value1 >
|
|
|
|
struct static_lcm_helper2_t
|
|
|
|
{
|
|
|
|
template < unsigned long Value2 >
|
|
|
|
struct helper
|
|
|
|
{
|
|
|
|
typedef static_gcd_helper_t<Value1, Value2> gcd_type;
|
|
|
|
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = Value1
|
|
|
|
/ gcd_type::value * Value2 );
|
|
|
|
};
|
|
|
|
|
|
|
|
template < >
|
|
|
|
struct helper< 0UL >
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = 0UL );
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Special case
|
|
|
|
template < >
|
|
|
|
struct static_lcm_helper2_t< 0UL >
|
|
|
|
{
|
|
|
|
template < unsigned long Value2 >
|
|
|
|
struct helper
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value = 0UL );
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Build the LCM from the above template(s)
|
|
|
|
template < unsigned long Value1, unsigned long Value2 >
|
|
|
|
struct static_lcm_helper_t
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value
|
|
|
|
= static_lcm_helper2_t<Value1>::BOOST_NESTED_TEMPLATE
|
|
|
|
helper<Value2>::value );
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
|
|
|
|
|
|
// Compile-time greatest common divisor evaluator class declaration --------//
|
|
|
|
|
|
|
|
template < unsigned long Value1, unsigned long Value2 >
|
|
|
|
struct static_gcd
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value
|
|
|
|
= (detail::static_gcd_helper_t<Value1, Value2>::value) );
|
|
|
|
|
|
|
|
}; // boost::math::static_gcd
|
|
|
|
|
|
|
|
|
|
|
|
// Compile-time least common multiple evaluator class declaration ----------//
|
|
|
|
|
|
|
|
template < unsigned long Value1, unsigned long Value2 >
|
|
|
|
struct static_lcm
|
|
|
|
{
|
|
|
|
BOOST_STATIC_CONSTANT( unsigned long, value
|
|
|
|
= (detail::static_lcm_helper_t<Value1, Value2>::value) );
|
|
|
|
|
|
|
|
}; // boost::math::static_lcm
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace math
|
|
|
|
} // namespace boost
|
|
|
|
|
|
|
|
|
|
|
|
#endif // BOOST_MATH_COMMON_FACTOR_CT_HPP
|