Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/intrusive/options.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 ///////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Ion Gaztanaga 2007-2013 | |
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_OPTIONS_HPP | |
14 #define BOOST_INTRUSIVE_OPTIONS_HPP | |
15 | |
16 #include <boost/intrusive/detail/config_begin.hpp> | |
17 #include <boost/intrusive/intrusive_fwd.hpp> | |
18 #include <boost/intrusive/link_mode.hpp> | |
19 #include <boost/intrusive/detail/mpl.hpp> | |
20 #include <boost/intrusive/detail/utilities.hpp> | |
21 #include <boost/static_assert.hpp> | |
22 | |
23 | |
24 namespace boost { | |
25 namespace intrusive { | |
26 | |
27 /// @cond | |
28 | |
29 //typedef void default_tag; | |
30 struct default_tag; | |
31 struct member_tag; | |
32 | |
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> | |
185 struct get_node_traits | |
186 { | |
187 typedef SupposedValueTraits supposed_value_traits; | |
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 | |
208 //!This option setter specifies if the intrusive | |
209 //!container stores its size as a member to | |
210 //!obtain constant-time size() member. | |
211 template<bool Enabled> | |
212 struct constant_time_size | |
213 { | |
214 /// @cond | |
215 template<class Base> | |
216 struct pack : Base | |
217 { | |
218 static const bool constant_time_size = Enabled; | |
219 }; | |
220 /// @endcond | |
221 }; | |
222 | |
223 //!This option setter specifies the type that | |
224 //!the container will use to store its size. | |
225 template<class SizeType> | |
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 | |
237 //!This option setter specifies the strict weak ordering | |
238 //!comparison functor for the value type | |
239 template<class 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 | |
251 //!This option setter for scapegoat containers specifies if | |
252 //!the intrusive scapegoat container should use a non-variable | |
253 //!alpha value that does not need floating-point operations. | |
254 //! | |
255 //!If activated, the fixed alpha value is 1/sqrt(2). This | |
256 //!option also saves some space in the container since | |
257 //!the alpha value and some additional data does not need | |
258 //!to be stored in the container. | |
259 //! | |
260 //!If the user only needs an alpha value near 1/sqrt(2), this | |
261 //!option also improves performance since avoids logarithm | |
262 //!and division operations when rebalancing the tree. | |
263 template<bool Enabled> | |
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 | |
275 //!This option setter specifies the equality | |
276 //!functor for the value type | |
277 template<class 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 | |
289 //!This option setter specifies the equality | |
290 //!functor for the value type | |
291 template<class 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 | |
303 //!This option setter specifies the hash | |
304 //!functor for the value type | |
305 template<class 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 | |
317 //!This option setter specifies the relationship between the type | |
318 //!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. | |
320 template<typename ValueTraits> | |
321 struct value_traits | |
322 { | |
323 /// @cond | |
324 template<class Base> | |
325 struct pack : Base | |
326 { | |
327 typedef ValueTraits proto_value_traits; | |
328 }; | |
329 /// @endcond | |
330 }; | |
331 | |
332 //!This option setter specifies the member hook the | |
333 //!container must use. | |
334 template< typename Parent | |
335 , typename MemberHook | |
336 , MemberHook Parent::* PtrToMember> | |
337 struct member_hook | |
338 { | |
339 /// @cond | |
340 /* | |
341 typedef typename MemberHook::hooktags::node_traits node_traits; | |
342 typedef typename node_traits::node node_type; | |
343 typedef node_type Parent::* Ptr2MemNode; | |
344 typedef mhtraits | |
345 < Parent | |
346 , node_traits | |
347 //This cast is really ugly but necessary to reduce template bloat. | |
348 //Since we control the layout between the hook and the node, and there is | |
349 //always single inheritance, the offset of the node is exactly the offset of | |
350 //the hook. Since the node type is shared between all member hooks, this saves | |
351 //quite a lot of symbol stuff. | |
352 , (Ptr2MemNode)PtrToMember | |
353 , MemberHook::hooktags::link_mode> member_value_traits; | |
354 */ | |
355 typedef mhtraits | |
356 < Parent | |
357 , MemberHook | |
358 , PtrToMember | |
359 > member_value_traits; | |
360 template<class Base> | |
361 struct pack : Base | |
362 { | |
363 typedef member_value_traits proto_value_traits; | |
364 }; | |
365 /// @endcond | |
366 }; | |
367 | |
368 | |
369 //!This option setter specifies the function object that will | |
370 //!be used to convert between values to be inserted in a container | |
371 //!and the hook to be used for that purpose. | |
372 template< typename Functor> | |
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 | |
387 //!This option setter specifies that the container | |
388 //!must use the specified base hook | |
389 template<typename BaseHook> | |
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 | |
401 //!This option setter specifies the type of | |
402 //!a void pointer. This will instruct the hook | |
403 //!to use this type of pointer instead of the | |
404 //!default one | |
405 template<class VoidPointer> | |
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 | |
417 //!This option setter specifies the type of | |
418 //!the tag of a base hook. A type cannot have two | |
419 //!base hooks of the same type, so a tag can be used | |
420 //!to differentiate two base hooks with otherwise same type | |
421 template<class 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 | |
433 //!This option setter specifies the link mode | |
434 //!(normal_link, safe_link or auto_unlink) | |
435 template<link_mode_type LinkType> | |
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 | |
447 //!This option setter specifies if the hook | |
448 //!should be optimized for size instead of for speed. | |
449 template<bool Enabled> | |
450 struct optimize_size | |
451 { | |
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. | |
463 template<bool Enabled> | |
464 struct linear | |
465 { | |
466 /// @cond | |
467 template<class Base> | |
468 struct pack : Base | |
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 | |
489 //!This option setter specifies the bucket traits | |
490 //!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 | |
492 template<class BucketTraits> | |
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 | |
504 //!This option setter specifies if the unordered hook | |
505 //!should offer room to store the hash value. | |
506 //!Storing the hash in the hook will speed up rehashing | |
507 //!processes in applications where rehashing is frequent, | |
508 //!rehashing might throw or the value is heavy to hash. | |
509 template<bool Enabled> | |
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 | |
521 //!This option setter specifies if the unordered hook | |
522 //!should offer room to store another link to another node | |
523 //!with the same key. | |
524 //!Storing this link will speed up lookups and insertions on | |
525 //!unordered_multiset containers with a great number of elements | |
526 //!with the same key. | |
527 template<bool Enabled> | |
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 | |
539 //!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 | |
541 //!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 | |
543 //!will be checked to through assertions to assure the bucket length is power of two. | |
544 template<bool Enabled> | |
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 | |
556 //!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. | |
558 //!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). | |
560 template<bool Enabled> | |
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 | |
573 //!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<> | |
575 //!is not true. | |
576 //!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 | |
578 //!stored hash values. | |
579 template<bool Enabled> | |
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 | |
591 //!This option setter specifies if the hash container will use incremental | |
592 //!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. | |
594 //!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 | |
596 //!(rehashing the whole bucket array) is not admisible. | |
597 template<bool Enabled> | |
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 | |
609 /// @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 | |
822 struct hook_defaults | |
823 { | |
824 typedef void* void_pointer; | |
825 static const link_mode_type link_mode = safe_link; | |
826 typedef default_tag tag; | |
827 static const bool optimize_size = false; | |
828 static const bool store_hash = false; | |
829 static const bool linear = false; | |
830 static const bool optimize_multikey = false; | |
831 }; | |
832 | |
833 /// @endcond | |
834 | |
835 } //namespace intrusive { | |
836 } //namespace boost { | |
837 | |
838 #include <boost/intrusive/detail/config_end.hpp> | |
839 | |
840 #endif //#ifndef BOOST_INTRUSIVE_OPTIONS_HPP |