1 /////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2010-2013
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)
9 // See http://www.boost.org/libs/intrusive for documentation.
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>
19 using namespace boost::intrusive
;
23 MyClass() : order(0) {}
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
<>
30 list_member_hook
<> listhook
;
31 slist_member_hook
<> slisthook
;
32 set_member_hook
<> sethook
;
33 unordered_set_member_hook
<> usethook
;
36 friend bool operator < (const MyClass
&l
, const MyClass
&r
)
37 { return l
.order
< r
.order
; }
38 friend bool operator == (const MyClass
&l
, const MyClass
&r
)
39 { return l
.order
== r
.order
; }
40 friend std::size_t hash_value(const MyClass
&value
)
41 { return std::size_t(value
.order
); }
44 //This functor converts between MyClass and the InnerNode member hook
45 #define InnerMemberHook(TAG, HOOKTYPE, MEMBERNAME)\
46 struct InnerMemberHookFunctor##TAG \
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;\
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)\
61 return get_parent_from_member<MyClass>\
62 (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
66 static const_pointer to_value_ptr(const_hook_ptr n)\
68 return get_parent_from_member<MyClass>\
69 (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
77 //This functor converts between MyClass and the InnerNode base hook
78 #define InnerBaseHook(TAG, HOOKTYPE)\
79 struct InnerBaseHookFunctor##TAG \
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;\
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)\
94 return get_parent_from_member<MyClass>(static_cast<MyClass::InnerNode*>(n),&MyClass::inner);\
96 static const_pointer to_value_ptr(const_hook_ptr n)\
98 return get_parent_from_member<MyClass>(static_cast<const MyClass::InnerNode*>(n),&MyClass::inner);\
104 InnerMemberHook(List
, list_member_hook
<>, listhook
)
105 InnerBaseHook(List
, list_base_hook
<>)
107 InnerMemberHook(Slist
, slist_member_hook
<>, slisthook
)
108 InnerBaseHook(Slist
, slist_base_hook
<>)
110 InnerMemberHook(Set
, set_member_hook
<>, sethook
)
111 InnerBaseHook(Set
, set_base_hook
<>)
113 InnerMemberHook(USet
, unordered_set_member_hook
<>, usethook
)
114 InnerBaseHook(USet
, unordered_set_base_hook
<>)
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
;
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));
140 listbase
.insert(listbase
.begin(), n
);
141 listmember
.insert(listmember
.begin(), n
);
142 slistbase
.insert(slistbase
.begin(), n
);
143 slistmember
.insert(slistmember
.begin(), n
);
147 usetmember
.insert(n
);