common_factor_ct.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Boost common_factor_ct.hpp header file ----------------------------------//
  2. // (C) Copyright Daryle Walker and Stephen Cleary 2001-2002.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // https://www.boost.org/LICENSE_1_0.txt)
  6. // See https://www.boost.org for updates, documentation, and revision history.
  7. #ifndef BOOST_INTEGER_COMMON_FACTOR_CT_HPP
  8. #define BOOST_INTEGER_COMMON_FACTOR_CT_HPP
  9. #include <boost/integer_fwd.hpp> // self include
  10. #include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
  11. namespace boost
  12. {
  13. namespace integer
  14. {
  15. // Implementation details --------------------------------------------------//
  16. namespace detail
  17. {
  18. // Build GCD with Euclid's recursive algorithm
  19. template < static_gcd_type Value1, static_gcd_type Value2 >
  20. struct static_gcd_helper_t
  21. {
  22. private:
  23. BOOST_STATIC_CONSTANT( static_gcd_type, new_value1 = Value2 );
  24. BOOST_STATIC_CONSTANT( static_gcd_type, new_value2 = Value1 % Value2 );
  25. #ifndef BOOST_BORLANDC
  26. #define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast<static_gcd_type>(Value)
  27. #else
  28. typedef static_gcd_helper_t self_type;
  29. #define BOOST_DETAIL_GCD_HELPER_VAL(Value) (self_type:: Value )
  30. #endif
  31. typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1),
  32. BOOST_DETAIL_GCD_HELPER_VAL(new_value2) > next_step_type;
  33. #undef BOOST_DETAIL_GCD_HELPER_VAL
  34. public:
  35. BOOST_STATIC_CONSTANT( static_gcd_type, value = next_step_type::value );
  36. };
  37. // Non-recursive case
  38. template < static_gcd_type Value1 >
  39. struct static_gcd_helper_t< Value1, 0UL >
  40. {
  41. BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 );
  42. };
  43. // Build the LCM from the GCD
  44. template < static_gcd_type Value1, static_gcd_type Value2 >
  45. struct static_lcm_helper_t
  46. {
  47. typedef static_gcd_helper_t<Value1, Value2> gcd_type;
  48. BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value
  49. * Value2 );
  50. };
  51. // Special case for zero-GCD values
  52. template < >
  53. struct static_lcm_helper_t< 0UL, 0UL >
  54. {
  55. BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL );
  56. };
  57. } // namespace detail
  58. // Compile-time greatest common divisor evaluator class declaration --------//
  59. template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd
  60. {
  61. BOOST_STATIC_CONSTANT( static_gcd_type, value = (detail::static_gcd_helper_t<Value1, Value2>::value) );
  62. }; // boost::integer::static_gcd
  63. #if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
  64. template< static_gcd_type Value1, static_gcd_type Value2 > static_gcd_type const static_gcd< Value1, Value2 >::value;
  65. #endif
  66. // Compile-time least common multiple evaluator class declaration ----------//
  67. template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm
  68. {
  69. BOOST_STATIC_CONSTANT( static_gcd_type, value = (detail::static_lcm_helper_t<Value1, Value2>::value) );
  70. }; // boost::integer::static_lcm
  71. #if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
  72. template< static_gcd_type Value1, static_gcd_type Value2 > static_gcd_type const static_lcm< Value1, Value2 >::value;
  73. #endif
  74. } // namespace integer
  75. } // namespace boost
  76. #endif // BOOST_INTEGER_COMMON_FACTOR_CT_HPP