Merge pull request #63 from mgalimullin/cmake-update
[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         /// Count of hazard pointer required
169         static CDS_CONSTEXPR const size_t c_nHazardPtrCount = base_class::c_nHazardPtrCount;
170
171     protected:
172         //@cond
173         typedef typename base_class::maker::traits::key_accessor key_accessor;
174         typedef typename base_class::node_type node_type;
175         //@endcond
176
177     public:
178         /// Guarded pointer
179         typedef typename gc::template guarded_ptr< node_type, value_type, details::guarded_ptr_cast_set<node_type, value_type> > guarded_ptr;
180
181     public:
182     ///@name Forward iterators (only for debugging purpose)
183     //@{
184         /// Forward iterator
185         /**
186             The forward iterator for a split-list has the following features:
187             - it has no post-increment operator
188             - it depends on underlying ordered list iterator
189             - The iterator object cannot be moved across thread boundary because it contains GC's guard that is thread-private GC data.
190             - Iterator ensures thread-safety even if you delete the item that iterator points to. However, in case of concurrent
191               deleting operations it is no guarantee that you iterate all item in the split-list.
192               Moreover, a crash is possible when you try to iterate the next element that has been deleted by concurrent thread.
193
194               @warning Use this iterator on the concurrent container for debugging purpose only.
195
196               The iterator interface:
197               \code
198               class iterator {
199               public:
200                   // Default constructor
201                   iterator();
202
203                   // Copy construtor
204                   iterator( iterator const& src );
205
206                   // Dereference operator
207                   value_type * operator ->() const;
208
209                   // Dereference operator
210                   value_type& operator *() const;
211
212                   // Preincrement operator
213                   iterator& operator ++();
214
215                   // Assignment operator
216                   iterator& operator = (iterator const& src);
217
218                   // Equality operators
219                   bool operator ==(iterator const& i ) const;
220                   bool operator !=(iterator const& i ) const;
221               };
222               \endcode
223         */
224         typedef typename base_class::iterator iterator;
225
226         /// Const forward iterator
227         typedef typename base_class::const_iterator const_iterator;
228
229         /// Returns a forward iterator addressing the first element in a map
230         /**
231             For empty map \code begin() == end() \endcode
232         */
233         iterator begin()
234         {
235             return base_class::begin();
236         }
237
238         /// Returns an iterator that addresses the location succeeding the last element in a map
239         /**
240             Do not use the value returned by <tt>end</tt> function to access any item.
241             The returned value can be used only to control reaching the end of the map.
242             For empty map \code begin() == end() \endcode
243         */
244         iterator end()
245         {
246             return base_class::end();
247         }
248
249         /// Returns a forward const iterator addressing the first element in a map
250         const_iterator begin() const
251         {
252             return base_class::begin();
253         }
254
255         /// Returns a forward const iterator addressing the first element in a map
256         const_iterator cbegin() const
257         {
258             return base_class::cbegin();
259         }
260
261         /// Returns an const iterator that addresses the location succeeding the last element in a map
262         const_iterator end() const
263         {
264             return base_class::end();
265         }
266
267         /// Returns an const iterator that addresses the location succeeding the last element in a map
268         const_iterator cend() const
269         {
270             return base_class::cend();
271         }
272     //@}
273
274     public:
275         /// Initializes split-ordered map of default capacity
276         /**
277             The default capacity is defined in bucket table constructor.
278             See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_bucket_table
279             which selects by \p intrusive::split_list::traits::dynamic_bucket_table.
280         */
281         SplitListMap()
282             : base_class()
283         {}
284
285         /// Initializes split-ordered map
286         SplitListMap(
287             size_t nItemCount           ///< estimated average item count
288             , size_t nLoadFactor = 1    ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
289             )
290             : base_class( nItemCount, nLoadFactor )
291         {}
292
293     public:
294         /// Inserts new node with key and default value
295         /**
296             The function creates a node with \p key and default value, and then inserts the node created into the map.
297
298             Preconditions:
299             - The \ref key_type should be constructible from value of type \p K.
300                 In trivial case, \p K is equal to \ref key_type.
301             - The \ref mapped_type should be default-constructible.
302
303             Returns \p true if inserting successful, \p false otherwise.
304         */
305         template <typename K>
306         bool insert( K const& key )
307         {
308             return base_class::emplace( key_type( key ), mapped_type() );
309         }
310
311         /// Inserts new node
312         /**
313             The function creates a node with copy of \p val value
314             and then inserts the node created into the map.
315
316             Preconditions:
317             - The \ref key_type should be constructible from \p key of type \p K.
318             - The \ref mapped_type should be constructible from \p val of type \p V.
319
320             Returns \p true if \p val is inserted into the map, \p false otherwise.
321         */
322         template <typename K, typename V>
323         bool insert( K const& key, V const& val )
324         {
325             return base_class::emplace( key_type( key ), mapped_type( val ));
326         }
327
328         /// Inserts new node and initialize it by a functor
329         /**
330             This function inserts new node with key \p key and if inserting is successful then it calls
331             \p func functor with signature
332             \code
333                 struct functor {
334                     void operator()( value_type& item );
335                 };
336             \endcode
337
338             The argument \p item of user-defined functor \p func is the reference
339             to the map's item inserted:
340                 - <tt>item.first</tt> is a const reference to item's key that cannot be changed.
341                 - <tt>item.second</tt> is a reference to item's value that may be changed.
342
343             It should be keep in mind that concurrent modifications of \p <tt>item.second</tt> may be possible.
344
345             The key_type should be constructible from value of type \p K.
346
347             The function allows to split creating of new item into two part:
348             - create item from \p key;
349             - insert new item into the map;
350             - if inserting is successful, initialize the value of item by calling \p func functor
351
352             This can be useful if complete initialization of object of \p mapped_type is heavyweight and
353             it is preferable that the initialization should be completed only if inserting is successful.
354
355             @warning For \ref cds_nonintrusive_MichaelKVList_gc "MichaelKVList" as the bucket see \ref cds_intrusive_item_creating "insert item troubleshooting".
356             \ref cds_nonintrusive_LazyKVList_gc "LazyKVList" provides exclusive access to inserted item and does not require any node-level
357             synchronization.
358         */
359         template <typename K, typename Func>
360         bool insert_with( K const& key, Func func )
361         {
362             //TODO: pass arguments by reference (make_pair makes copy)
363             return base_class::insert( std::make_pair( key_type( key ), mapped_type()), func );
364         }
365
366         /// For key \p key inserts data of type \p mapped_type created from \p args
367         /**
368             \p key_type should be constructible from type \p K
369
370             Returns \p true if inserting successful, \p false otherwise.
371         */
372         template <typename K, typename... Args>
373         bool emplace( K&& key, Args&&... args )
374         {
375             return base_class::emplace( key_type( std::forward<K>(key)), mapped_type( std::forward<Args>(args)...));
376         }
377
378         /// Updates the node
379         /**
380             The operation performs inserting or changing data with lock-free manner.
381
382             If \p key is not found in the map, then \p key is inserted iff \p bAllowInsert is \p true.
383             Otherwise, the functor \p func is called with item found.
384
385             The functor signature is:
386             \code
387                 struct my_functor {
388                     void operator()( bool bNew, value_type& item );
389                 };
390             \endcode
391
392             with arguments:
393             - \p bNew - \p true if the item has been inserted, \p false otherwise
394             - \p item - item of the map
395
396             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successful,
397             \p second is true if new item has been added or \p false if the item with \p key
398             already is in the map.
399
400             @warning For \ref cds_nonintrusive_MichaelKVList_gc "MichaelKVList" as the ordered list see \ref cds_intrusive_item_creating "insert item troubleshooting".
401             \ref cds_nonintrusive_LazyKVList_gc "LazyKVList" provides exclusive access to inserted item and does not require any node-level
402             synchronization.
403         */
404         template <typename K, typename Func>
405         std::pair<bool, bool> update( K const& key, Func func, bool bAllowInsert = true )
406         {
407             //TODO: pass arguments by reference (make_pair makes copy)
408             typedef decltype( std::make_pair( key_type( key ), mapped_type() )) arg_pair_type;
409
410             return base_class::update( std::make_pair( key_type( key ), mapped_type()),
411                 [&func]( bool bNew, value_type& item, arg_pair_type const& /*val*/ ) {
412                     func( bNew, item );
413                 },
414                 bAllowInsert );
415         }
416         //@cond
417         template <typename K, typename Func>
418         CDS_DEPRECATED("ensure() is deprecated, use update()")
419         std::pair<bool, bool> ensure( K const& key, Func func )
420         {
421             return update( key, func, true );
422         }
423         //@endcond
424
425         /// Deletes \p key from the map
426         /** \anchor cds_nonintrusive_SplitListMap_erase_val
427
428             Return \p true if \p key is found and deleted, \p false otherwise
429         */
430         template <typename K>
431         bool erase( K const& key )
432         {
433             return base_class::erase( key );
434         }
435
436         /// Deletes the item from the map using \p pred predicate for searching
437         /**
438             The function is an analog of \ref cds_nonintrusive_SplitListMap_erase_val "erase(K const&)"
439             but \p pred is used for key comparing.
440             \p Less functor has the interface like \p std::less.
441             \p Less must imply the same element order as the comparator used for building the map.
442         */
443         template <typename K, typename Less>
444         bool erase_with( K const& key, Less pred )
445         {
446             CDS_UNUSED( pred );
447             return base_class::erase_with( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
448         }
449
450         /// Deletes \p key from the map
451         /** \anchor cds_nonintrusive_SplitListMap_erase_func
452
453             The function searches an item with key \p key, calls \p f functor
454             and deletes the item. If \p key is not found, the functor is not called.
455
456             The functor \p Func interface is:
457             \code
458             struct extractor {
459                 void operator()(value_type& item) { ... }
460             };
461             \endcode
462
463             Return \p true if key is found and deleted, \p false otherwise
464         */
465         template <typename K, typename Func>
466         bool erase( K const& key, Func f )
467         {
468             return base_class::erase( key, f );
469         }
470
471         /// Deletes the item from the map using \p pred predicate for searching
472         /**
473             The function is an analog of \ref cds_nonintrusive_SplitListMap_erase_func "erase(K const&, Func)"
474             but \p pred is used for key comparing.
475             \p Less functor has the interface like \p std::less.
476             \p Less must imply the same element order as the comparator used for building the map.
477         */
478         template <typename K, typename Less, typename Func>
479         bool erase_with( K const& key, Less pred, Func f )
480         {
481             CDS_UNUSED( pred );
482             return base_class::erase_with( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>(), f );
483         }
484
485         /// Extracts the item with specified \p key
486         /** \anchor cds_nonintrusive_SplitListMap_hp_extract
487             The function searches an item with key equal to \p key,
488             unlinks it from the map, and returns it as \p guarded_ptr.
489             If \p key is not found the function returns an empty guarded pointer.
490
491             Note the compare functor should accept a parameter of type \p K that may be not the same as \p value_type.
492
493             The extracted item is freed automatically when returned \p guarded_ptr object will be destroyed or released.
494             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
495
496             Usage:
497             \code
498             typedef cds::container::SplitListMap< your_template_args > splitlist_map;
499             splitlist_map theMap;
500             // ...
501             {
502                 splitlist_map::guarded_ptr gp(theMap.extract( 5 ));
503                 if ( gp ) {
504                     // Deal with gp
505                     // ...
506                 }
507                 // Destructor of gp releases internal HP guard
508             }
509             \endcode
510         */
511         template <typename K>
512         guarded_ptr extract( K const& key )
513         {
514             guarded_ptr gp;
515             base_class::extract_( gp.guard(), key );
516             return gp;
517         }
518
519         /// Extracts the item using compare functor \p pred
520         /**
521             The function is an analog of \ref cds_nonintrusive_SplitListMap_hp_extract "extract(K const&)"
522             but \p pred predicate is used for key comparing.
523
524             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p K
525             in any order.
526             \p pred must imply the same element order as the comparator used for building the map.
527         */
528         template <typename K, typename Less>
529         guarded_ptr extract_with( K const& key, Less pred )
530         {
531             CDS_UNUSED( pred );
532             guarded_ptr gp;
533             base_class::extract_with_( gp.guard(), key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
534             return gp;
535         }
536
537         /// Finds the key \p key
538         /** \anchor cds_nonintrusive_SplitListMap_find_cfunc
539
540             The function searches the item with key equal to \p key and calls the functor \p f for item found.
541             The interface of \p Func functor is:
542             \code
543             struct functor {
544                 void operator()( value_type& item );
545             };
546             \endcode
547             where \p item is the item found.
548
549             The functor may change \p item.second. Note that the functor is only guarantee
550             that \p item cannot be disposed during functor is executing.
551             The functor does not serialize simultaneous access to the map's \p item. If such access is
552             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
553
554             The function returns \p true if \p key is found, \p false otherwise.
555         */
556         template <typename K, typename Func>
557         bool find( K const& key, Func f )
558         {
559             return base_class::find( key, [&f](value_type& pair, K const&){ f( pair ); } );
560         }
561
562         /// Finds the key \p val using \p pred predicate for searching
563         /**
564             The function is an analog of \ref cds_nonintrusive_SplitListMap_find_cfunc "find(K const&, Func)"
565             but \p pred is used for key comparing.
566             \p Less functor has the interface like \p std::less.
567             \p Less must imply the same element order as the comparator used for building the map.
568         */
569         template <typename K, typename Less, typename Func>
570         bool find_with( K const& key, Less pred, Func f )
571         {
572             CDS_UNUSED( pred );
573             return base_class::find_with( key,
574                 cds::details::predicate_wrapper<value_type, Less, key_accessor>(),
575                 [&f](value_type& pair, K const&){ f( pair ); } );
576         }
577
578         /// Checks whether the map contains \p key
579         /**
580             The function searches the item with key equal to \p key
581             and returns \p true if it is found, and \p false otherwise.
582
583             Note the hash functor specified for class \p Traits template parameter
584             should accept a parameter of type \p Q that can be not the same as \p value_type.
585             Otherwise, you may use \p contains( Q const&, Less pred ) functions with explicit predicate for key comparing.
586         */
587         template <typename K>
588         bool contains( K const& key )
589         {
590             return base_class::contains( key );
591         }
592         //@cond
593         template <typename K>
594         CDS_DEPRECATED("deprecated, use contains()")
595         bool find( K const& key )
596         {
597             return contains( key );
598         }
599         //@endcond
600
601         /// Checks whether the map contains \p key using \p pred predicate for searching
602         /**
603             The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
604             \p Less functor has the interface like \p std::less.
605             \p Less must imply the same element order as the comparator used for building the map.
606         */
607         template <typename K, typename Less>
608         bool contains( K const& key, Less pred )
609         {
610             CDS_UNUSED( pred );
611             return base_class::contains( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
612         }
613         //@cond
614         template <typename K, typename Less>
615         CDS_DEPRECATED("deprecated, use contains()")
616         bool find_with( K const& key, Less pred )
617         {
618             return contains( key, pred );
619         }
620         //@endcond
621
622         /// Finds \p key and return the item found
623         /** \anchor cds_nonintrusive_SplitListMap_hp_get
624             The function searches the item with key equal to \p key
625             and returns the item found as a guarded pointer.
626             If \p key is not found the function returns an empty guarded pointer.
627
628             @note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
629
630             Usage:
631             \code
632             typedef cds::container::SplitListMap< your_template_params >  splitlist_map;
633             splitlist_map theMap;
634             // ...
635             {
636                 splitlist_map::guarded_ptr gp(theMap.get( 5 ));
637                 if ( gp ) {
638                     // Deal with gp
639                     //...
640                 }
641                 // Destructor of guarded_ptr releases internal HP guard
642             }
643             \endcode
644
645             Note the compare functor specified for split-list map
646             should accept a parameter of type \p K that can be not the same as \p value_type.
647         */
648         template <typename K>
649         guarded_ptr get( K const& key )
650         {
651             guarded_ptr gp;
652             base_class::get_( gp.guard(), key );
653             return gp;
654         }
655
656         /// Finds \p key and return the item found
657         /**
658             The function is an analog of \ref cds_nonintrusive_SplitListMap_hp_get "get( K const&)"
659             but \p pred is used for comparing the keys.
660
661             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p K
662             in any order.
663             \p pred must imply the same element order as the comparator used for building the map.
664         */
665         template <typename K, typename Less>
666         guarded_ptr get_with( K const& key, Less pred )
667         {
668             CDS_UNUSED( pred );
669             guarded_ptr gp;
670             base_class::get_with_( gp.guard(), key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
671             return gp;
672         }
673
674         /// Clears the map (not atomic)
675         void clear()
676         {
677             base_class::clear();
678         }
679
680         /// Checks if the map is empty
681         /**
682             Emptiness is checked by item counting: if item count is zero then the map is empty.
683             Thus, the correct item counting is an important part of the map implementation.
684         */
685         bool empty() const
686         {
687             return base_class::empty();
688         }
689
690         /// Returns item count in the map
691         size_t size() const
692         {
693             return base_class::size();
694         }
695
696         /// Returns internal statistics
697         stat const& statistics() const
698         {
699             return base_class::statistics();
700         }
701     };
702
703
704 }} // namespace cds::container
705
706 #endif // #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_H