///////////////////////////////////////////////////////////////////////////// // // (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 #include #include #include #include #include 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\ (get_parent_from_member(n, &MyClass::InnerNode::MEMBERNAME)\ ,&MyClass::inner\ );\ }\ static const_pointer to_value_ptr(const_hook_ptr n)\ {\ return get_parent_from_member\ (get_parent_from_member(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(static_cast(n),&MyClass::inner);\ }\ static const_pointer to_value_ptr(const_hook_ptr n)\ {\ return get_parent_from_member(static_cast(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; }