Docfix
[libcds.git] / cds / container / split_list_map.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
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.
18
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.     
29 */
30
31 #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_H
32 #define CDSLIB_CONTAINER_SPLIT_LIST_MAP_H
33
34 #include <cds/container/split_list_set.h>
35 #include <cds/details/binary_functor_wrapper.h>
36
37 namespace cds { namespace container {
38
39     /// Split-ordered list map
40     /** @ingroup cds_nonintrusive_map
41         \anchor cds_nonintrusive_SplitListMap_hp
42
43         Hash table implementation based on split-ordered list algorithm discovered by Ori Shalev and Nir Shavit, see
44         - [2003] Ori Shalev, Nir Shavit "Split-Ordered Lists - Lock-free Resizable Hash Tables"
45         - [2008] Nir Shavit "The Art of Multiprocessor Programming"
46
47         See intrusive::SplitListSet for a brief description of the split-list algorithm.
48
49         Template parameters:
50         - \p GC - Garbage collector used like \p cds::gc::HP or \p cds::gc::DHP
51         - \p Key - key type of an item stored in the map. It should be copy-constructible
52         - \p Value - value type stored in the map
53         - \p Traits - map traits, default is \p split_list::traits. Instead of declaring \p %split_list::traits -based
54             struct you may apply option-based notation with \p split_list::make_traits metafunction.
55
56         There are the specializations:
57         - for \ref cds_urcu_desc "RCU" - declared in <tt>cd/container/split_list_map_rcu.h</tt>,
58             see \ref cds_nonintrusive_SplitListMap_rcu "SplitListMap<RCU>".
59         - for \ref cds::gc::nogc declared in <tt>cds/container/split_list_map_nogc.h</tt>,
60             see \ref cds_nonintrusive_SplitListMap_nogc "SplitListMap<gc::nogc>".
61
62         \par Usage
63
64         You should decide what garbage collector you want, and what ordered list you want to use. Split-ordered list
65         is original data structure based on an ordered list. Suppose, you want construct split-list map based on \p gc::HP GC
66         and \p MichaelList as ordered list implementation. Your map should map \p int key to \p std::string value.
67         So, you beginning your program with following include:
68         \code
69         #include <cds/container/michael_list_hp.h>
70         #include <cds/container/split_list_map.h>
71
72         namespace cc = cds::container;
73         \endcode
74         The inclusion order is important: first, include file for ordered-list implementation (for this example, <tt>cds/container/michael_list_hp.h</tt>),
75         then the header for split-list map <tt>cds/container/split_list_map.h</tt>.
76
77         Now, you should declare traits for split-list map. The main parts of traits are a hash functor and a comparing functor for the ordered list.
78         We use <tt>std::hash<int></tt> as hash functor and <tt>std::less<int></tt> predicate as comparing functor.
79
80         The second attention: instead of using \p %MichaelList in \p %SplitListMap traits we use a tag \p cds::contaner::michael_list_tag for the Michael's list.
81         The split-list requires significant support from underlying ordered list class and it is not good idea to dive you
82         into deep implementation details of split-list and ordered list interrelations. The tag paradigm simplifies split-list interface.
83
84         \code
85         // SplitListMap traits
86         struct foo_set_traits: public cc::split_list::traits
87         {
88             typedef cc::michael_list_tag   ordered_list    ;   // what type of ordered list we want to use
89             typedef std::hash<int>         hash            ;   // hash functor for the key stored in split-list map
90
91             // Type traits for our MichaelList class
92             struct ordered_list_traits: public cc::michael_list::traits
93             {
94             typedef std::less<int> less   ;   // use our std::less predicate as comparator to order list nodes
95             };
96         };
97         \endcode
98
99         Now you are ready to declare our map class based on \p %SplitListMap:
100         \code
101         typedef cc::SplitListMap< cds::gc::DHP, int, std::string, foo_set_traits > int_string_map;
102         \endcode
103
104         You may use the modern option-based declaration instead of classic type-traits-based one:
105         \code
106         typedef cc::SplitListMap<
107             cs::gc::DHP             // GC used
108             ,int                    // key type
109             ,std::string            // value type
110             ,cc::split_list::make_traits<      // metafunction to build split-list traits
111                 cc::split_list::ordered_list<cc::michael_list_tag>     // tag for underlying ordered list implementation
112                 ,cc::opt::hash< std::hash<int> >        // hash functor
113                 ,cc::split_list::ordered_list_traits<    // ordered list traits desired
114                     cc::michael_list::make_traits<    // metafunction to build lazy list traits
115                         cc::opt::less< std::less<int> >         // less-based compare functor
116                     >::type
117                 >
118             >::type
119         >  int_string_map;
120         \endcode
121         In case of option-based declaration with \p split_list::make_traits metafunction the struct \p foo_set_traits is not required.
122
123         Now, the map of type \p int_string_map is ready to use in your program.
124
125         Note that in this example we show only mandatory \p traits parts, optional ones is the default and they are inherited
126         from \p container::split_list::traits. There are many other options for deep tuning of the split-list and
127         ordered-list containers.
128     */
129     template <
130         class GC,
131         typename Key,
132         typename Value,
133 #ifdef CDS_DOXYGEN_INVOKED
134         class Traits = split_list::traits
135 #else
136         class Traits
137 #endif
138     >
139     class SplitListMap:
140         protected container::SplitListSet<
141             GC,
142             std::pair<Key const, Value>,
143             split_list::details::wrap_map_traits<Key, Value, Traits>
144         >
145     {
146         //@cond
147         typedef container::SplitListSet<
148             GC,
149             std::pair<Key const, Value>,
150             split_list::details::wrap_map_traits<Key, Value, Traits>
151         >  base_class;
152         //@endcond
153
154     public:
155         typedef GC     gc;          ///< Garbage collector
156         typedef Key    key_type;    ///< key type
157         typedef Value  mapped_type; ///< type of value to be stored in the map
158         typedef Traits traits;      ///< Map traits
159
160         typedef std::pair<key_type const, mapped_type>  value_type  ;   ///< key-value pair type
161         typedef typename base_class::ordered_list       ordered_list;   ///< Underlying ordered list class
162         typedef typename base_class::key_comparator     key_comparator; ///< key compare functor
163
164         typedef typename base_class::hash           hash;         ///< Hash functor for \ref key_type
165         typedef typename base_class::item_counter   item_counter; ///< Item counter type
166         typedef typename base_class::stat           stat;         ///< Internal statistics
167
168     protected:
169         //@cond
170         typedef typename base_class::maker::traits::key_accessor key_accessor;
171         typedef typename base_class::node_type node_type;
172         //@endcond
173
174     public:
175         /// Guarded pointer
176         typedef typename gc::template guarded_ptr< node_type, value_type, details::guarded_ptr_cast_set<node_type, value_type> > guarded_ptr;
177
178     public:
179     ///@name Forward iterators (only for debugging purpose)
180     //@{
181         /// Forward iterator
182         /**
183             The forward iterator for a split-list has the following features:
184             - it has no post-increment operator
185             - it depends on underlying ordered list iterator
186             - The iterator object cannot be moved across thread boundary because it contains GC's guard that is thread-private GC data.
187             - Iterator ensures thread-safety even if you delete the item that iterator points to. However, in case of concurrent
188               deleting operations it is no guarantee that you iterate all item in the split-list.
189               Moreover, a crash is possible when you try to iterate the next element that has been deleted by concurrent thread.
190
191               @warning Use this iterator on the concurrent container for debugging purpose only.
192
193               The iterator interface:
194               \code
195               class iterator {
196               public:
197                   // Default constructor
198                   iterator();
199
200                   // Copy construtor
201                   iterator( iterator const& src );
202
203                   // Dereference operator
204                   value_type * operator ->() const;
205
206                   // Dereference operator
207                   value_type& operator *() const;
208
209                   // Preincrement operator
210                   iterator& operator ++();
211
212                   // Assignment operator
213                   iterator& operator = (iterator const& src);
214
215                   // Equality operators
216                   bool operator ==(iterator const& i ) const;
217                   bool operator !=(iterator const& i ) const;
218               };
219               \endcode
220         */
221         typedef typename base_class::iterator iterator;
222
223         /// Const forward iterator
224         typedef typename base_class::const_iterator const_iterator;
225
226         /// Returns a forward iterator addressing the first element in a map
227         /**
228             For empty map \code begin() == end() \endcode
229         */
230         iterator begin()
231         {
232             return base_class::begin();
233         }
234
235         /// Returns an iterator that addresses the location succeeding the last element in a map
236         /**
237             Do not use the value returned by <tt>end</tt> function to access any item.
238             The returned value can be used only to control reaching the end of the map.
239             For empty map \code begin() == end() \endcode
240         */
241         iterator end()
242         {
243             return base_class::end();
244         }
245
246         /// Returns a forward const iterator addressing the first element in a map
247         const_iterator begin() const
248         {
249             return base_class::begin();
250         }
251
252         /// Returns a forward const iterator addressing the first element in a map
253         const_iterator cbegin() const
254         {
255             return base_class::cbegin();
256         }
257
258         /// Returns an const iterator that addresses the location succeeding the last element in a map
259         const_iterator end() const
260         {
261             return base_class::end();
262         }
263
264         /// Returns an const iterator that addresses the location succeeding the last element in a map
265         const_iterator cend() const
266         {
267             return base_class::cend();
268         }
269     //@}
270
271     public:
272         /// Initializes split-ordered map of default capacity
273         /**
274             The default capacity is defined in bucket table constructor.
275             See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_bucket_table
276             which selects by \p intrusive::split_list::traits::dynamic_bucket_table.
277         */
278         SplitListMap()
279             : base_class()
280         {}
281
282         /// Initializes split-ordered map
283         SplitListMap(
284             size_t nItemCount           ///< estimated average item count
285             , size_t nLoadFactor = 1    ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
286             )
287             : base_class( nItemCount, nLoadFactor )
288         {}
289
290     public:
291         /// Inserts new node with key and default value
292         /**
293             The function creates a node with \p key and default value, and then inserts the node created into the map.
294
295             Preconditions:
296             - The \ref key_type should be constructible from value of type \p K.
297                 In trivial case, \p K is equal to \ref key_type.
298             - The \ref mapped_type should be default-constructible.
299
300             Returns \p true if inserting successful, \p false otherwise.
301         */
302         template <typename K>
303         bool insert( K const& key )
304         {
305             //TODO: pass arguments by reference (make_pair makes copy)
306             return base_class::insert( std::make_pair( key, mapped_type()));
307         }
308
309         /// Inserts new node
310         /**
311             The function creates a node with copy of \p val value
312             and then inserts the node created into the map.
313
314             Preconditions:
315             - The \ref key_type should be constructible from \p key of type \p K.
316             - The \ref mapped_type should be constructible from \p val of type \p V.
317
318             Returns \p true if \p val is inserted into the map, \p false otherwise.
319         */
320         template <typename K, typename V>
321         bool insert( K const& key, V const& val )
322         {
323             //TODO: pass arguments by reference (make_pair makes copy)
324             return base_class::insert( std::make_pair(key, val));
325         }
326
327         /// Inserts new node and initialize it by a functor
328         /**
329             This function inserts new node with key \p key and if inserting is successful then it calls
330             \p func functor with signature
331             \code
332                 struct functor {
333                     void operator()( value_type& item );
334                 };
335             \endcode
336
337             The argument \p item of user-defined functor \p func is the reference
338             to the map's item inserted:
339                 - <tt>item.first</tt> is a const reference to item's key that cannot be changed.
340                 - <tt>item.second</tt> is a reference to item's value that may be changed.
341
342             It should be keep in mind that concurrent modifications of \p <tt>item.second</tt> may be possible.
343
344             The key_type should be constructible from value of type \p K.
345
346             The function allows to split creating of new item into two part:
347             - create item from \p key;
348             - insert new item into the map;
349             - if inserting is successful, initialize the value of item by calling \p func functor
350
351             This can be useful if complete initialization of object of \p mapped_type is heavyweight and
352             it is preferable that the initialization should be completed only if inserting is successful.
353
354             @warning For \ref cds_nonintrusive_MichaelKVList_gc "MichaelKVList" as the bucket see \ref cds_intrusive_item_creating "insert item troubleshooting".
355             \ref cds_nonintrusive_LazyKVList_gc "LazyKVList" provides exclusive access to inserted item and does not require any node-level
356             synchronization.
357         */
358         template <typename K, typename Func>
359         bool insert_with( K const& key, Func func )
360         {
361             //TODO: pass arguments by reference (make_pair makes copy)
362             return base_class::insert( std::make_pair( key, mapped_type()), func );
363         }
364
365         /// For key \p key inserts data of type \p mapped_type created from \p args
366         /**
367             \p key_type should be constructible from type \p K
368
369             Returns \p true if inserting successful, \p false otherwise.
370         */
371         template <typename K, typename... Args>
372         bool emplace( K&& key, Args&&... args )
373         {
374             return base_class::emplace( std::forward<K>(key), std::move(mapped_type(std::forward<Args>(args)...)));
375         }
376
377         /// Updates the node
378         /**
379             The operation performs inserting or changing data with lock-free manner.
380
381             If \p key is not found in the map, then \p key is inserted iff \p bAllowInsert is \p true.
382             Otherwise, the functor \p func is called with item found.
383
384             The functor signature is:
385             \code
386                 struct my_functor {
387                     void operator()( bool bNew, value_type& item );
388                 };
389             \endcode
390
391             with arguments:
392             - \p bNew - \p true if the item has been inserted, \p false otherwise
393             - \p item - item of the map
394
395             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
396             \p second is true if new item has been added or \p false if the item with \p key
397             already is in the map.
398
399             @warning For \ref cds_nonintrusive_MichaelKVList_gc "MichaelKVList" as the ordered list see \ref cds_intrusive_item_creating "insert item troubleshooting".
400             \ref cds_nonintrusive_LazyKVList_gc "LazyKVList" provides exclusive access to inserted item and does not require any node-level
401             synchronization.
402         */
403         template <typename K, typename Func>
404         std::pair<bool, bool> update( K const& key, Func func, bool bAllowInsert = true )
405         {
406             //TODO: pass arguments by reference (make_pair makes copy)
407             return base_class::update( std::make_pair( key, mapped_type()),
408                 [&func](bool bNew, value_type& item, value_type const& /*val*/) {
409                     func( bNew, item );
410                 },
411                 bAllowInsert );
412         }
413         //@cond
414         template <typename K, typename Func>
415         CDS_DEPRECATED("ensure() is deprecated, use update()")
416         std::pair<bool, bool> ensure( K const& key, Func func )
417         {
418             return update( key, func, true );
419         }
420         //@endcond
421
422         /// Deletes \p key from the map
423         /** \anchor cds_nonintrusive_SplitListMap_erase_val
424
425             Return \p true if \p key is found and deleted, \p false otherwise
426         */
427         template <typename K>
428         bool erase( K const& key )
429         {
430             return base_class::erase( key );
431         }
432
433         /// Deletes the item from the map using \p pred predicate for searching
434         /**
435             The function is an analog of \ref cds_nonintrusive_SplitListMap_erase_val "erase(K const&)"
436             but \p pred is used for key comparing.
437             \p Less functor has the interface like \p std::less.
438             \p Less must imply the same element order as the comparator used for building the map.
439         */
440         template <typename K, typename Less>
441         bool erase_with( K const& key, Less pred )
442         {
443             CDS_UNUSED( pred );
444             return base_class::erase_with( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
445         }
446
447         /// Deletes \p key from the map
448         /** \anchor cds_nonintrusive_SplitListMap_erase_func
449
450             The function searches an item with key \p key, calls \p f functor
451             and deletes the item. If \p key is not found, the functor is not called.
452
453             The functor \p Func interface is:
454             \code
455             struct extractor {
456                 void operator()(value_type& item) { ... }
457             };
458             \endcode
459
460             Return \p true if key is found and deleted, \p false otherwise
461         */
462         template <typename K, typename Func>
463         bool erase( K const& key, Func f )
464         {
465             return base_class::erase( key, f );
466         }
467
468         /// Deletes the item from the map using \p pred predicate for searching
469         /**
470             The function is an analog of \ref cds_nonintrusive_SplitListMap_erase_func "erase(K const&, Func)"
471             but \p pred is used for key comparing.
472             \p Less functor has the interface like \p std::less.
473             \p Less must imply the same element order as the comparator used for building the map.
474         */
475         template <typename K, typename Less, typename Func>
476         bool erase_with( K const& key, Less pred, Func f )
477         {
478             CDS_UNUSED( pred );
479             return base_class::erase_with( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>(), f );
480         }
481
482         /// Extracts the item with specified \p key
483         /** \anchor cds_nonintrusive_SplitListMap_hp_extract
484             The function searches an item with key equal to \p key,
485             unlinks it from the map, and returns it as \p guarded_ptr.
486             If \p key is not found the function returns an empty guarded pointer.
487
488             Note the compare functor should accept a parameter of type \p K that may be not the same as \p value_type.
489
490             The extracted item is freed automatically when returned \p guarded_ptr object will be destroyed or released.
491             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
492
493             Usage:
494             \code
495             typedef cds::container::SplitListMap< your_template_args > splitlist_map;
496             splitlist_map theMap;
497             // ...
498             {
499                 splitlist_map::guarded_ptr gp(theMap.extract( 5 ));
500                 if ( gp ) {
501                     // Deal with gp
502                     // ...
503                 }
504                 // Destructor of gp releases internal HP guard
505             }
506             \endcode
507         */
508         template <typename K>
509         guarded_ptr extract( K const& key )
510         {
511             guarded_ptr gp;
512             base_class::extract_( gp.guard(), key );
513             return gp;
514         }
515
516         /// Extracts the item using compare functor \p pred
517         /**
518             The function is an analog of \ref cds_nonintrusive_SplitListMap_hp_extract "extract(K const&)"
519             but \p pred predicate is used for key comparing.
520
521             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p K
522             in any order.
523             \p pred must imply the same element order as the comparator used for building the map.
524         */
525         template <typename K, typename Less>
526         guarded_ptr extract_with( K const& key, Less pred )
527         {
528             CDS_UNUSED( pred );
529             guarded_ptr gp;
530             base_class::extract_with_( gp.guard(), key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
531             return gp;
532         }
533
534         /// Finds the key \p key
535         /** \anchor cds_nonintrusive_SplitListMap_find_cfunc
536
537             The function searches the item with key equal to \p key and calls the functor \p f for item found.
538             The interface of \p Func functor is:
539             \code
540             struct functor {
541                 void operator()( value_type& item );
542             };
543             \endcode
544             where \p item is the item found.
545
546             The functor may change \p item.second. Note that the functor is only guarantee
547             that \p item cannot be disposed during functor is executing.
548             The functor does not serialize simultaneous access to the map's \p item. If such access is
549             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
550
551             The function returns \p true if \p key is found, \p false otherwise.
552         */
553         template <typename K, typename Func>
554         bool find( K const& key, Func f )
555         {
556             return base_class::find( key, [&f](value_type& pair, K const&){ f( pair ); } );
557         }
558
559         /// Finds the key \p val using \p pred predicate for searching
560         /**
561             The function is an analog of \ref cds_nonintrusive_SplitListMap_find_cfunc "find(K const&, Func)"
562             but \p pred is used for key comparing.
563             \p Less functor has the interface like \p std::less.
564             \p Less must imply the same element order as the comparator used for building the map.
565         */
566         template <typename K, typename Less, typename Func>
567         bool find_with( K const& key, Less pred, Func f )
568         {
569             CDS_UNUSED( pred );
570             return base_class::find_with( key,
571                 cds::details::predicate_wrapper<value_type, Less, key_accessor>(),
572                 [&f](value_type& pair, K const&){ f( pair ); } );
573         }
574
575         /// Checks whether the map contains \p key
576         /**
577             The function searches the item with key equal to \p key
578             and returns \p true if it is found, and \p false otherwise.
579
580             Note the hash functor specified for class \p Traits template parameter
581             should accept a parameter of type \p Q that can be not the same as \p value_type.
582             Otherwise, you may use \p contains( Q const&, Less pred ) functions with explicit predicate for key comparing.
583         */
584         template <typename K>
585         bool contains( K const& key )
586         {
587             return base_class::contains( key );
588         }
589         //@cond
590         template <typename K>
591         CDS_DEPRECATED("deprecated, use contains()")
592         bool find( K const& key )
593         {
594             return contains( key );
595         }
596         //@endcond
597
598         /// Checks whether the map contains \p key using \p pred predicate for searching
599         /**
600             The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
601             \p Less functor has the interface like \p std::less.
602             \p Less must imply the same element order as the comparator used for building the map.
603         */
604         template <typename K, typename Less>
605         bool contains( K const& key, Less pred )
606         {
607             CDS_UNUSED( pred );
608             return base_class::contains( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
609         }
610         //@cond
611         template <typename K, typename Less>
612         CDS_DEPRECATED("deprecated, use contains()")
613         bool find_with( K const& key, Less pred )
614         {
615             return contains( key, pred );
616         }
617         //@endcond
618
619         /// Finds \p key and return the item found
620         /** \anchor cds_nonintrusive_SplitListMap_hp_get
621             The function searches the item with key equal to \p key
622             and returns the item found as a guarded pointer.
623             If \p key is not found the function returns an empty guarded pointer.
624
625             @note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
626
627             Usage:
628             \code
629             typedef cds::container::SplitListMap< your_template_params >  splitlist_map;
630             splitlist_map theMap;
631             // ...
632             {
633                 splitlist_map::guarded_ptr gp(theMap.get( 5 ));
634                 if ( gp ) {
635                     // Deal with gp
636                     //...
637                 }
638                 // Destructor of guarded_ptr releases internal HP guard
639             }
640             \endcode
641
642             Note the compare functor specified for split-list map
643             should accept a parameter of type \p K that can be not the same as \p value_type.
644         */
645         template <typename K>
646         guarded_ptr get( K const& key )
647         {
648             guarded_ptr gp;
649             base_class::get_( gp.guard(), key );
650             return gp;
651         }
652
653         /// Finds \p key and return the item found
654         /**
655             The function is an analog of \ref cds_nonintrusive_SplitListMap_hp_get "get( K const&)"
656             but \p pred is used for comparing the keys.
657
658             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p K
659             in any order.
660             \p pred must imply the same element order as the comparator used for building the map.
661         */
662         template <typename K, typename Less>
663         guarded_ptr get_with( K const& key, Less pred )
664         {
665             CDS_UNUSED( pred );
666             guarded_ptr gp;
667             base_class::get_with_( gp.guard(), key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
668             return gp;
669         }
670
671         /// Clears the map (not atomic)
672         void clear()
673         {
674             base_class::clear();
675         }
676
677         /// Checks if the map is empty
678         /**
679             Emptiness is checked by item counting: if item count is zero then the map is empty.
680             Thus, the correct item counting is an important part of the map implementation.
681         */
682         bool empty() const
683         {
684             return base_class::empty();
685         }
686
687         /// Returns item count in the map
688         size_t size() const
689         {
690             return base_class::size();
691         }
692
693         /// Returns internal statistics
694         stat const& statistics() const
695         {
696             return base_class::statistics();
697         }
698     };
699
700
701 }} // namespace cds::container
702
703 #endif // #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_H