Remove MichaelDeque
[libcds.git] / cds / container / ellen_bintree_set_impl.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_ELLEN_BINTREE_SET_IMPL_H
4 #define __CDS_CONTAINER_ELLEN_BINTREE_SET_IMPL_H
5
6 #include <type_traits>
7 #include <cds/container/ellen_bintree_base.h>
8 #include <cds/intrusive/ellen_bintree_impl.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/ellen_bintree_set_impl.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     protected:
179         //@cond
180 #   ifndef CDS_CXX11_LAMBDA_SUPPORT
181         template <typename Func>
182         struct insert_functor
183         {
184             Func        m_func;
185
186             insert_functor ( Func f )
187                 : m_func(f)
188             {}
189
190             void operator()( leaf_node& node )
191             {
192                 cds::unref(m_func)( node.m_Value );
193             }
194         };
195
196         template <typename Q, typename Func>
197         struct ensure_functor
198         {
199             Func        m_func;
200             Q const&    m_arg;
201
202             ensure_functor( Q const& arg, Func f )
203                 : m_func(f)
204                 , m_arg( arg )
205             {}
206
207             void operator ()( bool bNew, leaf_node& node, leaf_node& )
208             {
209                 cds::unref(m_func)( bNew, node.m_Value, m_arg );
210             }
211         };
212
213         template <typename Func>
214         struct erase_functor
215         {
216             Func        m_func;
217
218             erase_functor( Func f )
219                 : m_func(f)
220             {}
221
222             void operator()( leaf_node const& node )
223             {
224                 cds::unref(m_func)( node.m_Value );
225             }
226         };
227
228         template <typename Func>
229         struct find_functor
230         {
231             Func    m_func;
232
233             find_functor( Func f )
234                 : m_func(f)
235             {}
236
237             template <typename Q>
238             void operator ()( leaf_node& node, Q& val )
239             {
240                 cds::unref(m_func)( node.m_Value, val );
241             }
242         };
243 #endif
244         //@endcond
245
246     public:
247         /// Default constructor
248         EllenBinTreeSet()
249             : base_class()
250         {
251             //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" );
252         }
253
254         /// Clears the set
255         ~EllenBinTreeSet()
256         {}
257
258         /// Inserts new node
259         /**
260             The function creates a node with copy of \p val value
261             and then inserts the node created into the set.
262
263             The type \p Q should contain at least the complete key for the node.
264             The object of \ref value_type should be constructible from a value of type \p Q.
265             In trivial case, \p Q is equal to \ref value_type.
266
267             Returns \p true if \p val is inserted into the set, \p false otherwise.
268         */
269         template <typename Q>
270         bool insert( Q const& val )
271         {
272             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
273             if ( base_class::insert( *sp.get() )) {
274                 sp.release();
275                 return true;
276             }
277             return false;
278         }
279
280         /// Inserts new node
281         /**
282             The function allows to split creating of new item into two part:
283             - create item with key only
284             - insert new item into the set
285             - if inserting is success, calls  \p f functor to initialize value-fields of \p val.
286
287             The functor signature is:
288             \code
289                 void func( value_type& val );
290             \endcode
291             where \p val is the item inserted. User-defined functor \p f should guarantee that during changing
292             \p val no any other changes could be made on this set's item by concurrent threads.
293             The user-defined functor is called only if the inserting is success. It may be passed by reference
294             using <tt>boost::ref</tt>
295         */
296         template <typename Q, typename Func>
297         bool insert( Q const& val, Func f )
298         {
299             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
300 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
301             if ( base_class::insert( *sp.get(), [&f]( leaf_node& val ) { cds::unref(f)( val.m_Value ); } ))
302 #       else
303             insert_functor<Func> wrapper(f);
304             if ( base_class::insert( *sp, cds::ref(wrapper) ))
305 #       endif
306             {
307                 sp.release();
308                 return true;
309             }
310             return false;
311         }
312
313         /// Ensures that the item exists in the set
314         /**
315             The operation performs inserting or changing data with lock-free manner.
316
317             If the \p val key not found in the set, then the new item created from \p val
318             is inserted into the set. Otherwise, the functor \p func is called with the item found.
319             The functor \p Func should be a function with signature:
320             \code
321                 void func( bool bNew, value_type& item, const Q& val );
322             \endcode
323             or a functor:
324             \code
325                 struct my_functor {
326                     void operator()( bool bNew, value_type& item, const Q& val );
327                 };
328             \endcode
329
330             with arguments:
331             - \p bNew - \p true if the item has been inserted, \p false otherwise
332             - \p item - item of the set
333             - \p val - argument \p key passed into the \p ensure function
334
335             The functor may change non-key fields of the \p item; however, \p func must guarantee
336             that during changing no any other modifications could be made on this item by concurrent threads.
337
338             You may pass \p func argument by reference using <tt>boost::ref</tt>.
339
340             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
341             \p second is true if new item has been added or \p false if the item with \p key
342             already is in the set.
343         */
344         template <typename Q, typename Func>
345         std::pair<bool, bool> ensure( const Q& val, Func func )
346         {
347             scoped_node_ptr sp( cxx_leaf_node_allocator().New( val ));
348 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
349             std::pair<bool, bool> bRes = base_class::ensure( *sp,
350                 [&func, &val](bool bNew, leaf_node& node, leaf_node&){ cds::unref(func)( bNew, node.m_Value, val ); });
351 #       else
352             ensure_functor<Q, Func> wrapper( val, func );
353             std::pair<bool, bool> bRes = base_class::ensure( *sp, cds::ref(wrapper));
354 #       endif
355             if ( bRes.first && bRes.second )
356                 sp.release();
357             return bRes;
358         }
359
360 #   ifdef CDS_EMPLACE_SUPPORT
361         /// Inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
362         /**
363             Returns \p true if inserting successful, \p false otherwise.
364
365             @note This function is available only for compiler that supports
366             variadic template and move semantics
367         */
368         template <typename... Args>
369         bool emplace( Args&&... args )
370         {
371             scoped_node_ptr sp( cxx_leaf_node_allocator().New( std::forward<Args>(args)... ));
372             if ( base_class::insert( *sp.get() )) {
373                 sp.release();
374                 return true;
375             }
376             return false;
377         }
378 #   endif
379
380         /// Delete \p key from the set
381         /** \anchor cds_nonintrusive_EllenBinTreeSet_erase_val
382
383             The item comparator should be able to compare the type \p value_type
384             and the type \p Q.
385
386             Return \p true if key is found and deleted, \p false otherwise
387         */
388         template <typename Q>
389         bool erase( Q const& key )
390         {
391             return base_class::erase( key );
392         }
393
394         /// Deletes the item from the set using \p pred predicate for searching
395         /**
396             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_erase_val "erase(Q const&)"
397             but \p pred is used for key comparing.
398             \p Less functor has the interface like \p std::less.
399             \p Less must imply the same element order as the comparator used for building the set.
400         */
401         template <typename Q, typename Less>
402         bool erase_with( Q const& key, Less pred )
403         {
404             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
405         }
406
407         /// Delete \p key from the set
408         /** \anchor cds_nonintrusive_EllenBinTreeSet_erase_func
409
410             The function searches an item with key \p key, calls \p f functor
411             and deletes the item. If \p key is not found, the functor is not called.
412
413             The functor \p Func interface:
414             \code
415             struct extractor {
416                 void operator()(value_type const& val);
417             };
418             \endcode
419             The functor may be passed by reference using <tt>boost:ref</tt>
420
421             Since the key of MichaelHashSet's \p value_type is not explicitly specified,
422             template parameter \p Q defines the key type searching in the list.
423             The list item comparator should be able to compare the type \p T of list item
424             and the type \p Q.
425
426             Return \p true if key is found and deleted, \p false otherwise
427         */
428         template <typename Q, typename Func>
429         bool erase( Q const& key, Func f )
430         {
431 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
432             return base_class::erase( key, [&f]( leaf_node const& node) { cds::unref(f)( node.m_Value ); } );
433 #       else
434             erase_functor<Func> wrapper(f);
435             return base_class::erase( key, cds::ref(wrapper));
436 #       endif
437         }
438
439         /// Deletes the item from the set using \p pred predicate for searching
440         /**
441             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_erase_func "erase(Q const&, Func)"
442             but \p pred is used for key comparing.
443             \p Less functor has the interface like \p std::less.
444             \p Less must imply the same element order as the comparator used for building the set.
445         */
446         template <typename Q, typename Less, typename Func>
447         bool erase_with( Q const& key, Less pred, Func f )
448         {
449 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
450             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
451                 [&f]( leaf_node const& node) { cds::unref(f)( node.m_Value ); } );
452 #       else
453             erase_functor<Func> wrapper(f);
454             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(), cds::ref(wrapper));
455 #       endif
456         }
457
458         /// Extracts an item with minimal key from the set
459         /**
460             If the set is not empty, the function returns \p true, \p result contains a pointer to minimum value.
461             If the set is empty, the function returns \p false, \p result is left unchanged.
462
463             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> minimum key.
464             It means that the function gets leftmost leaf of the tree and tries to unlink it.
465             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
466             So, the function returns the item with minimum key at the moment of tree traversing.
467
468             The guarded pointer \p dest prevents deallocation of returned item,
469             see cds::gc::guarded_ptr for explanation.
470             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
471         */
472         bool extract_min( guarded_ptr& result )
473         {
474             return base_class::extract_min_( result.guard() );
475         }
476
477         /// Extracts an item with maximal key from the set
478         /**
479             If the set is not empty, the function returns \p true, \p result contains a pointer to maximal value.
480             If the set is empty, the function returns \p false, \p result is left unchanged.
481
482             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> maximal key.
483             It means that the function gets rightmost leaf of the tree and tries to unlink it.
484             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
485             So, the function returns the item with maximum key at the moment of tree traversing.
486
487             The guarded pointer \p dest prevents deallocation of returned item,
488             see cds::gc::guarded_ptr for explanation.
489             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
490         */
491         bool extract_max( guarded_ptr& result )
492         {
493             return base_class::extract_max_( result.guard() );
494         }
495
496         /// Extracts an item from the tree
497         /** \anchor cds_nonintrusive_EllenBinTreeSet_extract
498             The function searches an item with key equal to \p key in the tree,
499             unlinks it, and returns pointer to an item found in \p result parameter.
500             If the item  is not found the function returns \p false.
501
502             The guarded pointer \p dest prevents deallocation of returned item,
503             see cds::gc::guarded_ptr for explanation.
504             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
505         */
506         template <typename Q>
507         bool extract( guarded_ptr& result, Q const& key )
508         {
509             return base_class::extract_( result.guard(), key );
510         }
511
512         /// Extracts an item from the set using \p pred for searching
513         /**
514             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_extract "extract(guarded_ptr& dest, Q const&)"
515             but \p pred is used for key compare.
516             \p Less has the interface like \p std::less.
517             \p pred must imply the same element order as the comparator used for building the set.
518         */
519         template <typename Q, typename Less>
520         bool extract_with( guarded_ptr& result, Q const& key, Less pred )
521         {
522             return base_class::extract_with_( result.guard(), key,
523                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
524         }
525
526         /// Find the key \p val
527         /**
528             @anchor cds_nonintrusive_EllenBinTreeSet_find_func
529
530             The function searches the item with key equal to \p val and calls the functor \p f for item found.
531             The interface of \p Func functor is:
532             \code
533             struct functor {
534                 void operator()( value_type& item, Q& val );
535             };
536             \endcode
537             where \p item is the item found, \p val is the <tt>find</tt> function argument.
538
539             You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
540
541             The functor may change non-key fields of \p item. Note that the functor is only guarantee
542             that \p item cannot be disposed during functor is executing.
543             The functor does not serialize simultaneous access to the set's \p item. If such access is
544             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
545
546             The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
547             can modify both arguments.
548
549             Note the hash functor specified for class \p Traits template parameter
550             should accept a parameter of type \p Q that may be not the same as \p value_type.
551
552             The function returns \p true if \p val is found, \p false otherwise.
553         */
554         template <typename Q, typename Func>
555         bool find( Q& val, Func f )
556         {
557 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
558             return base_class::find( val, [&f]( leaf_node& node, Q& v ) { cds::unref(f)( node.m_Value, v ); });
559 #       else
560             find_functor<Func> wrapper(f);
561             return base_class::find( val, cds::ref(wrapper));
562 #       endif
563         }
564
565         /// Finds the key \p val using \p pred predicate for searching
566         /**
567             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_func "find(Q&, Func)"
568             but \p pred is used for key comparing.
569             \p Less functor has the interface like \p std::less.
570             \p Less must imply the same element order as the comparator used for building the set.
571         */
572         template <typename Q, typename Less, typename Func>
573         bool find_with( Q& val, Less pred, Func f )
574         {
575 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
576             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
577                 [&f]( leaf_node& node, Q& v ) { cds::unref(f)( node.m_Value, v ); } );
578 #       else
579             find_functor<Func> wrapper(f);
580             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
581                 cds::ref(wrapper));
582 #       endif
583         }
584
585         /// Find the key \p val
586         /** @anchor cds_nonintrusive_EllenBinTreeSet_find_cfunc
587
588             The function searches the item with key equal to \p val and calls the functor \p f for item found.
589             The interface of \p Func functor is:
590             \code
591             struct functor {
592                 void operator()( value_type& item, Q const& val );
593             };
594             \endcode
595             where \p item is the item found, \p val is the <tt>find</tt> function argument.
596
597             You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
598
599             The functor may change non-key fields of \p item. Note that the functor is only guarantee
600             that \p item cannot be disposed during functor is executing.
601             The functor does not serialize simultaneous access to the set's \p item. If such access is
602             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
603
604             Note the hash functor specified for class \p Traits template parameter
605             should accept a parameter of type \p Q that may be not the same as \p value_type.
606
607             The function returns \p true if \p val is found, \p false otherwise.
608         */
609         template <typename Q, typename Func>
610         bool find( Q const& val, Func f )
611         {
612 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
613             return base_class::find( val, [&f]( leaf_node& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); });
614 #       else
615             find_functor<Func> wrapper(f);
616             return base_class::find( val, cds::ref(wrapper));
617 #       endif
618         }
619
620         /// Finds the key \p val using \p pred predicate for searching
621         /**
622             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_cfunc "find(Q const&, Func)"
623             but \p pred is used for key comparing.
624             \p Less functor has the interface like \p std::less.
625             \p Less must imply the same element order as the comparator used for building the set.
626         */
627         template <typename Q, typename Less, typename Func>
628         bool find_with( Q const& val, Less pred, Func f )
629         {
630 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
631             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
632                 [&f]( leaf_node& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); } );
633 #       else
634             find_functor<Func> wrapper(f);
635             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
636                 cds::ref(wrapper));
637 #       endif
638         }
639
640         /// Find the key \p val
641         /** @anchor cds_nonintrusive_EllenBinTreeSet_find_val
642
643             The function searches the item with key equal to \p val
644             and returns \p true if it is found, and \p false otherwise.
645
646             Note the hash functor specified for class \p Traits template parameter
647             should accept a parameter of type \p Q that may be not the same as \ref value_type.
648         */
649         template <typename Q>
650         bool find( Q const & val )
651         {
652             return base_class::find( val );
653         }
654
655         /// Finds the key \p val using \p pred predicate for searching
656         /**
657             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_val "find(Q const&)"
658             but \p pred is used for key comparing.
659             \p Less functor has the interface like \p std::less.
660             \p Less must imply the same element order as the comparator used for building the set.
661         */
662         template <typename Q, typename Less>
663         bool find_with( Q const& val, Less pred )
664         {
665             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
666         }
667
668         /// Finds \p key and returns the item found
669         /** @anchor cds_nonintrusive_EllenBinTreeSet_get
670             The function searches the item with key equal to \p key and returns the item found in \p result parameter.
671             The function returns \p true if \p key is found, \p false otherwise.
672
673             The guarded pointer \p dest prevents deallocation of returned item,
674             see cds::gc::guarded_ptr for explanation.
675             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
676         */
677         template <typename Q>
678         bool get( guarded_ptr& result, Q const& key )
679         {
680             return base_class::get_( result.guard(), key );
681         }
682
683         /// Finds \p key with predicate \p pred and returns the item found
684         /**
685             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_get "get(guarded_ptr&, Q const&)"
686             but \p pred is used for key comparing.
687             \p Less functor has the interface like \p std::less.
688             \p pred must imply the same element order as the comparator used for building the set.
689         */
690         template <typename Q, typename Less>
691         bool get_with( guarded_ptr& result, Q const& key, Less pred )
692         {
693             return base_class::get_with_( result.guard(), key,
694                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >() );
695         }
696
697         /// Clears the set (non-atomic)
698         /**
699             The function unlink all items from the tree.
700             The function is not atomic, thus, in multi-threaded environment with parallel insertions
701             this sequence
702             \code
703             set.clear();
704             assert( set.empty() );
705             \endcode
706             the assertion could be raised.
707
708             For each leaf the \ref disposer will be called after unlinking.
709         */
710         void clear()
711         {
712             base_class::clear();
713         }
714
715         /// Checks if the set is empty
716         bool empty() const
717         {
718             return base_class::empty();
719         }
720
721         /// Returns item count in the set
722         /**
723             Only leaf nodes containing user data are counted.
724
725             The value returned depends on item counter type provided by \p Traits template parameter.
726             If it is atomicity::empty_item_counter this function always returns 0.
727             Therefore, the function is not suitable for checking the tree emptiness, use \ref empty
728             member function for this purpose.
729         */
730         size_t size() const
731         {
732             return base_class::size();
733         }
734
735         /// Returns const reference to internal statistics
736         stat const& statistics() const
737         {
738             return base_class::statistics();
739         }
740
741         /// Checks internal consistency (not atomic, not thread-safe)
742         /**
743             The debugging function to check internal consistency of the tree.
744         */
745         bool check_consistency() const
746         {
747             return base_class::check_consistency();
748         }
749     };
750
751 }} // namespace cds::container
752
753 #endif // #ifndef __CDS_CONTAINER_ELLEN_BINTREE_SET_IMPL_H