///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. // (C) Copyright Ion Gaztanaga 2006-2007 // // 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_HASHSET_HOOK_HPP #define BOOST_INTRUSIVE_HASHSET_HOOK_HPP #include #include #include #include #include #include namespace boost { namespace intrusive { //! Derive a class from unordered_set_base_hook in order to store objects in //! in an unordered_set/unordered_multi_set. unordered_set_base_hook holds the data necessary to maintain //! the unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set. //! //! The first integer template argument defines a tag to identify the node. //! The same tag value can be used in different classes, but if a class is //! derived from more than one unordered_set_base_hook, then each unordered_set_base_hook needs its //! unique tag. //! //! The second boolean template parameter will specify the linking mode of the hook. //! //! The third argument is the pointer type that will be used internally in the hook //! and the unordered_set/unordered_multi_set configured from this hook. template< class Tag //= tag , linking_policy Policy //= safe_link , class VoidPointer //= void * > class unordered_set_base_hook { /// @cond typedef slist_base_hook IsListHook; IsListHook m_slisthook; typedef IsListHook implementation_defined; /// @endcond public: enum { linking_policy = Policy }; typedef typename implementation_defined::node_traits node_traits; typedef typename node_traits::node node; typedef typename boost::pointer_to_other ::type node_ptr; typedef typename boost::pointer_to_other ::type const_node_ptr; typedef unordered_set_base_hook this_type; typedef typename boost::pointer_to_other ::type this_type_ptr; typedef typename boost::pointer_to_other ::type const_this_type_ptr; //! Effects: If Policy is auto_unlink or safe_mode_linnk //! initializes the node to an unlinked state. //! //! Throws: Nothing. unordered_set_base_hook() : m_slisthook() {} //! Effects: If Policy is auto_unlink or safe_mode_linnk //! initializes the node to an unlinked state. The argument is ignored. //! //! Throws: Nothing. //! //! Rationale: Providing a copy-constructor //! makes classes using unordered_set_base_hook STL-compliant without forcing the //! user to do some additional work. "swap" can be used to emulate //! move-semantics. unordered_set_base_hook(const unordered_set_base_hook &other) : m_slisthook(other.m_slisthook) {} //! Effects: Empty function. The argument is ignored. //! //! Throws: Nothing. //! //! Rationale: Providing an assignment operator //! makes classes using unordered_set_base_hook STL-compliant without forcing the //! user to do some additional work. "swap" can be used to emulate //! move-semantics. unordered_set_base_hook& operator=(const unordered_set_base_hook &other) { return *this; } //! Effects: If Policy is normal_link, the destructor does //! nothing (ie. no code is generated). If Policy is safe_link and the //! object is stored in an list an assertion is raised. If Policy is //! auto_unlink and "is_linked()" is true, the node is unlinked. //! //! Throws: Nothing. ~unordered_set_base_hook() {} //m_slisthook's destructor does the job //! Precondition: Policy must be safe_link or auto_unlink. //! //! Returns: true, if the node belongs to a container, false //! otherwise. This function can be used to test whether unordered_set/unordered_multiset::iterator_to //! will return a valid iterator. //! //! Complexity: Constant bool is_linked() const { return m_slisthook.is_linked(); } //! The value_traits class is used as the first template argument for unordered_set/unordered_multiset. //! The template argument T defines the class type stored in unordered_set/unordered_multiset. Objects //! of type T and of types derived from T can be stored. T doesn't need to be //! copy-constructible or assignable. template struct value_traits : detail::derivation_hook_value_traits {}; //! Effects: Converts a pointer to a node into //! a pointer to the hook that holds that node. //! //! Throws: Nothing. static this_type_ptr to_hook_ptr(node_ptr p) { return this_type_ptr((this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p))); } //! Effects: Converts a const pointer to a node stored in a container into //! a const pointer to the hook that holds that node. //! //! Throws: Nothing. static const_this_type_ptr to_hook_ptr(const_node_ptr p) { return const_this_type_ptr((const this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p))); } //! Effects: Returns a pointer to the node that this hook holds. //! //! Throws: Nothing. node_ptr to_node_ptr() { return m_slisthook.to_node_ptr(); } //! Effects: Returns a const pointer to the node that this hook holds. //! //! Throws: Nothing. const_node_ptr to_node_ptr() const { return m_slisthook.to_node_ptr(); } }; //! Put a public data member unordered_set_member_hook in order to store objects of this class in //! an unordered_set/unordered_multi_set. unordered_set_member_hook holds the data necessary for maintaining the //! unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set. //! //! The first boolean template parameter will specify the linking mode of the hook. //! //! The second argument is the pointer type that will be used internally in the hook //! and the unordered_set/unordered_multi_set configured from this hook. template< linking_policy Policy //= safe_link , class VoidPointer //= void * > class unordered_set_member_hook { /// @cond typedef slist_member_hook IsListHook; IsListHook m_slisthook; typedef IsListHook implementation_defined; /// @endcond public: enum { linking_policy = Policy }; typedef typename implementation_defined::node_traits node_traits; typedef typename node_traits::node node; typedef typename boost::pointer_to_other ::type node_ptr; typedef typename boost::pointer_to_other ::type const_node_ptr; typedef unordered_set_member_hook this_type; typedef typename boost::pointer_to_other ::type this_type_ptr; typedef typename boost::pointer_to_other ::type const_this_type_ptr; public: //! Effects: If Policy is auto_unlink or safe_mode_linnk //! initializes the node to an unlinked state. //! //! Throws: Nothing. unordered_set_member_hook() : m_slisthook() {} //! Effects: If Policy is auto_unlink or safe_mode_linnk //! initializes the node to an unlinked state. The argument is ignored. //! //! Throws: Nothing. //! //! Rationale: Providing a copy-constructor //! makes classes using unordered_set_member_hook STL-compliant without forcing the //! user to do some additional work. unordered_set_member_hook(const unordered_set_member_hook &other) : m_slisthook(other.m_slisthook) {} //! Effects: Empty function. The argument is ignored. //! //! Throws: Nothing. //! //! Rationale: Providing an assignment operator //! makes classes using unordered_set_member_hook STL-compliant without forcing the //! user to do some additional work. unordered_set_member_hook& operator=(const unordered_set_member_hook &other) { return *this; } //! Effects: If Policy is normal_link, the destructor does //! nothing (ie. no code is generated). If Policy is safe_link and the //! object is stored in an list an assertion is raised. If Policy is //! auto_unlink and "is_linked()" is true, the node is unlinked. //! //! Throws: Nothing. ~unordered_set_member_hook() {} //m_slisthook's destructor does the job //! Precondition: Policy must be safe_link or auto_unlink. //! //! Complexity: Constant bool is_linked() const { return m_slisthook.is_linked(); } //! The value_traits class is used as the first template argument for unordered_set/unordered_multiset. //! The template argument is a pointer to member pointing to the node in //! the class. Objects of type T and of types derived from T can be stored. //! T doesn't need to be copy-constructible or assignable. template struct value_traits : detail::member_hook_value_traits {}; //! Effects: Removes the node if it's inserted in a container. //! This function is only allowed if Policy is auto_unlink. //! //! Throws: Nothing. void unlink() { m_slisthook.unlink(); } //! Effects: Converts a pointer to a node into //! a pointer to the hook that holds that node. //! //! Throws: Nothing. static this_type_ptr to_hook_ptr(node_ptr p) { return this_type_ptr((this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p))); } //! Effects: Converts a const pointer to a node stored in a container into //! a const pointer to the hook that holds that node. //! //! Throws: Nothing. static const_this_type_ptr to_hook_ptr(const_node_ptr p) { return const_this_type_ptr((const this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p))); } //! Effects: Returns a pointer to the node that this hook holds. //! //! Throws: Nothing. node_ptr to_node_ptr() { return m_slisthook.to_node_ptr(); } //! Effects: Returns a const pointer to the node that this hook holds. //! //! Throws: Nothing. const_node_ptr to_node_ptr() const { return m_slisthook.to_node_ptr(); } }; } //namespace intrusive } //namespace boost #include #endif //BOOST_INTRUSIVE_HASHSET_HOOK_HPP