File indexing completed on 2025-01-18 09:38:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP
0014 #define BOOST_INTRUSIVE_GENERIC_HOOK_HPP
0015
0016 #ifndef BOOST_CONFIG_HPP
0017 # include <boost/config.hpp>
0018 #endif
0019
0020 #if defined(BOOST_HAS_PRAGMA_ONCE)
0021 # pragma once
0022 #endif
0023
0024 #include <boost/intrusive/pointer_traits.hpp>
0025 #include <boost/intrusive/link_mode.hpp>
0026 #include <boost/intrusive/detail/mpl.hpp>
0027 #include <boost/intrusive/detail/assert.hpp>
0028 #include <boost/intrusive/detail/node_holder.hpp>
0029 #include <boost/intrusive/detail/algo_type.hpp>
0030 #include <boost/static_assert.hpp>
0031
0032 namespace boost {
0033 namespace intrusive {
0034
0035
0036
0037 namespace detail {
0038
0039 template <link_mode_type LinkMode>
0040 struct link_dispatch
0041 {};
0042
0043 template<class Hook>
0044 BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>)
0045 {
0046
0047
0048 (void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked());
0049 }
0050
0051 template<class Hook>
0052 BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>)
0053 { hook.unlink(); }
0054
0055 template<class Hook>
0056 BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
0057 {}
0058
0059 }
0060
0061 enum base_hook_type
0062 { NoBaseHookId
0063 , ListBaseHookId
0064 , SlistBaseHookId
0065 , RbTreeBaseHookId
0066 , HashBaseHookId
0067 , AvlTreeBaseHookId
0068 , BsTreeBaseHookId
0069 , TreapTreeBaseHookId
0070 , AnyBaseHookId
0071 };
0072
0073
0074 template <class HookTags, unsigned int>
0075 struct hook_tags_definer{};
0076
0077 template <class HookTags>
0078 struct hook_tags_definer<HookTags, ListBaseHookId>
0079 { typedef HookTags default_list_hook; };
0080
0081 template <class HookTags>
0082 struct hook_tags_definer<HookTags, SlistBaseHookId>
0083 { typedef HookTags default_slist_hook; };
0084
0085 template <class HookTags>
0086 struct hook_tags_definer<HookTags, RbTreeBaseHookId>
0087 { typedef HookTags default_rbtree_hook; };
0088
0089 template <class HookTags>
0090 struct hook_tags_definer<HookTags, HashBaseHookId>
0091 { typedef HookTags default_hashtable_hook; };
0092
0093 template <class HookTags>
0094 struct hook_tags_definer<HookTags, AvlTreeBaseHookId>
0095 { typedef HookTags default_avltree_hook; };
0096
0097 template <class HookTags>
0098 struct hook_tags_definer<HookTags, BsTreeBaseHookId>
0099 { typedef HookTags default_bstree_hook; };
0100
0101 template <class HookTags>
0102 struct hook_tags_definer<HookTags, AnyBaseHookId>
0103 { typedef HookTags default_any_hook; };
0104
0105 template
0106 < class NodeTraits
0107 , class Tag
0108 , link_mode_type LinkMode
0109 , base_hook_type BaseHookType
0110 >
0111 struct hooktags_impl
0112 {
0113 static const link_mode_type link_mode = LinkMode;
0114 typedef Tag tag;
0115 typedef NodeTraits node_traits;
0116 static const bool is_base_hook = !detail::is_same<Tag, member_tag>::value;
0117 static const bool safemode_or_autounlink = is_safe_autounlink<link_mode>::value;
0118 static const unsigned int type = BaseHookType;
0119 };
0120
0121
0122
0123 template
0124 < boost::intrusive::algo_types Algo
0125 , class NodeTraits
0126 , class Tag
0127 , link_mode_type LinkMode
0128 , base_hook_type BaseHookType
0129 >
0130 class generic_hook
0131
0132
0133
0134
0135
0136
0137
0138 : public detail::if_c
0139 < detail::is_same<Tag, member_tag>::value
0140 , typename NodeTraits::node
0141 , node_holder<typename NodeTraits::node, Tag, BaseHookType>
0142 >::type
0143
0144
0145
0146
0147 , public hook_tags_definer
0148 < generic_hook<Algo, NodeTraits, Tag, LinkMode, BaseHookType>
0149 , detail::is_same<Tag, dft_tag>::value ? BaseHookType : NoBaseHookId>
0150
0151 {
0152
0153 typedef typename get_algo<Algo, NodeTraits>::type node_algorithms;
0154 typedef typename node_algorithms::node node;
0155 typedef typename node_algorithms::node_ptr node_ptr;
0156 typedef typename node_algorithms::const_node_ptr const_node_ptr;
0157
0158 public:
0159
0160 typedef hooktags_impl
0161 < NodeTraits
0162 , Tag, LinkMode, BaseHookType> hooktags;
0163
0164 BOOST_INTRUSIVE_FORCEINLINE node_ptr this_ptr() BOOST_NOEXCEPT
0165 { return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*this)); }
0166
0167 BOOST_INTRUSIVE_FORCEINLINE const_node_ptr this_ptr() const BOOST_NOEXCEPT
0168 { return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(*this)); }
0169
0170 public:
0171
0172
0173 BOOST_INTRUSIVE_FORCEINLINE generic_hook() BOOST_NOEXCEPT
0174 {
0175 if(hooktags::safemode_or_autounlink){
0176 node_algorithms::init(this->this_ptr());
0177 }
0178 }
0179
0180 BOOST_INTRUSIVE_FORCEINLINE generic_hook(const generic_hook& ) BOOST_NOEXCEPT
0181 {
0182 if(hooktags::safemode_or_autounlink){
0183 node_algorithms::init(this->this_ptr());
0184 }
0185 }
0186
0187 BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) BOOST_NOEXCEPT
0188 { return *this; }
0189
0190 BOOST_INTRUSIVE_FORCEINLINE ~generic_hook()
0191 {
0192 destructor_impl
0193 (*this, detail::link_dispatch<hooktags::link_mode>());
0194 }
0195
0196 BOOST_INTRUSIVE_FORCEINLINE void swap_nodes(generic_hook &other) BOOST_NOEXCEPT
0197 {
0198 node_algorithms::swap_nodes
0199 (this->this_ptr(), other.this_ptr());
0200 }
0201
0202 BOOST_INTRUSIVE_FORCEINLINE bool is_linked() const BOOST_NOEXCEPT
0203 {
0204
0205 BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink ));
0206 return !node_algorithms::unique(this->this_ptr());
0207 }
0208
0209 BOOST_INTRUSIVE_FORCEINLINE void unlink() BOOST_NOEXCEPT
0210 {
0211 BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink ));
0212 node_ptr n(this->this_ptr());
0213 if(!node_algorithms::inited(n)){
0214 node_algorithms::unlink(n);
0215 node_algorithms::init(n);
0216 }
0217 }
0218 };
0219
0220 }
0221 }
0222
0223 #endif