os/ossrv/ossrv_pub/boost_apis/boost/pending/integer_log2.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// -------------------------------------
sl@0
     2
// integer_log2.hpp
sl@0
     3
//
sl@0
     4
//   Gives the integer part of the logarithm, in base 2, of a
sl@0
     5
// given number. Behavior is undefined if the argument is <= 0.
sl@0
     6
//
sl@0
     7
//
sl@0
     8
//       (C) Copyright Gennaro Prota 2003 - 2004.
sl@0
     9
//
sl@0
    10
// Distributed under the Boost Software License, Version 1.0.
sl@0
    11
//    (See accompanying file LICENSE_1_0.txt or copy at
sl@0
    12
//          http://www.boost.org/LICENSE_1_0.txt)
sl@0
    13
//
sl@0
    14
// ------------------------------------------------------
sl@0
    15
sl@0
    16
sl@0
    17
sl@0
    18
#ifndef BOOST_INTEGER_LOG2_HPP_GP_20030301
sl@0
    19
#define BOOST_INTEGER_LOG2_HPP_GP_20030301
sl@0
    20
sl@0
    21
#include <cassert>
sl@0
    22
#include <climits> // actually used for Borland only
sl@0
    23
#include "boost/limits.hpp"
sl@0
    24
#include "boost/config.hpp"
sl@0
    25
sl@0
    26
sl@0
    27
namespace boost {
sl@0
    28
 namespace detail {
sl@0
    29
sl@0
    30
  template <typename T>
sl@0
    31
  int integer_log2_impl(T x, int n) {
sl@0
    32
sl@0
    33
      int result = 0;
sl@0
    34
sl@0
    35
      while (x != 1) {
sl@0
    36
sl@0
    37
          const T t = x >> n;
sl@0
    38
          if (t) {
sl@0
    39
              result += n;
sl@0
    40
              x = t;
sl@0
    41
          }
sl@0
    42
          n /= 2;
sl@0
    43
sl@0
    44
      }
sl@0
    45
sl@0
    46
      return result;
sl@0
    47
  }
sl@0
    48
sl@0
    49
sl@0
    50
sl@0
    51
  // helper to find the maximum power of two
sl@0
    52
  // less than p (more involved than necessary,
sl@0
    53
  // to avoid PTS)
sl@0
    54
  //
sl@0
    55
  template <int p, int n>
sl@0
    56
  struct max_pow2_less {
sl@0
    57
sl@0
    58
      enum { c = 2*n < p };
sl@0
    59
sl@0
    60
      BOOST_STATIC_CONSTANT(int, value =
sl@0
    61
          c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
sl@0
    62
sl@0
    63
  };
sl@0
    64
sl@0
    65
  template <>
sl@0
    66
  struct max_pow2_less<0, 0> {
sl@0
    67
sl@0
    68
      BOOST_STATIC_CONSTANT(int, value = 0);
sl@0
    69
  };
sl@0
    70
sl@0
    71
  // this template is here just for Borland :(
sl@0
    72
  // we could simply rely on numeric_limits but sometimes
sl@0
    73
  // Borland tries to use numeric_limits<const T>, because
sl@0
    74
  // of its usual const-related problems in argument deduction
sl@0
    75
  // - gps
sl@0
    76
  template <typename T>
sl@0
    77
  struct width {
sl@0
    78
sl@0
    79
#ifdef __BORLANDC__
sl@0
    80
      BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
sl@0
    81
#else
sl@0
    82
      BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
sl@0
    83
#endif
sl@0
    84
sl@0
    85
  };
sl@0
    86
sl@0
    87
 } // detail
sl@0
    88
sl@0
    89
sl@0
    90
 // ---------
sl@0
    91
 // integer_log2
sl@0
    92
 // ---------------
sl@0
    93
 //
sl@0
    94
 template <typename T>
sl@0
    95
 int integer_log2(T x) {
sl@0
    96
sl@0
    97
     assert(x > 0);
sl@0
    98
sl@0
    99
     const int n = detail::max_pow2_less<
sl@0
   100
                     detail::width<T> :: value, 4
sl@0
   101
                   > :: value;
sl@0
   102
sl@0
   103
     return detail::integer_log2_impl(x, n);
sl@0
   104
sl@0
   105
 }
sl@0
   106
sl@0
   107
sl@0
   108
sl@0
   109
}
sl@0
   110
sl@0
   111
sl@0
   112
sl@0
   113
#endif // include guard