source: NonGTP/Boost/boost/pending/integer_log2.hpp @ 857

Revision 857, 2.3 KB checked in by igarcia, 18 years ago (diff)
Line 
1// -------------------------------------
2// integer_log2.hpp
3//
4//   Gives the integer part of the logarithm, in base 2, of a
5// given number. Behavior is undefined if the argument is <= 0.
6//
7//
8//       (C) Copyright Gennaro Prota 2003 - 2004.
9//
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)
13//
14// ------------------------------------------------------
15
16
17
18#ifndef BOOST_INTEGER_LOG2_HPP_GP_20030301
19#define BOOST_INTEGER_LOG2_HPP_GP_20030301
20
21#include <cassert>
22#include <climits> // actually used for Borland only
23#include "boost/limits.hpp"
24#include "boost/config.hpp"
25
26
27namespace boost {
28 namespace detail {
29
30  template <typename T>
31  int integer_log2_impl(T x, int n) {
32
33      int result = 0;
34
35      while (x != 1) {
36
37          const T t = x >> n;
38          if (t) {
39              result += n;
40              x = t;
41          }
42          n /= 2;
43
44      }
45
46      return result;
47  }
48
49
50
51  // helper to find the maximum power of two
52  // less than p (more involved than necessary,
53  // to avoid PTS)
54  //
55  template <int p, int n>
56  struct max_pow2_less {
57
58      enum { c = 2*n < p };
59
60      BOOST_STATIC_CONSTANT(int, value =
61          c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
62
63  };
64
65  template <>
66  struct max_pow2_less<0, 0> {
67
68      BOOST_STATIC_CONSTANT(int, value = 0);
69  };
70
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
75  // - gps
76  template <typename T>
77  struct width {
78
79#ifdef __BORLANDC__
80      BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
81#else
82      BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
83#endif
84
85  };
86
87 } // detail
88
89
90 // ---------
91 // integer_log2
92 // ---------------
93 //
94 template <typename T>
95 int integer_log2(T x) {
96
97     assert(x > 0);
98
99     const int n = detail::max_pow2_less<
100                     detail::width<T> :: value, 4
101                   > :: value;
102
103     return detail::integer_log2_impl(x, n);
104
105 }
106
107
108
109}
110
111
112
113#endif // include guard
Note: See TracBrowser for help on using the repository browser.