1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga  2006-2014
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_DETAIL_HOOK_TRAITS_HPP
14 #define BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
15 
16 #ifndef BOOST_CONFIG_HPP
17 #  include <boost/config.hpp>
18 #endif
19 
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
21 #  pragma once
22 #endif
23 
24 #include <boost/intrusive/detail/workaround.hpp>
25 #include <boost/intrusive/pointer_traits.hpp>
26 #include <boost/intrusive/detail/parent_from_member.hpp>
27 #include <boost/intrusive/link_mode.hpp>
28 #include <boost/intrusive/detail/mpl.hpp>
29 #include <boost/move/detail/to_raw_pointer.hpp>
30 #include <boost/intrusive/detail/node_holder.hpp>
31 
32 namespace boost {
33 namespace intrusive {
34 
35 template<class T, class NodePtr, class Tag, unsigned int Type>
36 struct bhtraits_base
37 {
38    public:
39    typedef NodePtr                                                   node_ptr;
40    typedef typename pointer_traits<node_ptr>::element_type           node;
41    typedef node_holder<node, Tag, Type>                              node_holder_type;
42    typedef T                                                         value_type;
43    typedef typename pointer_traits<node_ptr>::
44       template rebind_pointer<const node>::type                      const_node_ptr;
45    typedef typename pointer_traits<node_ptr>::
46       template rebind_pointer<T>::type                               pointer;
47    typedef typename pointer_traits<node_ptr>::
48       template rebind_pointer<const T>::type                         const_pointer;
49    //typedef typename pointer_traits<pointer>::reference               reference;
50    //typedef typename pointer_traits<const_pointer>::reference         const_reference;
51    typedef T &                                                       reference;
52    typedef const T &                                                 const_reference;
53    typedef node_holder_type &                                        node_holder_reference;
54    typedef const node_holder_type &                                  const_node_holder_reference;
55    typedef node&                                                     node_reference;
56    typedef const node &                                              const_node_reference;
57 
to_value_ptrboost::intrusive::bhtraits_base58    BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n)
59    {
60       pointer p = pointer_traits<pointer>::pointer_to
61          (static_cast<reference>(static_cast<node_holder_reference>(*n)));
62       BOOST_ASSERT(!!p);
63       return p;
64    }
65 
to_value_ptrboost::intrusive::bhtraits_base66    BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n)
67    {
68       const_pointer p = pointer_traits<const_pointer>::pointer_to
69          (static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
70       BOOST_ASSERT(!!p);
71       return p;
72    }
73 
to_node_ptrboost::intrusive::bhtraits_base74    BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value)
75    {
76       node_ptr p = pointer_traits<node_ptr>::pointer_to
77          (static_cast<node_reference>(static_cast<node_holder_reference>(value)));
78       BOOST_ASSERT(!!p);
79       return p;
80    }
81 
to_node_ptrboost::intrusive::bhtraits_base82    BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value)
83    {
84       const_node_ptr p = pointer_traits<const_node_ptr>::pointer_to
85          (static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
86       BOOST_ASSERT(!!p);
87       return p;
88    }
89 };
90 
91 template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, unsigned int Type>
92 struct bhtraits
93    : public bhtraits_base<T, typename NodeTraits::node_ptr, Tag, Type>
94 {
95    static const link_mode_type link_mode = LinkMode;
96    typedef NodeTraits node_traits;
97 };
98 
99 
100 template<class T, class Hook, Hook T::* P>
101 struct mhtraits
102 {
103    public:
104    typedef Hook                                                      hook_type;
105    typedef typename hook_type::hooktags::node_traits                 node_traits;
106    typedef typename node_traits::node                                node;
107    typedef T                                                         value_type;
108    typedef typename node_traits::node_ptr                            node_ptr;
109    typedef typename node_traits::const_node_ptr                      const_node_ptr;
110    typedef typename pointer_traits<node_ptr>::
111       template rebind_pointer<T>::type                               pointer;
112    typedef typename pointer_traits<node_ptr>::
113       template rebind_pointer<const T>::type                         const_pointer;
114    typedef T &                                                       reference;
115    typedef const T &                                                 const_reference;
116    typedef node&                                                     node_reference;
117    typedef const node &                                              const_node_reference;
118    typedef hook_type&                                                hook_reference;
119    typedef const hook_type &                                         const_hook_reference;
120 
121    static const link_mode_type link_mode = Hook::hooktags::link_mode;
122 
to_node_ptrboost::intrusive::mhtraits123    BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value)
124    {
125       return pointer_traits<node_ptr>::pointer_to
126          (static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
127    }
128 
to_node_ptrboost::intrusive::mhtraits129    BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value)
130    {
131       return pointer_traits<const_node_ptr>::pointer_to
132          (static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
133    }
134 
to_value_ptrboost::intrusive::mhtraits135    BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n)
136    {
137       return pointer_traits<pointer>::pointer_to
138          (*detail::parent_from_member<T, Hook>
139             (static_cast<Hook*>(boost::movelib::to_raw_pointer(n)), P));
140    }
141 
to_value_ptrboost::intrusive::mhtraits142    BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n)
143    {
144       return pointer_traits<const_pointer>::pointer_to
145          (*detail::parent_from_member<T, Hook>
146             (static_cast<const Hook*>(boost::movelib::to_raw_pointer(n)), P));
147    }
148 };
149 
150 
151 template<class Functor>
152 struct fhtraits
153 {
154    public:
155    typedef typename Functor::hook_type                               hook_type;
156    typedef typename Functor::hook_ptr                                hook_ptr;
157    typedef typename Functor::const_hook_ptr                          const_hook_ptr;
158    typedef typename hook_type::hooktags::node_traits                 node_traits;
159    typedef typename node_traits::node                                node;
160    typedef typename Functor::value_type                              value_type;
161    typedef typename node_traits::node_ptr                            node_ptr;
162    typedef typename node_traits::const_node_ptr                      const_node_ptr;
163    typedef typename pointer_traits<node_ptr>::
164       template rebind_pointer<value_type>::type                      pointer;
165    typedef typename pointer_traits<node_ptr>::
166       template rebind_pointer<const value_type>::type                const_pointer;
167    typedef value_type &                                              reference;
168    typedef const value_type &                                        const_reference;
169    static const link_mode_type link_mode = hook_type::hooktags::link_mode;
170 
to_node_ptrboost::intrusive::fhtraits171    static node_ptr to_node_ptr(reference value)
172    {  return static_cast<node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value)));  }
173 
to_node_ptrboost::intrusive::fhtraits174    static const_node_ptr to_node_ptr(const_reference value)
175    {  return static_cast<const node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value)));  }
176 
to_value_ptrboost::intrusive::fhtraits177    static pointer to_value_ptr(const node_ptr & n)
178    {  return Functor::to_value_ptr(to_hook_ptr(n));  }
179 
to_value_ptrboost::intrusive::fhtraits180    static const_pointer to_value_ptr(const const_node_ptr & n)
181    {  return Functor::to_value_ptr(to_hook_ptr(n));  }
182 
183    private:
to_hook_ptrboost::intrusive::fhtraits184    static hook_ptr to_hook_ptr(const node_ptr & n)
185    {  return hook_ptr(&*static_cast<hook_type*>(&*n));  }
186 
to_hook_ptrboost::intrusive::fhtraits187    static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
188    {  return const_hook_ptr(&*static_cast<const hook_type*>(&*n));  }
189 };
190 
191 
192 } //namespace intrusive
193 } //namespace boost
194 
195 #endif //BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
196