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
28namespace boost {
29namespace intrusive {
30
31#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
32
33template<class SupposedValueTraits>
34struct is_default_hook_tag
35{ static const bool value = false; };
36
37namespace detail{
38
39template <class T, class BaseHook>
40struct 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
51template <class BaseHook>
52struct concrete_hook_base_value_traits<void, BaseHook>
53{
54 typedef typename BaseHook::hooktags type;
55};
56
57template <class T, class AnyToSomeHook_ProtoValueTraits>
58struct 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
83template <class AnyToSomeHook_ProtoValueTraits>
84struct 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
98template<class MemberHook>
99struct get_member_value_traits
100{
101 typedef typename MemberHook::member_value_traits type;
102};
103
104BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
105BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
106
107template <class T>
108struct internal_member_value_traits
109{
110 template <class U> static yes_type test(...);
111 template <class U> static no_type test(typename U::member_value_traits* = 0);
112 static const bool value = sizeof(test<T>(0)) == sizeof(no_type);
113};
114
115template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>
116struct supposed_value_traits;
117
118template<class T, class BaseHook, bool = internal_any_hook_bool_is_true<BaseHook>::value>
119struct get_base_value_traits;
120
121template<class SupposedValueTraits, class T, bool = internal_base_hook_bool_is_true<SupposedValueTraits>::value>
122struct supposed_base_value_traits;
123
124template<class SupposedValueTraits, bool = internal_member_value_traits<SupposedValueTraits>::value>
125struct supposed_member_value_traits;
126
127template<class SupposedValueTraits, bool = internal_any_hook_bool_is_true<SupposedValueTraits>::value>
128struct any_or_concrete_value_traits;
129
130//Base any hook
131template<class T, class BaseHook>
132struct get_base_value_traits<T, BaseHook, true>
133 : any_hook_base_value_traits<T, BaseHook>
134{};
135
136//Non-any base hook
137template<class T, class BaseHook>
138struct get_base_value_traits<T, BaseHook, false>
139 : concrete_hook_base_value_traits<T, BaseHook>
140{};
141
142//...It's a default hook
143template<class SupposedValueTraits, class T>
144struct supposed_value_traits<SupposedValueTraits, T, true>
145{ typedef typename SupposedValueTraits::template apply<T>::type type; };
146
147//...Not a default hook
148template<class SupposedValueTraits, class T>
149struct supposed_value_traits<SupposedValueTraits, T, false>
150{ typedef SupposedValueTraits type; };
151
152//...It's a base hook
153template<class BaseHook, class T>
154struct 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
159template<class SupposedValueTraits, class T>
160struct supposed_base_value_traits<SupposedValueTraits, T, false>
161 : supposed_member_value_traits<SupposedValueTraits>
162{};
163
164//...It's a member hook
165template<class MemberHook>
166struct supposed_member_value_traits<MemberHook, true>
167 : get_member_value_traits<MemberHook>
168{};
169
170//...Not a member hook
171template<class SupposedValueTraits>
172struct supposed_member_value_traits<SupposedValueTraits, false>
173 : any_or_concrete_value_traits<SupposedValueTraits>
174{};
175
176template<class AnyToSomeHook_ProtoValueTraits>
177struct 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
192template<class SupposedValueTraits>
193struct any_or_concrete_value_traits<SupposedValueTraits, false>
194{
195 typedef SupposedValueTraits type;
196};
197
198////////////////////////////////////////
199// get_value_traits / get_node_traits
200////////////////////////////////////////
201
202template<class T, class SupposedValueTraits>
203struct get_value_traits
204 : supposed_base_value_traits<typename supposed_value_traits<SupposedValueTraits, T>::type, T>
205{};
206
207template<class SupposedValueTraits>
208struct 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