1 ///////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2007-2013 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // See http://www.boost.org/libs/intrusive for documentation. 10 // 11 ///////////////////////////////////////////////////////////////////////////// 12 13 #ifndef BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP 14 #define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP 15 16 #include <boost/intrusive/detail/config_begin.hpp> 17 #include <boost/intrusive/intrusive_fwd.hpp> 18 #include <boost/intrusive/detail/mpl.hpp> //ls_zeros 19 #include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT 20 21 #if defined(BOOST_HAS_PRAGMA_ONCE) 22 # pragma once 23 #endif 24 25 26 //GCC reports uninitialized values when an uninitialized pointer plus bits type 27 //is asigned some bits or some pointer value, but that's ok, because we don't want 28 //to default initialize parts that are not being updated. 29 #if defined(BOOST_GCC) 30 # if (BOOST_GCC >= 40600) 31 # pragma GCC diagnostic push 32 # pragma GCC diagnostic ignored "-Wuninitialized" 33 # if (BOOST_GCC >= 40700) 34 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 35 # endif 36 # endif 37 #endif 38 39 namespace boost { 40 namespace intrusive { 41 42 //!This trait class is used to know if a pointer 43 //!can embed extra bits of information if 44 //!it's going to be used to point to objects 45 //!with an alignment of "Alignment" bytes. 46 template<class VoidPointer, std::size_t Alignment> 47 struct max_pointer_plus_bits 48 { 49 static const std::size_t value = 0; 50 }; 51 52 //!This is a specialization for raw pointers. 53 //!Raw pointers can embed extra bits in the lower bits 54 //!if the alignment is multiple of 2pow(NumBits). 55 template<std::size_t Alignment> 56 struct max_pointer_plus_bits<void*, Alignment> 57 { 58 static const std::size_t value = detail::ls_zeros<Alignment>::value; 59 }; 60 61 //!This is class that is supposed to have static methods 62 //!to embed extra bits of information in a pointer. 63 //!This is a declaration and there is no default implementation, 64 //!because operations to embed the bits change with every pointer type. 65 //! 66 //!An implementation that detects that a pointer type whose 67 //!has_pointer_plus_bits<>::value is non-zero can make use of these 68 //!operations to embed the bits in the pointer. 69 template<class Pointer, std::size_t NumBits> 70 struct pointer_plus_bits 71 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED 72 {} 73 #endif 74 ; 75 76 //!This is the specialization to embed extra bits of information 77 //!in a raw pointer. The extra bits are stored in the lower bits of the pointer. 78 template<class T, std::size_t NumBits> 79 struct pointer_plus_bits<T*, NumBits> 80 { 81 static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1); 82 typedef T* pointer; 83 get_pointerboost::intrusive::pointer_plus_bits84 BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) 85 { return pointer(uintptr_t(n) & uintptr_t(~Mask)); } 86 set_pointerboost::intrusive::pointer_plus_bits87 BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) 88 { 89 BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask)); 90 n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask)); 91 } 92 get_bitsboost::intrusive::pointer_plus_bits93 BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) 94 { return std::size_t(uintptr_t(n) & Mask); } 95 set_bitsboost::intrusive::pointer_plus_bits96 BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) 97 { 98 BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask); 99 n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c)); 100 } 101 }; 102 103 } //namespace intrusive 104 } //namespace boost 105 106 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) 107 # pragma GCC diagnostic pop 108 #endif 109 110 #include <boost/intrusive/detail/config_end.hpp> 111 112 #endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP 113