2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_CONTAINER_STRIPED_SET_H
32 #define CDSLIB_CONTAINER_STRIPED_SET_H
34 #include <cds/intrusive/striped_set.h>
35 #include <cds/container/striped_set/adapter.h>
37 namespace cds { namespace container {
40 /** @ingroup cds_nonintrusive_set
43 - [2008] Maurice Herlihy, Nir Shavit "The Art of Multiprocessor Programming"
45 Lock striping is very simple technique.
46 The set consists of the bucket table and the array of locks.
47 Initially, the capacity of lock array and bucket table is the same.
48 When set is resized, bucket table capacity will be doubled but lock array will not.
49 The lock \p i protects each bucket \p j, where <tt> j = i mod L </tt>,
50 where \p L - the size of lock array.
53 - \p Container - the container class that is used as bucket table entry. The \p Container class should support
54 an uniform interface described below.
55 - \p Options - options
57 The \p %StripedSet class does not exactly dictate the type of container that should be used as a \p Container bucket.
58 Instead, the class supports different container type for the bucket, for exampe, \p std::list, \p std::set and others.
60 Remember that \p %StripedSet class algorithm ensures sequential blocking access to its bucket through the mutex type you specify
61 among \p Options template arguments.
64 - \p opt::mutex_policy - concurrent access policy.
65 Available policies: \p intrusive::striped_set::striping, \p intrusive::striped_set::refinable.
66 Default is \p %striped_set::striping.
67 - \p opt::hash - hash functor. Default option value see <tt>opt::v::hash_selector<opt::none> </tt>
68 which selects default hash functor for your compiler.
69 - \p opt::compare - key comparison functor. No default functor is provided.
70 If the option is not specified, the \p %opt::less is used.
71 - \p opt::less - specifies binary predicate used for key comparison. Default is \p std::less<T>.
72 - \p opt::item_counter - item counter type. Default is \p atomicity::item_counter since some operation on the counter is performed
73 without locks. Note that item counting is an essential part of the set algorithm, so dummy counter
74 like as \p atomicity::empty_item_counter is not suitable.
75 - \p opt::allocator - the allocator type using for memory allocation of bucket table and lock array. Default is \ref CDS_DEFAULT_ALLOCATOR.
76 - \p opt::resizing_policy - the resizing policy that is a functor that decides when to resize the hash set.
77 Default option value depends on bucket container type:
78 for sequential containers like \p std::list, \p std::vector the resizing policy is <tt>striped_set::load_factor_resizing<4> </tt>;
79 for other type of containers like \p std::set, \p std::unordered_set the resizing policy is \p striped_set::no_resizing.
80 See \ref cds_striped_resizing_policy "available resizing policy".
81 Note that the choose of resizing policy depends of \p Container type:
82 for sequential containers like \p std::list, \p std::vector and so on, right choosing of the policy can
83 significantly improve performance.
84 For other, non-sequential types of \p Container (like a \p std::set) the resizing policy is not so important.
85 - \p opt::copy_policy - the copy policy which is used to copy items from the old set to the new one when resizing.
86 The policy can be optionally used in adapted bucket container for performance reasons of resizing.
87 The detail of copy algorithm depends on type of bucket container and explains below.
89 \p %opt::compare or \p %opt::less options are used in some \p Container class for searching an item.
90 \p %opt::compare option has the highest priority: if \p %opt::compare is specified, \p %opt::less is not used.
92 You can pass other option that would be passed to <tt>adapt</tt> metafunction, see below.
94 <b>Internal details</b>
96 The \p %StripedSet class cannot utilize the \p Container container specified directly, but only its adapted variant which
97 supports an unified interface. Internally, the adaptation is made via striped_set::adapt metafunction that wraps bucket container
98 and provides the unified bucket interface suitable for \p %StripedSet. Such adaptation is completely transparent for you -
99 you don't need to call \p adapt metafunction directly, \p %StripedSet class's internal machinery itself invokes appropriate
100 \p adapt metafunction to adjust your \p Container container class to \p %StripedSet bucket's internal interface.
101 All you need is to include a right header before <tt>striped_hash_set.h</tt>.
103 By default, <tt>striped_set::adapt<AnyContainer, Options...> </tt> metafunction does not make any wrapping to \p AnyContainer,
104 so, the result <tt>striped_set::adapt<AnyContainer, Options...>::type </tt> is the same as \p AnyContainer.
105 However, there are a lot of specializations of <tt>striped_set::adapt</tt> for well-known containers, see table below.
106 Any of this specialization wraps corresponding container making it suitable for the set's bucket.
107 Remember, you should include the proper header file for \p adapt <b>before</b> including <tt>striped_hash_set.h</tt>.
111 <th>.h-file for \p adapt</th>
116 <td> \p std::list</td>
117 <td><tt><cds/container/striped_set/std_list.h></tt></td>
119 #include <cds/container/striped_set/std_list.h>
120 #include <cds/container/striped_hash_set.h>
121 typedef cds::container::StripedSet<
123 cds::opt::less< std::less<T> >
129 Template argument pack \p Options <b>must</b> contain cds::opt::less or cds::opt::compare for type \p T stored in the list
133 <td> \p std::vector</td>
134 <td><tt><cds/container/striped_set/std_vector.h></tt></td>
136 #include <cds/container/striped_set/std_vector.h>
137 #include <cds/container/striped_hash_set.h>
138 typedef cds::container::StripedSet<
140 cds::opt::less< std::less<T> >
145 The vector is ordered.
146 Template argument pack \p Options <b>must</b> contain \p cds::opt::less or \p cds::opt::compare for type \p T stored in the list
150 <td> \p std::set</td>
151 <td><tt><cds/container/striped_set/std_set.h></tt></td>
153 #include <cds/container/striped_set/std_set.h>
154 #include <cds/container/striped_hash_set.h>
155 typedef cds::container::StripedSet<
156 std::set< T, std::less<T> >
164 <td> \p std::unordered_set</td>
165 <td><tt><cds/container/striped_set/std_hash_set.h></tt></td>
167 #include <cds/container/striped_set/std_hash_set.h>
168 #include <cds/container/striped_hash_set.h>
169 typedef cds::container::StripedSet<
179 You should provide two different hash function \p h1 and \p h2 - one for \p std::unordered_set and other for \p %StripedSet.
180 For the best result, \p h1 and \p h2 must be orthogonal i.e. <tt> h1(X) != h2(X) </tt> for any value \p X.
184 <td> \p boost::container::slist</td>
185 <td><tt><cds/container/striped_set/boost_slist.h></tt></td>
187 #include <cds/container/striped_set/boost_slist.h>
188 #include <cds/container/striped_hash_set.h>
189 typedef cds::container::StripedSet<
190 boost::container::slist<T>
196 \p Options <b>must</b> contain \p cds::opt::less or \p cds::opt::compare.
200 <td> \p boost::container::list</td>
201 <td><tt><cds/container/striped_set/boost_list.h></tt></td>
203 #include <cds/container/striped_set/boost_list.h>
204 #include <cds/container/striped_hash_set.h>
205 typedef cds::container::StripedSet<
206 boost::container::list<T>
212 \p Options <b>must</b> contain \p cds::opt::less or \p cds::opt::compare.
216 <td> \p boost::container::vector</td>
217 <td><tt><cds/container/striped_set/boost_vector.h></tt></td>
219 #include <cds/container/striped_set/boost_vector.h>
220 #include <cds/container/striped_hash_set.h>
221 typedef cds::container::StripedSet<
222 boost::container::vector<T>,
223 cds::opt::less< std::less<T> >
228 The vector is ordered.
229 Template argument pack \p Options <b>must</b> contain \p cds::opt::less or \p cds::opt::compare for type \p T stored in the vector
233 <td> \p boost::container::stable_vector</td>
234 <td><tt><cds/container/striped_set/boost_stable_vector.h></tt></td>
236 #include <cds/container/striped_set/boost_stable_vector.h>
237 #include <cds/container/striped_hash_set.h>
238 typedef cds::container::StripedSet<
239 boost::container::stable_vector<T>,
240 cds::opt::less< std::less<T> >
245 The vector is ordered.
246 Template argument pack \p Options <b>must</b> contain \p cds::opt::less or \p cds::opt::compare for type \p T stored in the vector
250 <td> \p boost::container::set</td>
251 <td><tt><cds/container/striped_set/boost_set.h></tt></td>
253 #include <cds/container/striped_set/boost_set.h>
254 #include <cds/container/striped_hash_set.h>
255 typedef cds::container::StripedSet<
256 boost::container::set< T, std::less<T> >
264 <td> \p boost::container::flat_set</td>
265 <td><tt><cds/container/striped_set/boost_flat_set.h></tt></td>
267 #include <cds/container/striped_set/boost_flat_set.h>
268 #include <cds/container/striped_hash_set.h>
269 typedef cds::container::StripedSet<
270 boost::container::flat_set< T, std::less<T> >
278 <td> \p boost::unordered_set</td>
279 <td><tt><cds/container/striped_set/boost_unordered_set.h></tt></td>
281 #include <cds/container/striped_set/boost_unordered_set.h>
282 #include <cds/container/striped_hash_set.h>
283 typedef cds::container::StripedSet<
284 boost::unordered_set<
293 You should provide two different hash function \p h1 and \p h2 - one for \p boost::unordered_set and other for \p %StripedSet.
294 For the best result, \p h1 and \p h2 must be orthogonal i.e. <tt> h1(X) != h2(X) </tt> for any value \p X.
299 You can use another container type as set's bucket.
300 Suppose, you have a container class \p MyBestContainer and you want to integrate it with \p %StripedSet as bucket type.
301 There are two possibility:
302 - either your \p MyBestContainer class has native support of bucket's interface;
303 in this case, you can use default <tt>striped_set::adapt</tt> metafunction;
304 - or your \p MyBestContainer class does not support bucket's interface, which means, that you should develop a specialization
305 <tt>cds::container::striped_set::adapt<MyBestContainer> </tt> metafunction providing necessary interface.
307 The <tt>striped_set::adapt< Container, Options... ></tt> metafunction has two template argument:
308 - \p Container is the class that should be used as the bucket, for example, <tt>std::list< T ></tt>.
309 - \p Options pack is the options from \p %StripedSet declaration. The \p adapt metafunction can use
310 any option from \p Options for its internal use. For example, a \p compare option can be passed to \p adapt
311 metafunction via \p Options argument of \p %StripedSet declaration.
313 See striped_set::adapt metafunction for the description of interface that the bucket container must provide
314 to be %StripedSet compatible.
317 There are three predefined copy policy:
318 - \p cds::container::striped_set::copy_item - copy item from old bucket to new one when resizing using copy ctor. It is default policy for
319 any compiler that do not support move semantics
320 - \p cds::container::striped_set::move_item - move item from old bucket to new one when resizing using move semantics. It is default policy for
321 any compiler that support move semantics. If compiler does not support move semantics, the move policy is the same as \p copy_item
322 - \p cds::container::striped_set::swap_item - copy item from old bucket to new one when resizing using \p std::swap. Not all containers support
323 this copy policy, see details in table below.
325 You can define your own copy policy specifically for your case.
326 Note, right copy policy can significantly improve the performance of resizing.
339 - \p boost::stable_vector
343 void operator()( std::list<T>& list, std::list<T>::iterator itInsert, std::list<T>::iterator itWhat )
345 list.insert( itInsert, *itWhat );
350 // The type T stored in the list must be swappable
352 void operator()( std::list<T>& list, std::list<T>::iterator itInsert, std::list<T>::iterator itWhat )
354 std::swap( *list.insert( itInsert, T() ), *itWhat );
360 void operator()( std::list<T>& list, std::list<T>::iterator itInsert, std::list<T>::iterator itWhat )
362 list.insert( itInsert, std::move( *itWhat ) );
370 - \p std::unordered_set
374 void operator()( std::set<T>& set, std::set<T>::iterator itWhat )
376 set.insert( *itWhat );
379 \p swap_item is not applicable (same as \p copy_item)
383 void operator()( std::set<T>& set, std::set<T>::iterator itWhat )
385 set.insert( std::move( *itWhat ));
391 - \p boost::container::slist
395 void operator()( bc::slist<T>& list, bc::slist<T>::iterator itInsert, bc::slist<T>::iterator itWhat )
397 list.insert_after( itInsert, *itWhat );
402 // The type T stored in the list must be swappable
404 void operator()( bc::slist<T>& list, bc::slist<T>::iterator itInsert, bc::slist<T>::iterator itWhat )
406 std::swap( *list.insert_after( itInsert, T() ), *itWhat );
412 void operator()( bc::slist<T>& list, bc::slist<T>::iterator itInsert, bc::slist<T>::iterator itWhat )
414 list.insert_after( itInsert, std::move( *itWhat ) );
421 <b>Advanced functions</b>
423 <b>libcds</b> provides some advanced functions like \p erase_with(), \p find_with(),
424 that cannot be supported by all underlying containers.
425 The table below shows whether underlying container supports those functions
426 (the sign "+" means "container supports the function"):
431 <th>\p find_with</th>
432 <th>\p erse_with</th>
435 <td> \p std::list</td>
440 <td> \p std::vector</td>
445 <td> \p std::set</td>
450 <td> \p std::unordered_set</td>
455 <td> \p boost::container::slist</td>
460 <td> \p boost::container::list</td>
465 <td> \p boost::container::vector</td>
470 <td> \p boost::container::stable_vector</td>
475 <td> \p boost::container::set</td>
480 <td> \p boost::container::flat_set</td>
485 <td> \p boost::unordered_set</td>
491 template <class Container, typename... Options>
492 class StripedSet: protected intrusive::StripedSet<Container, Options...>
495 typedef intrusive::StripedSet<Container, Options...> base_class;
499 typedef typename base_class::default_options default_options;
500 typedef typename base_class::options options;
503 typedef Container underlying_container_type ; ///< original intrusive container type for the bucket
504 typedef typename base_class::bucket_type bucket_type ; ///< container type adapted for hash set
505 typedef typename bucket_type::value_type value_type ; ///< value type stored in the set
507 typedef typename base_class::hash hash ; ///< Hash functor
508 typedef typename base_class::item_counter item_counter ; ///< Item counter
509 typedef typename base_class::resizing_policy resizing_policy ; ///< Resizing policy
510 typedef typename base_class::allocator_type allocator_type ; ///< allocator type specified in options.
511 typedef typename base_class::mutex_policy mutex_policy ; ///< Mutex policy
515 typedef typename base_class::scoped_cell_lock scoped_cell_lock;
516 typedef typename base_class::scoped_full_lock scoped_full_lock;
517 typedef typename base_class::scoped_resize_lock scoped_resize_lock;
521 /// Default ctor. The initial capacity is 16.
526 /// Ctor with initial capacity specified
528 size_t nCapacity ///< Initial size of bucket table and lock array. Must be power of two, the minimum is 16.
531 : base_class( nCapacity )
534 /// Ctor with resizing policy (copy semantics)
536 This constructor initializes m_ResizingPolicy member with copy of \p resizingPolicy parameter
539 size_t nCapacity ///< Initial size of bucket table and lock array. Must be power of two, the minimum is 16.
540 ,resizing_policy const& resizingPolicy ///< Resizing policy
543 : base_class( nCapacity, resizingPolicy )
546 /// Ctor with resizing policy (move semantics)
548 This constructor initializes m_ResizingPolicy member moving \p resizingPolicy parameter
549 Move semantics is used. Available only for the compilers that supports C++11 rvalue reference.
552 size_t nCapacity ///< Initial size of bucket table and lock array. Must be power of two, the minimum is 16.
553 ,resizing_policy&& resizingPolicy ///< Resizing policy
556 : base_class( nCapacity, std::forward<resizing_policy>(resizingPolicy) )
559 /// Destructor destroys internal data
566 The function creates a node with copy of \p val value
567 and then inserts the node created into the set.
569 The type \p Q should contain as minimum the complete key for the node.
570 The object of \p value_type should be constructible from a value of type \p Q.
571 In trivial case, \p Q is equal to \p value_type.
573 Returns \p true if \p val is inserted into the set, \p false otherwise.
575 template <typename Q>
576 bool insert( Q const& val )
578 return insert( val, []( value_type& ) {} );
583 The function allows to split creating of new item into two part:
584 - create item with key only
585 - insert new item into the set
586 - if inserting is success, calls \p f functor to initialize value-field of new item .
588 The functor signature is:
590 void func( value_type& item );
592 where \p item is the item inserted.
594 The type \p Q can differ from \p value_type of items storing in the set.
595 Therefore, the \p value_type should be constructible from type \p Q.
597 The user-defined functor is called only if the inserting is success.
599 template <typename Q, typename Func>
600 bool insert( Q const& val, Func f )
604 size_t nHash = base_class::hashing( val );
605 bucket_type * pBucket;
607 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
608 pBucket = base_class::bucket( nHash );
609 bOk = pBucket->insert( val, f );
610 bResize = bOk && base_class::m_ResizingPolicy( ++base_class::m_ItemCounter, *this, *pBucket );
614 base_class::resize();
618 /// Inserts data of type \p %value_type constructed with <tt>std::forward<Args>(args)...</tt>
620 Returns \p true if inserting successful, \p false otherwise.
622 template <typename... Args>
623 bool emplace( Args&&... args )
627 value_type val( std::forward<Args>( args )... );
628 size_t nHash = base_class::hashing( val );
629 bucket_type * pBucket;
631 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
632 pBucket = base_class::bucket( nHash );
634 bOk = pBucket->emplace( std::move( val ));
635 bResize = bOk && base_class::m_ResizingPolicy( ++base_class::m_ItemCounter, *this, *pBucket );
639 base_class::resize();
645 The operation performs inserting or changing data with lock-free manner.
647 If \p key is not found in the set, then \p key is inserted iff \p bAllowInsert is \p true.
648 Otherwise, the functor \p func is called with item found.
650 The functor signature is:
653 void operator()( bool bNew, value_type& item, const Q& val );
657 - \p bNew - \p true if the item has been inserted, \p false otherwise
658 - \p item - item of the set
659 - \p val - argument \p val passed into the \p %update() function
661 The functor may change non-key fields of the \p item.
663 Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successful,
664 \p second is true if new item has been added or \p false if the item with \p key
665 already is in the map.
667 template <typename Q, typename Func>
668 std::pair<bool, bool> update( Q const& val, Func func, bool bAllowInsert = true )
670 std::pair<bool, bool> result;
671 bool bResize = false;
672 size_t nHash = base_class::hashing( val );
673 bucket_type * pBucket;
675 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
676 pBucket = base_class::bucket( nHash );
678 result = pBucket->update( val, func, bAllowInsert );
679 if ( result.first && result.second )
680 bResize = base_class::m_ResizingPolicy( ++base_class::m_ItemCounter, *this, *pBucket );
684 base_class::resize();
688 template <typename Q, typename Func>
689 CDS_DEPRECATED("ensure() is deprecated, use update()")
690 std::pair<bool, bool> ensure( Q const& val, Func func )
692 return update( val, func, true );
696 /// Delete \p key from the set
697 /** \anchor cds_nonintrusive_StripedSet_erase
699 The set item comparator should be able to compare the type \p value_type and the type \p Q.
700 Return \p true if key is found and deleted, \p false otherwise
702 template <typename Q>
703 bool erase( Q const& key )
705 return erase( key, [](value_type const&) {} );
708 /// Deletes the item from the set using \p pred predicate for searching
710 The function is an analog of \ref cds_nonintrusive_StripedSet_erase "erase(Q const&)"
711 but \p pred is used for key comparing.
712 \p Less functor has the interface like \p std::less.
713 \p pred must imply the same element order as the comparator used for building the set.
715 @note This function is enabled if the compiler supports C++11
716 default template arguments for function template <b>and</b> the underlying container
717 supports \p %erase_with feature.
719 template < typename Q, typename Less
720 ,typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_erase_with >::type >
721 bool erase_with( Q const& key, Less pred )
723 return erase_with( key, pred, [](value_type const&) {} );
726 /// Delete \p key from the set
727 /** \anchor cds_nonintrusive_StripedSet_erase_func
729 The function searches an item with key \p key, calls \p f functor with item found
730 and deletes it. If \p key is not found, the functor is not called.
732 The functor \p Func interface is:
735 void operator()(value_type const& val);
739 Return \p true if key is found and deleted, \p false otherwise
741 template <typename Q, typename Func>
742 bool erase( Q const& key, Func f )
745 size_t nHash = base_class::hashing( key );
747 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
748 bucket_type * pBucket = base_class::bucket( nHash );
750 bOk = pBucket->erase( key, f );
754 --base_class::m_ItemCounter;
758 /// Deletes the item from the set using \p pred predicate for searching
760 The function is an analog of \ref cds_nonintrusive_StripedSet_erase_func "erase(Q const&, Func)"
761 but \p pred is used for key comparing.
762 \p Less functor has the interface like \p std::less.
763 \p pred must imply the same element order as the comparator used for building the set.
765 @note This function is enabled if the compiler supports C++11
766 default template arguments for function template <b>and</b> the underlying container
767 supports \p %erase_with feature.
769 template < typename Q, typename Less, typename Func
770 , typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_erase_with >::type >
771 bool erase_with( Q const& key, Less pred, Func f )
774 size_t nHash = base_class::hashing( key );
776 scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
777 bucket_type * pBucket = base_class::bucket( nHash );
779 bOk = pBucket->erase( key, pred, f );
783 --base_class::m_ItemCounter;
787 /// Find the key \p val
788 /** \anchor cds_nonintrusive_StripedSet_find_func
790 The function searches the item with key equal to \p val and calls the functor \p f for item found.
791 The interface of \p Func functor is:
794 void operator()( value_type& item, Q& val );
797 where \p item is the item found, \p val is the <tt>find</tt> function argument.
799 The functor can change non-key fields of \p item.
800 The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
801 can modify both arguments.
803 The type \p Q can differ from \p value_type of items storing in the container.
804 Therefore, the \p value_type should be comparable with type \p Q.
806 The function returns \p true if \p val is found, \p false otherwise.
808 template <typename Q, typename Func>
809 bool find( Q& val, Func f )
811 return base_class::find( val, f );
814 /// Find the key \p val using \p pred predicate
816 The function is an analog of \ref cds_nonintrusive_StripedSet_find_func "find(Q&, Func)"
817 but \p pred is used for key comparing
818 \p Less has the interface like \p std::less.
819 \p pred must imply the same element order as the comparator used for building the set.
821 @note This function is enabled if the compiler supports C++11
822 default template arguments for function template <b>and</b> the underlying container
823 supports \p %find_with feature.
825 template <typename Q, typename Less, typename Func
826 , typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
827 bool find_with( Q& val, Less pred, Func f )
829 return base_class::find_with( val, pred, f );
832 /// Find the key \p val
833 /** \anchor cds_nonintrusive_StripedSet_find_cfunc
835 The function searches the item with key equal to \p val and calls the functor \p f for item found.
836 The interface of \p Func functor is:
839 void operator()( value_type& item, Q const& val );
842 where \p item is the item found, \p val is the <tt>find</tt> function argument.
844 The functor can change non-key fields of \p item.
846 The type \p Q can differ from \p value_type of items storing in the container.
847 Therefore, the \p value_type should be comparable with type \p Q.
849 The function returns \p true if \p val is found, \p false otherwise.
851 template <typename Q, typename Func>
852 bool find( Q const& val, Func f )
854 return base_class::find( val, f );
857 /// Find the key \p val using \p pred predicate
859 The function is an analog of \ref cds_nonintrusive_StripedSet_find_cfunc "find(Q const&, Func)"
860 but \p pred is used for key comparing
861 \p Less has the interface like \p std::less.
862 \p pred must imply the same element order as the comparator used for building the set.
864 @note This function is enabled if the compiler supports C++11
865 default template arguments for function template <b>and</b> the underlying container
866 supports \p %find_with feature.
868 template <typename Q, typename Less, typename Func
869 , typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
870 bool find_with( Q const& val, Less pred, Func f )
872 return base_class::find_with( val, pred, f );
875 /// Checks whether the set contains \p key
877 The function searches the item with key equal to \p key
878 and returns \p true if it is found, and \p false otherwise.
880 Note the hash functor specified for class \p Traits template parameter
881 should accept a parameter of type \p Q that can be not the same as \p value_type.
882 Otherwise, you may use \p contains( Q const&, Less pred ) functions with explicit predicate for key comparing.
884 template <typename Q>
885 bool contains( Q const& key )
887 return base_class::contains( key );
890 template <typename Q>
891 CDS_DEPRECATED("use contains()")
892 bool find( Q const& key )
894 return contains( key );
898 /// Checks whether the map contains \p key using \p pred predicate for searching
900 The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
901 \p Less functor has the interface like \p std::less.
902 \p Less must imply the same element order as the comparator used for building the map.
904 template <typename Q, typename Less
905 , typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
906 bool contains( Q const& key, Less pred )
908 return base_class::contains( key, pred );
911 template <typename Q, typename Less
912 , typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
913 CDS_DEPRECATED("use contains()")
914 bool find_with( Q const& val, Less pred )
916 return contains( val, pred );
922 The function erases all items from the set.
926 return base_class::clear();
929 /// Checks if the set is empty
931 Emptiness is checked by item counting: if item count is zero then the set is empty.
935 return base_class::empty();
938 /// Returns item count in the set
941 return base_class::size();
944 /// Returns the size of hash table
946 The hash table size is non-constant and can be increased via resizing.
948 size_t bucket_count() const
950 return base_class::bucket_count();
953 /// Returns lock array size
954 size_t lock_count() const
956 return base_class::lock_count();
959 /// Returns resizing policy object
960 resizing_policy& get_resizing_policy()
962 return base_class::get_resizing_policy();
965 /// Returns resizing policy (const version)
966 resizing_policy const& get_resizing_policy() const
968 return base_class::get_resizing_policy();
972 }} // namespace cds::container
975 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_SET_H