/Src/Dependencies/Boost/boost/pool/detail/ct_gcd_lcm.hpp

http://hadesmem.googlecode.com/ · C++ Header · 104 lines · 66 code · 17 blank · 21 comment · 6 complexity · 3d28901d3a40fce75dbdc07e69b9923d MD5 · raw file

  1. // Copyright (C) 2000 Stephen Cleary
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org for updates, documentation, and revision history.
  8. #ifndef BOOST_POOL_CT_GCD_LCM_HPP
  9. #define BOOST_POOL_CT_GCD_LCM_HPP
  10. #include <boost/static_assert.hpp>
  11. #include <boost/type_traits/ice.hpp>
  12. namespace boost {
  13. namespace details {
  14. namespace pool {
  15. // Compile-time calculation of greatest common divisor and least common multiple
  16. //
  17. // ct_gcd is a compile-time algorithm that calculates the greatest common
  18. // divisor of two unsigned integers, using Euclid's algorithm.
  19. //
  20. // assumes: A != 0 && B != 0
  21. //
  22. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  23. namespace details {
  24. template <unsigned A, unsigned B, bool Bis0>
  25. struct ct_gcd_helper;
  26. template <unsigned A, unsigned B>
  27. struct ct_gcd_helper<A, B, false>
  28. {
  29. BOOST_STATIC_CONSTANT(unsigned, A_mod_B_ = A % B);
  30. BOOST_STATIC_CONSTANT(unsigned, value =
  31. (::boost::details::pool::details::ct_gcd_helper<
  32. B, static_cast<unsigned>(A_mod_B_),
  33. ::boost::type_traits::ice_eq<A_mod_B_, 0>::value
  34. >::value) );
  35. };
  36. template <unsigned A, unsigned B>
  37. struct ct_gcd_helper<A, B, true>
  38. {
  39. BOOST_STATIC_CONSTANT(unsigned, value = A);
  40. };
  41. } // namespace details
  42. template <unsigned A, unsigned B>
  43. struct ct_gcd
  44. {
  45. BOOST_STATIC_ASSERT(A != 0 && B != 0);
  46. BOOST_STATIC_CONSTANT(unsigned, value =
  47. (::boost::details::pool::details::ct_gcd_helper<A, B, false>::value) );
  48. };
  49. #else
  50. // Thanks to Peter Dimov for providing this workaround!
  51. namespace details {
  52. template<unsigned A> struct ct_gcd2
  53. {
  54. template<unsigned B>
  55. struct helper
  56. {
  57. BOOST_STATIC_CONSTANT(unsigned, value = ct_gcd2<B>::helper<A % B>::value);
  58. };
  59. template<>
  60. struct helper<0>
  61. {
  62. BOOST_STATIC_CONSTANT(unsigned, value = A);
  63. };
  64. };
  65. } // namespace details
  66. template<unsigned A, unsigned B> struct ct_gcd
  67. {
  68. BOOST_STATIC_ASSERT(A != 0 && B != 0);
  69. enum { value = details::ct_gcd2<A>::helper<B>::value };
  70. };
  71. #endif
  72. //
  73. // ct_lcm is a compile-time algorithm that calculates the least common
  74. // multiple of two unsigned integers.
  75. //
  76. // assumes: A != 0 && B != 0
  77. //
  78. template <unsigned A, unsigned B>
  79. struct ct_lcm
  80. {
  81. BOOST_STATIC_CONSTANT(unsigned, value =
  82. (A / ::boost::details::pool::ct_gcd<A, B>::value * B) );
  83. };
  84. } // namespace pool
  85. } // namespace details
  86. } // namespace boost
  87. #endif