296 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			296 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								/////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// (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.shtml
							 | 
						||
| 
								 | 
							
								inline 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 enable_if< numbits_eq<SizeType, 32> >::type>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   static const SizeType value = 0xb504f334;
							 | 
						||
| 
								 | 
							
								   static const std::size_t pow   = 31;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BOOST_NO_INT64_T
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class SizeType>
							 | 
						||
| 
								 | 
							
								struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 64> >::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
							 |