| /* boost random/detail/integer_log2.hpp header file |
| * |
| * Copyright Steven Watanabe 2011 |
| * 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 most recent version including documentation. |
| * |
| * $Id$ |
| * |
| */ |
| |
| #ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP |
| #define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP |
| |
| #include <boost/config.hpp> |
| #include <boost/limits.hpp> |
| #include <boost/pending/integer_log2.hpp> |
| |
| namespace boost { |
| namespace random { |
| namespace detail { |
| |
| #if !defined(BOOST_NO_CXX11_CONSTEXPR) |
| #define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr |
| #elif defined(BOOST_MSVC) |
| #define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline |
| #elif defined(__GNUC__) && __GNUC__ >= 4 |
| #define BOOST_RANDOM_DETAIL_CONSTEXPR inline __attribute__((__const__)) __attribute__((__always_inline__)) |
| #else |
| #define BOOST_RANDOM_DETAIL_CONSTEXPR inline |
| #endif |
| |
| template<int Shift> |
| struct integer_log2_impl |
| { |
| #if defined(BOOST_NO_CXX11_CONSTEXPR) |
| template<class T> |
| BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) |
| { |
| int update = ((t >> Shift) != 0) * Shift; |
| return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update); |
| } |
| #else |
| template<class T> |
| BOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update) |
| { |
| return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update); |
| } |
| |
| template<class T> |
| BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) |
| { |
| return apply2(t, accum, ((t >> Shift) != 0) * Shift); |
| } |
| #endif |
| }; |
| |
| template<> |
| struct integer_log2_impl<1> |
| { |
| template<class T> |
| BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) |
| { |
| return int(t >> 1) + accum; |
| } |
| }; |
| |
| template<class T> |
| BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t) |
| { |
| return integer_log2_impl< |
| ::boost::detail::max_pow2_less< |
| ::std::numeric_limits<T>::digits, 4 |
| >::value |
| >::apply(t, 0); |
| } |
| |
| } // namespace detail |
| } // namespace random |
| } // namespace boost |
| |
| #endif // BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP |