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