options.hpp 21 KB

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