Split up set2 unit test to reduce compiling time and memory
[libcds.git] / cds / container / split_list_map_nogc.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H
4 #define CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H
5
6 #include <cds/container/split_list_set_nogc.h>
7 #include <cds/details/binary_functor_wrapper.h>
8
9 namespace cds { namespace container {
10
11     /// Split-ordered list map (template specialization for gc::nogc)
12     /** @ingroup cds_nonintrusive_map
13         \anchor cds_nonintrusive_SplitListMap_nogc
14
15         This specialization is so-called append-only.
16         The map does not support the removal of list item.
17
18         See \ref cds_nonintrusive_SplitListMap_hp "SplitListMap" for description of template parameters.
19
20         @warning Many member functions return an iterator pointing to an item.
21         The iterator can be used to set up field of the item,
22         but you should provide an exclusive access to it,
23         see \ref cds_intrusive_item_creating "insert item troubleshooting".
24     */
25     template <
26         typename Key,
27         typename Value,
28 #ifdef CDS_DOXYGEN_INVOKED
29         class Traits = split_list::traits
30 #else
31         class Traits
32 #endif
33     >
34     class SplitListMap<cds::gc::nogc, Key, Value, Traits>:
35         protected container::SplitListSet<
36             cds::gc::nogc,
37             std::pair<Key const, Value>,
38             split_list::details::wrap_map_traits<Key, Value, Traits>
39         >
40     {
41         //@cond
42         typedef container::SplitListSet<
43             cds::gc::nogc,
44             std::pair<Key const, Value>,
45             split_list::details::wrap_map_traits<Key, Value, Traits>
46         > base_class;
47         //@endcond
48     public:
49         typedef cds::gc::nogc gc;          ///< Garbage collector
50         typedef Key           key_type;    ///< key type
51         typedef Value         mapped_type; ///< type of value stored in the map
52
53         typedef std::pair<key_type const, mapped_type>  value_type  ;   ///< Pair type
54         typedef typename base_class::ordered_list       ordered_list;   ///< Underlying ordered list class
55         typedef typename base_class::key_comparator     key_comparator; ///< key comparison functor
56
57         typedef typename base_class::hash           hash;         ///< Hash functor for \ref key_type
58         typedef typename base_class::item_counter   item_counter; ///< Item counter type
59         typedef typename base_class::stat           stat;         ///< Internal statistics
60
61         //@cond
62         typedef cds::container::split_list::implementation_tag implementation_tag;
63         //@endcond
64
65     protected:
66         //@cond
67         typedef typename base_class::traits::key_accessor key_accessor;
68         //@endcond
69
70     public:
71         /// Forward iterator (see \p SplitListSet::iterator)
72         /**
73             Remember, the iterator <tt>operator -> </tt> and <tt>operator *</tt> returns \ref value_type pointer and reference.
74             To access item key and value use <tt>it->first</tt> and <tt>it->second</tt> respectively.
75         */
76         typedef typename base_class::iterator iterator;
77
78         /// Const forward iterator (see SplitListSet::const_iterator)
79         typedef typename base_class::const_iterator const_iterator;
80
81         /// Returns a forward iterator addressing the first element in a map
82         /**
83             For empty set \code begin() == end() \endcode
84         */
85         iterator begin()
86         {
87             return base_class::begin();
88         }
89
90         /// Returns an iterator that addresses the location succeeding the last element in a map
91         /**
92             Do not use the value returned by <tt>end</tt> function to access any item.
93             The returned value can be used only to control reaching the end of the set.
94             For empty set \code begin() == end() \endcode
95         */
96         iterator end()
97         {
98             return base_class::end();
99         }
100
101         /// Returns a forward const iterator addressing the first element in a map
102         //@{
103         const_iterator begin() const
104         {
105             return base_class::begin();
106         }
107         const_iterator cbegin() const
108         {
109             return base_class::cbegin();
110         }
111         //@}
112
113         /// Returns an const iterator that addresses the location succeeding the last element in a map
114         //@{
115         const_iterator end() const
116         {
117             return base_class::end();
118         }
119         const_iterator cend() const
120         {
121             return base_class::cend();
122         }
123         //@}
124
125     public:
126         /// Initialize split-ordered map of default capacity
127         /**
128             The default capacity is defined in bucket table constructor.
129             See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_ducket_table
130             which selects by \p intrusive::split_list::traits::dynamic_bucket_table.
131         */
132         SplitListMap()
133             : base_class()
134         {}
135
136         /// Initialize split-ordered map
137         SplitListMap(
138             size_t nItemCount           ///< estimated average item count
139             , size_t nLoadFactor = 1    ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
140             )
141             : base_class( nItemCount, nLoadFactor )
142         {}
143
144     public:
145         /// Inserts new node with key and default value
146         /**
147             The function creates a node with \p key and default value, and then inserts the node created into the map.
148
149             Preconditions:
150             - The \p key_type should be constructible from value of type \p K.
151                 In trivial case, \p K is equal to \ref key_type.
152             - The \p mapped_type should be default-constructible.
153
154             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
155         */
156         template <typename K>
157         iterator insert( K const& key )
158         {
159             //TODO: pass arguments by reference (make_pair makes copy)
160             return base_class::insert( std::make_pair( key, mapped_type() ) );
161         }
162
163         /// Inserts new node
164         /**
165             The function creates a node with copy of \p val value
166             and then inserts the node created into the map.
167
168             Preconditions:
169             - The \p key_type should be constructible from \p key of type \p K.
170             - The \p mapped_type should be constructible from \p val of type \p V.
171
172             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
173         */
174         template <typename K, typename V>
175         iterator insert( K const& key, V const& val )
176         {
177             //TODO: pass arguments by reference (make_pair makes copy)
178             return base_class::insert( std::make_pair( key, val ) );
179         }
180
181         /// Inserts new node and initialize it by a functor
182         /**
183             This function inserts new node with key \p key and if inserting is successful then it calls
184             \p func functor with signature
185             \code
186             struct functor {
187                 void operator()( value_type& item );
188             };
189             \endcode
190
191             The argument \p item of user-defined functor \p func is the reference
192             to the map's item inserted. \p item.second is a reference to item's value that may be changed.
193             User-defined functor \p func should guarantee that during changing item's value no any other changes
194             could be made on this map's item by concurrent threads.
195             The user-defined functor is called only if the inserting is successful.
196
197             The \p key_type should be constructible from value of type \p K.
198
199             The function allows to split creating of new item into two part:
200             - create item from \p key;
201             - insert new item into the map;
202             - if inserting is successful, initialize the value of item by calling \p f functor
203
204             This can be useful if complete initialization of object of \p mapped_type is heavyweight and
205             it is preferable that the initialization should be completed only if inserting is successful.
206
207             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
208         */
209         template <typename K, typename Func>
210         iterator insert_with( const K& key, Func func )
211         {
212             iterator it = insert( key );
213             if ( it != end() )
214                 func( (*it) );
215             return it;
216         }
217
218         /// For key \p key inserts data of type \p mapped_type created in-place from \p args
219         /**
220             \p key_type should be constructible from type \p K
221
222             Returns \p true if inserting successful, \p false otherwise.
223         */
224         template <typename K, typename... Args>
225         iterator emplace( K&& key, Args&&... args )
226         {
227             return base_class::emplace( std::forward<K>(key), std::move(mapped_type(std::forward<Args>(args)...)));
228         }
229
230         /// Ensures that the key \p key exists in the map
231         /**
232             The operation inserts new item if the key \p key is not found in the map.
233             Otherwise, the function returns an iterator that points to item found.
234
235             Returns <tt> std::pair<iterator, bool>  </tt> where \p first is an iterator pointing to
236             item found or inserted, \p second is true if new item has been added or \p false if the item
237             already is in the list.
238         */
239         template <typename K>
240         std::pair<iterator, bool> ensure( K const& key )
241         {
242             //TODO: pass arguments by reference (make_pair makes copy)
243             return base_class::ensure( std::make_pair( key, mapped_type() ));
244         }
245
246         /// Find the key \p key
247         /** \anchor cds_nonintrusive_SplitListMap_nogc_find
248
249             The function searches the item with key equal to \p key
250             and returns an iterator pointed to item found if the key is found,
251             and \p end() otherwise
252         */
253         template <typename K>
254         iterator find( K const& key )
255         {
256             return base_class::find( key );
257         }
258
259         /// Finds the key \p key using \p pred predicate for searching
260         /**
261             The function is an analog of \ref cds_nonintrusive_SplitListMap_nogc_find "find(K const&)"
262             but \p pred is used for key comparing.
263             \p Less functor has the interface like \p std::less.
264             \p Less must imply the same element order as the comparator used for building the map.
265         */
266         template <typename K, typename Less>
267         iterator find_with( K const& key, Less pred )
268         {
269             CDS_UNUSED( pred );
270             return base_class::find_with( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>() );
271         }
272
273         /// Checks if the map is empty
274         /**
275             Emptiness is checked by item counting: if item count is zero then the map is empty.
276             Thus, the correct item counting feature is an important part of Michael's map implementation.
277         */
278         bool empty() const
279         {
280             return base_class::empty();
281         }
282
283         /// Returns item count in the map
284         size_t size() const
285         {
286             return base_class::size();
287         }
288
289         /// Returns internal statistics
290         stat const& statistics() const
291         {
292             return base_class::statistics();
293         }
294     };
295 }}  // namespace cds::container
296
297
298 #endif // #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H