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.
     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 
    27 namespace 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