Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:24

0001 // -------------- Boost static_log2.hpp header file  ----------------------- //
0002 //
0003 //                 Copyright (C) 2001 Daryle Walker.
0004 //                 Copyright (C) 2003 Vesa Karvonen.
0005 //                 Copyright (C) 2003 Gennaro Prota.
0006 //
0007 //     Distributed under the Boost Software License, Version 1.0.
0008 //        (See accompanying file LICENSE_1_0.txt or copy at
0009 //              https://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 //         ---------------------------------------------------
0012 //       See https://www.boost.org/libs/integer for documentation.
0013 // ------------------------------------------------------------------------- //
0014 
0015 
0016 #ifndef BOOST_INTEGER_STATIC_LOG2_HPP
0017 #define BOOST_INTEGER_STATIC_LOG2_HPP
0018 
0019 #include <boost/config.hpp>
0020 #include <boost/integer_fwd.hpp>
0021 
0022 namespace boost {
0023 
0024  namespace detail {
0025 
0026      namespace static_log2_impl {
0027 
0028      // choose_initial_n<>
0029      //
0030      // Recursively doubles its integer argument, until it
0031      // becomes >= of the "width" (C99, 6.2.6.2p4) of
0032      // static_log2_argument_type.
0033      //
0034      // Used to get the maximum power of two less then the width.
0035      //
0036      // Example: if on your platform argument_type has 48 value
0037      //          bits it yields n=32.
0038      //
0039      // It's easy to prove that, starting from such a value
0040      // of n, the core algorithm works correctly for any width
0041      // of static_log2_argument_type and that recursion always
0042      // terminates with x = 1 and n = 0 (see the algorithm's
0043      // invariant).
0044 
0045      typedef boost::static_log2_argument_type argument_type;
0046      typedef boost::static_log2_result_type result_type;
0047 
0048      template <result_type n>
0049      struct choose_initial_n {
0050 
0051          BOOST_STATIC_CONSTANT(bool, c = (argument_type(1) << n << n) != 0);
0052          BOOST_STATIC_CONSTANT(
0053              result_type,
0054              value = !c*n + choose_initial_n<2*c*n>::value
0055          );
0056 
0057      };
0058 
0059      template <>
0060      struct choose_initial_n<0> {
0061          BOOST_STATIC_CONSTANT(result_type, value = 0);
0062      };
0063 
0064 
0065 
0066      // start computing from n_zero - must be a power of two
0067      const result_type n_zero = 16;
0068      const result_type initial_n = choose_initial_n<n_zero>::value;
0069 
0070      // static_log2_impl<>
0071      //
0072      // * Invariant:
0073      //                 2n
0074      //  1 <= x && x < 2    at the start of each recursion
0075      //                     (see also choose_initial_n<>)
0076      //
0077      // * Type requirements:
0078      //
0079      //   argument_type maybe any unsigned type with at least n_zero + 1
0080      //   value bits. (Note: If larger types will be standardized -e.g.
0081      //   unsigned long long- then the argument_type typedef can be
0082      //   changed without affecting the rest of the code.)
0083      //
0084 
0085      template <argument_type x, result_type n = initial_n>
0086      struct static_log2_impl {
0087 
0088          BOOST_STATIC_CONSTANT(bool, c = (x >> n) > 0); // x >= 2**n ?
0089          BOOST_STATIC_CONSTANT(
0090              result_type,
0091              value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value)
0092          );
0093 
0094      };
0095 
0096      template <>
0097      struct static_log2_impl<1, 0> {
0098         BOOST_STATIC_CONSTANT(result_type, value = 0);
0099      };
0100 
0101      }
0102  } // detail
0103 
0104 
0105 
0106  // --------------------------------------
0107  // static_log2<x>
0108  // ----------------------------------------
0109 
0110  template <static_log2_argument_type x>
0111  struct static_log2 {
0112 
0113      BOOST_STATIC_CONSTANT(
0114          static_log2_result_type,
0115          value = detail::static_log2_impl::static_log2_impl<x>::value
0116      );
0117 
0118  };
0119 
0120 
0121  template <>
0122  struct static_log2<0> { };
0123 
0124 }
0125 
0126 #endif // include guard