95 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// (C) Copyright Ion Gaztanaga  2007-2013
 | 
						|
//
 | 
						|
// 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_POINTER_PLUS_BITS_HPP
 | 
						|
#define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
 | 
						|
 | 
						|
#include <boost/intrusive/detail/config_begin.hpp>
 | 
						|
#include <boost/intrusive/intrusive_fwd.hpp>
 | 
						|
#include <boost/intrusive/detail/mpl.hpp> //ls_zeros
 | 
						|
#include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
 | 
						|
 | 
						|
#if defined(BOOST_HAS_PRAGMA_ONCE)
 | 
						|
#  pragma once
 | 
						|
#endif
 | 
						|
 | 
						|
namespace boost {
 | 
						|
namespace intrusive {
 | 
						|
 | 
						|
//!This trait class is used to know if a pointer
 | 
						|
//!can embed extra bits of information if
 | 
						|
//!it's going to be used to point to objects
 | 
						|
//!with an alignment of "Alignment" bytes.
 | 
						|
template<class VoidPointer, std::size_t Alignment>
 | 
						|
struct max_pointer_plus_bits
 | 
						|
{
 | 
						|
   static const std::size_t value = 0;
 | 
						|
};
 | 
						|
 | 
						|
//!This is a specialization for raw pointers.
 | 
						|
//!Raw pointers can embed extra bits in the lower bits
 | 
						|
//!if the alignment is multiple of 2pow(NumBits).
 | 
						|
template<std::size_t Alignment>
 | 
						|
struct max_pointer_plus_bits<void*, Alignment>
 | 
						|
{
 | 
						|
   static const std::size_t value = detail::ls_zeros<Alignment>::value;
 | 
						|
};
 | 
						|
 | 
						|
//!This is class that is supposed to have static methods
 | 
						|
//!to embed extra bits of information in a pointer.
 | 
						|
//!This is a declaration and there is no default implementation,
 | 
						|
//!because operations to embed the bits change with every pointer type.
 | 
						|
//!
 | 
						|
//!An implementation that detects that a pointer type whose
 | 
						|
//!has_pointer_plus_bits<>::value is non-zero can make use of these
 | 
						|
//!operations to embed the bits in the pointer.
 | 
						|
template<class Pointer, std::size_t NumBits>
 | 
						|
struct pointer_plus_bits
 | 
						|
   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
 | 
						|
   {}
 | 
						|
   #endif
 | 
						|
;
 | 
						|
 | 
						|
//!This is the specialization to embed extra bits of information
 | 
						|
//!in a raw pointer. The extra bits are stored in the lower bits of the pointer.
 | 
						|
template<class T, std::size_t NumBits>
 | 
						|
struct pointer_plus_bits<T*, NumBits>
 | 
						|
{
 | 
						|
   static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1);
 | 
						|
   typedef T*        pointer;
 | 
						|
 | 
						|
   BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n)
 | 
						|
   {  return pointer(uintptr_t(n) & uintptr_t(~Mask));  }
 | 
						|
 | 
						|
   BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p)
 | 
						|
   {
 | 
						|
      BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask));
 | 
						|
      n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask));
 | 
						|
   }
 | 
						|
 | 
						|
   BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n)
 | 
						|
   {  return std::size_t(uintptr_t(n) & Mask);  }
 | 
						|
 | 
						|
   BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c)
 | 
						|
   {
 | 
						|
      BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask);
 | 
						|
      n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c));
 | 
						|
   }
 | 
						|
};
 | 
						|
 | 
						|
} //namespace intrusive
 | 
						|
} //namespace boost
 | 
						|
 | 
						|
#include <boost/intrusive/detail/config_end.hpp>
 | 
						|
 | 
						|
#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
 |