annotate DEPENDENCIES/generic/include/boost/integer/static_log2.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // -------------- Boost static_log2.hpp header file ----------------------- //
Chris@16 2 //
Chris@16 3 // Copyright (C) 2001 Daryle Walker.
Chris@16 4 // Copyright (C) 2003 Vesa Karvonen.
Chris@16 5 // Copyright (C) 2003 Gennaro Prota.
Chris@16 6 //
Chris@16 7 // Distributed under the Boost Software License, Version 1.0.
Chris@16 8 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 9 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10 //
Chris@16 11 // ---------------------------------------------------
Chris@16 12 // See http://www.boost.org/libs/integer for documentation.
Chris@16 13 // ------------------------------------------------------------------------- //
Chris@16 14
Chris@16 15
Chris@16 16 #ifndef BOOST_INTEGER_STATIC_LOG2_HPP
Chris@16 17 #define BOOST_INTEGER_STATIC_LOG2_HPP
Chris@16 18
Chris@16 19 #include "boost/integer_fwd.hpp" // for boost::intmax_t
Chris@16 20
Chris@16 21 namespace boost {
Chris@16 22
Chris@16 23 namespace detail {
Chris@16 24
Chris@16 25 namespace static_log2_impl {
Chris@16 26
Chris@16 27 // choose_initial_n<>
Chris@16 28 //
Chris@16 29 // Recursively doubles its integer argument, until it
Chris@16 30 // becomes >= of the "width" (C99, 6.2.6.2p4) of
Chris@16 31 // static_log2_argument_type.
Chris@16 32 //
Chris@16 33 // Used to get the maximum power of two less then the width.
Chris@16 34 //
Chris@16 35 // Example: if on your platform argument_type has 48 value
Chris@16 36 // bits it yields n=32.
Chris@16 37 //
Chris@16 38 // It's easy to prove that, starting from such a value
Chris@16 39 // of n, the core algorithm works correctly for any width
Chris@16 40 // of static_log2_argument_type and that recursion always
Chris@16 41 // terminates with x = 1 and n = 0 (see the algorithm's
Chris@16 42 // invariant).
Chris@16 43
Chris@16 44 typedef boost::static_log2_argument_type argument_type;
Chris@16 45 typedef boost::static_log2_result_type result_type;
Chris@16 46
Chris@16 47 template <result_type n>
Chris@16 48 struct choose_initial_n {
Chris@16 49
Chris@16 50 BOOST_STATIC_CONSTANT(bool, c = (argument_type(1) << n << n) != 0);
Chris@16 51 BOOST_STATIC_CONSTANT(
Chris@16 52 result_type,
Chris@16 53 value = !c*n + choose_initial_n<2*c*n>::value
Chris@16 54 );
Chris@16 55
Chris@16 56 };
Chris@16 57
Chris@16 58 template <>
Chris@16 59 struct choose_initial_n<0> {
Chris@16 60 BOOST_STATIC_CONSTANT(result_type, value = 0);
Chris@16 61 };
Chris@16 62
Chris@16 63
Chris@16 64
Chris@16 65 // start computing from n_zero - must be a power of two
Chris@16 66 const result_type n_zero = 16;
Chris@16 67 const result_type initial_n = choose_initial_n<n_zero>::value;
Chris@16 68
Chris@16 69 // static_log2_impl<>
Chris@16 70 //
Chris@16 71 // * Invariant:
Chris@16 72 // 2n
Chris@16 73 // 1 <= x && x < 2 at the start of each recursion
Chris@16 74 // (see also choose_initial_n<>)
Chris@16 75 //
Chris@16 76 // * Type requirements:
Chris@16 77 //
Chris@16 78 // argument_type maybe any unsigned type with at least n_zero + 1
Chris@16 79 // value bits. (Note: If larger types will be standardized -e.g.
Chris@16 80 // unsigned long long- then the argument_type typedef can be
Chris@16 81 // changed without affecting the rest of the code.)
Chris@16 82 //
Chris@16 83
Chris@16 84 template <argument_type x, result_type n = initial_n>
Chris@16 85 struct static_log2_impl {
Chris@16 86
Chris@16 87 BOOST_STATIC_CONSTANT(bool, c = (x >> n) > 0); // x >= 2**n ?
Chris@16 88 BOOST_STATIC_CONSTANT(
Chris@16 89 result_type,
Chris@16 90 value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value)
Chris@16 91 );
Chris@16 92
Chris@16 93 };
Chris@16 94
Chris@16 95 template <>
Chris@16 96 struct static_log2_impl<1, 0> {
Chris@16 97 BOOST_STATIC_CONSTANT(result_type, value = 0);
Chris@16 98 };
Chris@16 99
Chris@16 100 }
Chris@16 101 } // detail
Chris@16 102
Chris@16 103
Chris@16 104
Chris@16 105 // --------------------------------------
Chris@16 106 // static_log2<x>
Chris@16 107 // ----------------------------------------
Chris@16 108
Chris@16 109 template <static_log2_argument_type x>
Chris@16 110 struct static_log2 {
Chris@16 111
Chris@16 112 BOOST_STATIC_CONSTANT(
Chris@16 113 static_log2_result_type,
Chris@16 114 value = detail::static_log2_impl::static_log2_impl<x>::value
Chris@16 115 );
Chris@16 116
Chris@16 117 };
Chris@16 118
Chris@16 119
Chris@16 120 template <>
Chris@16 121 struct static_log2<0> { };
Chris@16 122
Chris@16 123 }
Chris@16 124
Chris@16 125
Chris@16 126
Chris@16 127 #endif // include guard