From 08c1e93fa36a49f49325a07fe91ff92c964c2b6c Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Thu, 11 Dec 2014 18:55:56 +0900 Subject: Imported Upstream version 1.57.0 --- boost/intrusive/detail/generic_hook.hpp | 198 +++++++++++++++++--------------- 1 file changed, 103 insertions(+), 95 deletions(-) (limited to 'boost/intrusive/detail/generic_hook.hpp') 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 -#include +#if defined(_MSC_VER) +# pragma once +#endif + #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{}; +namespace detail { -template -struct default_definer; +template +struct link_dispatch +{}; + +template +void destructor_impl(Hook &hook, detail::link_dispatch) +{ //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 +void destructor_impl(Hook &hook, detail::link_dispatch) +{ hook.unlink(); } + +template +void destructor_impl(Hook &, detail::link_dispatch) +{} + +} //namespace detail { + +enum base_hook_type +{ NoBaseHookId +, ListBaseHookId +, SlistBaseHookId +, RbTreeBaseHookId +, HashBaseHookId +, AvlTreeBaseHookId +, BsTreeBaseHookId +, TreapTreeBaseHookId +, AnyBaseHookId +}; -template -struct default_definer -{ typedef Hook default_list_hook; }; -template -struct default_definer -{ typedef Hook default_slist_hook; }; +template +struct hook_tags_definer{}; -template -struct default_definer -{ typedef Hook default_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_list_hook; }; -template -struct default_definer -{ typedef Hook default_uset_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_slist_hook; }; -template -struct default_definer -{ typedef Hook default_splay_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_rbtree_hook; }; -template -struct default_definer -{ typedef Hook default_avl_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_hashtable_hook; }; -template -struct default_definer -{ typedef Hook default_bs_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_avltree_hook; }; -template -struct default_definer -{ typedef Hook default_any_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_bstree_hook; }; -template -struct make_default_definer -{ - typedef typename detail::if_c - < BaseHookType != 0 - , default_definer - , no_default_definer>::type type; -}; +template +struct hook_tags_definer +{ 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 - ::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::value; + static const bool safemode_or_autounlink = is_safe_autounlink::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 - , detail::is_same::value*HookType + : public detail::if_c + < detail::is_same::value + , typename NodeAlgorithms::node + , node_holder >::type - , public make_node_holder::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 + , detail::is_same::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::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::pointer_to(static_cast(*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()); + (*this, detail::link_dispatch()); } 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 - #endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP -- cgit v1.2.3