3 #ifndef __CDS_CONTAINER_SKIP_LIST_SET_IMPL_H
4 #define __CDS_CONTAINER_SKIP_LIST_SET_IMPL_H
6 #include <cds/details/binary_functor_wrapper.h>
7 #include <cds/gc/guarded_ptr.h>
8 #include <cds/container/details/guarded_ptr_cast.h>
10 namespace cds { namespace container {
12 /// Lock-free skip-list set
13 /** @ingroup cds_nonintrusive_set
14 \anchor cds_nonintrusive_SkipListSet_hp
16 The implementation of well-known probabilistic data structure called skip-list
17 invented by W.Pugh in his papers:
18 - [1989] W.Pugh Skip Lists: A Probabilistic Alternative to Balanced Trees
19 - [1990] W.Pugh A Skip List Cookbook
21 A skip-list is a probabilistic data structure that provides expected logarithmic
22 time search without the need of rebalance. The skip-list is a collection of sorted
23 linked list. Nodes are ordered by key. Each node is linked into a subset of the lists.
24 Each list has a level, ranging from 0 to 32. The bottom-level list contains
25 all the nodes, and each higher-level list is a sublist of the lower-level lists.
26 Each node is created with a random top level (with a random height), and belongs
27 to all lists up to that level. The probability that a node has the height 1 is 1/2.
28 The probability that a node has the height N is 1/2 ** N (more precisely,
29 the distribution depends on an random generator provided, but our generators
32 The lock-free variant of skip-list is implemented according to book
33 - [2008] M.Herlihy, N.Shavit "The Art of Multiprocessor Programming",
34 chapter 14.4 "A Lock-Free Concurrent Skiplist"
37 - \p GC - Garbage collector used.
38 - \p T - type to be stored in the list.
39 - \p Traits - type traits. See skip_list::type_traits for explanation.
41 It is possible to declare option-based list with cds::container::skip_list::make_traits metafunction istead of \p Traits template
43 Template argument list \p Options of cds::container::skip_list::make_traits metafunction are:
44 - opt::compare - key comparison functor. No default functor is provided.
45 If the option is not specified, the opt::less is used.
46 - opt::less - specifies binary predicate used for key comparison. Default is \p std::less<T>.
47 - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting.
48 - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
49 or opt::v::sequential_consistent (sequentially consisnent memory model).
50 - skip_list::random_level_generator - random level generator. Can be skip_list::xorshift, skip_list::turbo_pascal or
51 user-provided one. See skip_list::random_level_generator option description for explanation.
52 Default is \p %skip_list::turbo_pascal.
53 - opt::allocator - allocator for skip-list node. Default is \ref CDS_DEFAULT_ALLOCATOR.
54 - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::Default is used.
55 - opt::stat - internal statistics. Available types: skip_list::stat, skip_list::empty_stat (the default)
57 \warning The skip-list requires up to 67 hazard pointers that may be critical for some GCs for which
58 the guard count is limited (like as gc::HP, gc::HRC). Those GCs should be explicitly initialized with
59 hazard pointer enough: \code cds::gc::HP myhp( 67 ) \endcode. Otherwise an run-time exception may be raised
60 when you try to create skip-list object.
62 \note There are several specializations of \p %SkipListSet for each \p GC. You should include:
63 - <tt><cds/container/skip_list_set_hp.h></tt> for gc::HP garbage collector
64 - <tt><cds/container/skip_list_set_hrc.h></tt> for gc::HRC garbage collector
65 - <tt><cds/container/skip_list_set_ptb.h></tt> for gc::PTB garbage collector
66 - <tt><cds/container/skip_list_set_rcu.h></tt> for \ref cds_nonintrusive_SkipListSet_rcu "RCU type"
67 - <tt><cds/container/skip_list_set_nogc.h></tt> for \ref cds_nonintrusive_SkipListSet_nogc "non-deletable SkipListSet"
71 The class supports a forward iterator (\ref iterator and \ref const_iterator).
72 The iteration is ordered.
73 The iterator object is thread-safe: the element pointed by the iterator object is guarded,
74 so, the element cannot be reclaimed while the iterator object is alive.
75 However, passing an iterator object between threads is dangerous.
77 \warning Due to concurrent nature of skip-list set it is not guarantee that you can iterate
78 all elements in the set: any concurrent deletion can exclude the element
79 pointed by the iterator from the set, and your iteration can be terminated
80 before end of the set. Therefore, such iteration is more suitable for debugging purpose only
82 Remember, each iterator object requires 2 additional hazard pointers, that may be
83 a limited resource for \p GC like as gc::HP and gc::HRC (for gc::PTB the count of
86 The iterator class supports the following minimalistic interface:
93 iterator( iterator const& s);
95 value_type * operator ->() const;
96 value_type& operator *() const;
99 iterator& operator ++();
102 iterator& operator = (const iterator& src);
104 bool operator ==(iterator const& i ) const;
105 bool operator !=(iterator const& i ) const;
108 Note, the iterator object returned by \ref end, \p cend member functions points to \p nullptr and should not be dereferenced.
114 #ifdef CDS_DOXYGEN_INVOKED
115 typename Traits = skip_list::type_traits
121 #ifdef CDS_DOXYGEN_INVOKED
122 protected intrusive::SkipListSet< GC, T, Traits >
124 protected details::make_skip_list_set< GC, T, Traits >::type
128 typedef details::make_skip_list_set< GC, T, Traits > maker;
129 typedef typename maker::type base_class;
132 typedef typename base_class::gc gc ; ///< Garbage collector used
133 typedef T value_type ; ///< @anchor cds_containewr_SkipListSet_value_type Value type stored in the set
134 typedef Traits options ; ///< Options specified
136 typedef typename base_class::back_off back_off ; ///< Back-off strategy used
137 typedef typename options::allocator allocator_type ; ///< Allocator type used for allocate/deallocate the skip-list nodes
138 typedef typename base_class::item_counter item_counter ; ///< Item counting policy used
139 typedef typename maker::key_comparator key_comparator ; ///< key comparison functor
140 typedef typename base_class::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option
141 typedef typename options::random_level_generator random_level_generator ; ///< random level generator
142 typedef typename options::stat stat ; ///< internal statistics type
146 typedef typename maker::node_type node_type;
147 typedef typename maker::node_allocator node_allocator;
149 typedef std::unique_ptr< node_type, typename maker::node_deallocator > scoped_node_ptr;
154 typedef cds::gc::guarded_ptr< gc, node_type, value_type, details::guarded_ptr_cast_set<node_type, value_type> > guarded_ptr;
158 unsigned int random_level()
160 return base_class::random_level();
166 # ifndef CDS_CXX11_LAMBDA_SUPPORT
167 template <typename Func>
168 struct insert_functor
172 insert_functor ( Func f )
176 void operator()( node_type& node )
178 cds::unref(m_func)( node.m_Value );
182 template <typename Q, typename Func>
183 struct ensure_functor
188 ensure_functor( Q const& arg, Func f )
193 void operator ()( bool bNew, node_type& node, node_type& )
195 cds::unref(m_func)( bNew, node.m_Value, m_arg );
199 template <typename Func>
204 find_functor( Func f )
208 template <typename Q>
209 void operator ()( node_type& node, Q& val )
211 cds::unref(m_func)( node.m_Value, val );
215 struct copy_value_functor {
216 template <typename Q>
217 void operator()( Q& dest, value_type const& src ) const
223 template <typename Func>
228 erase_functor( Func f )
232 void operator()( node_type const& node )
234 cds::unref(m_func)( node.m_Value );
237 # endif // ifndef CDS_CXX11_LAMBDA_SUPPORT
247 /// Destructor destroys the set object
253 typedef skip_list::details::iterator< typename base_class::iterator > iterator;
255 /// Const iterator type
256 typedef skip_list::details::iterator< typename base_class::const_iterator > const_iterator;
258 /// Returns a forward iterator addressing the first element in a set
261 return iterator( base_class::begin() );
264 /// Returns a forward const iterator addressing the first element in a set
265 const_iterator begin() const
267 return const_iterator( base_class::begin() );
270 /// Returns a forward const iterator addressing the first element in a set
271 const_iterator cbegin()
273 return const_iterator( base_class::cbegin() );
276 /// Returns a forward iterator that addresses the location succeeding the last element in a set.
279 return iterator( base_class::end() );
282 /// Returns a forward const iterator that addresses the location succeeding the last element in a set.
283 const_iterator end() const
285 return const_iterator( base_class::end() );
288 /// Returns a forward const iterator that addresses the location succeeding the last element in a set.
289 const_iterator cend()
291 return const_iterator( base_class::cend() );
297 The function creates a node with copy of \p val value
298 and then inserts the node created into the set.
300 The type \p Q should contain as minimum the complete key for the node.
301 The object of \ref value_type should be constructible from a value of type \p Q.
302 In trivial case, \p Q is equal to \ref value_type.
304 Returns \p true if \p val is inserted into the set, \p false otherwise.
306 template <typename Q>
307 bool insert( Q const& val )
309 scoped_node_ptr sp( node_allocator().New( random_level(), val ));
310 if ( base_class::insert( *sp.get() )) {
319 The function allows to split creating of new item into two part:
320 - create item with key only
321 - insert new item into the set
322 - if inserting is success, calls \p f functor to initialize value-fields of \p val.
324 The functor signature is:
326 void func( value_type& val );
328 where \p val is the item inserted. User-defined functor \p f should guarantee that during changing
329 \p val no any other changes could be made on this set's item by concurrent threads.
330 The user-defined functor is called only if the inserting is success. It may be passed by reference
331 using <tt>boost::ref</tt>
333 template <typename Q, typename Func>
334 bool insert( Q const& val, Func f )
336 scoped_node_ptr sp( node_allocator().New( random_level(), val ));
337 # ifdef CDS_CXX11_LAMBDA_SUPPORT
338 if ( base_class::insert( *sp.get(), [&f]( node_type& val ) { cds::unref(f)( val.m_Value ); } ))
340 insert_functor<Func> wrapper(f);
341 if ( base_class::insert( *sp, cds::ref(wrapper) ))
350 /// Ensures that the item exists in the set
352 The operation performs inserting or changing data with lock-free manner.
354 If the \p val key not found in the set, then the new item created from \p val
355 is inserted into the set. Otherwise, the functor \p func is called with the item found.
356 The functor \p Func should be a function with signature:
358 void func( bool bNew, value_type& item, const Q& val );
363 void operator()( bool bNew, value_type& item, const Q& val );
368 - \p bNew - \p true if the item has been inserted, \p false otherwise
369 - \p item - item of the set
370 - \p val - argument \p key passed into the \p ensure function
372 The functor may change non-key fields of the \p item; however, \p func must guarantee
373 that during changing no any other modifications could be made on this item by concurrent threads.
375 You may pass \p func argument by reference using <tt>boost::ref</tt>.
377 Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
378 \p second is true if new item has been added or \p false if the item with \p key
379 already is in the set.
381 template <typename Q, typename Func>
382 std::pair<bool, bool> ensure( const Q& val, Func func )
384 scoped_node_ptr sp( node_allocator().New( random_level(), val ));
385 # ifdef CDS_CXX11_LAMBDA_SUPPORT
386 std::pair<bool, bool> bRes = base_class::ensure( *sp,
387 [&func, &val](bool bNew, node_type& node, node_type&){ cds::unref(func)( bNew, node.m_Value, val ); });
389 ensure_functor<Q, Func> wrapper( val, func );
390 std::pair<bool, bool> bRes = base_class::ensure( *sp, cds::ref(wrapper));
392 if ( bRes.first && bRes.second )
397 /// Inserts data of type \ref cds_containewr_SkipListSet_value_type "value_type" constructed with <tt>std::forward<Args>(args)...</tt>
399 Returns \p true if inserting successful, \p false otherwise.
401 template <typename... Args>
402 bool emplace( Args&&... args )
404 scoped_node_ptr sp( node_allocator().New( random_level(), std::forward<Args>(args)... ));
405 if ( base_class::insert( *sp.get() )) {
412 /// Delete \p key from the set
413 /** \anchor cds_nonintrusive_SkipListSet_erase_val
415 The set item comparator should be able to compare the type \p value_type
418 Return \p true if key is found and deleted, \p false otherwise
420 template <typename Q>
421 bool erase( Q const& key )
423 return base_class::erase( key );
426 /// Deletes the item from the set using \p pred predicate for searching
428 The function is an analog of \ref cds_nonintrusive_SkipListSet_erase_val "erase(Q const&)"
429 but \p pred is used for key comparing.
430 \p Less functor has the interface like \p std::less.
431 \p Less must imply the same element order as the comparator used for building the set.
433 template <typename Q, typename Less>
434 bool erase_with( Q const& key, Less pred )
436 return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >() );
439 /// Delete \p key from the set
440 /** \anchor cds_nonintrusive_SkipListSet_erase_func
442 The function searches an item with key \p key, calls \p f functor
443 and deletes the item. If \p key is not found, the functor is not called.
445 The functor \p Func interface:
448 void operator()(value_type const& val);
451 The functor may be passed by reference using <tt>boost:ref</tt>
453 Since the key of \p value_type is not explicitly specified,
454 template parameter \p Q defines the key type to search in the list.
455 The list item comparator should be able to compare the type \p T of list item
458 Return \p true if key is found and deleted, \p false otherwise
462 template <typename Q, typename Func>
463 bool erase( Q const& key, Func f )
465 # ifdef CDS_CXX11_LAMBDA_SUPPORT
466 return base_class::erase( key, [&f]( node_type const& node) { cds::unref(f)( node.m_Value ); } );
468 erase_functor<Func> wrapper(f);
469 return base_class::erase( key, cds::ref(wrapper));
473 /// Deletes the item from the set using \p pred predicate for searching
475 The function is an analog of \ref cds_nonintrusive_SkipListSet_erase_func "erase(Q const&, Func)"
476 but \p pred is used for key comparing.
477 \p Less functor has the interface like \p std::less.
478 \p Less must imply the same element order as the comparator used for building the set.
480 template <typename Q, typename Less, typename Func>
481 bool erase_with( Q const& key, Less pred, Func f )
483 # ifdef CDS_CXX11_LAMBDA_SUPPORT
484 return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
485 [&f]( node_type const& node) { cds::unref(f)( node.m_Value ); } );
487 erase_functor<Func> wrapper(f);
488 return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
493 /// Extracts the item from the set with specified \p key
494 /** \anchor cds_nonintrusive_SkipListSet_hp_extract
495 The function searches an item with key equal to \p key in the set,
496 unlinks it from the set, and returns it in \p result parameter.
497 If the item with key equal to \p key is not found the function returns \p false.
499 Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type.
501 The item extracted is freed automatically by garbage collector \p GC
502 when returned \ref guarded_ptr object will be destroyed or released.
503 @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
507 typedef cds::container::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
511 skip_list::guarded_ptr gp;
512 if ( theList.extract( gp, 5 ) ) {
516 // Destructor of gp releases internal HP guard and frees the pointer
520 template <typename Q>
521 bool extract( guarded_ptr& result, Q const& key )
523 return base_class::extract_( result.guard(), key, typename base_class::key_comparator() );
526 /// Extracts the item from the set with comparing functor \p pred
528 The function is an analog of \ref cds_nonintrusive_SkipListSet_hp_extract "extract(Q const&)"
529 but \p pred predicate is used for key comparing.
531 \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q
533 \p pred must imply the same element order as the comparator used for building the set.
535 template <typename Q, typename Less>
536 bool extract_with( guarded_ptr& ptr, Q const& key, Less pred )
538 typedef cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor > wrapped_less;
539 return base_class::extract_( ptr.guard(), key, cds::opt::details::make_comparator_from_less<wrapped_less>() );
542 /// Extracts an item with minimal key from the set
544 The function searches an item with minimal key, unlinks it, and returns the item found in \p result parameter.
545 If the skip-list is empty the function returns \p false.
547 The item extracted is freed automatically by garbage collector \p GC
548 when returned \ref guarded_ptr object will be destroyed or released.
549 @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
553 typedef cds::continer::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
557 skip_list::guarded_ptr gp;
558 if ( theList.extract_min( gp )) {
562 // Destructor of gp releases internal HP guard and then frees the pointer
566 bool extract_min( guarded_ptr& result)
568 return base_class::extract_min_( result.guard() );
571 /// Extracts an item with maximal key from the set
573 The function searches an item with maximal key, unlinks it, and returns the pointer to item found in \p result parameter.
574 If the skip-list is empty the function returns \p false.
576 The item found is freed by garbage collector \p GC automatically
577 when returned \ref guarded_ptr object will be destroyed or released.
578 @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
582 typedef cds::container::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
586 skip_list::guarded_ptr gp;
587 if ( theList.extract_max( gp )) {
591 // Destructor of gp releases internal HP guard and then frees the pointer
595 bool extract_max( guarded_ptr& result )
597 return base_class::extract_max_( result.guard() );
600 /// Find the key \p val
601 /** \anchor cds_nonintrusive_SkipListSet_find_func
603 The function searches the item with key equal to \p val and calls the functor \p f for item found.
604 The interface of \p Func functor is:
607 void operator()( value_type& item, Q& val );
610 where \p item is the item found, \p val is the <tt>find</tt> function argument.
612 You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
614 The functor may change non-key fields of \p item. Note that the functor is only guarantee
615 that \p item cannot be disposed during functor is executing.
616 The functor does not serialize simultaneous access to the set's \p item. If such access is
617 possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
619 The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
620 can modify both arguments.
622 Note the hash functor specified for class \p Traits template parameter
623 should accept a parameter of type \p Q that may be not the same as \p value_type.
625 The function returns \p true if \p val is found, \p false otherwise.
627 template <typename Q, typename Func>
628 bool find( Q& val, Func f )
630 # ifdef CDS_CXX11_LAMBDA_SUPPORT
631 return base_class::find( val, [&f]( node_type& node, Q& v ) { cds::unref(f)( node.m_Value, v ); });
633 find_functor<Func> wrapper(f);
634 return base_class::find( val, cds::ref(wrapper));
638 /// Finds the key \p val using \p pred predicate for searching
640 The function is an analog of \ref cds_nonintrusive_SkipListSet_find_func "find(Q&, Func)"
641 but \p pred is used for key comparing.
642 \p Less functor has the interface like \p std::less.
643 \p Less must imply the same element order as the comparator used for building the set.
645 template <typename Q, typename Less, typename Func>
646 bool find_with( Q& val, Less pred, Func f )
648 # ifdef CDS_CXX11_LAMBDA_SUPPORT
649 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
650 [&f]( node_type& node, Q& v ) { cds::unref(f)( node.m_Value, v ); } );
652 find_functor<Func> wrapper(f);
653 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(), cds::ref(wrapper));
657 /// Find the key \p val
658 /** \anchor cds_nonintrusive_SkipListSet_find_cfunc
660 The function searches the item with key equal to \p val and calls the functor \p f for item found.
661 The interface of \p Func functor is:
664 void operator()( value_type& item, Q const& val );
667 where \p item is the item found, \p val is the <tt>find</tt> function argument.
669 You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
671 The functor may change non-key fields of \p item. Note that the functor is only guarantee
672 that \p item cannot be disposed during functor is executing.
673 The functor does not serialize simultaneous access to the set's \p item. If such access is
674 possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
676 Note the hash functor specified for class \p Traits template parameter
677 should accept a parameter of type \p Q that may be not the same as \p value_type.
679 The function returns \p true if \p val is found, \p false otherwise.
681 template <typename Q, typename Func>
682 bool find( Q const& val, Func f )
684 # ifdef CDS_CXX11_LAMBDA_SUPPORT
685 return base_class::find( val, [&f]( node_type& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); });
687 find_functor<Func> wrapper(f);
688 return base_class::find( val, cds::ref(wrapper));
692 /// Finds the key \p val using \p pred predicate for searching
694 The function is an analog of \ref cds_nonintrusive_SkipListSet_find_cfunc "find(Q const&, Func)"
695 but \p pred is used for key comparing.
696 \p Less functor has the interface like \p std::less.
697 \p Less must imply the same element order as the comparator used for building the set.
699 template <typename Q, typename Less, typename Func>
700 bool find_with( Q const& val, Less cmp, Func f )
702 # ifdef CDS_CXX11_LAMBDA_SUPPORT
703 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
704 [&f]( node_type& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); } );
706 find_functor<Func> wrapper(f);
707 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
712 /// Find the key \p val
713 /** \anchor cds_nonintrusive_SkipListSet_find_val
715 The function searches the item with key equal to \p val
716 and returns \p true if it is found, and \p false otherwise.
718 Note the hash functor specified for class \p Traits template parameter
719 should accept a parameter of type \p Q that may be not the same as \ref value_type.
721 template <typename Q>
722 bool find( Q const& val )
724 return base_class::find( val );
727 /// Finds the key \p val using \p pred predicate for searching
729 The function is an analog of \ref cds_nonintrusive_SkipListSet_find_val "find(Q const&)"
730 but \p pred is used for key comparing.
731 \p Less functor has the interface like \p std::less.
732 \p Less must imply the same element order as the comparator used for building the set.
734 template <typename Q, typename Less>
735 bool find_with( Q const& val, Less pred )
737 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >());
740 /// Finds \p key and return the item found
741 /** \anchor cds_nonintrusive_SkipListSet_hp_get
742 The function searches the item with key equal to \p key
743 and assigns the item found to guarded pointer \p result.
744 The function returns \p true if \p key is found, and \p false otherwise.
745 If \p key is not found the \p result parameter is left unchanged.
747 It is safe when a concurrent thread erases the item returned in \p result guarded pointer.
748 In this case the item will be freed later by garbage collector \p GC automatically
749 when \p guarded_ptr object will be destroyed or released.
750 @note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
754 typedef cds::container::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
758 skip_list::guarded_ptr gp;
759 if ( theList.get( gp, 5 ) ) {
763 // Destructor of guarded_ptr releases internal HP guard
767 Note the compare functor specified for class \p Traits template parameter
768 should accept a parameter of type \p Q that can be not the same as \p value_type.
770 template <typename Q>
771 bool get( guarded_ptr& result, Q const& key )
773 return base_class::get_with_( result.guard(), key, typename base_class::key_comparator() );
776 /// Finds \p key and return the item found
778 The function is an analog of \ref cds_nonintrusive_SkipListSet_hp_get "get( guarded_ptr&, Q const&)"
779 but \p pred is used for comparing the keys.
781 \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q
783 \p pred must imply the same element order as the comparator used for building the set.
785 template <typename Q, typename Less>
786 bool get_with( guarded_ptr& result, Q const& key, Less pred )
788 typedef cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor > wrapped_less;
789 return base_class::get_with_( result.guard(), key, cds::opt::details::make_comparator_from_less< wrapped_less >());
792 /// Clears the set (non-atomic).
794 The function deletes all items from the set.
795 The function is not atomic, thus, in multi-threaded environment with parallel insertions
799 assert( set.empty() );
801 the assertion could be raised.
803 For each item the \ref disposer provided by \p Traits template parameter will be called.
810 /// Checks if the set is empty
813 return base_class::empty();
816 /// Returns item count in the set
818 The value returned depends on item counter type provided by \p Traits template parameter.
819 If it is atomicity::empty_item_counter this function always returns 0.
820 Therefore, the function is not suitable for checking the set emptiness, use \ref empty
821 member function for this purpose.
825 return base_class::size();
828 /// Returns const reference to internal statistics
829 stat const& statistics() const
831 return base_class::statistics();
836 }} // namespace cds::container
838 #endif // #ifndef __CDS_CONTAINER_SKIP_LIST_SET_IMPL_H