3 #ifndef __CDS_CONTAINER_ELLEN_BINTREE_BASE_H
4 #define __CDS_CONTAINER_ELLEN_BINTREE_BASE_H
6 #include <cds/intrusive/details/ellen_bintree_base.h>
7 #include <cds/container/base.h>
8 #include <cds/opt/compare.h>
9 #include <cds/details/binary_functor_wrapper.h>
12 namespace cds { namespace container {
13 /// EllenBinTree related definitions
14 /** @ingroup cds_nonintrusive_helper
16 namespace ellen_bintree {
18 #ifdef CDS_DOXYGEN_INVOKED
19 /// Typedef for cds::intrusive::ellen_bintree::update_desc
20 typedef cds::intrusive::ellen_bintree::update_desc update_desc;
22 /// Typedef for cds::intrusive::ellen_bintree::internal_node
23 typedef cds::intrusive::ellen_bintree::internal_node internal_node;
25 /// Typedef for cds::intrusive::ellen_bintree::key_extractor
26 typedef cds::intrusive::ellen_bintree::key_extractor key_extractor;
28 /// Typedef for cds::intrusive::ellen_bintree::update_desc_allocator
29 typedef cds::intrusive::ellen_bintree::update_desc_allocator update_desc_allocator;
31 /// Typedef for cds::intrusive::ellen_bintree::stat
32 typedef cds::intrusive::ellen_bintree::stat stat;
34 /// Typedef for cds::intrusive::ellen_bintree::empty_stat
35 typedef cds::intrusive::ellen_bintree::empty_stat empty_stat;
37 using cds::intrusive::ellen_bintree::update_desc;
38 using cds::intrusive::ellen_bintree::internal_node;
39 using cds::intrusive::ellen_bintree::key_extractor;
40 using cds::intrusive::ellen_bintree::update_desc_allocator;
41 using cds::intrusive::ellen_bintree::stat;
42 using cds::intrusive::ellen_bintree::empty_stat;
43 using cds::intrusive::ellen_bintree::node_types;
46 /// EllenBinTree leaf node
47 template <typename GC, typename T>
48 struct node: public cds::intrusive::ellen_bintree::node<GC>
50 typedef T value_type ; ///< Value type
52 T m_Value ; ///< Value
65 template <typename... Args>
66 node( Args const&... args)
70 #ifdef CDS_RVALUE_SUPPORT
72 template <typename... Args>
74 : m_Value( std::forward<Args>(args)... )
76 #endif // CDS_RVALUE_SUPPORT
79 /// EllenBinTreeMap leaf node
80 template <typename GC, typename Key, typename T>
81 struct map_node: public cds::intrusive::ellen_bintree::node< GC >
83 typedef Key key_type ; ///< key type
84 typedef T mapped_type ; ///< value type
85 typedef std::pair<key_type const, mapped_type> value_type ; ///< key-value pair stored in the map
87 value_type m_Value ; ///< Key-value pair stored in map leaf node
89 /// Initializes key field, value if default-constructed
91 map_node( K const& key )
92 : m_Value( std::make_pair( key_type(key), mapped_type() ))
95 /// Initializes key and value fields
96 template <typename K, typename Q>
97 map_node( K const& key, Q const& v )
98 : m_Value( std::make_pair(key_type(key), mapped_type(v) ))
102 /// Type traits for EllenBinTreeSet, EllenBinTreeMap and EllenBinTreePriorityQueue
105 /// Key extracting functor (only for EllenBinTreeSet)
107 You should explicit define a valid functor.
108 The functor has the following prototype:
110 struct key_extractor {
111 void operator ()( Key& dest, T const& src );
114 It should initialize \p dest key from \p src data.
115 The functor is used to initialize internal nodes.
117 typedef opt::none key_extractor;
119 /// Key comparison functor
121 No default functor is provided. If the option is not specified, the \p less is used.
123 See cds::opt::compare option description for functor interface.
125 You should provide \p compare or \p less functor.
126 See \ref cds_container_EllenBinTreeSet_rcu_less "predicate requirements".
128 typedef opt::none compare;
130 /// Specifies binary predicate used for key compare.
132 See cds::opt::less option description for predicate interface.
134 You should provide \p compare or \p less functor.
135 See \ref cds_container_EllenBinTreeSet_rcu_less "predicate requirements".
137 typedef opt::none less;
141 The type for item counting feature (see cds::opt::item_counter).
142 Default is no item counter (\ref atomicity::empty_item_counter)
144 typedef atomicity::empty_item_counter item_counter;
146 /// C++ memory ordering model
148 List of available memory ordering see opt::memory_model
150 typedef opt::v::relaxed_ordering memory_model;
152 /// Allocator for update descriptors
154 The allocator type is used for \ref update_desc.
156 Update descriptor is helping data structure with short lifetime and it is good candidate
157 for pooling. The number of simultaneously existing descriptors is a small number
158 limited the number of threads working with the tree.
159 Therefore, a bounded lock-free container like \p cds::container::VyukovMPMCCycleQueue
160 is good choice for the free-list of update descriptors,
161 see cds::memory::vyukov_queue_pool free-list implementation.
163 Also notice that size of update descriptor is not dependent on the type of data
164 stored in the tree so single free-list object can be used for several \p EllenBinTree object.
166 typedef CDS_DEFAULT_ALLOCATOR update_desc_allocator;
168 /// Allocator for internal nodes
170 The allocator type is used for \ref internal_node.
172 typedef CDS_DEFAULT_ALLOCATOR node_allocator;
174 /// Allocator for leaf nodes
176 Each leaf node contains data stored in the container.
178 typedef CDS_DEFAULT_ALLOCATOR allocator;
180 /// Internal statistics
182 Possible types: ellen_bintree::empty_stat (the default), ellen_bintree::stat or any
183 other with interface like \p %stat.
185 typedef empty_stat stat;
187 /// RCU deadlock checking policy (only for RCU-based EllenBinTree<i>XXX</i> classes)
189 List of available options see opt::rcu_check_deadlock
191 typedef cds::opt::v::rcu_throw_deadlock rcu_check_deadlock;
193 /// Key copy policy (for EllenBinTreeMap)
195 The key copy policy defines a functor to copy leaf node's key to internal node.
196 This policy is used only in EllenBinTreeMap. By default, assignment operator is used.
198 The copy functor interface is:
200 struct copy_functor {
201 void operator()( Key& dest, Key const& src );
205 typedef opt::none copy_policy;
209 /// Metafunction converting option list to EllenBinTreeSet traits
211 This is a wrapper for <tt> cds::opt::make_options< type_traits, Options...> </tt>
212 \p Options list see \ref cds_container_EllenBinTreeSet "EllenBinTreeSet".
214 template <CDS_DECL_OPTIONS11>
215 struct make_set_traits {
216 # ifdef CDS_DOXYGEN_INVOKED
217 typedef implementation_defined type ; ///< Metafunction result
219 typedef typename cds::opt::make_options<
220 typename cds::opt::find_type_traits< type_traits, CDS_OPTIONS11 >::type
226 /// Metafunction converting option list to EllenBinTreeMap traits
228 This is a wrapper for <tt> cds::opt::make_options< type_traits, Options...> </tt>
229 \p Options list see \ref cds_container_EllenBinTreeMap "EllenBinTreeMap".
231 template <CDS_DECL_OPTIONS11>
232 struct make_map_traits {
233 # ifdef CDS_DOXYGEN_INVOKED
234 typedef implementation_defined type ; ///< Metafunction result
236 typedef typename cds::opt::make_options<
237 typename cds::opt::find_type_traits< type_traits, CDS_OPTIONS11 >::type
246 template < class GC, typename Key, typename T, class Traits>
247 struct make_ellen_bintree_set
250 typedef Key key_type;
251 typedef T value_type;
252 typedef Traits original_type_traits;
254 typedef node< gc, value_type > leaf_node;
256 struct intrusive_key_extractor
258 void operator()( key_type& dest, leaf_node const& src ) const
260 typename original_type_traits::key_extractor()( dest, src.m_Value );
264 struct value_accessor
266 value_type const& operator()( leaf_node const& node ) const
272 typedef typename cds::opt::details::make_comparator< value_type, original_type_traits, false >::type key_comparator;
274 typedef cds::details::Allocator< leaf_node, typename original_type_traits::allocator> cxx_leaf_node_allocator;
275 struct leaf_deallocator
277 void operator()( leaf_node * p ) const
279 cxx_leaf_node_allocator().Delete( p );
283 struct intrusive_type_traits: public original_type_traits
285 typedef cds::intrusive::ellen_bintree::base_hook< cds::opt::gc< gc > > hook;
286 typedef intrusive_key_extractor key_extractor;
287 typedef leaf_deallocator disposer;
288 typedef cds::details::compare_wrapper< leaf_node, key_comparator, value_accessor > compare;
291 // Metafunction result
292 typedef cds::intrusive::EllenBinTree< gc, key_type, leaf_node, intrusive_type_traits > type;
295 template < class GC, typename Key, typename T, class Traits>
296 struct make_ellen_bintree_map
299 typedef Key key_type;
300 typedef T mapped_type;
301 typedef map_node< gc, key_type, mapped_type > leaf_node;
302 typedef typename leaf_node::value_type value_type;
304 typedef Traits original_type_traits;
306 struct assignment_copy_policy {
307 void operator()( key_type& dest, key_type const& src )
312 typedef typename std::conditional<
313 std::is_same< typename original_type_traits::copy_policy, opt::none >::value,
314 assignment_copy_policy,
315 typename original_type_traits::copy_policy
318 struct intrusive_key_extractor
320 void operator()( key_type& dest, leaf_node const& src ) const
322 copy_policy()( dest, src.m_Value.first );
328 key_type const& operator()( leaf_node const& node ) const
330 return node.m_Value.first;
334 typedef typename cds::opt::details::make_comparator< key_type, original_type_traits, false >::type key_comparator;
336 typedef cds::details::Allocator< leaf_node, typename original_type_traits::allocator> cxx_leaf_node_allocator;
337 struct leaf_deallocator
339 void operator()( leaf_node * p ) const
341 cxx_leaf_node_allocator().Delete( p );
345 struct intrusive_type_traits: public original_type_traits
347 typedef cds::intrusive::ellen_bintree::base_hook< cds::opt::gc< gc > > hook;
348 typedef intrusive_key_extractor key_extractor;
349 typedef leaf_deallocator disposer;
350 typedef cds::details::compare_wrapper< leaf_node, key_comparator, key_accessor > compare;
353 // Metafunction result
354 typedef cds::intrusive::EllenBinTree< gc, key_type, leaf_node, intrusive_type_traits > type;
357 } // namespace details
359 } // namespace ellen_bintree
361 // Forward declarations
363 template < class GC, typename Key, typename T, class Traits = ellen_bintree::type_traits >
364 class EllenBinTreeSet;
366 template < class GC, typename Key, typename T, class Traits = ellen_bintree::type_traits >
367 class EllenBinTreeMap;
370 }} // namespace cds::container
372 #endif // #ifndef __CDS_CONTAINER_ELLEN_BINTREE_BASE_H