1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/integer/static_log2.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,132 @@
1.4 +// -------------- Boost static_log2.hpp header file ----------------------- //
1.5 +//
1.6 +// Copyright (C) 2001 Daryle Walker.
1.7 +// Copyright (C) 2003 Vesa Karvonen.
1.8 +// Copyright (C) 2003 Gennaro Prota.
1.9 +//
1.10 +// Distributed under the Boost Software License, Version 1.0.
1.11 +// (See accompanying file LICENSE_1_0.txt or copy at
1.12 +// http://www.boost.org/LICENSE_1_0.txt)
1.13 +//
1.14 +// ---------------------------------------------------
1.15 +// See http://www.boost.org/libs/integer for documentation.
1.16 +// ------------------------------------------------------------------------- //
1.17 +
1.18 +
1.19 +#ifndef BOOST_INTEGER_STATIC_LOG2_HPP
1.20 +#define BOOST_INTEGER_STATIC_LOG2_HPP
1.21 +
1.22 +#include "boost/config.hpp" // for BOOST_STATIC_CONSTANT
1.23 +
1.24 +namespace boost {
1.25 +
1.26 + namespace detail {
1.27 +
1.28 + namespace static_log2_impl {
1.29 +
1.30 + // choose_initial_n<>
1.31 + //
1.32 + // Recursively doubles its integer argument, until it
1.33 + // becomes >= of the "width" (C99, 6.2.6.2p4) of
1.34 + // static_log2_argument_type.
1.35 + //
1.36 + // Used to get the maximum power of two less then the width.
1.37 + //
1.38 + // Example: if on your platform argument_type has 48 value
1.39 + // bits it yields n=32.
1.40 + //
1.41 + // It's easy to prove that, starting from such a value
1.42 + // of n, the core algorithm works correctly for any width
1.43 + // of static_log2_argument_type and that recursion always
1.44 + // terminates with x = 1 and n = 0 (see the algorithm's
1.45 + // invariant).
1.46 +
1.47 + typedef unsigned long argument_type;
1.48 + typedef int result_type;
1.49 +
1.50 +
1.51 + template <result_type n>
1.52 + struct choose_initial_n {
1.53 +
1.54 + enum { c = (argument_type(1) << n << n) != 0 };
1.55 + BOOST_STATIC_CONSTANT(
1.56 + result_type,
1.57 + value = !c*n + choose_initial_n<2*c*n>::value
1.58 + );
1.59 +
1.60 + };
1.61 +
1.62 + template <>
1.63 + struct choose_initial_n<0> {
1.64 + BOOST_STATIC_CONSTANT(result_type, value = 0);
1.65 + };
1.66 +
1.67 +
1.68 +
1.69 + // start computing from n_zero - must be a power of two
1.70 + const result_type n_zero = 16;
1.71 + const result_type initial_n = choose_initial_n<n_zero>::value;
1.72 +
1.73 + // static_log2_impl<>
1.74 + //
1.75 + // * Invariant:
1.76 + // 2n
1.77 + // 1 <= x && x < 2 at the start of each recursion
1.78 + // (see also choose_initial_n<>)
1.79 + //
1.80 + // * Type requirements:
1.81 + //
1.82 + // argument_type maybe any unsigned type with at least n_zero + 1
1.83 + // value bits. (Note: If larger types will be standardized -e.g.
1.84 + // unsigned long long- then the argument_type typedef can be
1.85 + // changed without affecting the rest of the code.)
1.86 + //
1.87 +
1.88 + template <argument_type x, result_type n = initial_n>
1.89 + struct static_log2_impl {
1.90 +
1.91 + enum { c = (x >> n) > 0 }; // x >= 2**n ?
1.92 + BOOST_STATIC_CONSTANT(
1.93 + result_type,
1.94 + value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value)
1.95 + );
1.96 +
1.97 + };
1.98 +
1.99 + template <>
1.100 + struct static_log2_impl<1, 0> {
1.101 + BOOST_STATIC_CONSTANT(result_type, value = 0);
1.102 + };
1.103 +
1.104 + }
1.105 + } // detail
1.106 +
1.107 +
1.108 +
1.109 + // --------------------------------------
1.110 + // static_log2<x>
1.111 + // ----------------------------------------
1.112 +
1.113 + typedef detail::static_log2_impl::argument_type static_log2_argument_type;
1.114 + typedef detail::static_log2_impl::result_type static_log2_result_type;
1.115 +
1.116 +
1.117 + template <static_log2_argument_type x>
1.118 + struct static_log2 {
1.119 +
1.120 + BOOST_STATIC_CONSTANT(
1.121 + static_log2_result_type,
1.122 + value = detail::static_log2_impl::static_log2_impl<x>::value
1.123 + );
1.124 +
1.125 + };
1.126 +
1.127 +
1.128 + template <>
1.129 + struct static_log2<0> { };
1.130 +
1.131 +}
1.132 +
1.133 +
1.134 +
1.135 +#endif // include guard