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