From 1a78a62555be32868418fe52f8e330c9d0f95d5a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 30 Oct 2012 12:57:26 -0700 Subject: Imported Upstream version 1.49.0 --- boost/intrusive/detail/generic_hook.hpp | 209 ++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 boost/intrusive/detail/generic_hook.hpp (limited to 'boost/intrusive/detail/generic_hook.hpp') diff --git a/boost/intrusive/detail/generic_hook.hpp b/boost/intrusive/detail/generic_hook.hpp new file mode 100644 index 0000000000..fc35610b8d --- /dev/null +++ b/boost/intrusive/detail/generic_hook.hpp @@ -0,0 +1,209 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2009 +// +// 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. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP +#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +/// @cond + +enum +{ NoBaseHook +, ListBaseHook +, SlistBaseHook +, SetBaseHook +, UsetBaseHook +, SplaySetBaseHook +, AvlSetBaseHook +, BsSetBaseHook +, AnyBaseHook +}; + +struct no_default_definer{}; + +template +struct default_definer; + +template +struct default_definer +{ typedef Hook default_list_hook; }; + +template +struct default_definer +{ typedef Hook default_slist_hook; }; + +template +struct default_definer +{ typedef Hook default_set_hook; }; + +template +struct default_definer +{ typedef Hook default_uset_hook; }; + +template +struct default_definer +{ typedef Hook default_splay_set_hook; }; + +template +struct default_definer +{ typedef Hook default_avl_set_hook; }; + +template +struct default_definer +{ typedef Hook default_bs_set_hook; }; + +template +struct default_definer +{ typedef Hook default_any_hook; }; + +template +struct make_default_definer +{ + typedef typename detail::if_c + < BaseHookType != 0 + , default_definer + , no_default_definer>::type type; +}; + +template + < class GetNodeAlgorithms + , class Tag + , link_mode_type LinkMode + , int HookType + > +struct make_node_holder +{ + typedef typename detail::if_c + ::value + , detail::node_holder + < typename GetNodeAlgorithms::type::node + , Tag + , LinkMode + , HookType> + , typename GetNodeAlgorithms::type::node + >::type type; +}; + +/// @endcond + +template + < class GetNodeAlgorithms + , class Tag + , link_mode_type LinkMode + , int HookType + > +class generic_hook + /// @cond + + //If the hook is a base hook, derive generic hook from detail::node_holder + //so that a unique base class is created to convert from the node + //to the type. This mechanism will be used by base_hook_traits. + // + //If the hook is a member hook, generic hook will directly derive + //from the hook. + : public make_default_definer + < generic_hook + , detail::is_same::value*HookType + >::type + , public make_node_holder::type + /// @endcond +{ + /// @cond + typedef typename GetNodeAlgorithms::type node_algorithms; + typedef typename node_algorithms::node node; + typedef typename node_algorithms::node_ptr node_ptr; + typedef typename node_algorithms::const_node_ptr const_node_ptr; + + public: + struct boost_intrusive_tags + { + static const int hook_type = HookType; + static const link_mode_type link_mode = LinkMode; + typedef Tag tag; + typedef typename GetNodeAlgorithms::type::node_traits node_traits; + static const bool is_base_hook = !detail::is_same::value; + static const bool safemode_or_autounlink = + (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link; + }; + + node_ptr this_ptr() + { return pointer_traits::pointer_to(static_cast(*this)); } + + const_node_ptr this_ptr() const + { return pointer_traits::pointer_to(static_cast(*this)); } + + public: + /// @endcond + + generic_hook() + { + if(boost_intrusive_tags::safemode_or_autounlink){ + node_algorithms::init(this->this_ptr()); + } + } + + generic_hook(const generic_hook& ) + { + if(boost_intrusive_tags::safemode_or_autounlink){ + node_algorithms::init(this->this_ptr()); + } + } + + generic_hook& operator=(const generic_hook& ) + { return *this; } + + ~generic_hook() + { + destructor_impl + (*this, detail::link_dispatch()); + } + + void swap_nodes(generic_hook &other) + { + node_algorithms::swap_nodes + (this->this_ptr(), other.this_ptr()); + } + + bool is_linked() const + { + //is_linked() can be only used in safe-mode or auto-unlink + BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink )); + return !node_algorithms::unique(this->this_ptr()); + } + + void unlink() + { + BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink )); + node_algorithms::unlink(this->this_ptr()); + node_algorithms::init(this->this_ptr()); + } +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP -- cgit v1.2.3