function_hook_test.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2010-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. #include <boost/intrusive/parent_from_member.hpp>
  13. #include <boost/intrusive/list.hpp>
  14. #include <boost/intrusive/slist.hpp>
  15. #include <boost/intrusive/set.hpp>
  16. #include <boost/intrusive/unordered_set.hpp>
  17. #include <boost/functional/hash.hpp>
  18. using namespace boost::intrusive;
  19. struct MyClass
  20. {
  21. MyClass() : order(0) {}
  22. int order;
  23. //This internal type has two hooks
  24. struct InnerNode : public list_base_hook<>, public slist_base_hook<>
  25. , public set_base_hook<>, public unordered_set_base_hook<>
  26. {
  27. list_member_hook<> listhook;
  28. slist_member_hook<> slisthook;
  29. set_member_hook<> sethook;
  30. unordered_set_member_hook<> usethook;
  31. } inner;
  32. friend bool operator < (const MyClass &l, const MyClass &r)
  33. { return l.order < r.order; }
  34. friend bool operator == (const MyClass &l, const MyClass &r)
  35. { return l.order == r.order; }
  36. friend std::size_t hash_value(const MyClass &value)
  37. { return std::size_t(value.order); }
  38. };
  39. //This functor converts between MyClass and the InnerNode member hook
  40. #define InnerMemberHook(TAG, HOOKTYPE, MEMBERNAME)\
  41. struct InnerMemberHookFunctor##TAG \
  42. {\
  43. typedef HOOKTYPE hook_type;\
  44. typedef hook_type* hook_ptr;\
  45. typedef const hook_type* const_hook_ptr;\
  46. typedef MyClass value_type;\
  47. typedef value_type* pointer;\
  48. typedef const value_type* const_pointer;\
  49. \
  50. static hook_ptr to_hook_ptr (value_type &value)\
  51. { return &value.inner.MEMBERNAME; }\
  52. static const_hook_ptr to_hook_ptr(const value_type &value)\
  53. { return &value.inner.MEMBERNAME; }\
  54. static pointer to_value_ptr(hook_ptr n)\
  55. {\
  56. return get_parent_from_member<MyClass>\
  57. (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
  58. ,&MyClass::inner\
  59. );\
  60. }\
  61. static const_pointer to_value_ptr(const_hook_ptr n)\
  62. {\
  63. return get_parent_from_member<MyClass>\
  64. (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
  65. ,&MyClass::inner\
  66. );\
  67. }\
  68. };\
  69. //
  70. //This functor converts between MyClass and the InnerNode base hook
  71. #define InnerBaseHook(TAG, HOOKTYPE)\
  72. struct InnerBaseHookFunctor##TAG \
  73. {\
  74. typedef HOOKTYPE hook_type;\
  75. typedef hook_type* hook_ptr;\
  76. typedef const hook_type* const_hook_ptr;\
  77. typedef MyClass value_type;\
  78. typedef value_type* pointer;\
  79. typedef const value_type* const_pointer;\
  80. \
  81. static hook_ptr to_hook_ptr (value_type &value)\
  82. { return &value.inner; }\
  83. static const_hook_ptr to_hook_ptr(const value_type &value)\
  84. { return &value.inner; }\
  85. static pointer to_value_ptr(hook_ptr n)\
  86. {\
  87. return get_parent_from_member<MyClass>(static_cast<MyClass::InnerNode*>(n),&MyClass::inner);\
  88. }\
  89. static const_pointer to_value_ptr(const_hook_ptr n)\
  90. {\
  91. return get_parent_from_member<MyClass>(static_cast<const MyClass::InnerNode*>(n),&MyClass::inner);\
  92. }\
  93. };\
  94. //
  95. //List
  96. InnerMemberHook(List, list_member_hook<>, listhook)
  97. InnerBaseHook(List, list_base_hook<>)
  98. //Slist
  99. InnerMemberHook(Slist, slist_member_hook<>, slisthook)
  100. InnerBaseHook(Slist, slist_base_hook<>)
  101. //Set
  102. InnerMemberHook(Set, set_member_hook<>, sethook)
  103. InnerBaseHook(Set, set_base_hook<>)
  104. //Unordered Set
  105. InnerMemberHook(USet, unordered_set_member_hook<>, usethook)
  106. InnerBaseHook(USet, unordered_set_base_hook<>)
  107. //Define containers
  108. typedef list < MyClass, function_hook< InnerMemberHookFunctorList> > CustomListMember;
  109. typedef list < MyClass, function_hook< InnerBaseHookFunctorList > > CustomListBase;
  110. typedef slist< MyClass, function_hook< InnerMemberHookFunctorSlist> > CustomSlistMember;
  111. typedef slist< MyClass, function_hook< InnerBaseHookFunctorSlist > > CustomSlistBase;
  112. typedef set < MyClass, function_hook< InnerMemberHookFunctorSet> > CustomSetMember;
  113. typedef set < MyClass, function_hook< InnerBaseHookFunctorSet > > CustomSetBase;
  114. typedef unordered_set< MyClass, function_hook< InnerMemberHookFunctorUSet> > CustomUSetMember;
  115. typedef unordered_set< MyClass, function_hook< InnerBaseHookFunctorUSet > > CustomUSetBase;
  116. int main()
  117. {
  118. MyClass n;
  119. CustomListBase listbase;
  120. CustomListMember listmember;
  121. CustomSlistBase slistbase;
  122. CustomSlistMember slistmember;
  123. CustomSetBase setbase;
  124. CustomSetMember setmember;
  125. CustomUSetBase::bucket_type buckets_uset[1];
  126. CustomUSetBase usetbase(CustomUSetBase::bucket_traits(buckets_uset, 1));
  127. CustomUSetBase::bucket_type buckets_umultiset[1];
  128. CustomUSetMember usetmember(CustomUSetMember::bucket_traits(buckets_umultiset, 1));
  129. listbase.insert(listbase.begin(), n);
  130. listmember.insert(listmember.begin(), n);
  131. slistbase.insert(slistbase.begin(), n);
  132. slistmember.insert(slistmember.begin(), n);
  133. setbase.insert(n);
  134. setmember.insert(n);
  135. usetbase.insert(n);
  136. usetmember.insert(n);
  137. return 0;
  138. }