summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/intrusive/test/function_hook_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/intrusive/test/function_hook_test.cpp')
-rw-r--r--src/boost/libs/intrusive/test/function_hook_test.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/boost/libs/intrusive/test/function_hook_test.cpp b/src/boost/libs/intrusive/test/function_hook_test.cpp
new file mode 100644
index 00000000..9b16395c
--- /dev/null
+++ b/src/boost/libs/intrusive/test/function_hook_test.cpp
@@ -0,0 +1,150 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2013
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/parent_from_member.hpp>
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/functional/hash.hpp>
+
+using namespace boost::intrusive;
+
+struct MyClass
+{
+ MyClass() : order(0) {}
+ int order;
+
+ //This internal type has two hooks
+ struct InnerNode : public list_base_hook<>, public slist_base_hook<>
+ , public set_base_hook<>, public unordered_set_base_hook<>
+ {
+ list_member_hook<> listhook;
+ slist_member_hook<> slisthook;
+ set_member_hook<> sethook;
+ unordered_set_member_hook<> usethook;
+ } inner;
+
+ friend bool operator < (const MyClass &l, const MyClass &r)
+ { return l.order < r.order; }
+ friend bool operator == (const MyClass &l, const MyClass &r)
+ { return l.order == r.order; }
+ friend std::size_t hash_value(const MyClass &value)
+ { return std::size_t(value.order); }
+};
+
+//This functor converts between MyClass and the InnerNode member hook
+#define InnerMemberHook(TAG, HOOKTYPE, MEMBERNAME)\
+ struct InnerMemberHookFunctor##TAG \
+ {\
+ typedef HOOKTYPE hook_type;\
+ typedef hook_type* hook_ptr;\
+ typedef const hook_type* const_hook_ptr;\
+ typedef MyClass value_type;\
+ typedef value_type* pointer;\
+ typedef const value_type* const_pointer;\
+ \
+ static hook_ptr to_hook_ptr (value_type &value)\
+ { return &value.inner.MEMBERNAME; }\
+ static const_hook_ptr to_hook_ptr(const value_type &value)\
+ { return &value.inner.MEMBERNAME; }\
+ static pointer to_value_ptr(hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>\
+ (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
+ ,&MyClass::inner\
+ );\
+ }\
+ static const_pointer to_value_ptr(const_hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>\
+ (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
+ ,&MyClass::inner\
+ );\
+ }\
+ };\
+//
+
+
+//This functor converts between MyClass and the InnerNode base hook
+#define InnerBaseHook(TAG, HOOKTYPE)\
+ struct InnerBaseHookFunctor##TAG \
+ {\
+ typedef HOOKTYPE hook_type;\
+ typedef hook_type* hook_ptr;\
+ typedef const hook_type* const_hook_ptr;\
+ typedef MyClass value_type;\
+ typedef value_type* pointer;\
+ typedef const value_type* const_pointer;\
+ \
+ static hook_ptr to_hook_ptr (value_type &value)\
+ { return &value.inner; }\
+ static const_hook_ptr to_hook_ptr(const value_type &value)\
+ { return &value.inner; }\
+ static pointer to_value_ptr(hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>(static_cast<MyClass::InnerNode*>(n),&MyClass::inner);\
+ }\
+ static const_pointer to_value_ptr(const_hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>(static_cast<const MyClass::InnerNode*>(n),&MyClass::inner);\
+ }\
+ };\
+//
+
+//List
+InnerMemberHook(List, list_member_hook<>, listhook)
+InnerBaseHook(List, list_base_hook<>)
+//Slist
+InnerMemberHook(Slist, slist_member_hook<>, slisthook)
+InnerBaseHook(Slist, slist_base_hook<>)
+//Set
+InnerMemberHook(Set, set_member_hook<>, sethook)
+InnerBaseHook(Set, set_base_hook<>)
+//Unordered Set
+InnerMemberHook(USet, unordered_set_member_hook<>, usethook)
+InnerBaseHook(USet, unordered_set_base_hook<>)
+
+//Define containers
+typedef list < MyClass, function_hook< InnerMemberHookFunctorList> > CustomListMember;
+typedef list < MyClass, function_hook< InnerBaseHookFunctorList > > CustomListBase;
+typedef slist< MyClass, function_hook< InnerMemberHookFunctorSlist> > CustomSlistMember;
+typedef slist< MyClass, function_hook< InnerBaseHookFunctorSlist > > CustomSlistBase;
+typedef set < MyClass, function_hook< InnerMemberHookFunctorSet> > CustomSetMember;
+typedef set < MyClass, function_hook< InnerBaseHookFunctorSet > > CustomSetBase;
+typedef unordered_set< MyClass, function_hook< InnerMemberHookFunctorUSet> > CustomUSetMember;
+typedef unordered_set< MyClass, function_hook< InnerBaseHookFunctorUSet > > CustomUSetBase;
+
+int main()
+{
+ MyClass n;
+ CustomListBase listbase;
+ CustomListMember listmember;
+ CustomSlistBase slistbase;
+ CustomSlistMember slistmember;
+ CustomSetBase setbase;
+ CustomSetMember setmember;
+ CustomUSetBase::bucket_type buckets_uset[1];
+ CustomUSetBase usetbase(CustomUSetBase::bucket_traits(buckets_uset, 1));
+ CustomUSetBase::bucket_type buckets_umultiset[1];
+ CustomUSetMember usetmember(CustomUSetMember::bucket_traits(buckets_umultiset, 1));
+
+ listbase.insert(listbase.begin(), n);
+ listmember.insert(listmember.begin(), n);
+ slistbase.insert(slistbase.begin(), n);
+ slistmember.insert(slistmember.begin(), n);
+ setbase.insert(n);
+ setmember.insert(n);
+ usetbase.insert(n);
+ usetmember.insert(n);
+
+ return 0;
+}