1 // -------------------------------------
4 // Gives the integer part of the logarithm, in base 2, of a
5 // given number. Behavior is undefined if the argument is <= 0.
8 // (C) Copyright Gennaro Prota 2003 - 2004.
10 // Distributed under the Boost Software License, Version 1.0.
11 // (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 // ------------------------------------------------------
18 #ifndef BOOST_INTEGER_LOG2_HPP_GP_20030301
19 #define BOOST_INTEGER_LOG2_HPP_GP_20030301
22 #include <climits> // actually used for Borland only
23 #include "boost/limits.hpp"
24 #include "boost/config.hpp"
31 int integer_log2_impl(T x, int n) {
51 // helper to find the maximum power of two
52 // less than p (more involved than necessary,
55 template <int p, int n>
56 struct max_pow2_less {
60 BOOST_STATIC_CONSTANT(int, value =
61 c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
66 struct max_pow2_less<0, 0> {
68 BOOST_STATIC_CONSTANT(int, value = 0);
71 // this template is here just for Borland :(
72 // we could simply rely on numeric_limits but sometimes
73 // Borland tries to use numeric_limits<const T>, because
74 // of its usual const-related problems in argument deduction
80 BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
82 BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
95 int integer_log2(T x) {
99 const int n = detail::max_pow2_less<
100 detail::width<T> :: value, 4
103 return detail::integer_log2_impl(x, n);
113 #endif // include guard