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
25namespace boost {
26namespace intrusive {
27
28//!This trait class is used to know if a pointer
29//!can embed extra bits of information if
30//!it's going to be used to point to objects
31//!with an alignment of "Alignment" bytes.
32template<class VoidPointer, std::size_t Alignment>
33struct max_pointer_plus_bits
34{
35 static const std::size_t value = 0;
36};
37
38//!This is a specialization for raw pointers.
39//!Raw pointers can embed extra bits in the lower bits
40//!if the alignment is multiple of 2pow(NumBits).
41template<std::size_t Alignment>
42struct max_pointer_plus_bits<void*, Alignment>
43{
44 static const std::size_t value = detail::ls_zeros<Alignment>::value;
45};
46
47//!This is class that is supposed to have static methods
48//!to embed extra bits of information in a pointer.
49//!This is a declaration and there is no default implementation,
50//!because operations to embed the bits change with every pointer type.
51//!
52//!An implementation that detects that a pointer type whose
53//!has_pointer_plus_bits<>::value is non-zero can make use of these
54//!operations to embed the bits in the pointer.
55template<class Pointer, std::size_t NumBits>
56struct pointer_plus_bits
57 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
58 {}
59 #endif
60;
61
62//!This is the specialization to embed extra bits of information
63//!in a raw pointer. The extra bits are stored in the lower bits of the pointer.
64template<class T, std::size_t NumBits>
65struct pointer_plus_bits<T*, NumBits>
66{
67 static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1);
68 typedef T* pointer;
69
70 static pointer get_pointer(pointer n)
71 { return pointer(uintptr_t(n) & uintptr_t(~Mask)); }
72
73 static void set_pointer(pointer &n, pointer p)
74 {
75 BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask));
76 n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask));
77 }
78
79 static std::size_t get_bits(pointer n)
80 { return std::size_t(uintptr_t(n) & Mask); }
81
82 static void set_bits(pointer &n, std::size_t c)
83 {
84 BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask);
85 n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c));
86 }
87};
88
89} //namespace intrusive
90} //namespace boost
91
92#include <boost/intrusive/detail/config_end.hpp>
93
94#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
95

source code of boost/boost/intrusive/pointer_plus_bits.hpp