Chris@102
|
1 /////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2014-2014
|
Chris@102
|
4 //
|
Chris@102
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@102
|
6 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
8 //
|
Chris@102
|
9 // See http://www.boost.org/libs/intrusive for documentation.
|
Chris@102
|
10 //
|
Chris@102
|
11 /////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
12
|
Chris@102
|
13 #ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP
|
Chris@102
|
14 #define BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP
|
Chris@102
|
15
|
Chris@102
|
16 #ifndef BOOST_CONFIG_HPP
|
Chris@102
|
17 # include <boost/config.hpp>
|
Chris@102
|
18 #endif
|
Chris@102
|
19
|
Chris@102
|
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@102
|
21 # pragma once
|
Chris@102
|
22 #endif
|
Chris@102
|
23
|
Chris@102
|
24 #include <boost/intrusive/detail/config_begin.hpp>
|
Chris@102
|
25 #include <boost/intrusive/detail/mpl.hpp>
|
Chris@102
|
26 #include <boost/intrusive/detail/hook_traits.hpp>
|
Chris@102
|
27
|
Chris@102
|
28 namespace boost {
|
Chris@102
|
29 namespace intrusive {
|
Chris@102
|
30
|
Chris@102
|
31 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
Chris@102
|
32
|
Chris@102
|
33 template<class SupposedValueTraits>
|
Chris@102
|
34 struct is_default_hook_tag
|
Chris@102
|
35 { static const bool value = false; };
|
Chris@102
|
36
|
Chris@102
|
37 namespace detail{
|
Chris@102
|
38
|
Chris@102
|
39 template <class T, class BaseHook>
|
Chris@102
|
40 struct concrete_hook_base_value_traits
|
Chris@102
|
41 {
|
Chris@102
|
42 typedef typename BaseHook::hooktags tags;
|
Chris@102
|
43 typedef bhtraits
|
Chris@102
|
44 < T
|
Chris@102
|
45 , typename tags::node_traits
|
Chris@102
|
46 , tags::link_mode
|
Chris@102
|
47 , typename tags::tag
|
Chris@102
|
48 , tags::type> type;
|
Chris@102
|
49 };
|
Chris@102
|
50
|
Chris@102
|
51 template <class BaseHook>
|
Chris@102
|
52 struct concrete_hook_base_value_traits<void, BaseHook>
|
Chris@102
|
53 {
|
Chris@102
|
54 typedef typename BaseHook::hooktags type;
|
Chris@102
|
55 };
|
Chris@102
|
56
|
Chris@102
|
57 template <class T, class AnyToSomeHook_ProtoValueTraits>
|
Chris@102
|
58 struct any_hook_base_value_traits
|
Chris@102
|
59 {
|
Chris@102
|
60 //AnyToSomeHook value_traits derive from a generic_hook
|
Chris@102
|
61 //The generic_hook is configured with any_node_traits
|
Chris@102
|
62 //and AnyToSomeHook::value_traits with the correct
|
Chris@102
|
63 //node traits for the container, so use node_traits
|
Chris@102
|
64 //from AnyToSomeHook_ProtoValueTraits and the rest of
|
Chris@102
|
65 //elements from the hooktags member of the generic_hook
|
Chris@102
|
66
|
Chris@102
|
67 typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
|
Chris@102
|
68 typedef typename pointer_rebind
|
Chris@102
|
69 < typename basic_hook_t::hooktags::node_traits::node_ptr
|
Chris@102
|
70 , void>::type void_pointer;
|
Chris@102
|
71 typedef typename AnyToSomeHook_ProtoValueTraits::template
|
Chris@102
|
72 node_traits_from_voidptr<void_pointer>::type node_traits;
|
Chris@102
|
73
|
Chris@102
|
74 typedef bhtraits
|
Chris@102
|
75 < T
|
Chris@102
|
76 , node_traits
|
Chris@102
|
77 , basic_hook_t::hooktags::link_mode
|
Chris@102
|
78 , typename basic_hook_t::hooktags::tag
|
Chris@102
|
79 , basic_hook_t::hooktags::type
|
Chris@102
|
80 > type;
|
Chris@102
|
81 };
|
Chris@102
|
82
|
Chris@102
|
83 template <class AnyToSomeHook_ProtoValueTraits>
|
Chris@102
|
84 struct any_hook_base_value_traits<void, AnyToSomeHook_ProtoValueTraits>
|
Chris@102
|
85 {
|
Chris@102
|
86 typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
|
Chris@102
|
87 typedef typename pointer_rebind
|
Chris@102
|
88 < typename basic_hook_t::hooktags::node_traits::node_ptr
|
Chris@102
|
89 , void>::type void_pointer;
|
Chris@102
|
90
|
Chris@102
|
91 struct type
|
Chris@102
|
92 {
|
Chris@102
|
93 typedef typename AnyToSomeHook_ProtoValueTraits::template
|
Chris@102
|
94 node_traits_from_voidptr<void_pointer>::type node_traits;
|
Chris@102
|
95 };
|
Chris@102
|
96 };
|
Chris@102
|
97
|
Chris@102
|
98 template<class MemberHook>
|
Chris@102
|
99 struct get_member_value_traits
|
Chris@102
|
100 {
|
Chris@102
|
101 typedef typename MemberHook::member_value_traits type;
|
Chris@102
|
102 };
|
Chris@102
|
103
|
Chris@102
|
104 BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
|
Chris@102
|
105 BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
|
Chris@102
|
106
|
Chris@102
|
107 template <class T>
|
Chris@102
|
108 struct internal_member_value_traits
|
Chris@102
|
109 {
|
Chris@102
|
110 template <class U> static one test(...);
|
Chris@102
|
111 template <class U> static two test(typename U::member_value_traits* = 0);
|
Chris@102
|
112 static const bool value = sizeof(test<T>(0)) == sizeof(two);
|
Chris@102
|
113 };
|
Chris@102
|
114
|
Chris@102
|
115 template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>
|
Chris@102
|
116 struct supposed_value_traits;
|
Chris@102
|
117
|
Chris@102
|
118 template<class T, class BaseHook, bool = internal_any_hook_bool_is_true<BaseHook>::value>
|
Chris@102
|
119 struct get_base_value_traits;
|
Chris@102
|
120
|
Chris@102
|
121 template<class SupposedValueTraits, class T, bool = internal_base_hook_bool_is_true<SupposedValueTraits>::value>
|
Chris@102
|
122 struct supposed_base_value_traits;
|
Chris@102
|
123
|
Chris@102
|
124 template<class SupposedValueTraits, bool = internal_member_value_traits<SupposedValueTraits>::value>
|
Chris@102
|
125 struct supposed_member_value_traits;
|
Chris@102
|
126
|
Chris@102
|
127 template<class SupposedValueTraits, bool = internal_any_hook_bool_is_true<SupposedValueTraits>::value>
|
Chris@102
|
128 struct any_or_concrete_value_traits;
|
Chris@102
|
129
|
Chris@102
|
130 //Base any hook
|
Chris@102
|
131 template<class T, class BaseHook>
|
Chris@102
|
132 struct get_base_value_traits<T, BaseHook, true>
|
Chris@102
|
133 : any_hook_base_value_traits<T, BaseHook>
|
Chris@102
|
134 {};
|
Chris@102
|
135
|
Chris@102
|
136 //Non-any base hook
|
Chris@102
|
137 template<class T, class BaseHook>
|
Chris@102
|
138 struct get_base_value_traits<T, BaseHook, false>
|
Chris@102
|
139 : concrete_hook_base_value_traits<T, BaseHook>
|
Chris@102
|
140 {};
|
Chris@102
|
141
|
Chris@102
|
142 //...It's a default hook
|
Chris@102
|
143 template<class SupposedValueTraits, class T>
|
Chris@102
|
144 struct supposed_value_traits<SupposedValueTraits, T, true>
|
Chris@102
|
145 { typedef typename SupposedValueTraits::template apply<T>::type type; };
|
Chris@102
|
146
|
Chris@102
|
147 //...Not a default hook
|
Chris@102
|
148 template<class SupposedValueTraits, class T>
|
Chris@102
|
149 struct supposed_value_traits<SupposedValueTraits, T, false>
|
Chris@102
|
150 { typedef SupposedValueTraits type; };
|
Chris@102
|
151
|
Chris@102
|
152 //...It's a base hook
|
Chris@102
|
153 template<class BaseHook, class T>
|
Chris@102
|
154 struct supposed_base_value_traits<BaseHook, T, true>
|
Chris@102
|
155 : get_base_value_traits<T, BaseHook>
|
Chris@102
|
156 {};
|
Chris@102
|
157
|
Chris@102
|
158 //...Not a base hook, try if it's a member or value_traits
|
Chris@102
|
159 template<class SupposedValueTraits, class T>
|
Chris@102
|
160 struct supposed_base_value_traits<SupposedValueTraits, T, false>
|
Chris@102
|
161 : supposed_member_value_traits<SupposedValueTraits>
|
Chris@102
|
162 {};
|
Chris@102
|
163
|
Chris@102
|
164 //...It's a member hook
|
Chris@102
|
165 template<class MemberHook>
|
Chris@102
|
166 struct supposed_member_value_traits<MemberHook, true>
|
Chris@102
|
167 : get_member_value_traits<MemberHook>
|
Chris@102
|
168 {};
|
Chris@102
|
169
|
Chris@102
|
170 //...Not a member hook
|
Chris@102
|
171 template<class SupposedValueTraits>
|
Chris@102
|
172 struct supposed_member_value_traits<SupposedValueTraits, false>
|
Chris@102
|
173 : any_or_concrete_value_traits<SupposedValueTraits>
|
Chris@102
|
174 {};
|
Chris@102
|
175
|
Chris@102
|
176 template<class AnyToSomeHook_ProtoValueTraits>
|
Chris@102
|
177 struct any_or_concrete_value_traits<AnyToSomeHook_ProtoValueTraits, true>
|
Chris@102
|
178 {
|
Chris@102
|
179 //A hook node (non-base, e.g.: member or other value traits
|
Chris@102
|
180 typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
|
Chris@102
|
181 typedef typename pointer_rebind
|
Chris@102
|
182 <typename basic_hook_t::node_ptr, void>::type void_pointer;
|
Chris@102
|
183 typedef typename AnyToSomeHook_ProtoValueTraits::template
|
Chris@102
|
184 node_traits_from_voidptr<void_pointer>::type any_node_traits;
|
Chris@102
|
185
|
Chris@102
|
186 struct type : basic_hook_t
|
Chris@102
|
187 {
|
Chris@102
|
188 typedef any_node_traits node_traits;
|
Chris@102
|
189 };
|
Chris@102
|
190 };
|
Chris@102
|
191
|
Chris@102
|
192 template<class SupposedValueTraits>
|
Chris@102
|
193 struct any_or_concrete_value_traits<SupposedValueTraits, false>
|
Chris@102
|
194 {
|
Chris@102
|
195 typedef SupposedValueTraits type;
|
Chris@102
|
196 };
|
Chris@102
|
197
|
Chris@102
|
198 ////////////////////////////////////////
|
Chris@102
|
199 // get_value_traits / get_node_traits
|
Chris@102
|
200 ////////////////////////////////////////
|
Chris@102
|
201
|
Chris@102
|
202 template<class T, class SupposedValueTraits>
|
Chris@102
|
203 struct get_value_traits
|
Chris@102
|
204 : supposed_base_value_traits<typename supposed_value_traits<SupposedValueTraits, T>::type, T>
|
Chris@102
|
205 {};
|
Chris@102
|
206
|
Chris@102
|
207 template<class SupposedValueTraits>
|
Chris@102
|
208 struct get_node_traits
|
Chris@102
|
209 {
|
Chris@102
|
210 typedef typename get_value_traits<void, SupposedValueTraits>::type::node_traits type;
|
Chris@102
|
211 };
|
Chris@102
|
212
|
Chris@102
|
213 } //namespace detail{
|
Chris@102
|
214
|
Chris@102
|
215 #endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
Chris@102
|
216
|
Chris@102
|
217 } //namespace intrusive {
|
Chris@102
|
218 } //namespace boost {
|
Chris@102
|
219
|
Chris@102
|
220 #include <boost/intrusive/detail/config_end.hpp>
|
Chris@102
|
221
|
Chris@102
|
222 #endif //#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP
|