epoc32/include/stdapis/boost/pending/integer_log2.hpp
branchSymbian2
changeset 2 2fe1408b6811
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/stdapis/boost/pending/integer_log2.hpp	Tue Mar 16 16:12:26 2010 +0000
     1.3 @@ -0,0 +1,113 @@
     1.4 +// -------------------------------------
     1.5 +// integer_log2.hpp
     1.6 +//
     1.7 +//   Gives the integer part of the logarithm, in base 2, of a
     1.8 +// given number. Behavior is undefined if the argument is <= 0.
     1.9 +//
    1.10 +//
    1.11 +//       (C) Copyright Gennaro Prota 2003 - 2004.
    1.12 +//
    1.13 +// Distributed under the Boost Software License, Version 1.0.
    1.14 +//    (See accompanying file LICENSE_1_0.txt or copy at
    1.15 +//          http://www.boost.org/LICENSE_1_0.txt)
    1.16 +//
    1.17 +// ------------------------------------------------------
    1.18 +
    1.19 +
    1.20 +
    1.21 +#ifndef BOOST_INTEGER_LOG2_HPP_GP_20030301
    1.22 +#define BOOST_INTEGER_LOG2_HPP_GP_20030301
    1.23 +
    1.24 +#include <cassert>
    1.25 +#include <climits> // actually used for Borland only
    1.26 +#include "boost/limits.hpp"
    1.27 +#include "boost/config.hpp"
    1.28 +
    1.29 +
    1.30 +namespace boost {
    1.31 + namespace detail {
    1.32 +
    1.33 +  template <typename T>
    1.34 +  int integer_log2_impl(T x, int n) {
    1.35 +
    1.36 +      int result = 0;
    1.37 +
    1.38 +      while (x != 1) {
    1.39 +
    1.40 +          const T t = x >> n;
    1.41 +          if (t) {
    1.42 +              result += n;
    1.43 +              x = t;
    1.44 +          }
    1.45 +          n /= 2;
    1.46 +
    1.47 +      }
    1.48 +
    1.49 +      return result;
    1.50 +  }
    1.51 +
    1.52 +
    1.53 +
    1.54 +  // helper to find the maximum power of two
    1.55 +  // less than p (more involved than necessary,
    1.56 +  // to avoid PTS)
    1.57 +  //
    1.58 +  template <int p, int n>
    1.59 +  struct max_pow2_less {
    1.60 +
    1.61 +      enum { c = 2*n < p };
    1.62 +
    1.63 +      BOOST_STATIC_CONSTANT(int, value =
    1.64 +          c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
    1.65 +
    1.66 +  };
    1.67 +
    1.68 +  template <>
    1.69 +  struct max_pow2_less<0, 0> {
    1.70 +
    1.71 +      BOOST_STATIC_CONSTANT(int, value = 0);
    1.72 +  };
    1.73 +
    1.74 +  // this template is here just for Borland :(
    1.75 +  // we could simply rely on numeric_limits but sometimes
    1.76 +  // Borland tries to use numeric_limits<const T>, because
    1.77 +  // of its usual const-related problems in argument deduction
    1.78 +  // - gps
    1.79 +  template <typename T>
    1.80 +  struct width {
    1.81 +
    1.82 +#ifdef __BORLANDC__
    1.83 +      BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
    1.84 +#else
    1.85 +      BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
    1.86 +#endif
    1.87 +
    1.88 +  };
    1.89 +
    1.90 + } // detail
    1.91 +
    1.92 +
    1.93 + // ---------
    1.94 + // integer_log2
    1.95 + // ---------------
    1.96 + //
    1.97 + template <typename T>
    1.98 + int integer_log2(T x) {
    1.99 +
   1.100 +     assert(x > 0);
   1.101 +
   1.102 +     const int n = detail::max_pow2_less<
   1.103 +                     detail::width<T> :: value, 4
   1.104 +                   > :: value;
   1.105 +
   1.106 +     return detail::integer_log2_impl(x, n);
   1.107 +
   1.108 + }
   1.109 +
   1.110 +
   1.111 +
   1.112 +}
   1.113 +
   1.114 +
   1.115 +
   1.116 +#endif // include guard