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/pointer_traits.hpp>
25#include <boost/intrusive/detail/parent_from_member.hpp>
26#include <boost/intrusive/link_mode.hpp>
27#include <boost/intrusive/detail/mpl.hpp>
28#include <boost/intrusive/detail/to_raw_pointer.hpp>
29#include <boost/intrusive/detail/node_holder.hpp>
30
31namespace boost {
32namespace intrusive {
33
34template<class T, class NodePtr, class Tag, unsigned int Type>
35struct bhtraits_base
36{
37 public:
38 typedef NodePtr node_ptr;
39 typedef typename pointer_traits<node_ptr>::element_type node;
40 typedef node_holder<node, Tag, Type> node_holder_type;
41 typedef T value_type;
42 typedef typename pointer_traits<node_ptr>::
43 template rebind_pointer<const node>::type const_node_ptr;
44 typedef typename pointer_traits<node_ptr>::
45 template rebind_pointer<T>::type pointer;
46 typedef typename pointer_traits<node_ptr>::
47 template rebind_pointer<const T>::type const_pointer;
48 //typedef typename pointer_traits<pointer>::reference reference;
49 //typedef typename pointer_traits<const_pointer>::reference const_reference;
50 typedef T & reference;
51 typedef const T & const_reference;
52 typedef node_holder_type & node_holder_reference;
53 typedef const node_holder_type & const_node_holder_reference;
54 typedef node& node_reference;
55 typedef const node & const_node_reference;
56
57 static pointer to_value_ptr(const node_ptr & n)
58 {
59 return pointer_traits<pointer>::pointer_to
60 (static_cast<reference>(static_cast<node_holder_reference>(*n)));
61 }
62
63 static const_pointer to_value_ptr(const const_node_ptr & n)
64 {
65 return pointer_traits<const_pointer>::pointer_to
66 (static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
67 }
68
69 static node_ptr to_node_ptr(reference value)
70 {
71 return pointer_traits<node_ptr>::pointer_to
72 (static_cast<node_reference>(static_cast<node_holder_reference>(value)));
73 }
74
75 static const_node_ptr to_node_ptr(const_reference value)
76 {
77 return pointer_traits<const_node_ptr>::pointer_to
78 (static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
79 }
80};
81
82template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, unsigned int Type>
83struct bhtraits
84 : public bhtraits_base<T, typename NodeTraits::node_ptr, Tag, Type>
85{
86 static const link_mode_type link_mode = LinkMode;
87 typedef NodeTraits node_traits;
88};
89
90
91template<class T, class Hook, Hook T::* P>
92struct mhtraits
93{
94 public:
95 typedef Hook hook_type;
96 typedef typename hook_type::hooktags::node_traits node_traits;
97 typedef typename node_traits::node node;
98 typedef T value_type;
99 typedef typename node_traits::node_ptr node_ptr;
100 typedef typename node_traits::const_node_ptr const_node_ptr;
101 typedef typename pointer_traits<node_ptr>::
102 template rebind_pointer<T>::type pointer;
103 typedef typename pointer_traits<node_ptr>::
104 template rebind_pointer<const T>::type const_pointer;
105 typedef T & reference;
106 typedef const T & const_reference;
107 typedef node& node_reference;
108 typedef const node & const_node_reference;
109 typedef hook_type& hook_reference;
110 typedef const hook_type & const_hook_reference;
111
112 static const link_mode_type link_mode = Hook::hooktags::link_mode;
113
114 static node_ptr to_node_ptr(reference value)
115 {
116 return pointer_traits<node_ptr>::pointer_to
117 (static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
118 }
119
120 static const_node_ptr to_node_ptr(const_reference value)
121 {
122 return pointer_traits<const_node_ptr>::pointer_to
123 (static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
124 }
125
126 static pointer to_value_ptr(const node_ptr & n)
127 {
128 return pointer_traits<pointer>::pointer_to
129 (*detail::parent_from_member<T, Hook>
130 (static_cast<Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
131 }
132
133 static const_pointer to_value_ptr(const const_node_ptr & n)
134 {
135 return pointer_traits<const_pointer>::pointer_to
136 (*detail::parent_from_member<T, Hook>
137 (static_cast<const Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
138 }
139};
140
141
142template<class Functor>
143struct fhtraits
144{
145 public:
146 typedef typename Functor::hook_type hook_type;
147 typedef typename Functor::hook_ptr hook_ptr;
148 typedef typename Functor::const_hook_ptr const_hook_ptr;
149 typedef typename hook_type::hooktags::node_traits node_traits;
150 typedef typename node_traits::node node;
151 typedef typename Functor::value_type value_type;
152 typedef typename node_traits::node_ptr node_ptr;
153 typedef typename node_traits::const_node_ptr const_node_ptr;
154 typedef typename pointer_traits<node_ptr>::
155 template rebind_pointer<value_type>::type pointer;
156 typedef typename pointer_traits<node_ptr>::
157 template rebind_pointer<const value_type>::type const_pointer;
158 typedef value_type & reference;
159 typedef const value_type & const_reference;
160 static const link_mode_type link_mode = hook_type::hooktags::link_mode;
161
162 static node_ptr to_node_ptr(reference value)
163 { return static_cast<node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
164
165 static const_node_ptr to_node_ptr(const_reference value)
166 { return static_cast<const node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
167
168 static pointer to_value_ptr(const node_ptr & n)
169 { return Functor::to_value_ptr(to_hook_ptr(n)); }
170
171 static const_pointer to_value_ptr(const const_node_ptr & n)
172 { return Functor::to_value_ptr(to_hook_ptr(n)); }
173
174 private:
175 static hook_ptr to_hook_ptr(const node_ptr & n)
176 { return hook_ptr(&*static_cast<hook_type*>(&*n)); }
177
178 static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
179 { return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
180};
181
182
183} //namespace intrusive
184} //namespace boost
185
186#endif //BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
187