Fixed -Wshadow warnings
[libcds.git] / cds / container / ellen_bintree_set_rcu.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSLIB_CONTAINER_ELLEN_BINTREE_SET_RCU_H
32 #define CDSLIB_CONTAINER_ELLEN_BINTREE_SET_RCU_H
33
34 #include <cds/container/details/ellen_bintree_base.h>
35 #include <cds/intrusive/ellen_bintree_rcu.h>
36
37 namespace cds { namespace container {
38
39     /// Set based on Ellen's et al binary search tree (RCU specialization)
40     /** @ingroup cds_nonintrusive_set
41         @ingroup cds_nonintrusive_tree
42         @anchor cds_container_EllenBinTreeSet_rcu
43
44         Source:
45             - [2010] F.Ellen, P.Fatourou, E.Ruppert, F.van Breugel "Non-blocking Binary Search Tree"
46
47         %EllenBinTreeSet is an unbalanced leaf-oriented binary search tree that implements the <i>set</i>
48         abstract data type. Nodes maintains child pointers but not parent pointers.
49         Every internal node has exactly two children, and all data of type \p T currently in
50         the tree are stored in the leaves. Internal nodes of the tree are used to direct \p find
51         operation along the path to the correct leaf. The keys (of \p Key type) stored in internal nodes
52         may or may not be in the set. \p Key type is a subset of \p T type.
53         There should be exactly defined a key extracting functor for converting object of type \p T to
54         object of type \p Key.
55
56         Due to \p extract_min and \p extract_max member functions the \p %EllenBinTreeSet can act as
57         a <i>priority queue</i>. In this case you should provide unique compound key, for example,
58         the priority value plus some uniformly distributed random value.
59
60         @warning Recall the tree is <b>unbalanced</b>. The complexity of operations is <tt>O(log N)</tt>
61         for uniformly distributed random keys, but in the worst case the complexity is <tt>O(N)</tt>.
62
63         @note In the current implementation we do not use helping technique described in original paper.
64         So, the current implementation is near to fine-grained lock-based tree.
65         Helping will be implemented in future release
66
67         <b>Template arguments</b> :
68         - \p RCU - one of \ref cds_urcu_gc "RCU type"
69         - \p Key - key type, a subset of \p T
70         - \p T - type to be stored in tree's leaf nodes.
71         - \p Traits - set traits, default is \p ellen_bintree::traits.
72             It is possible to declare option-based tree with \p ellen_bintree::make_set_traits metafunction
73             instead of \p Traits template argument.
74
75         @note Before including <tt><cds/container/ellen_bintree_set_rcu.h></tt> you should include appropriate RCU header file,
76         see \ref cds_urcu_gc "RCU type" for list of existing RCU class and corresponding header files.
77
78         @anchor cds_container_EllenBinTreeSet_rcu_less
79         <b>Predicate requirements</b>
80
81         opt::less, opt::compare and other predicates using with member fuctions should accept at least parameters
82         of type \p T and \p Key in any combination.
83         For example, for \p Foo struct with \p std::string key field the appropiate \p less functor is:
84         \code
85         struct Foo
86         {
87             std::string m_strKey;
88             ...
89         };
90
91         struct less {
92             bool operator()( Foo const& v1, Foo const& v2 ) const
93             { return v1.m_strKey < v2.m_strKey ; }
94
95             bool operator()( Foo const& v, std::string const& s ) const
96             { return v.m_strKey < s ; }
97
98             bool operator()( std::string const& s, Foo const& v ) const
99             { return s < v.m_strKey ; }
100
101             // Support comparing std::string and char const *
102             bool operator()( std::string const& s, char const * p ) const
103             { return s.compare(p) < 0 ; }
104
105             bool operator()( Foo const& v, char const * p ) const
106             { return v.m_strKey.compare(p) < 0 ; }
107
108             bool operator()( char const * p, std::string const& s ) const
109             { return s.compare(p) > 0; }
110
111             bool operator()( char const * p, Foo const& v ) const
112             { return v.m_strKey.compare(p) > 0; }
113         };
114         \endcode
115
116     */
117     template <
118         class RCU,
119         typename Key,
120         typename T,
121 #ifdef CDS_DOXYGEN_INVOKED
122         class Traits = ellen_bintree::traits
123 #else
124         class Traits
125 #endif
126     >
127     class EllenBinTreeSet< cds::urcu::gc<RCU>, Key, T, Traits >
128 #ifdef CDS_DOXYGEN_INVOKED
129         : public cds::intrusive::EllenBinTree< cds::urcu::gc<RCU>, Key, T, Traits >
130 #else
131         : public ellen_bintree::details::make_ellen_bintree_set< cds::urcu::gc<RCU>, Key, T, Traits >::type
132 #endif
133     {
134         //@cond
135         typedef ellen_bintree::details::make_ellen_bintree_set< cds::urcu::gc<RCU>, Key, T, Traits > maker;
136         typedef typename maker::type base_class;
137         //@endcond
138
139     public:
140         typedef cds::urcu::gc<RCU>  gc;   ///< RCU Garbage collector
141         typedef Key     key_type;   ///< type of a key stored in internal nodes; key is a part of \p value_type
142         typedef T       value_type; ///< type of value stored in the binary tree
143         typedef Traits  traits;     ///< Traits template parameter
144
145 #   ifdef CDS_DOXYGEN_INVOKED
146         typedef implementation_defined key_comparator;    ///< key compare functor based on \p Traits::compare and \p Traits::less
147 #   else
148         typedef typename maker::intrusive_traits::compare   key_comparator;
149 #   endif
150         typedef typename base_class::item_counter           item_counter;       ///< Item counting policy
151         typedef typename base_class::memory_model           memory_model;       ///< Memory ordering, see \p cds::opt::memory_model
152         typedef typename base_class::stat                   stat;               ///< internal statistics type
153         typedef typename base_class::rcu_check_deadlock     rcu_check_deadlock; ///< Deadlock checking policy
154         typedef typename traits::key_extractor              key_extractor;      ///< key extracting functor
155         typedef typename traits::back_off                   back_off;           ///< Back-off strategy
156
157
158         typedef typename traits::allocator                  allocator_type;     ///< Allocator for leaf nodes
159         typedef typename base_class::node_allocator         node_allocator;     ///< Internal node allocator
160         typedef typename base_class::update_desc_allocator  update_desc_allocator; ///< Update descriptor allocator
161
162         static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal; ///< Group of \p extract_xxx functions do not require external locking
163
164     protected:
165         //@cond
166         typedef typename maker::cxx_leaf_node_allocator cxx_leaf_node_allocator;
167         typedef typename base_class::value_type         leaf_node;
168         typedef typename base_class::internal_node      internal_node;
169         typedef std::unique_ptr< leaf_node, typename maker::intrusive_traits::disposer >    scoped_node_ptr;
170         //@endcond
171
172     public:
173         typedef typename gc::scoped_lock    rcu_lock;  ///< RCU scoped lock
174
175         /// pointer to extracted node
176         using exempt_ptr = cds::urcu::exempt_ptr < gc, leaf_node, value_type, typename maker::intrusive_traits::disposer,
177             cds::urcu::details::conventional_exempt_member_cast < leaf_node, value_type >
178         >;
179
180     public:
181         /// Default constructor
182         EllenBinTreeSet()
183             : base_class()
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             RCU \p synchronize() method can be called. RCU should not be locked.
200
201             Returns \p true if \p val is inserted into the set, \p false otherwise.
202         */
203         template <typename Q>
204         bool insert( Q const& val )
205         {
206             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
207             if ( base_class::insert( *sp.get())) {
208                 sp.release();
209                 return true;
210             }
211             return false;
212         }
213
214         /// Inserts new node
215         /**
216             The function allows to split creating of new item into two part:
217             - create item with key only
218             - insert new item into the set
219             - if inserting is success, calls  \p f functor to initialize value-fields of \p val.
220
221             The functor signature is:
222             \code
223                 void func( value_type& val );
224             \endcode
225             where \p val is the item inserted. User-defined functor \p f should guarantee that during changing
226             \p val no any other changes could be made on this set's item by concurrent threads.
227             The user-defined functor is called only if the inserting is success.
228
229             RCU \p synchronize() can be called. RCU should not be locked.
230         */
231         template <typename Q, typename Func>
232         bool insert( Q const& val, Func f )
233         {
234             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
235             if ( base_class::insert( *sp.get(), [&f]( leaf_node& v ) { f( v.m_Value ); } )) {
236                 sp.release();
237                 return true;
238             }
239             return false;
240         }
241
242         /// Updates the node
243         /**
244             The operation performs inserting or changing data with lock-free manner.
245
246             If the item \p val is not found in the set, then \p val is inserted into the set
247             iff \p bAllowInsert is \p true.
248             Otherwise, the functor \p func is called with item found.
249             The functor \p func signature is:
250             \code
251                 void func( bool bNew, value_type& item, value_type& val );
252             \endcode
253             with arguments:
254             - \p bNew - \p true if the item has been inserted, \p false otherwise
255             - \p item - item of the set
256             - \p val - argument \p val passed into the \p %update() function
257
258             The functor can change non-key fields of the \p item; however, \p func must guarantee
259             that during changing no any other modifications could be made on this item by concurrent threads.
260
261             RCU \p synchronize method can be called. RCU should not be locked.
262
263             Returns std::pair<bool, bool> where \p first is \p true if operation is successful,
264             i.e. the node has been inserted or updated,
265             \p second is \p true if new item has been added or \p false if the item with \p key
266             already exists.
267
268             @warning See \ref cds_intrusive_item_creating "insert item troubleshooting"
269         */
270         template <typename Q, typename Func>
271         std::pair<bool, bool> update( Q const& val, Func func, bool bAllowInsert = true )
272         {
273             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
274             std::pair<bool, bool> bRes = base_class::update( *sp,
275                 [&func, &val](bool bNew, leaf_node& node, leaf_node&){ func( bNew, node.m_Value, val ); },
276                 bAllowInsert );
277             if ( bRes.first && bRes.second )
278                 sp.release();
279             return bRes;
280         }
281         //@cond
282         template <typename Q, typename Func>
283         CDS_DEPRECATED("ensure() is deprecated, use update()")
284         std::pair<bool, bool> ensure( const Q& val, Func func )
285         {
286             return update( val, func, true );
287         }
288         //@endcond
289
290         /// Inserts data of type \p value_type created in-place from \p args
291         /**
292             Returns \p true if inserting successful, \p false otherwise.
293
294             RCU \p synchronize method can be called. RCU should not be locked.
295         */
296         template <typename... Args>
297         bool emplace( Args&&... args )
298         {
299             scoped_node_ptr sp( cxx_leaf_node_allocator().MoveNew( std::forward<Args>(args)... ));
300             if ( base_class::insert( *sp.get())) {
301                 sp.release();
302                 return true;
303             }
304             return false;
305         }
306
307         /// Delete \p key from the set
308         /** \anchor cds_nonintrusive_EllenBinTreeSet_rcu_erase_val
309
310             The item comparator should be able to compare the type \p value_type
311             and the type \p Q.
312
313             RCU \p synchronize method can be called. RCU should not be locked.
314
315             Return \p true if key is found and deleted, \p false otherwise
316         */
317         template <typename Q>
318         bool erase( Q const& key )
319         {
320             return base_class::erase( key );
321         }
322
323         /// Deletes the item from the set using \p pred predicate for searching
324         /**
325             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_rcu_erase_val "erase(Q const&)"
326             but \p pred is used for key comparing.
327             \p Less functor has the interface like \p std::less.
328             \p Less must imply the same element order as the comparator used for building the set.
329         */
330         template <typename Q, typename Less>
331         bool erase_with( Q const& key, Less pred )
332         {
333             CDS_UNUSED( pred );
334             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
335         }
336
337         /// Delete \p key from the set
338         /** \anchor cds_nonintrusive_EllenBinTreeSet_rcu_erase_func
339
340             The function searches an item with key \p key, calls \p f functor
341             and deletes the item. If \p key is not found, the functor is not called.
342
343             The functor \p Func interface:
344             \code
345             struct extractor {
346                 void operator()(value_type const& val);
347             };
348             \endcode
349
350             Since the key of MichaelHashSet's \p value_type is not explicitly specified,
351             template parameter \p Q defines the key type searching in the list.
352             The list item comparator should be able to compare the type \p T of list item
353             and the type \p Q.
354
355             RCU \p synchronize method can be called. RCU should not be locked.
356
357             Return \p true if key is found and deleted, \p false otherwise
358
359             See also: \ref erase
360         */
361         template <typename Q, typename Func>
362         bool erase( Q const& key, Func f )
363         {
364             return base_class::erase( key, [&f]( leaf_node const& node) { f( node.m_Value ); } );
365         }
366
367         /// Deletes the item from the set using \p pred predicate for searching
368         /**
369             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_rcu_erase_func "erase(Q const&, Func)"
370             but \p pred is used for key comparing.
371             \p Less functor has the interface like \p std::less.
372             \p Less must imply the same element order as the comparator used for building the set.
373         */
374         template <typename Q, typename Less, typename Func>
375         bool erase_with( Q const& key, Less pred, Func f )
376         {
377             CDS_UNUSED( pred );
378             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
379                 [&f]( leaf_node const& node) { f( node.m_Value ); } );
380         }
381
382         /// Extracts an item with minimal key from the set
383         /**
384             Returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the leftmost item.
385             If the set is empty, returns empty \p exempt_ptr.
386
387             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> minimum key.
388             It means that the function gets leftmost leaf of the tree and tries to unlink it.
389             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
390             So, the function returns the item with minimum key at the moment of tree traversing.
391
392             RCU \p synchronize method can be called. RCU should NOT be locked.
393             The function does not free the item.
394             The deallocator will be implicitly invoked when the returned object is destroyed or when
395             its \p release() member function is called.
396         */
397         exempt_ptr extract_min()
398         {
399             return exempt_ptr( base_class::extract_min_());
400         }
401
402         /// Extracts an item with maximal key from the set
403         /**
404             Returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the rightmost item.
405             If the set is empty, returns empty \p exempt_ptr.
406
407             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> maximal key.
408             It means that the function gets rightmost leaf of the tree and tries to unlink it.
409             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
410             So, the function returns the item with maximum key at the moment of tree traversing.
411
412             RCU \p synchronize method can be called. RCU should NOT be locked.
413             The function does not free the item.
414             The deallocator will be implicitly invoked when the returned object is destroyed or when
415             its \p release() member function is called.
416         */
417         exempt_ptr extract_max()
418         {
419             return exempt_ptr( base_class::extract_max_());
420         }
421
422         /// Extracts an item from the set
423         /** \anchor cds_nonintrusive_EllenBinTreeSet_rcu_extract
424             The function searches an item with key equal to \p key in the tree,
425             unlinks it, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to an item found.
426             If \p key is not found the function returns an empty \p exempt_ptr.
427
428             RCU \p synchronize method can be called. RCU should NOT be locked.
429             The function does not destroy the item found.
430             The dealloctor will be implicitly invoked when the returned object is destroyed or when
431             its release() member function is called.
432         */
433         template <typename Q>
434         exempt_ptr extract( Q const& key )
435         {
436             return exempt_ptr( base_class::extract_( key, typename base_class::node_compare()));
437         }
438
439         /// Extracts an item from the set using \p pred for searching
440         /**
441             The function is an analog of \p extract(Q const&) but \p pred is used for key compare.
442             \p Less has the interface like \p std::less and should meet \ref cds_container_EllenBinTreeSet_rcu_less
443             "predicate requirements".
444             \p pred must imply the same element order as the comparator used for building the set.
445         */
446         template <typename Q, typename Less>
447         exempt_ptr extract_with( Q const& key, Less pred )
448         {
449             CDS_UNUSED( pred );
450             return exempt_ptr( base_class::extract_with_( key,
451                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >()));
452         }
453
454         /// Find the key \p key
455         /**
456             @anchor cds_nonintrusive_EllenBinTreeSet_rcu_find_func
457
458             The function searches the item with key equal to \p key and calls the functor \p f for item found.
459             The interface of \p Func functor is:
460             \code
461             struct functor {
462                 void operator()( value_type& item, Q& key );
463             };
464             \endcode
465             where \p item is the item found, \p key is the <tt>find</tt> function argument.
466
467             The functor may change non-key fields of \p item. Note that the functor is only guarantee
468             that \p item cannot be disposed during functor is executing.
469             The functor does not serialize simultaneous access to the set's \p item. If such access is
470             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
471
472             The \p key argument is non-const since it can be used as \p f functor destination i.e., the functor
473             can modify both arguments.
474
475             Note the hash functor specified for class \p Traits template parameter
476             should accept a parameter of type \p Q that may be not the same as \p value_type.
477
478             The function applies RCU lock internally.
479
480             The function returns \p true if \p key is found, \p false otherwise.
481         */
482         template <typename Q, typename Func>
483         bool find( Q& key, Func f ) const
484         {
485             return base_class::find( key, [&f]( leaf_node& node, Q& v ) { f( node.m_Value, v ); });
486         }
487         //@cond
488         template <typename Q, typename Func>
489         bool find( Q const& key, Func f ) const
490         {
491             return base_class::find( key, [&f]( leaf_node& node, Q const& v ) { f( node.m_Value, v ); } );
492         }
493         //@endcond
494
495         /// Finds the key \p key using \p pred predicate for searching
496         /**
497             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_rcu_find_func "find(Q&, Func)"
498             but \p pred is used for key comparing.
499             \p Less functor has the interface like \p std::less.
500             \p Less must imply the same element order as the comparator used for building the set.
501         */
502         template <typename Q, typename Less, typename Func>
503         bool find_with( Q& key, Less pred, Func f ) const
504         {
505             CDS_UNUSED( pred );
506             return base_class::find_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
507                 [&f]( leaf_node& node, Q& v ) { f( node.m_Value, v ); } );
508         }
509         //@cond
510         template <typename Q, typename Less, typename Func>
511         bool find_with( Q const& key, Less pred, Func f ) const
512         {
513             CDS_UNUSED( pred );
514             return base_class::find_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
515                                           [&f]( leaf_node& node, Q const& v ) { f( node.m_Value, v ); } );
516         }
517         //@endcond
518
519         /// Checks whether the set contains \p key
520         /**
521             The function searches the item with key equal to \p key
522             and returns \p true if it is found, and \p false otherwise.
523
524             The function applies RCU lock internally.
525         */
526         template <typename Q>
527         bool contains( Q const& key ) const
528         {
529             return base_class::contains( key );
530         }
531         //@cond
532         template <typename Q>
533         CDS_DEPRECATED("deprecated, use contains()")
534         bool find( Q const& key ) const
535         {
536             return contains( key );
537         }
538         //@endcond
539
540         /// Checks whether the set contains \p key using \p pred predicate for searching
541         /**
542             The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
543             \p Less functor has the interface like \p std::less and should meet \ref cds_intrusive_EllenBinTree_rcu_less
544             "Predicate requirements".
545             \p Less must imply the same element order as the comparator used for building the set.
546             \p pred should accept arguments of type \p Q, \p key_type, \p value_type in any combination.
547         */
548         template <typename Q, typename Less>
549         bool contains( Q const& key, Less pred ) const
550         {
551             CDS_UNUSED( pred );
552             return base_class::contains( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
553         }
554         //@cond
555         template <typename Q, typename Less>
556         CDS_DEPRECATED("deprecated, use contains()")
557         bool find_with( Q const& key, Less pred ) const
558         {
559             return contains( key, pred );
560         }
561         //@endcond
562
563         /// Finds \p key and return the item found
564         /** \anchor cds_nonintrusive_EllenBinTreeSet_rcu_get
565             The function searches the item with key equal to \p key and returns the pointer to item found.
566             If \p key is not found it returns \p nullptr.
567
568             RCU should be locked before call the function.
569             Returned pointer is valid while RCU is locked.
570         */
571         template <typename Q>
572         value_type * get( Q const& key ) const
573         {
574             leaf_node * pNode = base_class::get( key );
575             return pNode ? &pNode->m_Value : nullptr;
576         }
577
578         /// Finds \p key with \p pred predicate and return the item found
579         /**
580             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_rcu_get "get(Q const&)"
581             but \p pred is used for comparing the keys.
582
583             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type
584             and \p Q in any order.
585             \p pred must imply the same element order as the comparator used for building the set.
586         */
587         template <typename Q, typename Less>
588         value_type * get_with( Q const& key, Less pred ) const
589         {
590             CDS_UNUSED( pred );
591             leaf_node * pNode = base_class::get_with( key,
592                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
593             return pNode ? &pNode->m_Value : nullptr;
594         }
595
596         /// Clears the set (non-atomic)
597         /**
598             The function unlink all items from the tree.
599             The function is not atomic, thus, in multi-threaded environment with parallel insertions
600             this sequence
601             \code
602             set.clear();
603             assert( set.empty());
604             \endcode
605             the assertion could be raised.
606
607             For each leaf the \ref disposer will be called after unlinking.
608
609             RCU \p synchronize method can be called. RCU should not be locked.
610         */
611         void clear()
612         {
613             base_class::clear();
614         }
615
616         /// Checks if the set is empty
617         bool empty() const
618         {
619             return base_class::empty();
620         }
621
622         /// Returns item count in the set
623         /**
624             Only leaf nodes containing user data are counted.
625
626             The value returned depends on item counter type provided by \p Traits template parameter.
627             If it is \p atomicity::empty_item_counter \p %size() always returns 0.
628             Therefore, the function is not suitable for checking the tree emptiness, use \p empty()
629             member function for this purpose.
630         */
631         size_t size() const
632         {
633             return base_class::size();
634         }
635
636         /// Returns const reference to internal statistics
637         stat const& statistics() const
638         {
639             return base_class::statistics();
640         }
641
642         /// Checks internal consistency (not atomic, not thread-safe)
643         /**
644             The debugging function to check internal consistency of the tree.
645         */
646         bool check_consistency() const
647         {
648             return base_class::check_consistency();
649         }
650     };
651 }}  // namespace cds::container
652
653 #endif // #ifndef CDSLIB_CONTAINER_ELLEN_BINTREE_SET_RCU_H