diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/intrusive/detail/generic_hook.hpp | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/intrusive/detail/generic_hook.hpp')
-rw-r--r-- | boost/intrusive/detail/generic_hook.hpp | 198 |
1 files changed, 103 insertions, 95 deletions
diff --git a/boost/intrusive/detail/generic_hook.hpp b/boost/intrusive/detail/generic_hook.hpp index 5ddd52074e..c5af081d65 100644 --- a/boost/intrusive/detail/generic_hook.hpp +++ b/boost/intrusive/detail/generic_hook.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -13,139 +13,147 @@ #ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP #define BOOST_INTRUSIVE_GENERIC_HOOK_HPP -#include <boost/intrusive/detail/config_begin.hpp> -#include <boost/intrusive/intrusive_fwd.hpp> +#if defined(_MSC_VER) +# pragma once +#endif + #include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/link_mode.hpp> -#include <boost/intrusive/detail/utilities.hpp> #include <boost/intrusive/detail/mpl.hpp> -#include <boost/intrusive/pointer_traits.hpp> +#include <boost/intrusive/detail/assert.hpp> +#include <boost/intrusive/detail/node_holder.hpp> #include <boost/static_assert.hpp> namespace boost { namespace intrusive { -namespace detail { /// @cond -enum -{ NoBaseHook -, ListBaseHook -, SlistBaseHook -, SetBaseHook -, UsetBaseHook -, SplaySetBaseHook -, AvlSetBaseHook -, BsSetBaseHook -, AnyBaseHook -}; - -struct no_default_definer{}; +namespace detail { -template <class Hook, unsigned int> -struct default_definer; +template <link_mode_type LinkMode> +struct link_dispatch +{}; + +template<class Hook> +void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>) +{ //If this assertion raises, you might have destroyed an object + //while it was still inserted in a container that is alive. + //If so, remove the object from the container before destroying it. + (void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked()); +} + +template<class Hook> +void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>) +{ hook.unlink(); } + +template<class Hook> +void destructor_impl(Hook &, detail::link_dispatch<normal_link>) +{} + +} //namespace detail { + +enum base_hook_type +{ NoBaseHookId +, ListBaseHookId +, SlistBaseHookId +, RbTreeBaseHookId +, HashBaseHookId +, AvlTreeBaseHookId +, BsTreeBaseHookId +, TreapTreeBaseHookId +, AnyBaseHookId +}; -template <class Hook> -struct default_definer<Hook, ListBaseHook> -{ typedef Hook default_list_hook; }; -template <class Hook> -struct default_definer<Hook, SlistBaseHook> -{ typedef Hook default_slist_hook; }; +template <class HookTags, unsigned int> +struct hook_tags_definer{}; -template <class Hook> -struct default_definer<Hook, SetBaseHook> -{ typedef Hook default_set_hook; }; +template <class HookTags> +struct hook_tags_definer<HookTags, ListBaseHookId> +{ typedef HookTags default_list_hook; }; -template <class Hook> -struct default_definer<Hook, UsetBaseHook> -{ typedef Hook default_uset_hook; }; +template <class HookTags> +struct hook_tags_definer<HookTags, SlistBaseHookId> +{ typedef HookTags default_slist_hook; }; -template <class Hook> -struct default_definer<Hook, SplaySetBaseHook> -{ typedef Hook default_splay_set_hook; }; +template <class HookTags> +struct hook_tags_definer<HookTags, RbTreeBaseHookId> +{ typedef HookTags default_rbtree_hook; }; -template <class Hook> -struct default_definer<Hook, AvlSetBaseHook> -{ typedef Hook default_avl_set_hook; }; +template <class HookTags> +struct hook_tags_definer<HookTags, HashBaseHookId> +{ typedef HookTags default_hashtable_hook; }; -template <class Hook> -struct default_definer<Hook, BsSetBaseHook> -{ typedef Hook default_bs_set_hook; }; +template <class HookTags> +struct hook_tags_definer<HookTags, AvlTreeBaseHookId> +{ typedef HookTags default_avltree_hook; }; -template <class Hook> -struct default_definer<Hook, AnyBaseHook> -{ typedef Hook default_any_hook; }; +template <class HookTags> +struct hook_tags_definer<HookTags, BsTreeBaseHookId> +{ typedef HookTags default_bstree_hook; }; -template <class Hook, unsigned int BaseHookType> -struct make_default_definer -{ - typedef typename detail::if_c - < BaseHookType != 0 - , default_definer<Hook, BaseHookType> - , no_default_definer>::type type; -}; +template <class HookTags> +struct hook_tags_definer<HookTags, AnyBaseHookId> +{ typedef HookTags default_any_hook; }; template - < class GetNodeAlgorithms + < class NodeTraits , class Tag , link_mode_type LinkMode - , int HookType + , base_hook_type BaseHookType > -struct make_node_holder +struct hooktags_impl { - typedef typename detail::if_c - <!detail::is_same<Tag, member_tag>::value - , detail::node_holder - < typename GetNodeAlgorithms::type::node - , Tag - , LinkMode - , HookType> - , typename GetNodeAlgorithms::type::node - >::type type; + static const link_mode_type link_mode = LinkMode; + typedef Tag tag; + typedef NodeTraits node_traits; + static const bool is_base_hook = !detail::is_same<Tag, member_tag>::value; + static const bool safemode_or_autounlink = is_safe_autounlink<link_mode>::value; + static const unsigned int type = BaseHookType; }; /// @endcond template - < class GetNodeAlgorithms + < class NodeAlgorithms , class Tag , link_mode_type LinkMode - , int HookType + , base_hook_type BaseHookType > class generic_hook /// @cond - - //If the hook is a base hook, derive generic hook from detail::node_holder + //If the hook is a base hook, derive generic hook from 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. + //to the type. This mechanism will be used by bhtraits. // //If the hook is a member hook, generic hook will directly derive //from the hook. - : public make_default_definer - < generic_hook<GetNodeAlgorithms, Tag, LinkMode, HookType> - , detail::is_same<Tag, default_tag>::value*HookType + : public detail::if_c + < detail::is_same<Tag, member_tag>::value + , typename NodeAlgorithms::node + , node_holder<typename NodeAlgorithms::node, Tag, BaseHookType> >::type - , public make_node_holder<GetNodeAlgorithms, Tag, LinkMode, HookType>::type + //If this is the a default-tagged base hook derive from a class that + //will define an special internal typedef. Containers will be able to detect this + //special typedef and obtain generic_hook's internal types in order to deduce + //value_traits for this hook. + , public hook_tags_definer + < generic_hook<NodeAlgorithms, Tag, LinkMode, BaseHookType> + , detail::is_same<Tag, default_tag>::value*BaseHookType> /// @endcond { /// @cond - typedef typename GetNodeAlgorithms::type node_algorithms; + typedef NodeAlgorithms 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<Tag, member_tag>::value; - static const bool safemode_or_autounlink = - (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link; - }; + + typedef hooktags_impl + < typename NodeAlgorithms::node_traits + , Tag, LinkMode, BaseHookType> hooktags; node_ptr this_ptr() { return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*this)); } @@ -158,14 +166,14 @@ class generic_hook generic_hook() { - if(boost_intrusive_tags::safemode_or_autounlink){ + if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } generic_hook(const generic_hook& ) { - if(boost_intrusive_tags::safemode_or_autounlink){ + if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } @@ -176,7 +184,7 @@ class generic_hook ~generic_hook() { destructor_impl - (*this, detail::link_dispatch<boost_intrusive_tags::link_mode>()); + (*this, detail::link_dispatch<hooktags::link_mode>()); } void swap_nodes(generic_hook &other) @@ -188,22 +196,22 @@ class generic_hook 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 )); + BOOST_STATIC_ASSERT(( hooktags::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()); + BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink )); + node_ptr n(this->this_ptr()); + if(!node_algorithms::inited(n)){ + node_algorithms::unlink(n); + node_algorithms::init(n); + } } }; -} //namespace detail } //namespace intrusive } //namespace boost -#include <boost/intrusive/detail/config_end.hpp> - #endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP |