85 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			85 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /* 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 |