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