Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/intrusive/options.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
1 ///////////////////////////////////////////////////////////////////////////// | 1 ///////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 // (C) Copyright Ion Gaztanaga 2007-2013 | 3 // (C) Copyright Ion Gaztanaga 2007-2014 |
4 // | 4 // |
5 // Distributed under the Boost Software License, Version 1.0. | 5 // Distributed under the Boost Software License, Version 1.0. |
6 // (See accompanying file LICENSE_1_0.txt or copy at | 6 // (See accompanying file LICENSE_1_0.txt or copy at |
7 // http://www.boost.org/LICENSE_1_0.txt) | 7 // http://www.boost.org/LICENSE_1_0.txt) |
8 // | 8 // |
14 #define BOOST_INTRUSIVE_OPTIONS_HPP | 14 #define BOOST_INTRUSIVE_OPTIONS_HPP |
15 | 15 |
16 #include <boost/intrusive/detail/config_begin.hpp> | 16 #include <boost/intrusive/detail/config_begin.hpp> |
17 #include <boost/intrusive/intrusive_fwd.hpp> | 17 #include <boost/intrusive/intrusive_fwd.hpp> |
18 #include <boost/intrusive/link_mode.hpp> | 18 #include <boost/intrusive/link_mode.hpp> |
19 #include <boost/intrusive/pack_options.hpp> | |
19 #include <boost/intrusive/detail/mpl.hpp> | 20 #include <boost/intrusive/detail/mpl.hpp> |
20 #include <boost/intrusive/detail/utilities.hpp> | 21 |
21 #include <boost/static_assert.hpp> | 22 #if defined(BOOST_HAS_PRAGMA_ONCE) |
22 | 23 # pragma once |
24 #endif | |
23 | 25 |
24 namespace boost { | 26 namespace boost { |
25 namespace intrusive { | 27 namespace intrusive { |
26 | 28 |
27 /// @cond | 29 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED |
28 | 30 |
29 //typedef void default_tag; | 31 struct empty |
30 struct default_tag; | 32 {}; |
33 | |
34 template<class Functor> | |
35 struct fhtraits; | |
36 | |
37 template<class T, class Hook, Hook T::* P> | |
38 struct mhtraits; | |
39 | |
40 struct dft_tag; | |
31 struct member_tag; | 41 struct member_tag; |
32 | 42 |
33 namespace detail{ | |
34 | |
35 struct default_hook_tag{}; | |
36 | |
37 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED | |
38 | |
39 #define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \ | |
40 struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\ | |
41 {\ | |
42 template <class T>\ | |
43 struct apply\ | |
44 { typedef typename T::BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER type; };\ | |
45 }\ | |
46 | |
47 BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_list_hook); | |
48 BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_slist_hook); | |
49 BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_rbtree_hook); | |
50 BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook); | |
51 BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook); | |
52 BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook); | |
53 //BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splaytree_hook); | |
54 //BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_sgtree_hook); | |
55 //BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_treap_hook); | |
56 | |
57 #undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION | |
58 | |
59 #endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED | |
60 | |
61 template <class ValueTraits> | |
62 struct eval_value_traits | |
63 { | |
64 typedef typename ValueTraits::value_traits type; | |
65 }; | |
66 | |
67 template<class ValueTraits> | |
68 struct get_real_value_traits | |
69 : public eval_if_c | |
70 < external_value_traits_bool_is_true<ValueTraits>::value | |
71 , eval_value_traits<ValueTraits> | |
72 , identity<ValueTraits> | |
73 > | |
74 {}; | |
75 | |
76 template <class BucketTraits> | |
77 struct eval_bucket_traits | |
78 { | |
79 typedef typename BucketTraits::bucket_traits type; | |
80 }; | |
81 | |
82 template <class T, class BaseHook> | |
83 struct concrete_hook_base_value_traits | |
84 { | |
85 typedef typename BaseHook::hooktags tags; | |
86 typedef bhtraits | |
87 < T | |
88 , typename tags::node_traits | |
89 , tags::link_mode | |
90 , typename tags::tag | |
91 , tags::type> type; | |
92 }; | |
93 | |
94 template <class BaseHook> | |
95 struct concrete_hook_base_node_traits | |
96 { typedef typename BaseHook::hooktags::node_traits type; }; | |
97 | |
98 template <class T, class AnyToSomeHook_ProtoValueTraits> | |
99 struct any_hook_base_value_traits | |
100 { | |
101 //AnyToSomeHook value_traits derive from a generic_hook | |
102 //The generic_hook is configured with any_node_traits | |
103 //and AnyToSomeHook::value_traits with the correct | |
104 //node traits for the container, so use node_traits | |
105 //from AnyToSomeHook_ProtoValueTraits and the rest of | |
106 //elements from the hooktags member of the generic_hook | |
107 typedef AnyToSomeHook_ProtoValueTraits proto_value_traits; | |
108 typedef bhtraits | |
109 < T | |
110 , typename proto_value_traits::node_traits | |
111 , proto_value_traits::hooktags::link_mode | |
112 , typename proto_value_traits::hooktags::tag | |
113 , proto_value_traits::hooktags::type | |
114 > type; | |
115 }; | |
116 | |
117 template <class BaseHook> | |
118 struct any_hook_base_node_traits | |
119 { typedef typename BaseHook::node_traits type; }; | |
120 | |
121 template<class T, class BaseHook> | |
122 struct get_base_value_traits | |
123 { | |
124 typedef typename detail::eval_if_c | |
125 < internal_any_hook_bool_is_true<BaseHook>::value | |
126 , any_hook_base_value_traits<T, BaseHook> | |
127 , concrete_hook_base_value_traits<T, BaseHook> | |
128 >::type type; | |
129 }; | |
130 | |
131 template<class BaseHook> | |
132 struct get_base_node_traits | |
133 { | |
134 typedef typename detail::eval_if_c | |
135 < internal_any_hook_bool_is_true<BaseHook>::value | |
136 , any_hook_base_node_traits<BaseHook> | |
137 , concrete_hook_base_node_traits<BaseHook> | |
138 >::type type; | |
139 }; | |
140 | |
141 template<class T, class MemberHook> | |
142 struct get_member_value_traits | |
143 { | |
144 typedef typename MemberHook::member_value_traits type; | |
145 }; | |
146 | |
147 template<class MemberHook> | |
148 struct get_member_node_traits | |
149 { | |
150 typedef typename MemberHook::member_value_traits::node_traits type; | |
151 }; | |
152 | |
153 template<class T, class SupposedValueTraits> | |
154 struct get_value_traits | |
155 { | |
156 typedef typename detail::eval_if_c | |
157 <detail::is_convertible<SupposedValueTraits*, detail::default_hook_tag*>::value | |
158 ,detail::apply<SupposedValueTraits, T> | |
159 ,detail::identity<SupposedValueTraits> | |
160 >::type supposed_value_traits; | |
161 | |
162 //...if it's a default hook | |
163 typedef typename detail::eval_if_c | |
164 < internal_base_hook_bool_is_true<supposed_value_traits>::value | |
165 //...get it's internal value traits using | |
166 //the provided T value type. | |
167 , get_base_value_traits<T, supposed_value_traits> | |
168 //...else use it's internal value traits tag | |
169 //(member hooks and custom value traits are in this group) | |
170 , detail::eval_if_c | |
171 < internal_member_value_traits<supposed_value_traits>::value | |
172 , get_member_value_traits<T, supposed_value_traits> | |
173 , detail::identity<supposed_value_traits> | |
174 > | |
175 >::type type; | |
176 }; | |
177 | |
178 template<class ValueTraits> | |
179 struct get_explicit_node_traits | |
180 { | |
181 typedef typename ValueTraits::node_traits type; | |
182 }; | |
183 | |
184 template<class SupposedValueTraits> | 43 template<class SupposedValueTraits> |
185 struct get_node_traits | 44 struct is_default_hook_tag; |
186 { | 45 |
187 typedef SupposedValueTraits supposed_value_traits; | 46 #endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED |
188 //...if it's a base hook | |
189 typedef typename detail::eval_if_c | |
190 < internal_base_hook_bool_is_true<supposed_value_traits>::value | |
191 //...get it's internal value traits using | |
192 //the provided T value type. | |
193 , get_base_node_traits<supposed_value_traits> | |
194 //...else use it's internal value traits tag | |
195 //(member hooks and custom value traits are in this group) | |
196 , detail::eval_if_c | |
197 < internal_member_value_traits<supposed_value_traits>::value | |
198 , get_member_node_traits<supposed_value_traits> | |
199 , get_explicit_node_traits<supposed_value_traits> | |
200 > | |
201 >::type type; | |
202 }; | |
203 | |
204 } //namespace detail{ | |
205 | |
206 /// @endcond | |
207 | 47 |
208 //!This option setter specifies if the intrusive | 48 //!This option setter specifies if the intrusive |
209 //!container stores its size as a member to | 49 //!container stores its size as a member to |
210 //!obtain constant-time size() member. | 50 //!obtain constant-time size() member. |
211 template<bool Enabled> | 51 BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size) |
212 struct constant_time_size | 52 |
213 { | 53 //!This option setter specifies a container header holder type |
214 /// @cond | 54 BOOST_INTRUSIVE_OPTION_TYPE(header_holder_type, HeaderHolder, HeaderHolder, header_holder_type) |
215 template<class Base> | |
216 struct pack : Base | |
217 { | |
218 static const bool constant_time_size = Enabled; | |
219 }; | |
220 /// @endcond | |
221 }; | |
222 | 55 |
223 //!This option setter specifies the type that | 56 //!This option setter specifies the type that |
224 //!the container will use to store its size. | 57 //!the container will use to store its size. |
225 template<class SizeType> | 58 BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type) |
226 struct size_type | |
227 { | |
228 /// @cond | |
229 template<class Base> | |
230 struct pack : Base | |
231 { | |
232 typedef SizeType size_type; | |
233 }; | |
234 /// @endcond | |
235 }; | |
236 | 59 |
237 //!This option setter specifies the strict weak ordering | 60 //!This option setter specifies the strict weak ordering |
238 //!comparison functor for the value type | 61 //!comparison functor for the value type |
239 template<class Compare> | 62 BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare) |
240 struct compare | |
241 { | |
242 /// @cond | |
243 template<class Base> | |
244 struct pack : Base | |
245 { | |
246 typedef Compare compare; | |
247 }; | |
248 /// @endcond | |
249 }; | |
250 | 63 |
251 //!This option setter for scapegoat containers specifies if | 64 //!This option setter for scapegoat containers specifies if |
252 //!the intrusive scapegoat container should use a non-variable | 65 //!the intrusive scapegoat container should use a non-variable |
253 //!alpha value that does not need floating-point operations. | 66 //!alpha value that does not need floating-point operations. |
254 //! | 67 //! |
258 //!to be stored in the container. | 71 //!to be stored in the container. |
259 //! | 72 //! |
260 //!If the user only needs an alpha value near 1/sqrt(2), this | 73 //!If the user only needs an alpha value near 1/sqrt(2), this |
261 //!option also improves performance since avoids logarithm | 74 //!option also improves performance since avoids logarithm |
262 //!and division operations when rebalancing the tree. | 75 //!and division operations when rebalancing the tree. |
263 template<bool Enabled> | 76 BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point) |
264 struct floating_point | |
265 { | |
266 /// @cond | |
267 template<class Base> | |
268 struct pack : Base | |
269 { | |
270 static const bool floating_point = Enabled; | |
271 }; | |
272 /// @endcond | |
273 }; | |
274 | 77 |
275 //!This option setter specifies the equality | 78 //!This option setter specifies the equality |
276 //!functor for the value type | 79 //!functor for the value type |
277 template<class Equal> | 80 BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal) |
278 struct equal | |
279 { | |
280 /// @cond | |
281 template<class Base> | |
282 struct pack : Base | |
283 { | |
284 typedef Equal equal; | |
285 }; | |
286 /// @endcond | |
287 }; | |
288 | 81 |
289 //!This option setter specifies the equality | 82 //!This option setter specifies the equality |
290 //!functor for the value type | 83 //!functor for the value type |
291 template<class Priority> | 84 BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority) |
292 struct priority | |
293 { | |
294 /// @cond | |
295 template<class Base> | |
296 struct pack : Base | |
297 { | |
298 typedef Priority priority; | |
299 }; | |
300 /// @endcond | |
301 }; | |
302 | 85 |
303 //!This option setter specifies the hash | 86 //!This option setter specifies the hash |
304 //!functor for the value type | 87 //!functor for the value type |
305 template<class Hash> | 88 BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash) |
306 struct hash | |
307 { | |
308 /// @cond | |
309 template<class Base> | |
310 struct pack : Base | |
311 { | |
312 typedef Hash hash; | |
313 }; | |
314 /// @endcond | |
315 }; | |
316 | 89 |
317 //!This option setter specifies the relationship between the type | 90 //!This option setter specifies the relationship between the type |
318 //!to be managed by the container (the value type) and the node to be | 91 //!to be managed by the container (the value type) and the node to be |
319 //!used in the node algorithms. It also specifies the linking policy. | 92 //!used in the node algorithms. It also specifies the linking policy. |
320 template<typename ValueTraits> | 93 BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits) |
321 struct value_traits | 94 |
322 { | 95 //#define BOOST_INTRUSIVE_COMMA , |
323 /// @cond | 96 //#define BOOST_INTRUSIVE_LESS < |
324 template<class Base> | 97 //#define BOOST_INTRUSIVE_MORE > |
325 struct pack : Base | 98 //BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits) |
326 { | 99 //template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember> |
327 typedef ValueTraits proto_value_traits; | 100 //struct member_hook { |
328 }; | 101 // template<class Base> struct pack : Base { |
329 /// @endcond | 102 // typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits; |
330 }; | 103 // }; |
104 //}; | |
105 // | |
106 //#undef BOOST_INTRUSIVE_COMMA | |
107 //#undef BOOST_INTRUSIVE_LESS | |
108 //#undef BOOST_INTRUSIVE_MORE | |
331 | 109 |
332 //!This option setter specifies the member hook the | 110 //!This option setter specifies the member hook the |
333 //!container must use. | 111 //!container must use. |
334 template< typename Parent | 112 template< typename Parent |
335 , typename MemberHook | 113 , typename MemberHook |
336 , MemberHook Parent::* PtrToMember> | 114 , MemberHook Parent::* PtrToMember> |
337 struct member_hook | 115 struct member_hook |
338 { | 116 { |
339 /// @cond | 117 // @cond |
340 /* | 118 // typedef typename MemberHook::hooktags::node_traits node_traits; |
341 typedef typename MemberHook::hooktags::node_traits node_traits; | 119 // typedef typename node_traits::node node_type; |
342 typedef typename node_traits::node node_type; | 120 // typedef node_type Parent::* Ptr2MemNode; |
343 typedef node_type Parent::* Ptr2MemNode; | 121 // typedef mhtraits |
344 typedef mhtraits | 122 // < Parent |
345 < Parent | 123 // , node_traits |
346 , node_traits | 124 // //This cast is really ugly but necessary to reduce template bloat. |
347 //This cast is really ugly but necessary to reduce template bloat. | 125 // //Since we control the layout between the hook and the node, and there is |
348 //Since we control the layout between the hook and the node, and there is | 126 // //always single inheritance, the offset of the node is exactly the offset of |
349 //always single inheritance, the offset of the node is exactly the offset of | 127 // //the hook. Since the node type is shared between all member hooks, this saves |
350 //the hook. Since the node type is shared between all member hooks, this saves | 128 // //quite a lot of symbol stuff. |
351 //quite a lot of symbol stuff. | 129 // , (Ptr2MemNode)PtrToMember |
352 , (Ptr2MemNode)PtrToMember | 130 // , MemberHook::hooktags::link_mode> member_value_traits; |
353 , MemberHook::hooktags::link_mode> member_value_traits; | 131 typedef mhtraits <Parent, MemberHook, PtrToMember> member_value_traits; |
354 */ | |
355 typedef mhtraits | |
356 < Parent | |
357 , MemberHook | |
358 , PtrToMember | |
359 > member_value_traits; | |
360 template<class Base> | 132 template<class Base> |
361 struct pack : Base | 133 struct pack : Base |
362 { | 134 { |
363 typedef member_value_traits proto_value_traits; | 135 typedef member_value_traits proto_value_traits; |
364 }; | 136 }; |
365 /// @endcond | 137 /// @endcond |
366 }; | 138 }; |
367 | 139 |
368 | |
369 //!This option setter specifies the function object that will | 140 //!This option setter specifies the function object that will |
370 //!be used to convert between values to be inserted in a container | 141 //!be used to convert between values to be inserted in a container |
371 //!and the hook to be used for that purpose. | 142 //!and the hook to be used for that purpose. |
372 template< typename Functor> | 143 BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits<Functor>, proto_value_traits) |
373 struct function_hook | |
374 { | |
375 /// @cond | |
376 typedef fhtraits | |
377 <Functor> function_value_traits; | |
378 template<class Base> | |
379 struct pack : Base | |
380 { | |
381 typedef function_value_traits proto_value_traits; | |
382 }; | |
383 /// @endcond | |
384 }; | |
385 | |
386 | 144 |
387 //!This option setter specifies that the container | 145 //!This option setter specifies that the container |
388 //!must use the specified base hook | 146 //!must use the specified base hook |
389 template<typename BaseHook> | 147 BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits) |
390 struct base_hook | |
391 { | |
392 /// @cond | |
393 template<class Base> | |
394 struct pack : Base | |
395 { | |
396 typedef BaseHook proto_value_traits; | |
397 }; | |
398 /// @endcond | |
399 }; | |
400 | 148 |
401 //!This option setter specifies the type of | 149 //!This option setter specifies the type of |
402 //!a void pointer. This will instruct the hook | 150 //!a void pointer. This will instruct the hook |
403 //!to use this type of pointer instead of the | 151 //!to use this type of pointer instead of the |
404 //!default one | 152 //!default one |
405 template<class VoidPointer> | 153 BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer) |
406 struct void_pointer | |
407 { | |
408 /// @cond | |
409 template<class Base> | |
410 struct pack : Base | |
411 { | |
412 typedef VoidPointer void_pointer; | |
413 }; | |
414 /// @endcond | |
415 }; | |
416 | 154 |
417 //!This option setter specifies the type of | 155 //!This option setter specifies the type of |
418 //!the tag of a base hook. A type cannot have two | 156 //!the tag of a base hook. A type cannot have two |
419 //!base hooks of the same type, so a tag can be used | 157 //!base hooks of the same type, so a tag can be used |
420 //!to differentiate two base hooks with otherwise same type | 158 //!to differentiate two base hooks with otherwise same type |
421 template<class Tag> | 159 BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag) |
422 struct tag | |
423 { | |
424 /// @cond | |
425 template<class Base> | |
426 struct pack : Base | |
427 { | |
428 typedef Tag tag; | |
429 }; | |
430 /// @endcond | |
431 }; | |
432 | 160 |
433 //!This option setter specifies the link mode | 161 //!This option setter specifies the link mode |
434 //!(normal_link, safe_link or auto_unlink) | 162 //!(normal_link, safe_link or auto_unlink) |
435 template<link_mode_type LinkType> | 163 BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode) |
436 struct link_mode | |
437 { | |
438 /// @cond | |
439 template<class Base> | |
440 struct pack : Base | |
441 { | |
442 static const link_mode_type link_mode = LinkType; | |
443 }; | |
444 /// @endcond | |
445 }; | |
446 | 164 |
447 //!This option setter specifies if the hook | 165 //!This option setter specifies if the hook |
448 //!should be optimized for size instead of for speed. | 166 //!should be optimized for size instead of for speed. |
449 template<bool Enabled> | 167 BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size) |
450 struct optimize_size | 168 |
451 { | 169 //!This option setter specifies if the slist container should |
452 /// @cond | |
453 template<class Base> | |
454 struct pack : Base | |
455 { | |
456 static const bool optimize_size = Enabled; | |
457 }; | |
458 /// @endcond | |
459 }; | |
460 | |
461 //!This option setter specifies if the list container should | |
462 //!use a linear implementation instead of a circular one. | 170 //!use a linear implementation instead of a circular one. |
463 template<bool Enabled> | 171 BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear) |
464 struct linear | 172 |
465 { | 173 //!If true, slist also stores a pointer to the last element of the singly linked list. |
466 /// @cond | 174 //!This allows O(1) swap and splice_after(iterator, slist &) for circular slists and makes |
467 template<class Base> | 175 //!possible new functions like push_back(reference) and back(). |
468 struct pack : Base | 176 BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last) |
469 { | |
470 static const bool linear = Enabled; | |
471 }; | |
472 /// @endcond | |
473 }; | |
474 | |
475 //!This option setter specifies if the list container should | |
476 //!use a linear implementation instead of a circular one. | |
477 template<bool Enabled> | |
478 struct cache_last | |
479 { | |
480 /// @cond | |
481 template<class Base> | |
482 struct pack : Base | |
483 { | |
484 static const bool cache_last = Enabled; | |
485 }; | |
486 /// @endcond | |
487 }; | |
488 | 177 |
489 //!This option setter specifies the bucket traits | 178 //!This option setter specifies the bucket traits |
490 //!class for unordered associative containers. When this option is specified, | 179 //!class for unordered associative containers. When this option is specified, |
491 //!instead of using the default bucket traits, a user defined holder will be defined | 180 //!instead of using the default bucket traits, a user defined holder will be defined |
492 template<class BucketTraits> | 181 BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits) |
493 struct bucket_traits | |
494 { | |
495 /// @cond | |
496 template<class Base> | |
497 struct pack : Base | |
498 { | |
499 typedef BucketTraits bucket_traits; | |
500 }; | |
501 /// @endcond | |
502 }; | |
503 | 182 |
504 //!This option setter specifies if the unordered hook | 183 //!This option setter specifies if the unordered hook |
505 //!should offer room to store the hash value. | 184 //!should offer room to store the hash value. |
506 //!Storing the hash in the hook will speed up rehashing | 185 //!Storing the hash in the hook will speed up rehashing |
507 //!processes in applications where rehashing is frequent, | 186 //!processes in applications where rehashing is frequent, |
508 //!rehashing might throw or the value is heavy to hash. | 187 //!rehashing might throw or the value is heavy to hash. |
509 template<bool Enabled> | 188 BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) |
510 struct store_hash | |
511 { | |
512 /// @cond | |
513 template<class Base> | |
514 struct pack : Base | |
515 { | |
516 static const bool store_hash = Enabled; | |
517 }; | |
518 /// @endcond | |
519 }; | |
520 | 189 |
521 //!This option setter specifies if the unordered hook | 190 //!This option setter specifies if the unordered hook |
522 //!should offer room to store another link to another node | 191 //!should offer room to store another link to another node |
523 //!with the same key. | 192 //!with the same key. |
524 //!Storing this link will speed up lookups and insertions on | 193 //!Storing this link will speed up lookups and insertions on |
525 //!unordered_multiset containers with a great number of elements | 194 //!unordered_multiset containers with a great number of elements |
526 //!with the same key. | 195 //!with the same key. |
527 template<bool Enabled> | 196 BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey) |
528 struct optimize_multikey | |
529 { | |
530 /// @cond | |
531 template<class Base> | |
532 struct pack : Base | |
533 { | |
534 static const bool optimize_multikey = Enabled; | |
535 }; | |
536 /// @endcond | |
537 }; | |
538 | 197 |
539 //!This option setter specifies if the bucket array will be always power of two. | 198 //!This option setter specifies if the bucket array will be always power of two. |
540 //!This allows using masks instead of the default modulo operation to determine | 199 //!This allows using masks instead of the default modulo operation to determine |
541 //!the bucket number from the hash value, leading to better performance. | 200 //!the bucket number from the hash value, leading to better performance. |
542 //!In debug mode, if power of two buckets mode is activated, the bucket length | 201 //!In debug mode, if power of two buckets mode is activated, the bucket length |
543 //!will be checked to through assertions to assure the bucket length is power of two. | 202 //!will be checked to through assertions to assure the bucket length is power of two. |
544 template<bool Enabled> | 203 BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets) |
545 struct power_2_buckets | |
546 { | |
547 /// @cond | |
548 template<class Base> | |
549 struct pack : Base | |
550 { | |
551 static const bool power_2_buckets = Enabled; | |
552 }; | |
553 /// @endcond | |
554 }; | |
555 | 204 |
556 //!This option setter specifies if the container will cache a pointer to the first | 205 //!This option setter specifies if the container will cache a pointer to the first |
557 //!non-empty bucket so that begin() is always constant-time. | 206 //!non-empty bucket so that begin() is always constant-time. |
558 //!This is specially helpful when we can have containers with a few elements | 207 //!This is specially helpful when we can have containers with a few elements |
559 //!but with big bucket arrays (that is, hashtables with low load factors). | 208 //!but with big bucket arrays (that is, hashtables with low load factors). |
560 template<bool Enabled> | 209 BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin) |
561 struct cache_begin | |
562 { | |
563 /// @cond | |
564 template<class Base> | |
565 struct pack : Base | |
566 { | |
567 static const bool cache_begin = Enabled; | |
568 }; | |
569 /// @endcond | |
570 }; | |
571 | |
572 | 210 |
573 //!This option setter specifies if the container will compare the hash value | 211 //!This option setter specifies if the container will compare the hash value |
574 //!before comparing objects. This option can't be specified if store_hash<> | 212 //!before comparing objects. This option can't be specified if store_hash<> |
575 //!is not true. | 213 //!is not true. |
576 //!This is specially helpful when we have containers with a high load factor. | 214 //!This is specially helpful when we have containers with a high load factor. |
577 //!and the comparison function is much more expensive that comparing already | 215 //!and the comparison function is much more expensive that comparing already |
578 //!stored hash values. | 216 //!stored hash values. |
579 template<bool Enabled> | 217 BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash) |
580 struct compare_hash | |
581 { | |
582 /// @cond | |
583 template<class Base> | |
584 struct pack : Base | |
585 { | |
586 static const bool compare_hash = Enabled; | |
587 }; | |
588 /// @endcond | |
589 }; | |
590 | 218 |
591 //!This option setter specifies if the hash container will use incremental | 219 //!This option setter specifies if the hash container will use incremental |
592 //!hashing. With incremental hashing the cost of hash table expansion is spread | 220 //!hashing. With incremental hashing the cost of hash table expansion is spread |
593 //!out across each hash table insertion operation, as opposed to be incurred all at once. | 221 //!out across each hash table insertion operation, as opposed to be incurred all at once. |
594 //!Therefore linear hashing is well suited for interactive applications or real-time | 222 //!Therefore linear hashing is well suited for interactive applications or real-time |
595 //!appplications where the worst-case insertion time of non-incremental hash containers | 223 //!appplications where the worst-case insertion time of non-incremental hash containers |
596 //!(rehashing the whole bucket array) is not admisible. | 224 //!(rehashing the whole bucket array) is not admisible. |
597 template<bool Enabled> | 225 BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental) |
598 struct incremental | |
599 { | |
600 /// @cond | |
601 template<class Base> | |
602 struct pack : Base | |
603 { | |
604 static const bool incremental = Enabled; | |
605 }; | |
606 /// @endcond | |
607 }; | |
608 | 226 |
609 /// @cond | 227 /// @cond |
610 | |
611 struct none | |
612 { | |
613 template<class Base> | |
614 struct pack : Base | |
615 {}; | |
616 }; | |
617 | |
618 //To-do: pass to variadic templates | |
619 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) | |
620 | |
621 template<class Prev, class Next> | |
622 struct do_pack | |
623 { | |
624 //Use "pack" member template to pack options | |
625 typedef typename Next::template pack<Prev> type; | |
626 }; | |
627 | |
628 template<class Prev> | |
629 struct do_pack<Prev, void> | |
630 { | |
631 //Avoid packing "void" to shorten template names | |
632 typedef Prev type; | |
633 }; | |
634 | |
635 template | |
636 < class DefaultOptions | |
637 , class O1 = void | |
638 , class O2 = void | |
639 , class O3 = void | |
640 , class O4 = void | |
641 , class O5 = void | |
642 , class O6 = void | |
643 , class O7 = void | |
644 , class O8 = void | |
645 , class O9 = void | |
646 , class O10 = void | |
647 , class O11 = void | |
648 > | |
649 struct pack_options | |
650 { | |
651 // join options | |
652 typedef | |
653 typename do_pack | |
654 < typename do_pack | |
655 < typename do_pack | |
656 < typename do_pack | |
657 < typename do_pack | |
658 < typename do_pack | |
659 < typename do_pack | |
660 < typename do_pack | |
661 < typename do_pack | |
662 < typename do_pack | |
663 < typename do_pack | |
664 < DefaultOptions | |
665 , O1 | |
666 >::type | |
667 , O2 | |
668 >::type | |
669 , O3 | |
670 >::type | |
671 , O4 | |
672 >::type | |
673 , O5 | |
674 >::type | |
675 , O6 | |
676 >::type | |
677 , O7 | |
678 >::type | |
679 , O8 | |
680 >::type | |
681 , O9 | |
682 >::type | |
683 , O10 | |
684 >::type | |
685 , O11 | |
686 >::type | |
687 type; | |
688 }; | |
689 #else | |
690 | |
691 //index_tuple | |
692 template<int... Indexes> | |
693 struct index_tuple{}; | |
694 | |
695 //build_number_seq | |
696 template<std::size_t Num, typename Tuple = index_tuple<> > | |
697 struct build_number_seq; | |
698 | |
699 template<std::size_t Num, int... Indexes> | |
700 struct build_number_seq<Num, index_tuple<Indexes...> > | |
701 : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> > | |
702 {}; | |
703 | |
704 template<int... Indexes> | |
705 struct build_number_seq<0, index_tuple<Indexes...> > | |
706 { typedef index_tuple<Indexes...> type; }; | |
707 | |
708 template<class ...Types> | |
709 struct typelist | |
710 {}; | |
711 | |
712 //invert_typelist | |
713 template<class T> | |
714 struct invert_typelist; | |
715 | |
716 template<int I, typename Tuple> | |
717 struct typelist_element; | |
718 | |
719 template<int I, typename Head, typename... Tail> | |
720 struct typelist_element<I, typelist<Head, Tail...> > | |
721 { | |
722 typedef typename typelist_element<I-1, typelist<Tail...> >::type type; | |
723 }; | |
724 | |
725 template<typename Head, typename... Tail> | |
726 struct typelist_element<0, typelist<Head, Tail...> > | |
727 { | |
728 typedef Head type; | |
729 }; | |
730 | |
731 template<int ...Ints, class ...Types> | |
732 typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...> | |
733 inverted_typelist(index_tuple<Ints...>, typelist<Types...>) | |
734 { | |
735 return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>(); | |
736 } | |
737 | |
738 //sizeof_typelist | |
739 template<class Typelist> | |
740 struct sizeof_typelist; | |
741 | |
742 template<class ...Types> | |
743 struct sizeof_typelist< typelist<Types...> > | |
744 { | |
745 static const std::size_t value = sizeof...(Types); | |
746 }; | |
747 | |
748 //invert_typelist_impl | |
749 template<class Typelist, class Indexes> | |
750 struct invert_typelist_impl; | |
751 | |
752 | |
753 template<class Typelist, int ...Ints> | |
754 struct invert_typelist_impl< Typelist, index_tuple<Ints...> > | |
755 { | |
756 static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1; | |
757 typedef typelist | |
758 <typename typelist_element<last_idx - Ints, Typelist>::type...> type; | |
759 }; | |
760 | |
761 template<class Typelist, int Int> | |
762 struct invert_typelist_impl< Typelist, index_tuple<Int> > | |
763 { | |
764 typedef Typelist type; | |
765 }; | |
766 | |
767 template<class Typelist> | |
768 struct invert_typelist_impl< Typelist, index_tuple<> > | |
769 { | |
770 typedef Typelist type; | |
771 }; | |
772 | |
773 //invert_typelist | |
774 template<class Typelist> | |
775 struct invert_typelist; | |
776 | |
777 template<class ...Types> | |
778 struct invert_typelist< typelist<Types...> > | |
779 { | |
780 typedef typelist<Types...> typelist_t; | |
781 typedef typename build_number_seq<sizeof...(Types)>::type indexes_t; | |
782 typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type; | |
783 }; | |
784 | |
785 //Do pack | |
786 template<class Typelist> | |
787 struct do_pack; | |
788 | |
789 template<> | |
790 struct do_pack<typelist<> >; | |
791 | |
792 template<class Prev> | |
793 struct do_pack<typelist<Prev> > | |
794 { | |
795 typedef Prev type; | |
796 }; | |
797 | |
798 template<class Prev, class Last> | |
799 struct do_pack<typelist<Prev, Last> > | |
800 { | |
801 typedef typename Prev::template pack<Last> type; | |
802 }; | |
803 | |
804 template<class Prev, class ...Others> | |
805 struct do_pack<typelist<Prev, Others...> > | |
806 { | |
807 typedef typename Prev::template pack | |
808 <typename do_pack<typelist<Others...> >::type> type; | |
809 }; | |
810 | |
811 | |
812 template<class ...Options> | |
813 struct pack_options | |
814 { | |
815 typedef typelist<Options...> typelist_t; | |
816 typedef typename invert_typelist<typelist_t>::type inverted_typelist; | |
817 typedef typename do_pack<inverted_typelist>::type type; | |
818 }; | |
819 | |
820 #endif | |
821 | 228 |
822 struct hook_defaults | 229 struct hook_defaults |
823 { | 230 { |
824 typedef void* void_pointer; | 231 typedef void* void_pointer; |
825 static const link_mode_type link_mode = safe_link; | 232 static const link_mode_type link_mode = safe_link; |
826 typedef default_tag tag; | 233 typedef dft_tag tag; |
827 static const bool optimize_size = false; | 234 static const bool optimize_size = false; |
828 static const bool store_hash = false; | 235 static const bool store_hash = false; |
829 static const bool linear = false; | 236 static const bool linear = false; |
830 static const bool optimize_multikey = false; | 237 static const bool optimize_multikey = false; |
831 }; | 238 }; |