d230b77b35f49af49d284e3b98bdfb9e1ff0890f
[libcds.git] / cds / container / split_list_map_nogc.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_SPLIT_LIST_MAP_NOGC_H
4 #define __CDS_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
60     protected:
61         //@cond
62         typedef typename base_class::options::traits::key_accessor key_accessor;
63         //@endcond
64
65     public:
66         /// Forward iterator (see \p SplitListSet::iterator)
67         /**
68             Remember, the iterator <tt>operator -> </tt> and <tt>operator *</tt> returns \ref value_type pointer and reference.
69             To access item key and value use <tt>it->first</tt> and <tt>it->second</tt> respectively.
70         */
71         typedef typename base_class::iterator iterator;
72
73         /// Const forward iterator (see SplitListSet::const_iterator)
74         typedef typename base_class::const_iterator const_iterator;
75
76         /// Returns a forward iterator addressing the first element in a map
77         /**
78             For empty set \code begin() == end() \endcode
79         */
80         iterator begin()
81         {
82             return base_class::begin();
83         }
84
85         /// Returns an iterator that addresses the location succeeding the last element in a map
86         /**
87             Do not use the value returned by <tt>end</tt> function to access any item.
88             The returned value can be used only to control reaching the end of the set.
89             For empty set \code begin() == end() \endcode
90         */
91         iterator end()
92         {
93             return base_class::end();
94         }
95
96         /// Returns a forward const iterator addressing the first element in a map
97         //@{
98         const_iterator begin() const
99         {
100             return base_class::begin();
101         }
102         const_iterator cbegin()
103         {
104             return base_class::cbegin();
105         }
106         //@}
107
108         /// Returns an const iterator that addresses the location succeeding the last element in a map
109         //@{
110         const_iterator end() const
111         {
112             return base_class::end();
113         }
114         const_iterator cend()
115         {
116             return base_class::cend();
117         }
118         //@}
119
120     public:
121         /// Initialize split-ordered map of default capacity
122         /**
123             The default capacity is defined in bucket table constructor.
124             See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_ducket_table
125             which selects by \p intrusive::split_list::traits::dynamic_bucket_table.
126         */
127         SplitListMap()
128             : base_class()
129         {}
130
131         /// Initialize split-ordered map
132         SplitListMap(
133             size_t nItemCount           ///< estimated average item count
134             , size_t nLoadFactor = 1    ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
135             )
136             : base_class( nItemCount, nLoadFactor )
137         {}
138
139     public:
140         /// Inserts new node with key and default value
141         /**
142             The function creates a node with \p key and default value, and then inserts the node created into the map.
143
144             Preconditions:
145             - The \p key_type should be constructible from value of type \p K.
146                 In trivial case, \p K is equal to \ref key_type.
147             - The \p mapped_type should be default-constructible.
148
149             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
150         */
151         template <typename K>
152         iterator insert( K const& key )
153         {
154             //TODO: pass arguments by reference (make_pair makes copy)
155             return base_class::insert( std::make_pair( key, mapped_type() ) );
156         }
157
158         /// Inserts new node
159         /**
160             The function creates a node with copy of \p val value
161             and then inserts the node created into the map.
162
163             Preconditions:
164             - The \p key_type should be constructible from \p key of type \p K.
165             - The \p mapped_type should be constructible from \p val of type \p V.
166
167             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
168         */
169         template <typename K, typename V>
170         iterator insert( K const& key, V const& val )
171         {
172             //TODO: pass arguments by reference (make_pair makes copy)
173             return base_class::insert( std::make_pair( key, val ) );
174         }
175
176         /// Inserts new node and initialize it by a functor
177         /**
178             This function inserts new node with key \p key and if inserting is successful then it calls
179             \p func functor with signature
180             \code
181             struct functor {
182                 void operator()( value_type& item );
183             };
184             \endcode
185
186             The argument \p item of user-defined functor \p func is the reference
187             to the map's item inserted. \p item.second is a reference to item's value that may be changed.
188             User-defined functor \p func should guarantee that during changing item's value no any other changes
189             could be made on this map's item by concurrent threads.
190             The user-defined functor is called only if the inserting is successful.
191
192             The \p key_type should be constructible from value of type \p K.
193
194             The function allows to split creating of new item into two part:
195             - create item from \p key;
196             - insert new item into the map;
197             - if inserting is successful, initialize the value of item by calling \p f functor
198
199             This can be useful if complete initialization of object of \p mapped_type is heavyweight and
200             it is preferable that the initialization should be completed only if inserting is successful.
201
202             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
203         */
204         template <typename K, typename Func>
205         iterator insert_key( const K& key, Func func )
206         {
207             iterator it = insert( key );
208             if ( it != end() )
209                 func( (*it) );
210             return it;
211         }
212
213         /// For key \p key inserts data of type \p mapped_type created in-place from \p args
214         /**
215             \p key_type should be constructible from type \p K
216
217             Returns \p true if inserting successful, \p false otherwise.
218         */
219         template <typename K, typename... Args>
220         iterator emplace( K&& key, Args&&... args )
221         {
222             return base_class::emplace( std::forward<K>(key), std::move(mapped_type(std::forward<Args>(args)...)));
223         }
224
225         /// Ensures that the key \p key exists in the map
226         /**
227             The operation inserts new item if the key \p key is not found in the map.
228             Otherwise, the function returns an iterator that points to item found.
229
230             Returns <tt> std::pair<iterator, bool>  </tt> where \p first is an iterator pointing to
231             item found or inserted, \p second is true if new item has been added or \p false if the item
232             already is in the list.
233         */
234         template <typename K>
235         std::pair<iterator, bool> ensure( K const& key )
236         {
237             //TODO: pass arguments by reference (make_pair makes copy)
238             return base_class::ensure( std::make_pair( key, mapped_type() ));
239         }
240
241         /// Find the key \p key
242         /** \anchor cds_nonintrusive_SplitListMap_nogc_find
243
244             The function searches the item with key equal to \p key
245             and returns an iterator pointed to item found if the key is found,
246             and \p end() otherwise
247         */
248         template <typename K>
249         iterator find( K const& key )
250         {
251             return base_class::find( key );
252         }
253
254         /// Finds the key \p key using \p pred predicate for searching
255         /**
256             The function is an analog of \ref cds_nonintrusive_SplitListMap_nogc_find "find(K const&)"
257             but \p pred is used for key comparing.
258             \p Less functor has the interface like \p std::less.
259             \p Less must imply the same element order as the comparator used for building the map.
260         */
261         template <typename K, typename Less>
262         iterator find_with( K const& key, Less pred )
263         {
264             return base_class::find_with( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>() );
265         }
266
267         /// Checks if the map is empty
268         /**
269             Emptiness is checked by item counting: if item count is zero then the map is empty.
270             Thus, the correct item counting feature is an important part of Michael's map implementation.
271         */
272         bool empty() const
273         {
274             return base_class::empty();
275         }
276
277         /// Returns item count in the map
278         size_t size() const
279         {
280             return base_class::size();
281         }
282     };
283 }}  // namespace cds::container
284
285
286 #endif // #ifndef __CDS_CONTAINER_SPLIT_LIST_MAP_NOGC_H