epoc32/include/stdapis/boost/pending/integer_log2.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     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