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 NULL 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 # ifdef CDS_EMPLACE_SUPPORT
398 /// Inserts data of type \ref cds_containewr_SkipListSet_value_type "value_type" constructed with <tt>std::forward<Args>(args)...</tt>
400 Returns \p true if inserting successful, \p false otherwise.
402 @note This function is available only for compiler that supports
403 variadic template and move semantics
405 template <typename... Args>
406 bool emplace( Args&&... args )
408 scoped_node_ptr sp( node_allocator().New( random_level(), std::forward<Args>(args)... ));
409 if ( base_class::insert( *sp.get() )) {
417 /// Delete \p key from the set
418 /** \anchor cds_nonintrusive_SkipListSet_erase_val
420 The set item comparator should be able to compare the type \p value_type
423 Return \p true if key is found and deleted, \p false otherwise
425 template <typename Q>
426 bool erase( Q const& key )
428 return base_class::erase( key );
431 /// Deletes the item from the set using \p pred predicate for searching
433 The function is an analog of \ref cds_nonintrusive_SkipListSet_erase_val "erase(Q const&)"
434 but \p pred is used for key comparing.
435 \p Less functor has the interface like \p std::less.
436 \p Less must imply the same element order as the comparator used for building the set.
438 template <typename Q, typename Less>
439 bool erase_with( Q const& key, Less pred )
441 return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >() );
444 /// Delete \p key from the set
445 /** \anchor cds_nonintrusive_SkipListSet_erase_func
447 The function searches an item with key \p key, calls \p f functor
448 and deletes the item. If \p key is not found, the functor is not called.
450 The functor \p Func interface:
453 void operator()(value_type const& val);
456 The functor may be passed by reference using <tt>boost:ref</tt>
458 Since the key of \p value_type is not explicitly specified,
459 template parameter \p Q defines the key type to search in the list.
460 The list item comparator should be able to compare the type \p T of list item
463 Return \p true if key is found and deleted, \p false otherwise
467 template <typename Q, typename Func>
468 bool erase( Q const& key, Func f )
470 # ifdef CDS_CXX11_LAMBDA_SUPPORT
471 return base_class::erase( key, [&f]( node_type const& node) { cds::unref(f)( node.m_Value ); } );
473 erase_functor<Func> wrapper(f);
474 return base_class::erase( key, cds::ref(wrapper));
478 /// Deletes the item from the set using \p pred predicate for searching
480 The function is an analog of \ref cds_nonintrusive_SkipListSet_erase_func "erase(Q const&, Func)"
481 but \p pred is used for key comparing.
482 \p Less functor has the interface like \p std::less.
483 \p Less must imply the same element order as the comparator used for building the set.
485 template <typename Q, typename Less, typename Func>
486 bool erase_with( Q const& key, Less pred, Func f )
488 # ifdef CDS_CXX11_LAMBDA_SUPPORT
489 return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
490 [&f]( node_type const& node) { cds::unref(f)( node.m_Value ); } );
492 erase_functor<Func> wrapper(f);
493 return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
498 /// Extracts the item from the set with specified \p key
499 /** \anchor cds_nonintrusive_SkipListSet_hp_extract
500 The function searches an item with key equal to \p key in the set,
501 unlinks it from the set, and returns it in \p result parameter.
502 If the item with key equal to \p key is not found the function returns \p false.
504 Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type.
506 The item extracted is freed automatically by garbage collector \p GC
507 when returned \ref guarded_ptr object will be destroyed or released.
508 @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
512 typedef cds::container::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
516 skip_list::guarded_ptr gp;
517 if ( theList.extract( gp, 5 ) ) {
521 // Destructor of gp releases internal HP guard and frees the pointer
525 template <typename Q>
526 bool extract( guarded_ptr& result, Q const& key )
528 return base_class::extract_( result.guard(), key, typename base_class::key_comparator() );
531 /// Extracts the item from the set with comparing functor \p pred
533 The function is an analog of \ref cds_nonintrusive_SkipListSet_hp_extract "extract(Q const&)"
534 but \p pred predicate is used for key comparing.
536 \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q
538 \p pred must imply the same element order as the comparator used for building the set.
540 template <typename Q, typename Less>
541 bool extract_with( guarded_ptr& ptr, Q const& key, Less pred )
543 typedef cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor > wrapped_less;
544 return base_class::extract_( ptr.guard(), key, cds::opt::details::make_comparator_from_less<wrapped_less>() );
547 /// Extracts an item with minimal key from the set
549 The function searches an item with minimal key, unlinks it, and returns the item found in \p result parameter.
550 If the skip-list is empty the function returns \p false.
552 The item extracted is freed automatically by garbage collector \p GC
553 when returned \ref guarded_ptr object will be destroyed or released.
554 @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
558 typedef cds::continer::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
562 skip_list::guarded_ptr gp;
563 if ( theList.extract_min( gp )) {
567 // Destructor of gp releases internal HP guard and then frees the pointer
571 bool extract_min( guarded_ptr& result)
573 return base_class::extract_min_( result.guard() );
576 /// Extracts an item with maximal key from the set
578 The function searches an item with maximal key, unlinks it, and returns the pointer to item found in \p result parameter.
579 If the skip-list is empty the function returns \p false.
581 The item found is freed by garbage collector \p GC automatically
582 when returned \ref guarded_ptr object will be destroyed or released.
583 @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
587 typedef cds::container::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
591 skip_list::guarded_ptr gp;
592 if ( theList.extract_max( gp )) {
596 // Destructor of gp releases internal HP guard and then frees the pointer
600 bool extract_max( guarded_ptr& result )
602 return base_class::extract_max_( result.guard() );
605 /// Find the key \p val
606 /** \anchor cds_nonintrusive_SkipListSet_find_func
608 The function searches the item with key equal to \p val and calls the functor \p f for item found.
609 The interface of \p Func functor is:
612 void operator()( value_type& item, Q& val );
615 where \p item is the item found, \p val is the <tt>find</tt> function argument.
617 You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
619 The functor may change non-key fields of \p item. Note that the functor is only guarantee
620 that \p item cannot be disposed during functor is executing.
621 The functor does not serialize simultaneous access to the set's \p item. If such access is
622 possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
624 The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
625 can modify both arguments.
627 Note the hash functor specified for class \p Traits template parameter
628 should accept a parameter of type \p Q that may be not the same as \p value_type.
630 The function returns \p true if \p val is found, \p false otherwise.
632 template <typename Q, typename Func>
633 bool find( Q& val, Func f )
635 # ifdef CDS_CXX11_LAMBDA_SUPPORT
636 return base_class::find( val, [&f]( node_type& node, Q& v ) { cds::unref(f)( node.m_Value, v ); });
638 find_functor<Func> wrapper(f);
639 return base_class::find( val, cds::ref(wrapper));
643 /// Finds the key \p val using \p pred predicate for searching
645 The function is an analog of \ref cds_nonintrusive_SkipListSet_find_func "find(Q&, Func)"
646 but \p pred is used for key comparing.
647 \p Less functor has the interface like \p std::less.
648 \p Less must imply the same element order as the comparator used for building the set.
650 template <typename Q, typename Less, typename Func>
651 bool find_with( Q& val, Less pred, Func f )
653 # ifdef CDS_CXX11_LAMBDA_SUPPORT
654 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
655 [&f]( node_type& node, Q& v ) { cds::unref(f)( node.m_Value, v ); } );
657 find_functor<Func> wrapper(f);
658 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(), cds::ref(wrapper));
662 /// Find the key \p val
663 /** \anchor cds_nonintrusive_SkipListSet_find_cfunc
665 The function searches the item with key equal to \p val and calls the functor \p f for item found.
666 The interface of \p Func functor is:
669 void operator()( value_type& item, Q const& val );
672 where \p item is the item found, \p val is the <tt>find</tt> function argument.
674 You may pass \p f argument by reference using <tt>boost::ref</tt> or cds::ref.
676 The functor may change non-key fields of \p item. Note that the functor is only guarantee
677 that \p item cannot be disposed during functor is executing.
678 The functor does not serialize simultaneous access to the set's \p item. If such access is
679 possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
681 Note the hash functor specified for class \p Traits template parameter
682 should accept a parameter of type \p Q that may be not the same as \p value_type.
684 The function returns \p true if \p val is found, \p false otherwise.
686 template <typename Q, typename Func>
687 bool find( Q const& val, Func f )
689 # ifdef CDS_CXX11_LAMBDA_SUPPORT
690 return base_class::find( val, [&f]( node_type& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); });
692 find_functor<Func> wrapper(f);
693 return base_class::find( val, cds::ref(wrapper));
697 /// Finds the key \p val using \p pred predicate for searching
699 The function is an analog of \ref cds_nonintrusive_SkipListSet_find_cfunc "find(Q const&, Func)"
700 but \p pred is used for key comparing.
701 \p Less functor has the interface like \p std::less.
702 \p Less must imply the same element order as the comparator used for building the set.
704 template <typename Q, typename Less, typename Func>
705 bool find_with( Q const& val, Less cmp, Func f )
707 # ifdef CDS_CXX11_LAMBDA_SUPPORT
708 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
709 [&f]( node_type& node, Q const& v ) { cds::unref(f)( node.m_Value, v ); } );
711 find_functor<Func> wrapper(f);
712 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >(),
717 /// Find the key \p val
718 /** \anchor cds_nonintrusive_SkipListSet_find_val
720 The function searches the item with key equal to \p val
721 and returns \p true if it is found, and \p false otherwise.
723 Note the hash functor specified for class \p Traits template parameter
724 should accept a parameter of type \p Q that may be not the same as \ref value_type.
726 template <typename Q>
727 bool find( Q const& val )
729 return base_class::find( val );
732 /// Finds the key \p val using \p pred predicate for searching
734 The function is an analog of \ref cds_nonintrusive_SkipListSet_find_val "find(Q const&)"
735 but \p pred is used for key comparing.
736 \p Less functor has the interface like \p std::less.
737 \p Less must imply the same element order as the comparator used for building the set.
739 template <typename Q, typename Less>
740 bool find_with( Q const& val, Less pred )
742 return base_class::find_with( val, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >());
745 /// Finds \p key and return the item found
746 /** \anchor cds_nonintrusive_SkipListSet_hp_get
747 The function searches the item with key equal to \p key
748 and assigns the item found to guarded pointer \p result.
749 The function returns \p true if \p key is found, and \p false otherwise.
750 If \p key is not found the \p result parameter is left unchanged.
752 It is safe when a concurrent thread erases the item returned in \p result guarded pointer.
753 In this case the item will be freed later by garbage collector \p GC automatically
754 when \p guarded_ptr object will be destroyed or released.
755 @note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
759 typedef cds::container::SkipListSet< cds::gc::HP, foo, my_traits > skip_list;
763 skip_list::guarded_ptr gp;
764 if ( theList.get( gp, 5 ) ) {
768 // Destructor of guarded_ptr releases internal HP guard
772 Note the compare functor specified for class \p Traits template parameter
773 should accept a parameter of type \p Q that can be not the same as \p value_type.
775 template <typename Q>
776 bool get( guarded_ptr& result, Q const& key )
778 return base_class::get_with_( result.guard(), key, typename base_class::key_comparator() );
781 /// Finds \p key and return the item found
783 The function is an analog of \ref cds_nonintrusive_SkipListSet_hp_get "get( guarded_ptr&, Q const&)"
784 but \p pred is used for comparing the keys.
786 \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q
788 \p pred must imply the same element order as the comparator used for building the set.
790 template <typename Q, typename Less>
791 bool get_with( guarded_ptr& result, Q const& key, Less pred )
793 typedef cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor > wrapped_less;
794 return base_class::get_with_( result.guard(), key, cds::opt::details::make_comparator_from_less< wrapped_less >());
797 /// Clears the set (non-atomic).
799 The function deletes all items from the set.
800 The function is not atomic, thus, in multi-threaded environment with parallel insertions
804 assert( set.empty() );
806 the assertion could be raised.
808 For each item the \ref disposer provided by \p Traits template parameter will be called.
815 /// Checks if the set is empty
818 return base_class::empty();
821 /// Returns item count in the set
823 The value returned depends on item counter type provided by \p Traits template parameter.
824 If it is atomicity::empty_item_counter this function always returns 0.
825 Therefore, the function is not suitable for checking the set emptiness, use \ref empty
826 member function for this purpose.
830 return base_class::size();
833 /// Returns const reference to internal statistics
834 stat const& statistics() const
836 return base_class::statistics();
841 }} // namespace cds::container
843 #endif // #ifndef __CDS_CONTAINER_SKIP_LIST_SET_IMPL_H