Remove CDS_EMPLACE_SUPPORT macro and unused code
[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         /// Inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
361         /**
362             Returns \p true if inserting successful, \p false otherwise.
363         */
364         template <typename... Args>
365         bool emplace( Args&&... args )
366         {
367             scoped_node_ptr sp( cxx_leaf_node_allocator().New( std::forward<Args>(args)... ));
368             if ( base_class::insert( *sp.get() )) {
369                 sp.release();
370                 return true;
371             }
372             return false;
373         }
374
375         /// Delete \p key from the set
376         /** \anchor cds_nonintrusive_EllenBinTreeSet_erase_val
377
378             The item comparator should be able to compare the type \p value_type
379             and the type \p Q.
380
381             Return \p true if key is found and deleted, \p false otherwise
382         */
383         template <typename Q>
384         bool erase( Q const& key )
385         {
386             return base_class::erase( key );
387         }
388
389         /// Deletes the item from the set using \p pred predicate for searching
390         /**
391             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_erase_val "erase(Q const&)"
392             but \p pred is used for key comparing.
393             \p Less functor has the interface like \p std::less.
394             \p Less must imply the same element order as the comparator used for building the set.
395         */
396         template <typename Q, typename Less>
397         bool erase_with( Q const& key, Less pred )
398         {
399             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
400         }
401
402         /// Delete \p key from the set
403         /** \anchor cds_nonintrusive_EllenBinTreeSet_erase_func
404
405             The function searches an item with key \p key, calls \p f functor
406             and deletes the item. If \p key is not found, the functor is not called.
407
408             The functor \p Func interface:
409             \code
410             struct extractor {
411                 void operator()(value_type const& val);
412             };
413             \endcode
414             The functor may be passed by reference using <tt>boost:ref</tt>
415
416             Since the key of MichaelHashSet's \p value_type is not explicitly specified,
417             template parameter \p Q defines the key type searching in the list.
418             The list item comparator should be able to compare the type \p T of list item
419             and the type \p Q.
420
421             Return \p true if key is found and deleted, \p false otherwise
422         */
423         template <typename Q, typename Func>
424         bool erase( Q const& key, Func f )
425         {
426 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
427             return base_class::erase( key, [&f]( leaf_node const& node) { cds::unref(f)( node.m_Value ); } );
428 #       else
429             erase_functor<Func> wrapper(f);
430             return base_class::erase( key, cds::ref(wrapper));
431 #       endif
432         }
433
434         /// Deletes the item from the set using \p pred predicate for searching
435         /**
436             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_erase_func "erase(Q const&, Func)"
437             but \p pred is used for key comparing.
438             \p Less functor has the interface like \p std::less.
439             \p Less must imply the same element order as the comparator used for building the set.
440         */
441         template <typename Q, typename Less, typename Func>
442         bool erase_with( Q const& key, Less pred, Func f )
443         {
444 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
445             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
446                 [&f]( leaf_node const& node) { cds::unref(f)( node.m_Value ); } );
447 #       else
448             erase_functor<Func> wrapper(f);
449             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(), cds::ref(wrapper));
450 #       endif
451         }
452
453         /// Extracts an item with minimal key from the set
454         /**
455             If the set is not empty, the function returns \p true, \p result contains a pointer to minimum value.
456             If the set is empty, the function returns \p false, \p result is left unchanged.
457
458             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> minimum key.
459             It means that the function gets leftmost leaf of the tree and tries to unlink it.
460             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
461             So, the function returns the item with minimum key at the moment of tree traversing.
462
463             The guarded pointer \p dest prevents deallocation of returned item,
464             see cds::gc::guarded_ptr for explanation.
465             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
466         */
467         bool extract_min( guarded_ptr& result )
468         {
469             return base_class::extract_min_( result.guard() );
470         }
471
472         /// Extracts an item with maximal key from the set
473         /**
474             If the set is not empty, the function returns \p true, \p result contains a pointer to maximal value.
475             If the set is empty, the function returns \p false, \p result is left unchanged.
476
477             @note Due the concurrent nature of the set, the function extracts <i>nearly</i> maximal key.
478             It means that the function gets rightmost leaf of the tree and tries to unlink it.
479             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
480             So, the function returns the item with maximum key at the moment of tree traversing.
481
482             The guarded pointer \p dest prevents deallocation of returned item,
483             see cds::gc::guarded_ptr for explanation.
484             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
485         */
486         bool extract_max( guarded_ptr& result )
487         {
488             return base_class::extract_max_( result.guard() );
489         }
490
491         /// Extracts an item from the tree
492         /** \anchor cds_nonintrusive_EllenBinTreeSet_extract
493             The function searches an item with key equal to \p key in the tree,
494             unlinks it, and returns pointer to an item found in \p result parameter.
495             If the item  is not found the function returns \p false.
496
497             The guarded pointer \p dest prevents deallocation of returned item,
498             see cds::gc::guarded_ptr for explanation.
499             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
500         */
501         template <typename Q>
502         bool extract( guarded_ptr& result, Q const& key )
503         {
504             return base_class::extract_( result.guard(), key );
505         }
506
507         /// Extracts an item from the set using \p pred for searching
508         /**
509             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_extract "extract(guarded_ptr& dest, Q const&)"
510             but \p pred is used for key compare.
511             \p Less has the interface like \p std::less.
512             \p pred must imply the same element order as the comparator used for building the set.
513         */
514         template <typename Q, typename Less>
515         bool extract_with( guarded_ptr& result, Q const& key, Less pred )
516         {
517             return base_class::extract_with_( result.guard(), key,
518                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
519         }
520
521         /// Find the key \p val
522         /**
523             @anchor cds_nonintrusive_EllenBinTreeSet_find_func
524
525             The function searches the item with key equal to \p val and calls the functor \p f for item found.
526             The interface of \p Func functor is:
527             \code
528             struct functor {
529                 void operator()( value_type& item, Q& val );
530             };
531             \endcode
532             where \p item is the item found, \p val is the <tt>find</tt> function argument.
533
534             You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
535
536             The functor may change non-key fields of \p item. Note that the functor is only guarantee
537             that \p item cannot be disposed during functor is executing.
538             The functor does not serialize simultaneous access to the set's \p item. If such access is
539             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
540
541             The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
542             can modify both arguments.
543
544             Note the hash functor specified for class \p Traits template parameter
545             should accept a parameter of type \p Q that may be not the same as \p value_type.
546
547             The function returns \p true if \p val is found, \p false otherwise.
548         */
549         template <typename Q, typename Func>
550         bool find( Q& val, Func f )
551         {
552 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
553             return base_class::find( val, [&f]( leaf_node& node, Q& v ) { cds::unref(f)( node.m_Value, v ); });
554 #       else
555             find_functor<Func> wrapper(f);
556             return base_class::find( val, cds::ref(wrapper));
557 #       endif
558         }
559
560         /// Finds the key \p val using \p pred predicate for searching
561         /**
562             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_func "find(Q&, Func)"
563             but \p pred is used for key comparing.
564             \p Less functor has the interface like \p std::less.
565             \p Less must imply the same element order as the comparator used for building the set.
566         */
567         template <typename Q, typename Less, typename Func>
568         bool find_with( Q& val, Less pred, Func f )
569         {
570 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
571             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
572                 [&f]( leaf_node& node, Q& v ) { cds::unref(f)( node.m_Value, v ); } );
573 #       else
574             find_functor<Func> wrapper(f);
575             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
576                 cds::ref(wrapper));
577 #       endif
578         }
579
580         /// Find the key \p val
581         /** @anchor cds_nonintrusive_EllenBinTreeSet_find_cfunc
582
583             The function searches the item with key equal to \p val and calls the functor \p f for item found.
584             The interface of \p Func functor is:
585             \code
586             struct functor {
587                 void operator()( value_type& item, Q const& val );
588             };
589             \endcode
590             where \p item is the item found, \p val is the <tt>find</tt> function argument.
591
592             You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
593
594             The functor may change non-key fields of \p item. Note that the functor is only guarantee
595             that \p item cannot be disposed during functor is executing.
596             The functor does not serialize simultaneous access to the set's \p item. If such access is
597             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
598
599             Note the hash functor specified for class \p Traits template parameter
600             should accept a parameter of type \p Q that may be not the same as \p value_type.
601
602             The function returns \p true if \p val is found, \p false otherwise.
603         */
604         template <typename Q, typename Func>
605         bool find( Q const& val, Func f )
606         {
607 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
608             return base_class::find( val, [&f]( leaf_node& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); });
609 #       else
610             find_functor<Func> wrapper(f);
611             return base_class::find( val, cds::ref(wrapper));
612 #       endif
613         }
614
615         /// Finds the key \p val using \p pred predicate for searching
616         /**
617             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_cfunc "find(Q const&, Func)"
618             but \p pred is used for key comparing.
619             \p Less functor has the interface like \p std::less.
620             \p Less must imply the same element order as the comparator used for building the set.
621         */
622         template <typename Q, typename Less, typename Func>
623         bool find_with( Q const& val, Less pred, Func f )
624         {
625 #       ifdef CDS_CXX11_LAMBDA_SUPPORT
626             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
627                 [&f]( leaf_node& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); } );
628 #       else
629             find_functor<Func> wrapper(f);
630             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >(),
631                 cds::ref(wrapper));
632 #       endif
633         }
634
635         /// Find the key \p val
636         /** @anchor cds_nonintrusive_EllenBinTreeSet_find_val
637
638             The function searches the item with key equal to \p val
639             and returns \p true if it is found, and \p false otherwise.
640
641             Note the hash functor specified for class \p Traits template parameter
642             should accept a parameter of type \p Q that may be not the same as \ref value_type.
643         */
644         template <typename Q>
645         bool find( Q const & val )
646         {
647             return base_class::find( val );
648         }
649
650         /// Finds the key \p val using \p pred predicate for searching
651         /**
652             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_find_val "find(Q const&)"
653             but \p pred is used for key comparing.
654             \p Less functor has the interface like \p std::less.
655             \p Less must imply the same element order as the comparator used for building the set.
656         */
657         template <typename Q, typename Less>
658         bool find_with( Q const& val, Less pred )
659         {
660             return base_class::find_with( val, cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >());
661         }
662
663         /// Finds \p key and returns the item found
664         /** @anchor cds_nonintrusive_EllenBinTreeSet_get
665             The function searches the item with key equal to \p key and returns the item found in \p result parameter.
666             The function returns \p true if \p key is found, \p false otherwise.
667
668             The guarded pointer \p dest prevents deallocation of returned item,
669             see cds::gc::guarded_ptr for explanation.
670             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
671         */
672         template <typename Q>
673         bool get( guarded_ptr& result, Q const& key )
674         {
675             return base_class::get_( result.guard(), key );
676         }
677
678         /// Finds \p key with predicate \p pred and returns the item found
679         /**
680             The function is an analog of \ref cds_nonintrusive_EllenBinTreeSet_get "get(guarded_ptr&, Q const&)"
681             but \p pred is used for key comparing.
682             \p Less functor has the interface like \p std::less.
683             \p pred must imply the same element order as the comparator used for building the set.
684         */
685         template <typename Q, typename Less>
686         bool get_with( guarded_ptr& result, Q const& key, Less pred )
687         {
688             return base_class::get_with_( result.guard(), key,
689                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::value_accessor >() );
690         }
691
692         /// Clears the set (non-atomic)
693         /**
694             The function unlink all items from the tree.
695             The function is not atomic, thus, in multi-threaded environment with parallel insertions
696             this sequence
697             \code
698             set.clear();
699             assert( set.empty() );
700             \endcode
701             the assertion could be raised.
702
703             For each leaf the \ref disposer will be called after unlinking.
704         */
705         void clear()
706         {
707             base_class::clear();
708         }
709
710         /// Checks if the set is empty
711         bool empty() const
712         {
713             return base_class::empty();
714         }
715
716         /// Returns item count in the set
717         /**
718             Only leaf nodes containing user data are counted.
719
720             The value returned depends on item counter type provided by \p Traits template parameter.
721             If it is atomicity::empty_item_counter this function always returns 0.
722             Therefore, the function is not suitable for checking the tree emptiness, use \ref empty
723             member function for this purpose.
724         */
725         size_t size() const
726         {
727             return base_class::size();
728         }
729
730         /// Returns const reference to internal statistics
731         stat const& statistics() const
732         {
733             return base_class::statistics();
734         }
735
736         /// Checks internal consistency (not atomic, not thread-safe)
737         /**
738             The debugging function to check internal consistency of the tree.
739         */
740         bool check_consistency() const
741         {
742             return base_class::check_consistency();
743         }
744     };
745
746 }} // namespace cds::container
747
748 #endif // #ifndef __CDS_CONTAINER_ELLEN_BINTREE_SET_IMPL_H