annotate DEPENDENCIES/generic/include/boost/integer/integer_log2.hpp @ 133:4acb5d8d80b6 tip

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