| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 | ///////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga  2014-2014//// 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)//// See http://www.boost.org/libs/intrusive for documentation.///////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTRUSIVE_DETAIL_MATH_HPP#define BOOST_INTRUSIVE_DETAIL_MATH_HPP#ifndef BOOST_CONFIG_HPP#  include <boost/config.hpp>#endif#if defined(BOOST_HAS_PRAGMA_ONCE)#  pragma once#endif#include <cstddef>#include <climits>#include <boost/intrusive/detail/mpl.hpp>namespace boost {namespace intrusive {namespace detail {///////////////////////////// floor_log2  Dispatcher////////////////////////////#if defined(_MSC_VER) && (_MSC_VER >= 1300)   }}} //namespace boost::intrusive::detail   //Use _BitScanReverseXX intrinsics   #if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IA64)   //64 bit target      #define BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT   #endif   #ifndef __INTRIN_H_   // Avoid including any windows system header      #ifdef __cplusplus      extern "C" {      #endif // __cplusplus      #if defined(BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT)   //64 bit target         unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);         #pragma intrinsic(_BitScanReverse64)      #else //32 bit target         unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);         #pragma intrinsic(_BitScanReverse)      #endif      #ifdef __cplusplus      }      #endif // __cplusplus   #endif // __INTRIN_H_   #ifdef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT      #define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse64      #undef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT   #else      #define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse   #endif   namespace boost {   namespace intrusive {   namespace detail {   inline std::size_t floor_log2 (std::size_t x)   {      unsigned long log2;      BOOST_INTRUSIVE_BSR_INTRINSIC( &log2, (unsigned long)x );      return log2;   }   #undef BOOST_INTRUSIVE_BSR_INTRINSIC#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4   //Compile-time error in case of missing specialization   template<class Uint>   struct builtin_clz_dispatch;   #if defined(BOOST_HAS_LONG_LONG)   template<>   struct builtin_clz_dispatch< ::boost::ulong_long_type >   {      static ::boost::ulong_long_type call(::boost::ulong_long_type n)      {  return __builtin_clzll(n); }   };   #endif   template<>   struct builtin_clz_dispatch<unsigned long>   {      static unsigned long call(unsigned long n)      {  return __builtin_clzl(n); }   };   template<>   struct builtin_clz_dispatch<unsigned int>   {      static unsigned int call(unsigned int n)      {  return __builtin_clz(n); }   };   inline std::size_t floor_log2(std::size_t n)   {      return sizeof(std::size_t)*CHAR_BIT - std::size_t(1) - builtin_clz_dispatch<std::size_t>::call(n);   }#else //Portable methods////////////////////////////// Generic method////////////////////////////   inline std::size_t floor_log2_get_shift(std::size_t n, true_ )//power of two size_t   {  return n >> 1;  }   inline std::size_t floor_log2_get_shift(std::size_t n, false_ )//non-power of two size_t   {  return (n >> 1) + ((n & 1u) & (n != 1)); }   template<std::size_t N>   inline std::size_t floor_log2 (std::size_t x, integral_constant<std::size_t, N>)   {      const std::size_t Bits = N;      const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));      std::size_t n = x;      std::size_t log2 = 0;      std::size_t remaining_bits = Bits;      std::size_t shift = floor_log2_get_shift(remaining_bits, bool_<Size_t_Bits_Power_2>());      while(shift){         std::size_t tmp = n >> shift;         if (tmp){            log2 += shift, n = tmp;         }         shift = floor_log2_get_shift(shift, bool_<Size_t_Bits_Power_2>());      }      return log2;   }   ////////////////////////////   // DeBruijn method   ////////////////////////////   //Taken from:   //http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers   //Thanks to Desmond Hume   inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 32>)   {      static const int MultiplyDeBruijnBitPosition[32] =      {         0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,         8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31      };      v |= v >> 1;      v |= v >> 2;      v |= v >> 4;      v |= v >> 8;      v |= v >> 16;      return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27];   }   inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 64>)   {      static const std::size_t MultiplyDeBruijnBitPosition[64] = {      63,  0, 58,  1, 59, 47, 53,  2,      60, 39, 48, 27, 54, 33, 42,  3,      61, 51, 37, 40, 49, 18, 28, 20,      55, 30, 34, 11, 43, 14, 22,  4,      62, 57, 46, 52, 38, 26, 32, 41,      50, 36, 17, 19, 29, 10, 13, 21,      56, 45, 25, 31, 35, 16,  9, 12,      44, 24, 15,  8, 23,  7,  6,  5};      v |= v >> 1;      v |= v >> 2;      v |= v >> 4;      v |= v >> 8;      v |= v >> 16;      v |= v >> 32;      return MultiplyDeBruijnBitPosition[((std::size_t)((v - (v >> 1))*0x07EDD5E59A4E28C2ULL)) >> 58];   }   inline std::size_t floor_log2 (std::size_t x)   {      const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;      return floor_log2(x, integral_constant<std::size_t, Bits>());   }#endif//Thanks to Laurent de Soras in//http://www.flipcode.com/archives/Fast_log_Function.shtmlinline float fast_log2 (float val){   union caster_t   {      unsigned x;      float val;   } caster;   caster.val = val;   unsigned x = caster.x;   const int log_2 = int((x >> 23) & 255) - 128;   x &= ~(unsigned(255u) << 23u);   x += unsigned(127) << 23u;   caster.x = x;   val = caster.val;   //1+log2(m), m ranging from 1 to 2   //3rd degree polynomial keeping first derivate continuity.   //For less precision the line can be commented out   val = ((-1.f/3.f) * val + 2.f) * val - (2.f/3.f);   return val + static_cast<float>(log_2);}inline bool is_pow2(std::size_t x){  return (x & (x-1)) == 0;  }template<std::size_t N>struct static_is_pow2{   static const bool value = (N & (N-1)) == 0;};inline std::size_t ceil_log2 (std::size_t x){   return static_cast<std::size_t>(!(is_pow2)(x)) + floor_log2(x);}inline std::size_t ceil_pow2 (std::size_t x){   return std::size_t(1u) << (ceil_log2)(x);}inline std::size_t previous_or_equal_pow2(std::size_t x){   return std::size_t(1u) << floor_log2(x);}template<class SizeType, std::size_t N>struct numbits_eq{   static const bool value = sizeof(SizeType)*CHAR_BIT == N;};template<class SizeType, class Enabler = void >struct sqrt2_pow_max;template <class SizeType>struct sqrt2_pow_max<SizeType, typename voider<typename enable_if< numbits_eq<SizeType, 32> >::type>::type>{   static const SizeType value = 0xb504f334;   static const std::size_t pow   = 31;};#ifndef BOOST_NO_INT64_Ttemplate <class SizeType>struct sqrt2_pow_max<SizeType, typename voider<typename enable_if< numbits_eq<SizeType, 64> >::type>::type>{   static const SizeType value = 0xb504f333f9de6484ull;   static const std::size_t pow   = 63;};#endif   //BOOST_NO_INT64_T// Returns floor(pow(sqrt(2), x * 2 + 1)).// Defined for X from 0 up to the number of bits in size_t minus 1.inline std::size_t sqrt2_pow_2xplus1 (std::size_t x){   const std::size_t value = (std::size_t)sqrt2_pow_max<std::size_t>::value;   const std::size_t pow   = (std::size_t)sqrt2_pow_max<std::size_t>::pow;   return (value >> (pow - x)) + 1;}} //namespace detail} //namespace intrusive} //namespace boost#endif //BOOST_INTRUSIVE_DETAIL_MATH_HPP
 |