diff --git a/include/boost/integer/integer_log2.hpp b/include/boost/integer/integer_log2.hpp new file mode 100644 index 0000000..8b34ce7 --- /dev/null +++ b/include/boost/integer/integer_log2.hpp @@ -0,0 +1,112 @@ +// ----------------------------------------------------------- +// integer_log2.hpp +// +// Gives the integer part of the logarithm, in base 2, of a +// given number. Behavior is undefined if the argument is <= 0. +// +// Copyright (c) 2003-2004, 2008 Gennaro Prota +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// ----------------------------------------------------------- + +#ifndef BOOST_INTEGER_INTEGER_LOG2_HPP +#define BOOST_INTEGER_INTEGER_LOG2_HPP + +#include +#ifdef __BORLANDC__ +#include +#endif +#include +#include + + +namespace boost { + namespace detail { + + template + int integer_log2_impl(T x, int n) { + + int result = 0; + + while (x != 1) { + + const T t = static_cast(x >> n); + if (t) { + result += n; + x = t; + } + n /= 2; + + } + + return result; + } + + + + // helper to find the maximum power of two + // less than p (more involved than necessary, + // to avoid PTS) + // + template + struct max_pow2_less { + + enum { c = 2*n < p }; + + BOOST_STATIC_CONSTANT(int, value = + c ? (max_pow2_less< c*p, 2*c*n>::value) : n); + + }; + + template <> + struct max_pow2_less<0, 0> { + + BOOST_STATIC_CONSTANT(int, value = 0); + }; + + // this template is here just for Borland :( + // we could simply rely on numeric_limits but sometimes + // Borland tries to use numeric_limits, because + // of its usual const-related problems in argument deduction + // - gps + template + struct width { + +#ifdef __BORLANDC__ + BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT); +#else + BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits::digits)); +#endif + + }; + + } // detail + + + // --------- + // integer_log2 + // --------------- + // + template + int integer_log2(T x) { + + assert(x > 0); + + const int n = detail::max_pow2_less< + detail::width :: value, 4 + > :: value; + + return detail::integer_log2_impl(x, n); + + } + + + +} + + + +#endif // include guard diff --git a/include/boost/pending/integer_log2.hpp b/include/boost/pending/integer_log2.hpp index f4bc846..023ec7a 100644 --- a/include/boost/pending/integer_log2.hpp +++ b/include/boost/pending/integer_log2.hpp @@ -1,112 +1,9 @@ -// ----------------------------------------------------------- -// integer_log2.hpp -// -// Gives the integer part of the logarithm, in base 2, of a -// given number. Behavior is undefined if the argument is <= 0. -// -// Copyright (c) 2003-2004, 2008 Gennaro Prota -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// ----------------------------------------------------------- +#ifndef BOOST_PENDING_INTEGER_LOG2_HPP +#define BOOST_PENDING_INTEGER_LOG2_HPP -#ifndef BOOST_INTEGER_LOG2_HPP_GP_20030301 -#define BOOST_INTEGER_LOG2_HPP_GP_20030301 +// The header file at this path is deprecated; +// use boost/integer/integer_log2.hpp instead. + +#include -#include -#ifdef __BORLANDC__ -#include #endif -#include "boost/limits.hpp" -#include "boost/config.hpp" - - -namespace boost { - namespace detail { - - template - int integer_log2_impl(T x, int n) { - - int result = 0; - - while (x != 1) { - - const T t = static_cast(x >> n); - if (t) { - result += n; - x = t; - } - n /= 2; - - } - - return result; - } - - - - // helper to find the maximum power of two - // less than p (more involved than necessary, - // to avoid PTS) - // - template - struct max_pow2_less { - - enum { c = 2*n < p }; - - BOOST_STATIC_CONSTANT(int, value = - c ? (max_pow2_less< c*p, 2*c*n>::value) : n); - - }; - - template <> - struct max_pow2_less<0, 0> { - - BOOST_STATIC_CONSTANT(int, value = 0); - }; - - // this template is here just for Borland :( - // we could simply rely on numeric_limits but sometimes - // Borland tries to use numeric_limits, because - // of its usual const-related problems in argument deduction - // - gps - template - struct width { - -#ifdef __BORLANDC__ - BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT); -#else - BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits::digits)); -#endif - - }; - - } // detail - - - // --------- - // integer_log2 - // --------------- - // - template - int integer_log2(T x) { - - assert(x > 0); - - const int n = detail::max_pow2_less< - detail::width :: value, 4 - > :: value; - - return detail::integer_log2_impl(x, n); - - } - - - -} - - - -#endif // include guard