e47739db95a61ea85687cdb9a70b9d92a1ad4774
[libcds.git] / cds / container / impl / ellen_bintree_set.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_IMPL_ELLEN_BINTREE_SET_H
4 #define __CDS_CONTAINER_IMPL_ELLEN_BINTREE_SET_H
5
6 #include <type_traits>
7 #include <cds/container/details/ellen_bintree_base.h>
8 #include <cds/intrusive/impl/ellen_bintree.h>
9 #include <cds/container/details/guarded_ptr_cast.h>
10
11 namespace cds { namespace container {
12
13     /// Set based on Ellen's et al binary search tree
14     /** @ingroup cds_nonintrusive_set
15         @ingroup cds_nonintrusive_tree
16         @anchor cds_container_EllenBinTreeSet
17
18         Source:
19             - [2010] F.Ellen, P.Fatourou, E.Ruppert, F.van Breugel "Non-blocking Binary Search Tree"
20
21         %EllenBinTreeSet is an unbalanced leaf-oriented binary search tree that implements the <i>set</i>
22         abstract data type. Nodes maintains child pointers but not parent pointers.
23         Every internal node has exactly two children, and all data of type \p T currently in
24         the tree are stored in the leaves. Internal nodes of the tree are used to direct \p find
25         operation along the path to the correct leaf. The keys (of \p Key type) stored in internal nodes
26         may or may not be in the set. \p Key type is a subset of \p T type.
27         There should be exactly defined a key extracting functor for converting object of type \p T to
28         object of type \p Key.
29
30         Due to \p extract_min and \p extract_max member functions the \p %EllenBinTreeSet can act as
31         a <i>priority queue</i>. In this case you should provide unique compound key, for example,
32         the priority value plus some uniformly distributed random value.
33
34         @warning Recall the tree is <b>unbalanced</b>. The complexity of operations is <tt>O(log N)</tt>
35         for uniformly distributed random keys, but in worst case the complexity is <tt>O(N)</tt>.
36
37         @note In the current implementation we do not use helping technique described in original paper.
38         So, the current implementation is near to fine-grained lock-based tree.
39         Helping will be implemented in future release
40
41         <b>Template arguments</b> :
42         - \p GC - safe memory reclamation (i.e. light-weight garbage collector) type, like cds::gc::HP, cds::gc::PTB
43             Note that cds::gc::HRC is not supported.
44         - \p Key - key type, a subset of \p T
45         - \p T - type to be stored in tree's leaf nodes.
46         - \p Traits - type traits. See ellen_bintree::type_traits for explanation.
47
48         It is possible to declare option-based tree with ellen_bintree::make_set_traits metafunction
49         instead of \p Traits template argument.
50         Template argument list \p Options of ellen_bintree::make_set_traits metafunction are:
51         - ellen_bintree::key_extractor - key extracting functor, mandatory option. The functor has the following prototype:
52             \code
53                 struct key_extractor {
54                     void operator ()( Key& dest, T const& src );
55                 };
56             \endcode
57             It should initialize \p dest key from \p src data. The functor is used to initialize internal nodes.
58         - opt::compare - key compare functor. No default functor is provided.
59             If the option is not specified, \p %opt::less is used.
60         - opt::less - specifies binary predicate used for key compare. At least \p %opt::compare or \p %opt::less should be defined.
61         - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting.
62         - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
63             or opt::v::sequential_consistent (sequentially consisnent memory model).
64         - opt::allocator - the allocator used for \ref ellen_bintree::node "leaf nodes" which contains data.
65             Default is \ref CDS_DEFAULT_ALLOCATOR.
66         - opt::node_allocator - the allocator used for internal nodes. Default is \ref CDS_DEFAULT_ALLOCATOR.
67         - ellen_bintree::update_desc_allocator - an allocator of \ref ellen_bintree::update_desc "update descriptors",
68             default is \ref CDS_DEFAULT_ALLOCATOR.
69             Note that update descriptor is helping data structure with short lifetime and it is good candidate for pooling.
70             The number of simultaneously existing descriptors is a relatively small number limited the number of threads
71             working with the tree and GC buffer size.
72             Therefore, a bounded lock-free container like \p cds::container::VyukovMPMCCycleQueue is good choice for the free-list
73             of update descriptors, see cds::memory::vyukov_queue_pool free-list implementation.
74             Also notice that size of update descriptor is not dependent on the type of data
75             stored in the tree so single free-list object can be used for several EllenBinTree-based object.
76         - opt::stat - internal statistics. Available types: ellen_bintree::stat, ellen_bintree::empty_stat (the default)
77
78         @note Do not include <tt><cds/container/impl/ellen_bintree_set.h></tt> header file directly.
79         There are header file for each GC type:
80         - <tt><cds/container/ellen_bintree_set_hp.h></tt> - for Hazard Pointer GC cds::gc::HP
81         - <tt><cds/container/ellen_bintree_set_ptb.h></tt> - for Pass-the-Buck GC cds::gc::PTB
82         - <tt><cds/container/ellen_bintree_set_rcu.h></tt> - for RCU GC
83             (see \ref cds_container_EllenBinTreeSet_rcu "RCU-based EllenBinTreeSet")
84
85         @anchor cds_container_EllenBinTreeSet_less
86         <b>Predicate requirements</b>
87
88         opt::less, opt::compare and other predicates using with member fuctions should accept at least parameters
89         of type \p T and \p Key in any combination.
90         For example, for \p Foo struct with \p std::string key field the appropiate \p less functor is:
91         \code
92         struct Foo
93         {
94             std::string m_strKey;
95             ...
96         };
97
98         struct less {
99             bool operator()( Foo const& v1, Foo const& v2 ) const
100             { return v1.m_strKey < v2.m_strKey ; }
101
102             bool operator()( Foo const& v, std::string const& s ) const
103             { return v.m_strKey < s ; }
104
105             bool operator()( std::string const& s, Foo const& v ) const
106             { return s < v.m_strKey ; }
107
108             // Support comparing std::string and char const *
109             bool operator()( std::string const& s, char const * p ) const
110             { return s.compare(p) < 0 ; }
111
112             bool operator()( Foo const& v, char const * p ) const
113             { return v.m_strKey.compare(p) < 0 ; }
114
115             bool operator()( char const * p, std::string const& s ) const
116             { return s.compare(p) > 0; }
117
118             bool operator()( char const * p, Foo const& v ) const
119             { return v.m_strKey.compare(p) > 0; }
120         };
121         \endcode
122     */
123     template <
124         class GC,
125         typename Key,
126         typename T,
127 #ifdef CDS_DOXYGEN_INVOKED
128         class Traits = ellen_bintree::type_traits
129 #else
130         class Traits
131 #endif
132     >
133     class EllenBinTreeSet
134 #ifdef CDS_DOXYGEN_INVOKED
135         : public cds::intrusive::EllenBinTree< GC, Key, T, Traits >
136 #else
137         : public ellen_bintree::details::make_ellen_bintree_set< GC, Key, T, Traits >::type
138 #endif
139     {
140         //@cond
141         typedef ellen_bintree::details::make_ellen_bintree_set< GC, Key, T, Traits > maker;
142         typedef typename maker::type base_class;
143         //@endcond
144
145     public:
146         typedef GC      gc              ;   ///< Garbage collector
147         typedef Key     key_type        ;   ///< type of a key stored in internal nodes; key is a part of \p value_type
148         typedef T       value_type      ;   ///< type of value stored in the binary tree
149         typedef Traits  options         ;   ///< Traits template parameter
150
151 #   ifdef CDS_DOXYGEN_INVOKED
152         typedef implementation_defined key_comparator  ;    ///< key compare functor based on opt::compare and opt::less option setter.
153 #   else
154         typedef typename maker::intrusive_type_traits::compare   key_comparator;
155 #   endif
156         typedef typename base_class::item_counter           item_counter        ; ///< Item counting policy used
157         typedef typename base_class::memory_model           memory_model        ; ///< Memory ordering. See cds::opt::memory_model option
158         typedef typename base_class::stat                   stat                ; ///< internal statistics type
159         typedef typename options::key_extractor             key_extractor       ; ///< key extracting functor
160
161         typedef typename options::allocator                 allocator_type      ;   ///< Allocator for leaf nodes
162         typedef typename base_class::node_allocator         node_allocator      ;   ///< Internal node allocator
163         typedef typename base_class::update_desc_allocator  update_desc_allocator ; ///< Update descriptor allocator
164
165     protected:
166         //@cond
167         typedef typename maker::cxx_leaf_node_allocator cxx_leaf_node_allocator;
168         typedef typename base_class::value_type         leaf_node;
169         typedef typename base_class::internal_node      internal_node;
170
171         typedef std::unique_ptr< leaf_node, typename maker::leaf_deallocator > scoped_node_ptr;
172         //@endcond
173
174     public:
175         /// Guarded pointer
176         typedef cds::gc::guarded_ptr< gc, leaf_node, value_type, details::guarded_ptr_cast_set<leaf_node, value_type> > guarded_ptr;
177
178     public:
179         /// Default constructor
180         EllenBinTreeSet()
181             : base_class()
182         {
183             //static_assert( (std::is_same<gc, cds::gc::HP>::value || std::is_same<gc, cds::gc::PTB>::value), "GC must be cds::gc::HP or cds:gc::PTB" );
184         }
185
186         /// Clears the set
187         ~EllenBinTreeSet()
188         {}
189
190         /// Inserts new node
191         /**
192             The function creates a node with copy of \p val value
193             and then inserts the node created into the set.
194
195             The type \p Q should contain at least the complete key for the node.
196             The object of \ref value_type should be constructible from a value of type \p Q.
197             In trivial case, \p Q is equal to \ref value_type.
198
199             Returns \p true if \p val is inserted into the set, \p false otherwise.
200         */
201         template <typename Q>
202         bool insert( Q const& val )
203         {
204             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
205             if ( base_class::insert( *sp.get() )) {
206                 sp.release();
207                 return true;
208             }
209             return false;
210         }
211
212         /// Inserts new node
213         /**
214             The function allows to split creating of new item into two part:
215             - create item with key only
216             - insert new item into the set
217             - if inserting is success, calls  \p f functor to initialize value-fields of \p val.
218
219             The functor signature is:
220             \code
221                 void func( value_type& val );
222             \endcode
223             where \p val is the item inserted. User-defined functor \p f should guarantee that during changing
224             \p val no any other changes could be made on this set's item by concurrent threads.
225             The user-defined functor is called only if the inserting is success. It may be passed by reference
226             using <tt>boost::ref</tt>
227         */
228         template <typename Q, typename Func>
229         bool insert( Q const& val, Func f )
230         {
231             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
232             if ( base_class::insert( *sp.get(), [&f]( leaf_node& val ) { cds::unref(f)( val.m_Value ); } )) {
233                 sp.release();
234                 return true;
235             }
236             return false;
237         }
238
239         /// Ensures that the item exists in the set
240         /**
241             The operation performs inserting or changing data with lock-free manner.
242
243             If the \p val key not found in the set, then the new item created from \p val
244             is inserted into the set. Otherwise, the functor \p func is called with the item found.
245             The functor \p Func should be a function with signature:
246             \code
247                 void func( bool bNew, value_type& item, const Q& val );
248             \endcode
249             or a functor:
250             \code
251                 struct my_functor {
252                     void operator()( bool bNew, value_type& item, const Q& val );
253                 };
254             \endcode
255
256             with arguments:
257             - \p bNew - \p true if the item has been inserted, \p false otherwise
258             - \p item - item of the set
259             - \p val - argument \p key passed into the \p ensure function
260
261             The functor may change non-key fields of the \p item; however, \p func must guarantee
262             that during changing no any other modifications could be made on this item by concurrent threads.
263
264             You may pass \p func argument by reference using <tt>boost::ref</tt>.
265
266             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
267             \p second is true if new item has been added or \p false if the item with \p key
268             already is in the set.
269         */
270         template <typename Q, typename Func>
271         std::pair<bool, bool> ensure( const Q& val, Func func )
272         {
273             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
274             std::pair<bool, bool> bRes = base_class::ensure( *sp,
275                 [&func, &val](bool bNew, leaf_node& node, leaf_node&){ cds::unref(func)( bNew, node.m_Value, val ); });
276             if ( bRes.first && bRes.second )
277                 sp.release();
278             return bRes;
279         }
280
281         /// Inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
282         /**
283             Returns \p true if inserting successful, \p false otherwise.
284         */
285         template <typename... Args>
286         bool emplace( Args&&... args )
287         {
288             scoped_node_ptr sp( cxx_leaf_node_allocator().New( std::forward<Args>(args)... ));
289             if ( base_class::insert( *sp.get() )) {
290                 sp.release();
291                 return true;
292             }
293             return false;
294         }
295
296         /// Delete \p key from the set
297         /** \anchor cds_nonintrusive_EllenBinTreeSet_erase_val
298
299             The item comparator should be able to compare the type \p value_type
300             and the type \p Q.
301
302             Return \p true if key is found and deleted, \p false otherwise
303         */
304         template <typename Q>
305         bool erase( Q const& key )
306         {
307             return base_class::erase( key );
308         }
309
310         /// Deletes the item from the set using \p pred predicate for searching
311         /**
312             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_erase_val "erase(Q const&)"
313             but \p pred is used for key comparing.
314             \p Less functor has the interface like \p std::less.
315             \p Less must imply the same element order as the comparator used for building the set.
316         */
317         template <typename Q, typename Less>
318         bool erase_with( Q const& key, Less pred )
319         {
320             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
321         }
322
323         /// Delete \p key from the set
324         /** \anchor cds_nonintrusive_EllenBinTreeSet_erase_func
325
326             The function searches an item with key \p key, calls \p f functor
327             and deletes the item. If \p key is not found, the functor is not called.
328
329             The functor \p Func interface:
330             \code
331             struct extractor {
332                 void operator()(value_type const& val);
333             };
334             \endcode
335             The functor may be passed by reference using <tt>boost:ref</tt>
336
337             Since the key of MichaelHashSet's \p value_type is not explicitly specified,
338             template parameter \p Q defines the key type searching in the list.
339             The list item comparator should be able to compare the type \p T of list item
340             and the type \p Q.
341
342             Return \p true if key is found and deleted, \p false otherwise
343         */
344         template <typename Q, typename Func>
345         bool erase( Q const& key, Func f )
346         {
347             return base_class::erase( key, [&f]( leaf_node const& node) { cds::unref(f)( node.m_Value ); } );
348         }
349
350         /// Deletes the item from the set using \p pred predicate for searching
351         /**
352             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_erase_func "erase(Q const&, Func)"
353             but \p pred is used for key comparing.
354             \p Less functor has the interface like \p std::less.
355             \p Less must imply the same element order as the comparator used for building the set.
356         */
357         template <typename Q, typename Less, typename Func>
358         bool erase_with( Q const& key, Less pred, Func f )
359         {
360             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
361                 [&f]( leaf_node const& node) { cds::unref(f)( node.m_Value ); } );
362         }
363
364         /// Extracts an item with minimal key from the set
365         /**
366             If the set is not empty, the function returns \p true, \p result contains a pointer to minimum value.
367             If the set is empty, the function returns \p false, \p result is left unchanged.
368
369             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> minimum key.
370             It means that the function gets leftmost leaf of the tree and tries to unlink it.
371             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
372             So, the function returns the item with minimum key at the moment of tree traversing.
373
374             The guarded pointer \p dest prevents deallocation of returned item,
375             see cds::gc::guarded_ptr for explanation.
376             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
377         */
378         bool extract_min( guarded_ptr& result )
379         {
380             return base_class::extract_min_( result.guard() );
381         }
382
383         /// Extracts an item with maximal key from the set
384         /**
385             If the set is not empty, the function returns \p true, \p result contains a pointer to maximal value.
386             If the set is empty, the function returns \p false, \p result is left unchanged.
387
388             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> maximal key.
389             It means that the function gets rightmost leaf of the tree and tries to unlink it.
390             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
391             So, the function returns the item with maximum key at the moment of tree traversing.
392
393             The guarded pointer \p dest prevents deallocation of returned item,
394             see cds::gc::guarded_ptr for explanation.
395             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
396         */
397         bool extract_max( guarded_ptr& result )
398         {
399             return base_class::extract_max_( result.guard() );
400         }
401
402         /// Extracts an item from the tree
403         /** \anchor cds_nonintrusive_EllenBinTreeSet_extract
404             The function searches an item with key equal to \p key in the tree,
405             unlinks it, and returns pointer to an item found in \p result parameter.
406             If the item  is not found the function returns \p false.
407
408             The guarded pointer \p dest prevents deallocation of returned item,
409             see cds::gc::guarded_ptr for explanation.
410             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
411         */
412         template <typename Q>
413         bool extract( guarded_ptr& result, Q const& key )
414         {
415             return base_class::extract_( result.guard(), key );
416         }
417
418         /// Extracts an item from the set using \p pred for searching
419         /**
420             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_extract "extract(guarded_ptr& dest, Q const&)"
421             but \p pred is used for key compare.
422             \p Less has the interface like \p std::less.
423             \p pred must imply the same element order as the comparator used for building the set.
424         */
425         template <typename Q, typename Less>
426         bool extract_with( guarded_ptr& result, Q const& key, Less pred )
427         {
428             return base_class::extract_with_( result.guard(), key,
429                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
430         }
431
432         /// Find the key \p val
433         /**
434             @anchor cds_nonintrusive_EllenBinTreeSet_find_func
435
436             The function searches the item with key equal to \p val and calls the functor \p f for item found.
437             The interface of \p Func functor is:
438             \code
439             struct functor {
440                 void operator()( value_type& item, Q& val );
441             };
442             \endcode
443             where \p item is the item found, \p val is the <tt>find</tt> function argument.
444
445             You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
446
447             The functor may change non-key fields of \p item. Note that the functor is only guarantee
448             that \p item cannot be disposed during functor is executing.
449             The functor does not serialize simultaneous access to the set's \p item. If such access is
450             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
451
452             The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
453             can modify both arguments.
454
455             Note the hash functor specified for class \p Traits template parameter
456             should accept a parameter of type \p Q that may be not the same as \p value_type.
457
458             The function returns \p true if \p val is found, \p false otherwise.
459         */
460         template <typename Q, typename Func>
461         bool find( Q& val, Func f )
462         {
463             return base_class::find( val, [&f]( leaf_node& node, Q& v ) { cds::unref(f)( node.m_Value, v ); });
464         }
465
466         /// Finds the key \p val using \p pred predicate for searching
467         /**
468             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_func "find(Q&, Func)"
469             but \p pred is used for key comparing.
470             \p Less functor has the interface like \p std::less.
471             \p Less must imply the same element order as the comparator used for building the set.
472         */
473         template <typename Q, typename Less, typename Func>
474         bool find_with( Q& val, Less pred, Func f )
475         {
476             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
477                 [&f]( leaf_node& node, Q& v ) { cds::unref(f)( node.m_Value, v ); } );
478         }
479
480         /// Find the key \p val
481         /** @anchor cds_nonintrusive_EllenBinTreeSet_find_cfunc
482
483             The function searches the item with key equal to \p val and calls the functor \p f for item found.
484             The interface of \p Func functor is:
485             \code
486             struct functor {
487                 void operator()( value_type& item, Q const& val );
488             };
489             \endcode
490             where \p item is the item found, \p val is the <tt>find</tt> function argument.
491
492             You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
493
494             The functor may change non-key fields of \p item. Note that the functor is only guarantee
495             that \p item cannot be disposed during functor is executing.
496             The functor does not serialize simultaneous access to the set's \p item. If such access is
497             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
498
499             Note the hash functor specified for class \p Traits template parameter
500             should accept a parameter of type \p Q that may be not the same as \p value_type.
501
502             The function returns \p true if \p val is found, \p false otherwise.
503         */
504         template <typename Q, typename Func>
505         bool find( Q const& val, Func f )
506         {
507             return base_class::find( val, [&f]( leaf_node& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); });
508         }
509
510         /// Finds the key \p val using \p pred predicate for searching
511         /**
512             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_cfunc "find(Q const&, Func)"
513             but \p pred is used for key comparing.
514             \p Less functor has the interface like \p std::less.
515             \p Less must imply the same element order as the comparator used for building the set.
516         */
517         template <typename Q, typename Less, typename Func>
518         bool find_with( Q const& val, Less pred, Func f )
519         {
520             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
521                 [&f]( leaf_node& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); } );
522         }
523
524         /// Find the key \p val
525         /** @anchor cds_nonintrusive_EllenBinTreeSet_find_val
526
527             The function searches the item with key equal to \p val
528             and returns \p true if it is found, and \p false otherwise.
529
530             Note the hash functor specified for class \p Traits template parameter
531             should accept a parameter of type \p Q that may be not the same as \ref value_type.
532         */
533         template <typename Q>
534         bool find( Q const & val )
535         {
536             return base_class::find( val );
537         }
538
539         /// Finds the key \p val using \p pred predicate for searching
540         /**
541             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_val "find(Q const&)"
542             but \p pred is used for key comparing.
543             \p Less functor has the interface like \p std::less.
544             \p Less must imply the same element order as the comparator used for building the set.
545         */
546         template <typename Q, typename Less>
547         bool find_with( Q const& val, Less pred )
548         {
549             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
550         }
551
552         /// Finds \p key and returns the item found
553         /** @anchor cds_nonintrusive_EllenBinTreeSet_get
554             The function searches the item with key equal to \p key and returns the item found in \p result parameter.
555             The function returns \p true if \p key is found, \p false otherwise.
556
557             The guarded pointer \p dest prevents deallocation of returned item,
558             see cds::gc::guarded_ptr for explanation.
559             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
560         */
561         template <typename Q>
562         bool get( guarded_ptr& result, Q const& key )
563         {
564             return base_class::get_( result.guard(), key );
565         }
566
567         /// Finds \p key with predicate \p pred and returns the item found
568         /**
569             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_get "get(guarded_ptr&, Q const&)"
570             but \p pred is used for key comparing.
571             \p Less functor has the interface like \p std::less.
572             \p pred must imply the same element order as the comparator used for building the set.
573         */
574         template <typename Q, typename Less>
575         bool get_with( guarded_ptr& result, Q const& key, Less pred )
576         {
577             return base_class::get_with_( result.guard(), key,
578                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >() );
579         }
580
581         /// Clears the set (non-atomic)
582         /**
583             The function unlink all items from the tree.
584             The function is not atomic, thus, in multi-threaded environment with parallel insertions
585             this sequence
586             \code
587             set.clear();
588             assert( set.empty() );
589             \endcode
590             the assertion could be raised.
591
592             For each leaf the \ref disposer will be called after unlinking.
593         */
594         void clear()
595         {
596             base_class::clear();
597         }
598
599         /// Checks if the set is empty
600         bool empty() const
601         {
602             return base_class::empty();
603         }
604
605         /// Returns item count in the set
606         /**
607             Only leaf nodes containing user data are counted.
608
609             The value returned depends on item counter type provided by \p Traits template parameter.
610             If it is atomicity::empty_item_counter this function always returns 0.
611             Therefore, the function is not suitable for checking the tree emptiness, use \ref empty
612             member function for this purpose.
613         */
614         size_t size() const
615         {
616             return base_class::size();
617         }
618
619         /// Returns const reference to internal statistics
620         stat const& statistics() const
621         {
622             return base_class::statistics();
623         }
624
625         /// Checks internal consistency (not atomic, not thread-safe)
626         /**
627             The debugging function to check internal consistency of the tree.
628         */
629         bool check_consistency() const
630         {
631             return base_class::check_consistency();
632         }
633     };
634
635 }} // namespace cds::container
636
637 #endif // #ifndef __CDS_CONTAINER_IMPL_ELLEN_BINTREE_SET_H