integer_log2.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* boost random/detail/integer_log2.hpp header file
  2. *
  3. * Copyright Steven Watanabe 2011
  4. * Distributed under the Boost Software License, Version 1.0. (See
  5. * accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * See http://www.boost.org for most recent version including documentation.
  9. *
  10. * $Id$
  11. *
  12. */
  13. #ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
  14. #define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
  15. #include <boost/config.hpp>
  16. #include <boost/limits.hpp>
  17. #include <boost/integer/integer_log2.hpp>
  18. namespace boost {
  19. namespace random {
  20. namespace detail {
  21. #if !defined(BOOST_NO_CXX11_CONSTEXPR)
  22. #define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr
  23. #elif defined(BOOST_MSVC)
  24. #define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline
  25. #elif defined(__GNUC__) && __GNUC__ >= 4
  26. #define BOOST_RANDOM_DETAIL_CONSTEXPR inline __attribute__((__const__)) __attribute__((__always_inline__))
  27. #else
  28. #define BOOST_RANDOM_DETAIL_CONSTEXPR inline
  29. #endif
  30. template<int Shift>
  31. struct integer_log2_impl
  32. {
  33. #if defined(BOOST_NO_CXX11_CONSTEXPR)
  34. template<class T>
  35. BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
  36. {
  37. int update = ((t >> Shift) != 0) * Shift;
  38. return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
  39. }
  40. #else
  41. template<class T>
  42. BOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update)
  43. {
  44. return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
  45. }
  46. template<class T>
  47. BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
  48. {
  49. return apply2(t, accum, ((t >> Shift) != 0) * Shift);
  50. }
  51. #endif
  52. };
  53. template<>
  54. struct integer_log2_impl<1>
  55. {
  56. template<class T>
  57. BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
  58. {
  59. return int(t >> 1) + accum;
  60. }
  61. };
  62. template<class T>
  63. BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t)
  64. {
  65. return integer_log2_impl<
  66. ::boost::detail::max_pow2_less<
  67. ::std::numeric_limits<T>::digits, 4
  68. >::value
  69. >::apply(t, 0);
  70. }
  71. } // namespace detail
  72. } // namespace random
  73. } // namespace boost
  74. #endif // BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP