Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:21

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga  2007-2013
0004 //
0005 // Distributed under the Boost Software License, Version 1.0.
0006 //    (See accompanying file LICENSE_1_0.txt or copy at
0007 //          http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // See http://www.boost.org/libs/intrusive for documentation.
0010 //
0011 /////////////////////////////////////////////////////////////////////////////
0012 
0013 #ifndef BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
0014 #define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
0015 
0016 #include <boost/intrusive/detail/config_begin.hpp>
0017 #include <boost/intrusive/intrusive_fwd.hpp>
0018 #include <boost/intrusive/detail/mpl.hpp> //ls_zeros
0019 #include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
0020 
0021 #if defined(BOOST_HAS_PRAGMA_ONCE)
0022 #  pragma once
0023 #endif
0024 
0025 
0026 //GCC reports uninitialized values when an uninitialized pointer plus bits type
0027 //is asigned some bits or some pointer value, but that's ok, because we don't want
0028 //to default initialize parts that are not being updated.
0029 #if defined(BOOST_GCC)
0030 #  if (BOOST_GCC >= 40600)
0031 #     pragma GCC diagnostic push
0032 #     pragma GCC diagnostic ignored "-Wuninitialized"
0033 #     if (BOOST_GCC >= 40700)
0034 #        pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0035 #     endif
0036 #  endif
0037 #endif
0038 
0039 namespace boost {
0040 namespace intrusive {
0041 
0042 //!This trait class is used to know if a pointer
0043 //!can embed extra bits of information if
0044 //!it's going to be used to point to objects
0045 //!with an alignment of "Alignment" bytes.
0046 template<class VoidPointer, std::size_t Alignment>
0047 struct max_pointer_plus_bits
0048 {
0049    static const std::size_t value = 0;
0050 };
0051 
0052 //!This is a specialization for raw pointers.
0053 //!Raw pointers can embed extra bits in the lower bits
0054 //!if the alignment is multiple of 2pow(NumBits).
0055 template<std::size_t Alignment>
0056 struct max_pointer_plus_bits<void*, Alignment>
0057 {
0058    static const std::size_t value = detail::ls_zeros<Alignment>::value;
0059 };
0060 
0061 //!This is class that is supposed to have static methods
0062 //!to embed extra bits of information in a pointer.
0063 //!This is a declaration and there is no default implementation,
0064 //!because operations to embed the bits change with every pointer type.
0065 //!
0066 //!An implementation that detects that a pointer type whose
0067 //!has_pointer_plus_bits<>::value is non-zero can make use of these
0068 //!operations to embed the bits in the pointer.
0069 template<class Pointer, std::size_t NumBits>
0070 struct pointer_plus_bits
0071    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0072    {}
0073    #endif
0074 ;
0075 
0076 //!This is the specialization to embed extra bits of information
0077 //!in a raw pointer. The extra bits are stored in the lower bits of the pointer.
0078 template<class T, std::size_t NumBits>
0079 struct pointer_plus_bits<T*, NumBits>
0080 {
0081    static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1);
0082    typedef T*        pointer;
0083 
0084    BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) BOOST_NOEXCEPT
0085    {  return pointer(uintptr_t(n) & uintptr_t(~Mask));  }
0086 
0087    BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) BOOST_NOEXCEPT
0088    {
0089       BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask));
0090       n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask));
0091    }
0092 
0093    BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) BOOST_NOEXCEPT
0094    {  return std::size_t(uintptr_t(n) & Mask);  }
0095 
0096    BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) BOOST_NOEXCEPT
0097    {
0098       BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask);
0099       n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c));
0100    }
0101 };
0102 
0103 } //namespace intrusive
0104 } //namespace boost
0105 
0106 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
0107 #  pragma GCC diagnostic pop
0108 #endif
0109 
0110 #include <boost/intrusive/detail/config_end.hpp>
0111 
0112 #endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP