Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/container/map.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
1 ////////////////////////////////////////////////////////////////////////////// | 1 ////////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost | 3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost |
4 // Software License, Version 1.0. (See accompanying file | 4 // Software License, Version 1.0. (See accompanying file |
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 // | 6 // |
7 // See http://www.boost.org/libs/container for documentation. | 7 // See http://www.boost.org/libs/container for documentation. |
8 // | 8 // |
9 ////////////////////////////////////////////////////////////////////////////// | 9 ////////////////////////////////////////////////////////////////////////////// |
10 | |
11 #ifndef BOOST_CONTAINER_MAP_HPP | 10 #ifndef BOOST_CONTAINER_MAP_HPP |
12 #define BOOST_CONTAINER_MAP_HPP | 11 #define BOOST_CONTAINER_MAP_HPP |
13 | 12 |
14 #if defined(_MSC_VER) | 13 #ifndef BOOST_CONFIG_HPP |
14 # include <boost/config.hpp> | |
15 #endif | |
16 | |
17 #if defined(BOOST_HAS_PRAGMA_ONCE) | |
15 # pragma once | 18 # pragma once |
16 #endif | 19 #endif |
17 | 20 |
18 #include <boost/container/detail/config_begin.hpp> | 21 #include <boost/container/detail/config_begin.hpp> |
19 #include <boost/container/detail/workaround.hpp> | 22 #include <boost/container/detail/workaround.hpp> |
20 | 23 |
24 // container | |
21 #include <boost/container/container_fwd.hpp> | 25 #include <boost/container/container_fwd.hpp> |
22 #include <utility> | 26 #include <boost/container/new_allocator.hpp> //new_allocator |
23 #include <functional> | 27 #include <boost/container/throw_exception.hpp> |
24 #include <memory> | 28 // container/detail |
29 #include <boost/container/detail/mpl.hpp> | |
25 #include <boost/container/detail/tree.hpp> | 30 #include <boost/container/detail/tree.hpp> |
31 #include <boost/container/detail/type_traits.hpp> | |
26 #include <boost/container/detail/value_init.hpp> | 32 #include <boost/container/detail/value_init.hpp> |
27 #include <boost/type_traits/has_trivial_destructor.hpp> | |
28 #include <boost/container/detail/mpl.hpp> | |
29 #include <boost/container/detail/utilities.hpp> | |
30 #include <boost/container/detail/pair.hpp> | 33 #include <boost/container/detail/pair.hpp> |
31 #include <boost/container/detail/type_traits.hpp> | 34 // move |
32 #include <boost/container/throw_exception.hpp> | 35 #include <boost/move/traits.hpp> |
33 #include <boost/move/utility.hpp> | 36 #include <boost/move/utility_core.hpp> |
37 // move/detail | |
38 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
39 #include <boost/move/detail/fwd_macros.hpp> | |
40 #endif | |
34 #include <boost/move/detail/move_helpers.hpp> | 41 #include <boost/move/detail/move_helpers.hpp> |
42 // intrusive/detail | |
43 #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair | |
44 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal | |
45 // other | |
35 #include <boost/static_assert.hpp> | 46 #include <boost/static_assert.hpp> |
36 #include <boost/container/detail/value_init.hpp> | 47 #include <boost/core/no_exceptions_support.hpp> |
37 #include <boost/detail/no_exceptions_support.hpp> | 48 // std |
49 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
50 #include <initializer_list> | |
51 #endif | |
38 | 52 |
39 namespace boost { | 53 namespace boost { |
40 namespace container { | 54 namespace container { |
41 | 55 |
42 /// @cond | 56 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED |
43 // Forward declarations of operators == and <, needed for friend declarations. | |
44 template <class Key, class T, class Compare, class Allocator> | |
45 inline bool operator==(const map<Key,T,Compare,Allocator>& x, | |
46 const map<Key,T,Compare,Allocator>& y); | |
47 | |
48 template <class Key, class T, class Compare, class Allocator> | |
49 inline bool operator<(const map<Key,T,Compare,Allocator>& x, | |
50 const map<Key,T,Compare,Allocator>& y); | |
51 /// @endcond | |
52 | 57 |
53 //! A map is a kind of associative container that supports unique keys (contains at | 58 //! A map is a kind of associative container that supports unique keys (contains at |
54 //! most one of each key value) and provides for fast retrieval of values of another | 59 //! most one of each key value) and provides for fast retrieval of values of another |
55 //! type T based on the keys. The map class supports bidirectional iterators. | 60 //! type T based on the keys. The map class supports bidirectional iterators. |
56 //! | 61 //! |
57 //! A map satisfies all of the requirements of a container and of a reversible | 62 //! A map satisfies all of the requirements of a container and of a reversible |
58 //! container and of an associative container. For a | 63 //! container and of an associative container. The <code>value_type</code> stored |
59 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>. | 64 //! by this container is the value_type is std::pair<const Key, T>. |
60 //! | 65 //! |
61 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). | 66 //! \tparam Key is the key_type of the map |
62 //! | 67 //! \tparam T is the <code>mapped_type</code> |
63 //! Allocator is the allocator to allocate the value_types | 68 //! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). |
64 //! (e.g. <i>allocator< std::pair<const Key, T> > </i>). | 69 //! \tparam Allocator is the allocator to allocate the <code>value_type</code>s |
65 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | 70 //! (e.g. <i>allocator< std::pair<const Key, T> > </i>). |
66 template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > > | 71 //! \tparam MapOptions is an packed option type generated using using boost::container::tree_assoc_options. |
72 template < class Key, class T, class Compare = std::less<Key> | |
73 , class Allocator = new_allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults > | |
67 #else | 74 #else |
68 template <class Key, class T, class Compare, class Allocator> | 75 template <class Key, class T, class Compare, class Allocator, class MapOptions> |
69 #endif | 76 #endif |
70 class map | 77 class map |
78 ///@cond | |
79 : public container_detail::tree | |
80 < Key, std::pair<const Key, T> | |
81 , container_detail::select1st< std::pair<const Key, T> > | |
82 , Compare, Allocator, MapOptions> | |
83 ///@endcond | |
71 { | 84 { |
72 /// @cond | 85 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED |
73 private: | 86 private: |
74 BOOST_COPYABLE_AND_MOVABLE(map) | 87 BOOST_COPYABLE_AND_MOVABLE(map) |
75 | 88 |
76 typedef std::pair<const Key, T> value_type_impl; | 89 typedef std::pair<const Key, T> value_type_impl; |
77 typedef container_detail::rbtree | 90 typedef container_detail::tree |
78 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t; | 91 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, MapOptions> base_t; |
79 typedef container_detail::pair <Key, T> movable_value_type_impl; | 92 typedef container_detail::pair <Key, T> movable_value_type_impl; |
80 typedef container_detail::tree_value_compare | 93 typedef container_detail::tree_value_compare |
81 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> | 94 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> |
82 > value_compare_impl; | 95 > value_compare_impl; |
83 tree_t m_tree; // red-black tree representing map | 96 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED |
84 /// @endcond | 97 |
98 public: | |
99 ////////////////////////////////////////////// | |
100 // | |
101 // types | |
102 // | |
103 ////////////////////////////////////////////// | |
104 | |
105 typedef Key key_type; | |
106 typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type; | |
107 typedef T mapped_type; | |
108 typedef std::pair<const Key, T> value_type; | |
109 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; | |
110 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; | |
111 typedef typename boost::container::allocator_traits<Allocator>::reference reference; | |
112 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; | |
113 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; | |
114 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; | |
115 typedef Allocator allocator_type; | |
116 typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; | |
117 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; | |
118 typedef Compare key_compare; | |
119 typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; | |
120 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; | |
121 typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; | |
122 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; | |
123 typedef std::pair<key_type, mapped_type> nonconst_value_type; | |
124 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; | |
125 | |
126 ////////////////////////////////////////////// | |
127 // | |
128 // construct/copy/destroy | |
129 // | |
130 ////////////////////////////////////////////// | |
131 | |
132 //! <b>Effects</b>: Default constructs an empty map. | |
133 //! | |
134 //! <b>Complexity</b>: Constant. | |
135 map() | |
136 : base_t() | |
137 { | |
138 //A type must be std::pair<CONST Key, T> | |
139 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
140 } | |
141 | |
142 //! <b>Effects</b>: Constructs an empty map using the specified comparison object | |
143 //! and allocator. | |
144 //! | |
145 //! <b>Complexity</b>: Constant. | |
146 explicit map(const Compare& comp, const allocator_type& a = allocator_type()) | |
147 : base_t(comp, a) | |
148 { | |
149 //A type must be std::pair<CONST Key, T> | |
150 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
151 } | |
152 | |
153 //! <b>Effects</b>: Constructs an empty map using the specified allocator. | |
154 //! | |
155 //! <b>Complexity</b>: Constant. | |
156 explicit map(const allocator_type& a) | |
157 : base_t(a) | |
158 { | |
159 //A type must be std::pair<CONST Key, T> | |
160 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
161 } | |
162 | |
163 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and | |
164 //! allocator, and inserts elements from the range [first ,last ). | |
165 //! | |
166 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
167 //! comp and otherwise N logN, where N is last - first. | |
168 template <class InputIterator> | |
169 map(InputIterator first, InputIterator last, const Compare& comp = Compare(), | |
170 const allocator_type& a = allocator_type()) | |
171 : base_t(true, first, last, comp, a) | |
172 { | |
173 //A type must be std::pair<CONST Key, T> | |
174 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
175 } | |
176 | |
177 //! <b>Effects</b>: Constructs an empty map using the specified | |
178 //! allocator, and inserts elements from the range [first ,last ). | |
179 //! | |
180 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
181 //! comp and otherwise N logN, where N is last - first. | |
182 template <class InputIterator> | |
183 map(InputIterator first, InputIterator last, const allocator_type& a) | |
184 : base_t(true, first, last, Compare(), a) | |
185 { | |
186 //A type must be std::pair<CONST Key, T> | |
187 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
188 } | |
189 | |
190 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and | |
191 //! allocator, and inserts elements from the ordered unique range [first ,last). This function | |
192 //! is more efficient than the normal range creation for ordered ranges. | |
193 //! | |
194 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be | |
195 //! unique values. | |
196 //! | |
197 //! <b>Complexity</b>: Linear in N. | |
198 //! | |
199 //! <b>Note</b>: Non-standard extension. | |
200 template <class InputIterator> | |
201 map( ordered_unique_range_t, InputIterator first, InputIterator last | |
202 , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) | |
203 : base_t(ordered_range, first, last, comp, a) | |
204 { | |
205 //A type must be std::pair<CONST Key, T> | |
206 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
207 } | |
208 | |
209 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
210 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and | |
211 //! allocator, and inserts elements from the range [il.begin(), il.end()). | |
212 //! | |
213 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
214 //! comp and otherwise N logN, where N is il.first() - il.end(). | |
215 map(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) | |
216 : base_t(true, il.begin(), il.end(), comp, a) | |
217 { | |
218 //A type must be std::pair<CONST Key, T> | |
219 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
220 } | |
221 | |
222 //! <b>Effects</b>: Constructs an empty map using the specified | |
223 //! allocator, and inserts elements from the range [il.begin(), il.end()). | |
224 //! | |
225 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
226 //! comp and otherwise N logN, where N is il.first() - il.end(). | |
227 map(std::initializer_list<value_type> il, const allocator_type& a) | |
228 : base_t(true, il.begin(), il.end(), Compare(), a) | |
229 { | |
230 //A type must be std::pair<CONST Key, T> | |
231 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
232 } | |
233 | |
234 //! <b>Effects</b>: Constructs an empty set using the specified comparison object and | |
235 //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function | |
236 //! is more efficient than the normal range creation for ordered ranges. | |
237 //! | |
238 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be | |
239 //! unique values. | |
240 //! | |
241 //! <b>Complexity</b>: Linear in N. | |
242 //! | |
243 //! <b>Note</b>: Non-standard extension. | |
244 map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), | |
245 const allocator_type& a = allocator_type()) | |
246 : base_t(ordered_range, il.begin(), il.end(), comp, a) | |
247 { | |
248 //A type must be std::pair<CONST Key, T> | |
249 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
250 } | |
251 #endif | |
252 | |
253 //! <b>Effects</b>: Copy constructs a map. | |
254 //! | |
255 //! <b>Complexity</b>: Linear in x.size(). | |
256 map(const map& x) | |
257 : base_t(static_cast<const base_t&>(x)) | |
258 { | |
259 //A type must be std::pair<CONST Key, T> | |
260 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
261 } | |
262 | |
263 //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources. | |
264 //! | |
265 //! <b>Complexity</b>: Constant. | |
266 //! | |
267 //! <b>Postcondition</b>: x is emptied. | |
268 map(BOOST_RV_REF(map) x) | |
269 : base_t(BOOST_MOVE_BASE(base_t, x)) | |
270 { | |
271 //A type must be std::pair<CONST Key, T> | |
272 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
273 } | |
274 | |
275 //! <b>Effects</b>: Copy constructs a map using the specified allocator. | |
276 //! | |
277 //! <b>Complexity</b>: Linear in x.size(). | |
278 map(const map& x, const allocator_type &a) | |
279 : base_t(static_cast<const base_t&>(x), a) | |
280 { | |
281 //A type must be std::pair<CONST Key, T> | |
282 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
283 } | |
284 | |
285 //! <b>Effects</b>: Move constructs a map using the specified allocator. | |
286 //! Constructs *this using x's resources. | |
287 //! | |
288 //! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise. | |
289 //! | |
290 //! <b>Postcondition</b>: x is emptied. | |
291 map(BOOST_RV_REF(map) x, const allocator_type &a) | |
292 : base_t(BOOST_MOVE_BASE(base_t, x), a) | |
293 { | |
294 //A type must be std::pair<CONST Key, T> | |
295 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
296 } | |
297 | |
298 //! <b>Effects</b>: Makes *this a copy of x. | |
299 //! | |
300 //! <b>Complexity</b>: Linear in x.size(). | |
301 map& operator=(BOOST_COPY_ASSIGN_REF(map) x) | |
302 { return static_cast<map&>(this->base_t::operator=(static_cast<const base_t&>(x))); } | |
303 | |
304 //! <b>Effects</b>: this->swap(x.get()). | |
305 //! | |
306 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment | |
307 //! is false and (allocation throws or value_type's move constructor throws) | |
308 //! | |
309 //! <b>Complexity</b>: Constant if allocator_traits_type:: | |
310 //! propagate_on_container_move_assignment is true or | |
311 //! this->get>allocator() == x.get_allocator(). Linear otherwise. | |
312 map& operator=(BOOST_RV_REF(map) x) | |
313 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value | |
314 && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value ) | |
315 | |
316 { return static_cast<map&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } | |
317 | |
318 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
319 //! <b>Effects</b>: Assign content of il to *this. | |
320 //! | |
321 map& operator=(std::initializer_list<value_type> il) | |
322 { | |
323 this->clear(); | |
324 insert(il.begin(), il.end()); | |
325 return *this; | |
326 } | |
327 #endif | |
328 | |
329 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
330 | |
331 //! <b>Effects</b>: Returns a copy of the allocator that | |
332 //! was passed to the object's constructor. | |
333 //! | |
334 //! <b>Complexity</b>: Constant. | |
335 allocator_type get_allocator() const; | |
336 | |
337 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
338 //! | |
339 //! <b>Throws</b>: Nothing | |
340 //! | |
341 //! <b>Complexity</b>: Constant. | |
342 //! | |
343 //! <b>Note</b>: Non-standard extension. | |
344 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW; | |
345 | |
346 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
347 //! | |
348 //! <b>Throws</b>: Nothing | |
349 //! | |
350 //! <b>Complexity</b>: Constant. | |
351 //! | |
352 //! <b>Note</b>: Non-standard extension. | |
353 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; | |
354 | |
355 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. | |
356 //! | |
357 //! <b>Throws</b>: Nothing. | |
358 //! | |
359 //! <b>Complexity</b>: Constant. | |
360 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW; | |
361 | |
362 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
363 //! | |
364 //! <b>Throws</b>: Nothing. | |
365 //! | |
366 //! <b>Complexity</b>: Constant. | |
367 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW; | |
368 | |
369 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
370 //! | |
371 //! <b>Throws</b>: Nothing. | |
372 //! | |
373 //! <b>Complexity</b>: Constant. | |
374 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW; | |
375 | |
376 //! <b>Effects</b>: Returns an iterator to the end of the container. | |
377 //! | |
378 //! <b>Throws</b>: Nothing. | |
379 //! | |
380 //! <b>Complexity</b>: Constant. | |
381 iterator end() BOOST_NOEXCEPT_OR_NOTHROW; | |
382 | |
383 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
384 //! | |
385 //! <b>Throws</b>: Nothing. | |
386 //! | |
387 //! <b>Complexity</b>: Constant. | |
388 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; | |
389 | |
390 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
391 //! | |
392 //! <b>Throws</b>: Nothing. | |
393 //! | |
394 //! <b>Complexity</b>: Constant. | |
395 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; | |
396 | |
397 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning | |
398 //! of the reversed container. | |
399 //! | |
400 //! <b>Throws</b>: Nothing. | |
401 //! | |
402 //! <b>Complexity</b>: Constant. | |
403 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; | |
404 | |
405 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
406 //! of the reversed container. | |
407 //! | |
408 //! <b>Throws</b>: Nothing. | |
409 //! | |
410 //! <b>Complexity</b>: Constant. | |
411 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; | |
412 | |
413 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
414 //! of the reversed container. | |
415 //! | |
416 //! <b>Throws</b>: Nothing. | |
417 //! | |
418 //! <b>Complexity</b>: Constant. | |
419 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; | |
420 | |
421 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end | |
422 //! of the reversed container. | |
423 //! | |
424 //! <b>Throws</b>: Nothing. | |
425 //! | |
426 //! <b>Complexity</b>: Constant. | |
427 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; | |
428 | |
429 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
430 //! of the reversed container. | |
431 //! | |
432 //! <b>Throws</b>: Nothing. | |
433 //! | |
434 //! <b>Complexity</b>: Constant. | |
435 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; | |
436 | |
437 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
438 //! of the reversed container. | |
439 //! | |
440 //! <b>Throws</b>: Nothing. | |
441 //! | |
442 //! <b>Complexity</b>: Constant. | |
443 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; | |
444 | |
445 //! <b>Effects</b>: Returns true if the container contains no elements. | |
446 //! | |
447 //! <b>Throws</b>: Nothing. | |
448 //! | |
449 //! <b>Complexity</b>: Constant. | |
450 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW; | |
451 | |
452 //! <b>Effects</b>: Returns the number of the elements contained in the container. | |
453 //! | |
454 //! <b>Throws</b>: Nothing. | |
455 //! | |
456 //! <b>Complexity</b>: Constant. | |
457 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW; | |
458 | |
459 //! <b>Effects</b>: Returns the largest possible size of the container. | |
460 //! | |
461 //! <b>Throws</b>: Nothing. | |
462 //! | |
463 //! <b>Complexity</b>: Constant. | |
464 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW; | |
465 | |
466 #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
467 | |
468 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
469 //! Effects: If there is no key equivalent to x in the map, inserts | |
470 //! value_type(x, T()) into the map. | |
471 //! | |
472 //! Returns: A reference to the mapped_type corresponding to x in *this. | |
473 //! | |
474 //! Complexity: Logarithmic. | |
475 mapped_type& operator[](const key_type &k); | |
476 | |
477 //! Effects: If there is no key equivalent to x in the map, inserts | |
478 //! value_type(boost::move(x), T()) into the map (the key is move-constructed) | |
479 //! | |
480 //! Returns: A reference to the mapped_type corresponding to x in *this. | |
481 //! | |
482 //! Complexity: Logarithmic. | |
483 mapped_type& operator[](key_type &&k); | |
484 #else | |
485 BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript) | |
486 #endif | |
487 | |
488 //! Returns: A reference to the element whose key is equivalent to x. | |
489 //! Throws: An exception object of type out_of_range if no such element is present. | |
490 //! Complexity: logarithmic. | |
491 T& at(const key_type& k) | |
492 { | |
493 iterator i = this->find(k); | |
494 if(i == this->end()){ | |
495 throw_out_of_range("map::at key not found"); | |
496 } | |
497 return i->second; | |
498 } | |
499 | |
500 //! Returns: A reference to the element whose key is equivalent to x. | |
501 //! Throws: An exception object of type out_of_range if no such element is present. | |
502 //! Complexity: logarithmic. | |
503 const T& at(const key_type& k) const | |
504 { | |
505 const_iterator i = this->find(k); | |
506 if(i == this->end()){ | |
507 throw_out_of_range("map::at key not found"); | |
508 } | |
509 return i->second; | |
510 } | |
511 | |
512 ////////////////////////////////////////////// | |
513 // | |
514 // modifiers | |
515 // | |
516 ////////////////////////////////////////////// | |
517 | |
518 //! <b>Effects</b>: Inserts x if and only if there is no element in the container | |
519 //! with key equivalent to the key of x. | |
520 //! | |
521 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
522 //! if the insertion takes place, and the iterator component of the pair | |
523 //! points to the element with key equivalent to the key of x. | |
524 //! | |
525 //! <b>Complexity</b>: Logarithmic. | |
526 std::pair<iterator,bool> insert(const value_type& x) | |
527 { return this->base_t::insert_unique(x); } | |
528 | |
529 //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if | |
530 //! there is no element in the container with key equivalent to the key of x. | |
531 //! | |
532 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
533 //! if the insertion takes place, and the iterator component of the pair | |
534 //! points to the element with key equivalent to the key of x. | |
535 //! | |
536 //! <b>Complexity</b>: Logarithmic. | |
537 std::pair<iterator,bool> insert(const nonconst_value_type& x) | |
538 { return this->base_t::insert_unique(x); } | |
539 | |
540 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and | |
541 //! only if there is no element in the container with key equivalent to the key of x. | |
542 //! | |
543 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
544 //! if the insertion takes place, and the iterator component of the pair | |
545 //! points to the element with key equivalent to the key of x. | |
546 //! | |
547 //! <b>Complexity</b>: Logarithmic. | |
548 std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x) | |
549 { return this->base_t::insert_unique(boost::move(x)); } | |
550 | |
551 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and | |
552 //! only if there is no element in the container with key equivalent to the key of x. | |
553 //! | |
554 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
555 //! if the insertion takes place, and the iterator component of the pair | |
556 //! points to the element with key equivalent to the key of x. | |
557 //! | |
558 //! <b>Complexity</b>: Logarithmic. | |
559 std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x) | |
560 { return this->base_t::insert_unique(boost::move(x)); } | |
561 | |
562 //! <b>Effects</b>: Move constructs a new value from x if and only if there is | |
563 //! no element in the container with key equivalent to the key of x. | |
564 //! | |
565 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
566 //! if the insertion takes place, and the iterator component of the pair | |
567 //! points to the element with key equivalent to the key of x. | |
568 //! | |
569 //! <b>Complexity</b>: Logarithmic. | |
570 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) | |
571 { return this->base_t::insert_unique(boost::move(x)); } | |
572 | |
573 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is | |
574 //! no element in the container with key equivalent to the key of x. | |
575 //! p is a hint pointing to where the insert should start to search. | |
576 //! | |
577 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
578 //! to the key of x. | |
579 //! | |
580 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
581 //! is inserted right before p. | |
582 iterator insert(const_iterator p, const value_type& x) | |
583 { return this->base_t::insert_unique(p, x); } | |
584 | |
585 //! <b>Effects</b>: Move constructs a new value from x if and only if there is | |
586 //! no element in the container with key equivalent to the key of x. | |
587 //! p is a hint pointing to where the insert should start to search. | |
588 //! | |
589 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
590 //! to the key of x. | |
591 //! | |
592 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
593 //! is inserted right before p. | |
594 iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x) | |
595 { return this->base_t::insert_unique(p, boost::move(x)); } | |
596 | |
597 //! <b>Effects</b>: Move constructs a new value from x if and only if there is | |
598 //! no element in the container with key equivalent to the key of x. | |
599 //! p is a hint pointing to where the insert should start to search. | |
600 //! | |
601 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
602 //! to the key of x. | |
603 //! | |
604 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
605 //! is inserted right before p. | |
606 iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x) | |
607 { return this->base_t::insert_unique(p, boost::move(x)); } | |
608 | |
609 //! <b>Effects</b>: Inserts a copy of x in the container. | |
610 //! p is a hint pointing to where the insert should start to search. | |
611 //! | |
612 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. | |
613 //! | |
614 //! <b>Complexity</b>: Logarithmic. | |
615 iterator insert(const_iterator p, const nonconst_value_type& x) | |
616 { return this->base_t::insert_unique(p, x); } | |
617 | |
618 //! <b>Effects</b>: Inserts an element move constructed from x in the container. | |
619 //! p is a hint pointing to where the insert should start to search. | |
620 //! | |
621 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. | |
622 //! | |
623 //! <b>Complexity</b>: Logarithmic. | |
624 iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) | |
625 { return this->base_t::insert_unique(p, boost::move(x)); } | |
626 | |
627 //! <b>Requires</b>: first, last are not iterators into *this. | |
628 //! | |
629 //! <b>Effects</b>: inserts each element from the range [first,last) if and only | |
630 //! if there is no element with key equivalent to the key of that element. | |
631 //! | |
632 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
633 template <class InputIterator> | |
634 void insert(InputIterator first, InputIterator last) | |
635 { this->base_t::insert_unique(first, last); } | |
636 | |
637 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
638 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only | |
639 //! if there is no element with key equivalent to the key of that element. | |
640 //! | |
641 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end()) | |
642 void insert(std::initializer_list<value_type> il) | |
643 { this->base_t::insert_unique(il.begin(), il.end()); } | |
644 #endif | |
645 | |
646 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
647 | |
648 //! <b>Effects</b>: Inserts an object x of type T constructed with | |
649 //! std::forward<Args>(args)... in the container if and only if there is | |
650 //! no element in the container with an equivalent key. | |
651 //! p is a hint pointing to where the insert should start to search. | |
652 //! | |
653 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
654 //! if the insertion takes place, and the iterator component of the pair | |
655 //! points to the element with key equivalent to the key of x. | |
656 //! | |
657 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
658 //! is inserted right before p. | |
659 template <class... Args> | |
660 std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args) | |
661 { return this->base_t::emplace_unique(boost::forward<Args>(args)...); } | |
662 | |
663 //! <b>Effects</b>: Inserts an object of type T constructed with | |
664 //! std::forward<Args>(args)... in the container if and only if there is | |
665 //! no element in the container with an equivalent key. | |
666 //! p is a hint pointing to where the insert should start to search. | |
667 //! | |
668 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
669 //! to the key of x. | |
670 //! | |
671 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
672 //! is inserted right before p. | |
673 template <class... Args> | |
674 iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) | |
675 { return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); } | |
676 | |
677 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
678 | |
679 #define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \ | |
680 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ | |
681 std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\ | |
682 { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\ | |
683 \ | |
684 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ | |
685 iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ | |
686 { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ | |
687 // | |
688 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE) | |
689 #undef BOOST_CONTAINER_MAP_EMPLACE_CODE | |
690 | |
691 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
692 | |
693 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
694 | |
695 //! <b>Effects</b>: Erases the element pointed to by p. | |
696 //! | |
697 //! <b>Returns</b>: Returns an iterator pointing to the element immediately | |
698 //! following q prior to the element being erased. If no such element exists, | |
699 //! returns end(). | |
700 //! | |
701 //! <b>Complexity</b>: Amortized constant time | |
702 iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW; | |
703 | |
704 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. | |
705 //! | |
706 //! <b>Returns</b>: Returns the number of erased elements. | |
707 //! | |
708 //! <b>Complexity</b>: log(size()) + count(k) | |
709 size_type erase(const key_type& x) BOOST_NOEXCEPT_OR_NOTHROW; | |
710 | |
711 //! <b>Effects</b>: Erases all the elements in the range [first, last). | |
712 //! | |
713 //! <b>Returns</b>: Returns last. | |
714 //! | |
715 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. | |
716 iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW; | |
717 | |
718 //! <b>Effects</b>: Swaps the contents of *this and x. | |
719 //! | |
720 //! <b>Throws</b>: Nothing. | |
721 //! | |
722 //! <b>Complexity</b>: Constant. | |
723 void swap(map& x) | |
724 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value | |
725 && boost::container::container_detail::is_nothrow_swappable<Compare>::value ) | |
726 | |
727 //! <b>Effects</b>: erase(a.begin(),a.end()). | |
728 //! | |
729 //! <b>Postcondition</b>: size() == 0. | |
730 //! | |
731 //! <b>Complexity</b>: linear in size(). | |
732 void clear() BOOST_NOEXCEPT_OR_NOTHROW; | |
733 | |
734 //! <b>Effects</b>: Returns the comparison object out | |
735 //! of which a was constructed. | |
736 //! | |
737 //! <b>Complexity</b>: Constant. | |
738 key_compare key_comp() const; | |
739 | |
740 //! <b>Effects</b>: Returns an object of value_compare constructed out | |
741 //! of the comparison object. | |
742 //! | |
743 //! <b>Complexity</b>: Constant. | |
744 value_compare value_comp() const; | |
745 | |
746 //! <b>Returns</b>: An iterator pointing to an element with the key | |
747 //! equivalent to x, or end() if such an element is not found. | |
748 //! | |
749 //! <b>Complexity</b>: Logarithmic. | |
750 iterator find(const key_type& x); | |
751 | |
752 //! <b>Returns</b>: A const_iterator pointing to an element with the key | |
753 //! equivalent to x, or end() if such an element is not found. | |
754 //! | |
755 //! <b>Complexity</b>: Logarithmic. | |
756 const_iterator find(const key_type& x) const; | |
757 | |
758 #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
759 | |
760 //! <b>Returns</b>: The number of elements with key equivalent to x. | |
761 //! | |
762 //! <b>Complexity</b>: log(size())+count(k) | |
763 size_type count(const key_type& x) const | |
764 { return static_cast<size_type>(this->find(x) != this->cend()); } | |
765 | |
766 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
767 | |
768 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
769 //! than k, or a.end() if such an element is not found. | |
770 //! | |
771 //! <b>Complexity</b>: Logarithmic | |
772 iterator lower_bound(const key_type& x); | |
773 | |
774 //! <b>Returns</b>: A const iterator pointing to the first element with key not | |
775 //! less than k, or a.end() if such an element is not found. | |
776 //! | |
777 //! <b>Complexity</b>: Logarithmic | |
778 const_iterator lower_bound(const key_type& x) const; | |
779 | |
780 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
781 //! than x, or end() if such an element is not found. | |
782 //! | |
783 //! <b>Complexity</b>: Logarithmic | |
784 iterator upper_bound(const key_type& x); | |
785 | |
786 //! <b>Returns</b>: A const iterator pointing to the first element with key not | |
787 //! less than x, or end() if such an element is not found. | |
788 //! | |
789 //! <b>Complexity</b>: Logarithmic | |
790 const_iterator upper_bound(const key_type& x) const; | |
791 | |
792 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
793 //! | |
794 //! <b>Complexity</b>: Logarithmic | |
795 std::pair<iterator,iterator> equal_range(const key_type& x); | |
796 | |
797 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
798 //! | |
799 //! <b>Complexity</b>: Logarithmic | |
800 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const; | |
801 | |
802 //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees. | |
803 //! | |
804 //! <b>Complexity</b>: Linear | |
805 void rebalance(); | |
806 | |
807 //! <b>Effects</b>: Returns true if x and y are equal | |
808 //! | |
809 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
810 friend bool operator==(const map& x, const map& y); | |
811 | |
812 //! <b>Effects</b>: Returns true if x and y are unequal | |
813 //! | |
814 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
815 friend bool operator!=(const map& x, const map& y); | |
816 | |
817 //! <b>Effects</b>: Returns true if x is less than y | |
818 //! | |
819 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
820 friend bool operator<(const map& x, const map& y); | |
821 | |
822 //! <b>Effects</b>: Returns true if x is greater than y | |
823 //! | |
824 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
825 friend bool operator>(const map& x, const map& y); | |
826 | |
827 //! <b>Effects</b>: Returns true if x is equal or less than y | |
828 //! | |
829 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
830 friend bool operator<=(const map& x, const map& y); | |
831 | |
832 //! <b>Effects</b>: Returns true if x is equal or greater than y | |
833 //! | |
834 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
835 friend bool operator>=(const map& x, const map& y); | |
836 | |
837 //! <b>Effects</b>: x.swap(y) | |
838 //! | |
839 //! <b>Complexity</b>: Constant. | |
840 friend void swap(map& x, map& y); | |
841 | |
842 #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
843 | |
844 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
845 private: | |
846 mapped_type& priv_subscript(const key_type &k) | |
847 { | |
848 //we can optimize this | |
849 iterator i = this->lower_bound(k); | |
850 // i->first is greater than or equivalent to k. | |
851 if (i == this->end() || this->key_comp()(k, (*i).first)){ | |
852 container_detail::value_init<mapped_type> m; | |
853 movable_value_type val(k, boost::move(m.m_t)); | |
854 i = insert(i, boost::move(val)); | |
855 } | |
856 return (*i).second; | |
857 } | |
858 | |
859 mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk) | |
860 { | |
861 key_type &k = mk; | |
862 //we can optimize this | |
863 iterator i = this->lower_bound(k); | |
864 // i->first is greater than or equivalent to k. | |
865 if (i == this->end() || this->key_comp()(k, (*i).first)){ | |
866 container_detail::value_init<mapped_type> m; | |
867 movable_value_type val(boost::move(k), boost::move(m.m_t)); | |
868 i = insert(i, boost::move(val)); | |
869 } | |
870 return (*i).second; | |
871 } | |
872 | |
873 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
874 }; | |
875 | |
876 | |
877 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
878 | |
879 } //namespace container { | |
880 | |
881 //!has_trivial_destructor_after_move<> == true_type | |
882 //!specialization for optimizations | |
883 template <class Key, class T, class Compare, class Allocator> | |
884 struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator> > | |
885 { | |
886 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; | |
887 static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && | |
888 ::boost::has_trivial_destructor_after_move<pointer>::value && | |
889 ::boost::has_trivial_destructor_after_move<Compare>::value; | |
890 }; | |
891 | |
892 namespace container { | |
893 | |
894 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
895 | |
896 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
897 | |
898 //! A multimap is a kind of associative container that supports equivalent keys | |
899 //! (possibly containing multiple copies of the same key value) and provides for | |
900 //! fast retrieval of values of another type T based on the keys. The multimap class | |
901 //! supports bidirectional iterators. | |
902 //! | |
903 //! A multimap satisfies all of the requirements of a container and of a reversible | |
904 //! container and of an associative container. The <code>value_type</code> stored | |
905 //! by this container is the value_type is std::pair<const Key, T>. | |
906 //! | |
907 //! \tparam Key is the key_type of the map | |
908 //! \tparam Value is the <code>mapped_type</code> | |
909 //! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). | |
910 //! \tparam Allocator is the allocator to allocate the <code>value_type</code>s | |
911 //! (e.g. <i>allocator< std::pair<const Key, T> > </i>). | |
912 //! \tparam MultiMapOptions is an packed option type generated using using boost::container::tree_assoc_options. | |
913 template < class Key, class T, class Compare = std::less<Key> | |
914 , class Allocator = new_allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults> | |
915 #else | |
916 template <class Key, class T, class Compare, class Allocator, class MultiMapOptions> | |
917 #endif | |
918 class multimap | |
919 ///@cond | |
920 : public container_detail::tree | |
921 < Key, std::pair<const Key, T> | |
922 , container_detail::select1st< std::pair<const Key, T> > | |
923 , Compare, Allocator, MultiMapOptions> | |
924 ///@endcond | |
925 { | |
926 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
927 private: | |
928 BOOST_COPYABLE_AND_MOVABLE(multimap) | |
929 | |
930 typedef std::pair<const Key, T> value_type_impl; | |
931 typedef container_detail::tree | |
932 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, MultiMapOptions> base_t; | |
933 typedef container_detail::pair <Key, T> movable_value_type_impl; | |
934 typedef container_detail::tree_value_compare | |
935 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> | |
936 > value_compare_impl; | |
937 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
938 | |
939 typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type; | |
85 | 940 |
86 public: | 941 public: |
87 ////////////////////////////////////////////// | 942 ////////////////////////////////////////////// |
88 // | 943 // |
89 // types | 944 // types |
98 typedef typename boost::container::allocator_traits<Allocator>::reference reference; | 953 typedef typename boost::container::allocator_traits<Allocator>::reference reference; |
99 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; | 954 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; |
100 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; | 955 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; |
101 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; | 956 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; |
102 typedef Allocator allocator_type; | 957 typedef Allocator allocator_type; |
103 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; | 958 typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; |
104 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; | 959 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; |
105 typedef Compare key_compare; | 960 typedef Compare key_compare; |
106 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; | 961 typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; |
107 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; | 962 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; |
108 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; | 963 typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; |
109 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; | 964 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; |
110 typedef std::pair<key_type, mapped_type> nonconst_value_type; | 965 typedef std::pair<key_type, mapped_type> nonconst_value_type; |
111 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; | 966 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; |
112 | 967 |
113 ////////////////////////////////////////////// | 968 ////////////////////////////////////////////// |
114 // | 969 // |
115 // construct/copy/destroy | 970 // construct/copy/destroy |
116 // | 971 // |
117 ////////////////////////////////////////////// | 972 ////////////////////////////////////////////// |
118 | 973 |
119 //! <b>Effects</b>: Default constructs an empty map. | |
120 //! | |
121 //! <b>Complexity</b>: Constant. | |
122 map() | |
123 : m_tree() | |
124 { | |
125 //Allocator type must be std::pair<CONST Key, T> | |
126 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
127 } | |
128 | |
129 //! <b>Effects</b>: Constructs an empty map using the specified comparison object | |
130 //! and allocator. | |
131 //! | |
132 //! <b>Complexity</b>: Constant. | |
133 explicit map(const Compare& comp, | |
134 const allocator_type& a = allocator_type()) | |
135 : m_tree(comp, a) | |
136 { | |
137 //Allocator type must be std::pair<CONST Key, T> | |
138 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
139 } | |
140 | |
141 //! <b>Effects</b>: Constructs an empty map using the specified allocator. | |
142 //! | |
143 //! <b>Complexity</b>: Constant. | |
144 explicit map(const allocator_type& a) | |
145 : m_tree(a) | |
146 { | |
147 //Allocator type must be std::pair<CONST Key, T> | |
148 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
149 } | |
150 | |
151 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and | |
152 //! allocator, and inserts elements from the range [first ,last ). | |
153 //! | |
154 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
155 //! comp and otherwise N logN, where N is last - first. | |
156 template <class InputIterator> | |
157 map(InputIterator first, InputIterator last, const Compare& comp = Compare(), | |
158 const allocator_type& a = allocator_type()) | |
159 : m_tree(true, first, last, comp, a) | |
160 { | |
161 //Allocator type must be std::pair<CONST Key, T> | |
162 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
163 } | |
164 | |
165 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and | |
166 //! allocator, and inserts elements from the ordered unique range [first ,last). This function | |
167 //! is more efficient than the normal range creation for ordered ranges. | |
168 //! | |
169 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be | |
170 //! unique values. | |
171 //! | |
172 //! <b>Complexity</b>: Linear in N. | |
173 //! | |
174 //! <b>Note</b>: Non-standard extension. | |
175 template <class InputIterator> | |
176 map( ordered_unique_range_t, InputIterator first, InputIterator last | |
177 , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) | |
178 : m_tree(ordered_range, first, last, comp, a) | |
179 { | |
180 //Allocator type must be std::pair<CONST Key, T> | |
181 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
182 } | |
183 | |
184 //! <b>Effects</b>: Copy constructs a map. | |
185 //! | |
186 //! <b>Complexity</b>: Linear in x.size(). | |
187 map(const map& x) | |
188 : m_tree(x.m_tree) | |
189 { | |
190 //Allocator type must be std::pair<CONST Key, T> | |
191 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
192 } | |
193 | |
194 //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources. | |
195 //! | |
196 //! <b>Complexity</b>: Constant. | |
197 //! | |
198 //! <b>Postcondition</b>: x is emptied. | |
199 map(BOOST_RV_REF(map) x) | |
200 : m_tree(boost::move(x.m_tree)) | |
201 { | |
202 //Allocator type must be std::pair<CONST Key, T> | |
203 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
204 } | |
205 | |
206 //! <b>Effects</b>: Copy constructs a map using the specified allocator. | |
207 //! | |
208 //! <b>Complexity</b>: Linear in x.size(). | |
209 map(const map& x, const allocator_type &a) | |
210 : m_tree(x.m_tree, a) | |
211 { | |
212 //Allocator type must be std::pair<CONST Key, T> | |
213 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
214 } | |
215 | |
216 //! <b>Effects</b>: Move constructs a map using the specified allocator. | |
217 //! Constructs *this using x's resources. | |
218 //! | |
219 //! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise. | |
220 //! | |
221 //! <b>Postcondition</b>: x is emptied. | |
222 map(BOOST_RV_REF(map) x, const allocator_type &a) | |
223 : m_tree(boost::move(x.m_tree), a) | |
224 { | |
225 //Allocator type must be std::pair<CONST Key, T> | |
226 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
227 } | |
228 | |
229 //! <b>Effects</b>: Makes *this a copy of x. | |
230 //! | |
231 //! <b>Complexity</b>: Linear in x.size(). | |
232 map& operator=(BOOST_COPY_ASSIGN_REF(map) x) | |
233 { m_tree = x.m_tree; return *this; } | |
234 | |
235 //! <b>Effects</b>: this->swap(x.get()). | |
236 //! | |
237 //! <b>Complexity</b>: Constant. | |
238 map& operator=(BOOST_RV_REF(map) x) | |
239 { m_tree = boost::move(x.m_tree); return *this; } | |
240 | |
241 //! <b>Effects</b>: Returns a copy of the Allocator that | |
242 //! was passed to the object's constructor. | |
243 //! | |
244 //! <b>Complexity</b>: Constant. | |
245 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT | |
246 { return m_tree.get_allocator(); } | |
247 | |
248 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
249 //! | |
250 //! <b>Throws</b>: Nothing | |
251 //! | |
252 //! <b>Complexity</b>: Constant. | |
253 //! | |
254 //! <b>Note</b>: Non-standard extension. | |
255 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT | |
256 { return m_tree.get_stored_allocator(); } | |
257 | |
258 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
259 //! | |
260 //! <b>Throws</b>: Nothing | |
261 //! | |
262 //! <b>Complexity</b>: Constant. | |
263 //! | |
264 //! <b>Note</b>: Non-standard extension. | |
265 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT | |
266 { return m_tree.get_stored_allocator(); } | |
267 | |
268 ////////////////////////////////////////////// | |
269 // | |
270 // iterators | |
271 // | |
272 ////////////////////////////////////////////// | |
273 | |
274 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. | |
275 //! | |
276 //! <b>Throws</b>: Nothing. | |
277 //! | |
278 //! <b>Complexity</b>: Constant. | |
279 iterator begin() BOOST_CONTAINER_NOEXCEPT | |
280 { return m_tree.begin(); } | |
281 | |
282 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
283 //! | |
284 //! <b>Throws</b>: Nothing. | |
285 //! | |
286 //! <b>Complexity</b>: Constant. | |
287 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT | |
288 { return this->cbegin(); } | |
289 | |
290 //! <b>Effects</b>: Returns an iterator to the end of the container. | |
291 //! | |
292 //! <b>Throws</b>: Nothing. | |
293 //! | |
294 //! <b>Complexity</b>: Constant. | |
295 iterator end() BOOST_CONTAINER_NOEXCEPT | |
296 { return m_tree.end(); } | |
297 | |
298 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
299 //! | |
300 //! <b>Throws</b>: Nothing. | |
301 //! | |
302 //! <b>Complexity</b>: Constant. | |
303 const_iterator end() const BOOST_CONTAINER_NOEXCEPT | |
304 { return this->cend(); } | |
305 | |
306 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning | |
307 //! of the reversed container. | |
308 //! | |
309 //! <b>Throws</b>: Nothing. | |
310 //! | |
311 //! <b>Complexity</b>: Constant. | |
312 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT | |
313 { return m_tree.rbegin(); } | |
314 | |
315 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
316 //! of the reversed container. | |
317 //! | |
318 //! <b>Throws</b>: Nothing. | |
319 //! | |
320 //! <b>Complexity</b>: Constant. | |
321 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT | |
322 { return this->crbegin(); } | |
323 | |
324 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end | |
325 //! of the reversed container. | |
326 //! | |
327 //! <b>Throws</b>: Nothing. | |
328 //! | |
329 //! <b>Complexity</b>: Constant. | |
330 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT | |
331 { return m_tree.rend(); } | |
332 | |
333 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
334 //! of the reversed container. | |
335 //! | |
336 //! <b>Throws</b>: Nothing. | |
337 //! | |
338 //! <b>Complexity</b>: Constant. | |
339 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT | |
340 { return this->crend(); } | |
341 | |
342 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
343 //! | |
344 //! <b>Throws</b>: Nothing. | |
345 //! | |
346 //! <b>Complexity</b>: Constant. | |
347 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT | |
348 { return m_tree.begin(); } | |
349 | |
350 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
351 //! | |
352 //! <b>Throws</b>: Nothing. | |
353 //! | |
354 //! <b>Complexity</b>: Constant. | |
355 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT | |
356 { return m_tree.end(); } | |
357 | |
358 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
359 //! of the reversed container. | |
360 //! | |
361 //! <b>Throws</b>: Nothing. | |
362 //! | |
363 //! <b>Complexity</b>: Constant. | |
364 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT | |
365 { return m_tree.rbegin(); } | |
366 | |
367 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
368 //! of the reversed container. | |
369 //! | |
370 //! <b>Throws</b>: Nothing. | |
371 //! | |
372 //! <b>Complexity</b>: Constant. | |
373 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT | |
374 { return m_tree.rend(); } | |
375 | |
376 ////////////////////////////////////////////// | |
377 // | |
378 // capacity | |
379 // | |
380 ////////////////////////////////////////////// | |
381 | |
382 //! <b>Effects</b>: Returns true if the container contains no elements. | |
383 //! | |
384 //! <b>Throws</b>: Nothing. | |
385 //! | |
386 //! <b>Complexity</b>: Constant. | |
387 bool empty() const BOOST_CONTAINER_NOEXCEPT | |
388 { return m_tree.empty(); } | |
389 | |
390 //! <b>Effects</b>: Returns the number of the elements contained in the container. | |
391 //! | |
392 //! <b>Throws</b>: Nothing. | |
393 //! | |
394 //! <b>Complexity</b>: Constant. | |
395 size_type size() const BOOST_CONTAINER_NOEXCEPT | |
396 { return m_tree.size(); } | |
397 | |
398 //! <b>Effects</b>: Returns the largest possible size of the container. | |
399 //! | |
400 //! <b>Throws</b>: Nothing. | |
401 //! | |
402 //! <b>Complexity</b>: Constant. | |
403 size_type max_size() const BOOST_CONTAINER_NOEXCEPT | |
404 { return m_tree.max_size(); } | |
405 | |
406 ////////////////////////////////////////////// | |
407 // | |
408 // element access | |
409 // | |
410 ////////////////////////////////////////////// | |
411 | |
412 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
413 //! Effects: If there is no key equivalent to x in the map, inserts | |
414 //! value_type(x, T()) into the map. | |
415 //! | |
416 //! Returns: Allocator reference to the mapped_type corresponding to x in *this. | |
417 //! | |
418 //! Complexity: Logarithmic. | |
419 mapped_type& operator[](const key_type &k); | |
420 | |
421 //! Effects: If there is no key equivalent to x in the map, inserts | |
422 //! value_type(boost::move(x), T()) into the map (the key is move-constructed) | |
423 //! | |
424 //! Returns: Allocator reference to the mapped_type corresponding to x in *this. | |
425 //! | |
426 //! Complexity: Logarithmic. | |
427 mapped_type& operator[](key_type &&k); | |
428 #else | |
429 BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript) | |
430 #endif | |
431 | |
432 //! Returns: Allocator reference to the element whose key is equivalent to x. | |
433 //! Throws: An exception object of type out_of_range if no such element is present. | |
434 //! Complexity: logarithmic. | |
435 T& at(const key_type& k) | |
436 { | |
437 iterator i = this->find(k); | |
438 if(i == this->end()){ | |
439 throw_out_of_range("map::at key not found"); | |
440 } | |
441 return i->second; | |
442 } | |
443 | |
444 //! Returns: Allocator reference to the element whose key is equivalent to x. | |
445 //! Throws: An exception object of type out_of_range if no such element is present. | |
446 //! Complexity: logarithmic. | |
447 const T& at(const key_type& k) const | |
448 { | |
449 const_iterator i = this->find(k); | |
450 if(i == this->end()){ | |
451 throw_out_of_range("map::at key not found"); | |
452 } | |
453 return i->second; | |
454 } | |
455 | |
456 ////////////////////////////////////////////// | |
457 // | |
458 // modifiers | |
459 // | |
460 ////////////////////////////////////////////// | |
461 | |
462 //! <b>Effects</b>: Inserts x if and only if there is no element in the container | |
463 //! with key equivalent to the key of x. | |
464 //! | |
465 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
466 //! if the insertion takes place, and the iterator component of the pair | |
467 //! points to the element with key equivalent to the key of x. | |
468 //! | |
469 //! <b>Complexity</b>: Logarithmic. | |
470 std::pair<iterator,bool> insert(const value_type& x) | |
471 { return m_tree.insert_unique(x); } | |
472 | |
473 //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if | |
474 //! there is no element in the container with key equivalent to the key of x. | |
475 //! | |
476 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
477 //! if the insertion takes place, and the iterator component of the pair | |
478 //! points to the element with key equivalent to the key of x. | |
479 //! | |
480 //! <b>Complexity</b>: Logarithmic. | |
481 std::pair<iterator,bool> insert(const nonconst_value_type& x) | |
482 { return m_tree.insert_unique(x); } | |
483 | |
484 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and | |
485 //! only if there is no element in the container with key equivalent to the key of x. | |
486 //! | |
487 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
488 //! if the insertion takes place, and the iterator component of the pair | |
489 //! points to the element with key equivalent to the key of x. | |
490 //! | |
491 //! <b>Complexity</b>: Logarithmic. | |
492 std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x) | |
493 { return m_tree.insert_unique(boost::move(x)); } | |
494 | |
495 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and | |
496 //! only if there is no element in the container with key equivalent to the key of x. | |
497 //! | |
498 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
499 //! if the insertion takes place, and the iterator component of the pair | |
500 //! points to the element with key equivalent to the key of x. | |
501 //! | |
502 //! <b>Complexity</b>: Logarithmic. | |
503 std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x) | |
504 { return m_tree.insert_unique(boost::move(x)); } | |
505 | |
506 //! <b>Effects</b>: Move constructs a new value from x if and only if there is | |
507 //! no element in the container with key equivalent to the key of x. | |
508 //! | |
509 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
510 //! if the insertion takes place, and the iterator component of the pair | |
511 //! points to the element with key equivalent to the key of x. | |
512 //! | |
513 //! <b>Complexity</b>: Logarithmic. | |
514 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) | |
515 { return m_tree.insert_unique(boost::move(x)); } | |
516 | |
517 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is | |
518 //! no element in the container with key equivalent to the key of x. | |
519 //! p is a hint pointing to where the insert should start to search. | |
520 //! | |
521 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
522 //! to the key of x. | |
523 //! | |
524 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
525 //! is inserted right before p. | |
526 iterator insert(const_iterator position, const value_type& x) | |
527 { return m_tree.insert_unique(position, x); } | |
528 | |
529 //! <b>Effects</b>: Move constructs a new value from x if and only if there is | |
530 //! no element in the container with key equivalent to the key of x. | |
531 //! p is a hint pointing to where the insert should start to search. | |
532 //! | |
533 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
534 //! to the key of x. | |
535 //! | |
536 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
537 //! is inserted right before p. | |
538 iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) | |
539 { return m_tree.insert_unique(position, boost::move(x)); } | |
540 | |
541 //! <b>Effects</b>: Move constructs a new value from x if and only if there is | |
542 //! no element in the container with key equivalent to the key of x. | |
543 //! p is a hint pointing to where the insert should start to search. | |
544 //! | |
545 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
546 //! to the key of x. | |
547 //! | |
548 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
549 //! is inserted right before p. | |
550 iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) | |
551 { return m_tree.insert_unique(position, boost::move(x)); } | |
552 | |
553 //! <b>Effects</b>: Inserts a copy of x in the container. | |
554 //! p is a hint pointing to where the insert should start to search. | |
555 //! | |
556 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. | |
557 //! | |
558 //! <b>Complexity</b>: Logarithmic. | |
559 iterator insert(const_iterator position, const nonconst_value_type& x) | |
560 { return m_tree.insert_unique(position, x); } | |
561 | |
562 //! <b>Effects</b>: Inserts an element move constructed from x in the container. | |
563 //! p is a hint pointing to where the insert should start to search. | |
564 //! | |
565 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. | |
566 //! | |
567 //! <b>Complexity</b>: Logarithmic. | |
568 iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) | |
569 { return m_tree.insert_unique(position, boost::move(x)); } | |
570 | |
571 //! <b>Requires</b>: first, last are not iterators into *this. | |
572 //! | |
573 //! <b>Effects</b>: inserts each element from the range [first,last) if and only | |
574 //! if there is no element with key equivalent to the key of that element. | |
575 //! | |
576 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
577 template <class InputIterator> | |
578 void insert(InputIterator first, InputIterator last) | |
579 { m_tree.insert_unique(first, last); } | |
580 | |
581 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
582 | |
583 //! <b>Effects</b>: Inserts an object x of type T constructed with | |
584 //! std::forward<Args>(args)... in the container if and only if there is | |
585 //! no element in the container with an equivalent key. | |
586 //! p is a hint pointing to where the insert should start to search. | |
587 //! | |
588 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
589 //! if the insertion takes place, and the iterator component of the pair | |
590 //! points to the element with key equivalent to the key of x. | |
591 //! | |
592 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
593 //! is inserted right before p. | |
594 template <class... Args> | |
595 std::pair<iterator,bool> emplace(Args&&... args) | |
596 { return m_tree.emplace_unique(boost::forward<Args>(args)...); } | |
597 | |
598 //! <b>Effects</b>: Inserts an object of type T constructed with | |
599 //! std::forward<Args>(args)... in the container if and only if there is | |
600 //! no element in the container with an equivalent key. | |
601 //! p is a hint pointing to where the insert should start to search. | |
602 //! | |
603 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
604 //! to the key of x. | |
605 //! | |
606 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
607 //! is inserted right before p. | |
608 template <class... Args> | |
609 iterator emplace_hint(const_iterator hint, Args&&... args) | |
610 { return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); } | |
611 | |
612 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
613 | |
614 #define BOOST_PP_LOCAL_MACRO(n) \ | |
615 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
616 std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
617 { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
618 \ | |
619 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
620 iterator emplace_hint(const_iterator hint \ | |
621 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
622 { return m_tree.emplace_hint_unique(hint \ | |
623 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ | |
624 //! | |
625 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
626 #include BOOST_PP_LOCAL_ITERATE() | |
627 | |
628 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
629 | |
630 //! <b>Effects</b>: Erases the element pointed to by position. | |
631 //! | |
632 //! <b>Returns</b>: Returns an iterator pointing to the element immediately | |
633 //! following q prior to the element being erased. If no such element exists, | |
634 //! returns end(). | |
635 //! | |
636 //! <b>Complexity</b>: Amortized constant time | |
637 iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT | |
638 { return m_tree.erase(position); } | |
639 | |
640 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. | |
641 //! | |
642 //! <b>Returns</b>: Returns the number of erased elements. | |
643 //! | |
644 //! <b>Complexity</b>: log(size()) + count(k) | |
645 size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT | |
646 { return m_tree.erase(x); } | |
647 | |
648 //! <b>Effects</b>: Erases all the elements in the range [first, last). | |
649 //! | |
650 //! <b>Returns</b>: Returns last. | |
651 //! | |
652 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. | |
653 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT | |
654 { return m_tree.erase(first, last); } | |
655 | |
656 //! <b>Effects</b>: Swaps the contents of *this and x. | |
657 //! | |
658 //! <b>Throws</b>: Nothing. | |
659 //! | |
660 //! <b>Complexity</b>: Constant. | |
661 void swap(map& x) | |
662 { m_tree.swap(x.m_tree); } | |
663 | |
664 //! <b>Effects</b>: erase(a.begin(),a.end()). | |
665 //! | |
666 //! <b>Postcondition</b>: size() == 0. | |
667 //! | |
668 //! <b>Complexity</b>: linear in size(). | |
669 void clear() BOOST_CONTAINER_NOEXCEPT | |
670 { m_tree.clear(); } | |
671 | |
672 ////////////////////////////////////////////// | |
673 // | |
674 // observers | |
675 // | |
676 ////////////////////////////////////////////// | |
677 | |
678 //! <b>Effects</b>: Returns the comparison object out | |
679 //! of which a was constructed. | |
680 //! | |
681 //! <b>Complexity</b>: Constant. | |
682 key_compare key_comp() const | |
683 { return m_tree.key_comp(); } | |
684 | |
685 //! <b>Effects</b>: Returns an object of value_compare constructed out | |
686 //! of the comparison object. | |
687 //! | |
688 //! <b>Complexity</b>: Constant. | |
689 value_compare value_comp() const | |
690 { return value_compare(m_tree.key_comp()); } | |
691 | |
692 ////////////////////////////////////////////// | |
693 // | |
694 // map operations | |
695 // | |
696 ////////////////////////////////////////////// | |
697 | |
698 //! <b>Returns</b>: An iterator pointing to an element with the key | |
699 //! equivalent to x, or end() if such an element is not found. | |
700 //! | |
701 //! <b>Complexity</b>: Logarithmic. | |
702 iterator find(const key_type& x) | |
703 { return m_tree.find(x); } | |
704 | |
705 //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key | |
706 //! equivalent to x, or end() if such an element is not found. | |
707 //! | |
708 //! <b>Complexity</b>: Logarithmic. | |
709 const_iterator find(const key_type& x) const | |
710 { return m_tree.find(x); } | |
711 | |
712 //! <b>Returns</b>: The number of elements with key equivalent to x. | |
713 //! | |
714 //! <b>Complexity</b>: log(size())+count(k) | |
715 size_type count(const key_type& x) const | |
716 { return static_cast<size_type>(m_tree.find(x) != m_tree.end()); } | |
717 | |
718 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
719 //! than k, or a.end() if such an element is not found. | |
720 //! | |
721 //! <b>Complexity</b>: Logarithmic | |
722 iterator lower_bound(const key_type& x) | |
723 { return m_tree.lower_bound(x); } | |
724 | |
725 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
726 //! less than k, or a.end() if such an element is not found. | |
727 //! | |
728 //! <b>Complexity</b>: Logarithmic | |
729 const_iterator lower_bound(const key_type& x) const | |
730 { return m_tree.lower_bound(x); } | |
731 | |
732 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
733 //! than x, or end() if such an element is not found. | |
734 //! | |
735 //! <b>Complexity</b>: Logarithmic | |
736 iterator upper_bound(const key_type& x) | |
737 { return m_tree.upper_bound(x); } | |
738 | |
739 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
740 //! less than x, or end() if such an element is not found. | |
741 //! | |
742 //! <b>Complexity</b>: Logarithmic | |
743 const_iterator upper_bound(const key_type& x) const | |
744 { return m_tree.upper_bound(x); } | |
745 | |
746 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
747 //! | |
748 //! <b>Complexity</b>: Logarithmic | |
749 std::pair<iterator,iterator> equal_range(const key_type& x) | |
750 { return m_tree.equal_range(x); } | |
751 | |
752 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
753 //! | |
754 //! <b>Complexity</b>: Logarithmic | |
755 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const | |
756 { return m_tree.equal_range(x); } | |
757 | |
758 /// @cond | |
759 template <class K1, class T1, class C1, class A1> | |
760 friend bool operator== (const map<K1, T1, C1, A1>&, | |
761 const map<K1, T1, C1, A1>&); | |
762 template <class K1, class T1, class C1, class A1> | |
763 friend bool operator< (const map<K1, T1, C1, A1>&, | |
764 const map<K1, T1, C1, A1>&); | |
765 private: | |
766 mapped_type& priv_subscript(const key_type &k) | |
767 { | |
768 //we can optimize this | |
769 iterator i = lower_bound(k); | |
770 // i->first is greater than or equivalent to k. | |
771 if (i == end() || key_comp()(k, (*i).first)){ | |
772 container_detail::value_init<mapped_type> m; | |
773 movable_value_type val(k, boost::move(m.m_t)); | |
774 i = insert(i, boost::move(val)); | |
775 } | |
776 return (*i).second; | |
777 } | |
778 | |
779 mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk) | |
780 { | |
781 key_type &k = mk; | |
782 //we can optimize this | |
783 iterator i = lower_bound(k); | |
784 // i->first is greater than or equivalent to k. | |
785 if (i == end() || key_comp()(k, (*i).first)){ | |
786 container_detail::value_init<mapped_type> m; | |
787 movable_value_type val(boost::move(k), boost::move(m.m_t)); | |
788 i = insert(i, boost::move(val)); | |
789 } | |
790 return (*i).second; | |
791 } | |
792 | |
793 /// @endcond | |
794 }; | |
795 | |
796 template <class Key, class T, class Compare, class Allocator> | |
797 inline bool operator==(const map<Key,T,Compare,Allocator>& x, | |
798 const map<Key,T,Compare,Allocator>& y) | |
799 { return x.m_tree == y.m_tree; } | |
800 | |
801 template <class Key, class T, class Compare, class Allocator> | |
802 inline bool operator<(const map<Key,T,Compare,Allocator>& x, | |
803 const map<Key,T,Compare,Allocator>& y) | |
804 { return x.m_tree < y.m_tree; } | |
805 | |
806 template <class Key, class T, class Compare, class Allocator> | |
807 inline bool operator!=(const map<Key,T,Compare,Allocator>& x, | |
808 const map<Key,T,Compare,Allocator>& y) | |
809 { return !(x == y); } | |
810 | |
811 template <class Key, class T, class Compare, class Allocator> | |
812 inline bool operator>(const map<Key,T,Compare,Allocator>& x, | |
813 const map<Key,T,Compare,Allocator>& y) | |
814 { return y < x; } | |
815 | |
816 template <class Key, class T, class Compare, class Allocator> | |
817 inline bool operator<=(const map<Key,T,Compare,Allocator>& x, | |
818 const map<Key,T,Compare,Allocator>& y) | |
819 { return !(y < x); } | |
820 | |
821 template <class Key, class T, class Compare, class Allocator> | |
822 inline bool operator>=(const map<Key,T,Compare,Allocator>& x, | |
823 const map<Key,T,Compare,Allocator>& y) | |
824 { return !(x < y); } | |
825 | |
826 template <class Key, class T, class Compare, class Allocator> | |
827 inline void swap(map<Key,T,Compare,Allocator>& x, map<Key,T,Compare,Allocator>& y) | |
828 { x.swap(y); } | |
829 | |
830 /// @cond | |
831 | |
832 // Forward declaration of operators < and ==, needed for friend declaration. | |
833 | |
834 template <class Key, class T, class Compare, class Allocator> | |
835 inline bool operator==(const multimap<Key,T,Compare,Allocator>& x, | |
836 const multimap<Key,T,Compare,Allocator>& y); | |
837 | |
838 template <class Key, class T, class Compare, class Allocator> | |
839 inline bool operator<(const multimap<Key,T,Compare,Allocator>& x, | |
840 const multimap<Key,T,Compare,Allocator>& y); | |
841 | |
842 } //namespace container { | |
843 | |
844 //!has_trivial_destructor_after_move<> == true_type | |
845 //!specialization for optimizations | |
846 template <class K, class T, class C, class Allocator> | |
847 struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocator> > | |
848 { | |
849 static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value; | |
850 }; | |
851 | |
852 namespace container { | |
853 | |
854 /// @endcond | |
855 | |
856 //! A multimap is a kind of associative container that supports equivalent keys | |
857 //! (possibly containing multiple copies of the same key value) and provides for | |
858 //! fast retrieval of values of another type T based on the keys. The multimap class | |
859 //! supports bidirectional iterators. | |
860 //! | |
861 //! A multimap satisfies all of the requirements of a container and of a reversible | |
862 //! container and of an associative container. For a | |
863 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>. | |
864 //! | |
865 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). | |
866 //! | |
867 //! Allocator is the allocator to allocate the value_types | |
868 //!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>). | |
869 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
870 template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > > | |
871 #else | |
872 template <class Key, class T, class Compare, class Allocator> | |
873 #endif | |
874 class multimap | |
875 { | |
876 /// @cond | |
877 private: | |
878 BOOST_COPYABLE_AND_MOVABLE(multimap) | |
879 | |
880 typedef std::pair<const Key, T> value_type_impl; | |
881 typedef container_detail::rbtree | |
882 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t; | |
883 typedef container_detail::pair <Key, T> movable_value_type_impl; | |
884 typedef container_detail::tree_value_compare | |
885 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> | |
886 > value_compare_impl; | |
887 tree_t m_tree; // red-black tree representing map | |
888 /// @endcond | |
889 | |
890 public: | |
891 ////////////////////////////////////////////// | |
892 // | |
893 // types | |
894 // | |
895 ////////////////////////////////////////////// | |
896 | |
897 typedef Key key_type; | |
898 typedef T mapped_type; | |
899 typedef std::pair<const Key, T> value_type; | |
900 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; | |
901 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; | |
902 typedef typename boost::container::allocator_traits<Allocator>::reference reference; | |
903 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; | |
904 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; | |
905 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; | |
906 typedef Allocator allocator_type; | |
907 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; | |
908 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; | |
909 typedef Compare key_compare; | |
910 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; | |
911 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; | |
912 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; | |
913 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; | |
914 typedef std::pair<key_type, mapped_type> nonconst_value_type; | |
915 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; | |
916 | |
917 ////////////////////////////////////////////// | |
918 // | |
919 // construct/copy/destroy | |
920 // | |
921 ////////////////////////////////////////////// | |
922 | |
923 //! <b>Effects</b>: Default constructs an empty multimap. | 974 //! <b>Effects</b>: Default constructs an empty multimap. |
924 //! | 975 //! |
925 //! <b>Complexity</b>: Constant. | 976 //! <b>Complexity</b>: Constant. |
926 multimap() | 977 multimap() |
927 : m_tree() | 978 : base_t() |
928 { | 979 { |
929 //Allocator type must be std::pair<CONST Key, T> | 980 //A type must be std::pair<CONST Key, T> |
930 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 981 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
931 } | 982 } |
932 | 983 |
933 //! <b>Effects</b>: Constructs an empty multimap using the specified allocator. | 984 //! <b>Effects</b>: Constructs an empty multimap using the specified allocator. |
934 //! | 985 //! |
935 //! <b>Complexity</b>: Constant. | 986 //! <b>Complexity</b>: Constant. |
936 explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) | 987 explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) |
937 : m_tree(comp, a) | 988 : base_t(comp, a) |
938 { | 989 { |
939 //Allocator type must be std::pair<CONST Key, T> | 990 //A type must be std::pair<CONST Key, T> |
940 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 991 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
941 } | 992 } |
942 | 993 |
943 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison | 994 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison |
944 //! object and allocator. | 995 //! object and allocator. |
945 //! | 996 //! |
946 //! <b>Complexity</b>: Constant. | 997 //! <b>Complexity</b>: Constant. |
947 explicit multimap(const allocator_type& a) | 998 explicit multimap(const allocator_type& a) |
948 : m_tree(a) | 999 : base_t(a) |
949 { | 1000 { |
950 //Allocator type must be std::pair<CONST Key, T> | 1001 //A type must be std::pair<CONST Key, T> |
951 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 1002 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
952 } | 1003 } |
953 | 1004 |
954 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object | 1005 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object |
955 //! and allocator, and inserts elements from the range [first ,last ). | 1006 //! and allocator, and inserts elements from the range [first ,last ). |
958 //! comp and otherwise N logN, where N is last - first. | 1009 //! comp and otherwise N logN, where N is last - first. |
959 template <class InputIterator> | 1010 template <class InputIterator> |
960 multimap(InputIterator first, InputIterator last, | 1011 multimap(InputIterator first, InputIterator last, |
961 const Compare& comp = Compare(), | 1012 const Compare& comp = Compare(), |
962 const allocator_type& a = allocator_type()) | 1013 const allocator_type& a = allocator_type()) |
963 : m_tree(false, first, last, comp, a) | 1014 : base_t(false, first, last, comp, a) |
964 { | 1015 { |
965 //Allocator type must be std::pair<CONST Key, T> | 1016 //A type must be std::pair<CONST Key, T> |
1017 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
1018 } | |
1019 | |
1020 //! <b>Effects</b>: Constructs an empty multimap using the specified | |
1021 //! allocator, and inserts elements from the range [first ,last ). | |
1022 //! | |
1023 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
1024 //! comp and otherwise N logN, where N is last - first. | |
1025 template <class InputIterator> | |
1026 multimap(InputIterator first, InputIterator last, const allocator_type& a) | |
1027 : base_t(false, first, last, Compare(), a) | |
1028 { | |
1029 //A type must be std::pair<CONST Key, T> | |
966 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 1030 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
967 } | 1031 } |
968 | 1032 |
969 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and | 1033 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and |
970 //! allocator, and inserts elements from the ordered range [first ,last). This function | 1034 //! allocator, and inserts elements from the ordered range [first ,last). This function |
976 //! | 1040 //! |
977 //! <b>Note</b>: Non-standard extension. | 1041 //! <b>Note</b>: Non-standard extension. |
978 template <class InputIterator> | 1042 template <class InputIterator> |
979 multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), | 1043 multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), |
980 const allocator_type& a = allocator_type()) | 1044 const allocator_type& a = allocator_type()) |
981 : m_tree(ordered_range, first, last, comp, a) | 1045 : base_t(ordered_range, first, last, comp, a) |
982 {} | 1046 {} |
1047 | |
1048 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
1049 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and | |
1050 //! allocator, and inserts elements from the range [il.begin(), il.end()). | |
1051 //! | |
1052 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
1053 //! comp and otherwise N logN, where N is il.first() - il.end(). | |
1054 multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(), | |
1055 const allocator_type& a = allocator_type()) | |
1056 : base_t(false, il.begin(), il.end(), comp, a) | |
1057 { | |
1058 //A type must be std::pair<CONST Key, T> | |
1059 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
1060 } | |
1061 | |
1062 //! <b>Effects</b>: Constructs an empty multimap using the specified | |
1063 //! allocator, and inserts elements from the range [il.begin(), il.end()). | |
1064 //! | |
1065 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
1066 //! comp and otherwise N logN, where N is il.first() - il.end(). | |
1067 multimap(std::initializer_list<value_type> il, const allocator_type& a) | |
1068 : base_t(false, il.begin(), il.end(), Compare(), a) | |
1069 { | |
1070 //A type must be std::pair<CONST Key, T> | |
1071 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
1072 } | |
1073 | |
1074 //! <b>Effects</b>: Constructs an empty set using the specified comparison object and | |
1075 //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function | |
1076 //! is more efficient than the normal range creation for ordered ranges. | |
1077 //! | |
1078 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate. | |
1079 //! | |
1080 //! <b>Complexity</b>: Linear in N. | |
1081 //! | |
1082 //! <b>Note</b>: Non-standard extension. | |
1083 multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), | |
1084 const allocator_type& a = allocator_type()) | |
1085 : base_t(ordered_range, il.begin(), il.end(), comp, a) | |
1086 { | |
1087 //A type must be std::pair<CONST Key, T> | |
1088 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | |
1089 } | |
1090 #endif | |
983 | 1091 |
984 //! <b>Effects</b>: Copy constructs a multimap. | 1092 //! <b>Effects</b>: Copy constructs a multimap. |
985 //! | 1093 //! |
986 //! <b>Complexity</b>: Linear in x.size(). | 1094 //! <b>Complexity</b>: Linear in x.size(). |
987 multimap(const multimap& x) | 1095 multimap(const multimap& x) |
988 : m_tree(x.m_tree) | 1096 : base_t(static_cast<const base_t&>(x)) |
989 { | 1097 { |
990 //Allocator type must be std::pair<CONST Key, T> | 1098 //A type must be std::pair<CONST Key, T> |
991 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 1099 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
992 } | 1100 } |
993 | 1101 |
994 //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources. | 1102 //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources. |
995 //! | 1103 //! |
996 //! <b>Complexity</b>: Constant. | 1104 //! <b>Complexity</b>: Constant. |
997 //! | 1105 //! |
998 //! <b>Postcondition</b>: x is emptied. | 1106 //! <b>Postcondition</b>: x is emptied. |
999 multimap(BOOST_RV_REF(multimap) x) | 1107 multimap(BOOST_RV_REF(multimap) x) |
1000 : m_tree(boost::move(x.m_tree)) | 1108 : base_t(BOOST_MOVE_BASE(base_t, x)) |
1001 { | 1109 { |
1002 //Allocator type must be std::pair<CONST Key, T> | 1110 //A type must be std::pair<CONST Key, T> |
1003 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 1111 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
1004 } | 1112 } |
1005 | 1113 |
1006 //! <b>Effects</b>: Copy constructs a multimap. | 1114 //! <b>Effects</b>: Copy constructs a multimap. |
1007 //! | 1115 //! |
1008 //! <b>Complexity</b>: Linear in x.size(). | 1116 //! <b>Complexity</b>: Linear in x.size(). |
1009 multimap(const multimap& x, const allocator_type &a) | 1117 multimap(const multimap& x, const allocator_type &a) |
1010 : m_tree(x.m_tree, a) | 1118 : base_t(static_cast<const base_t&>(x), a) |
1011 { | 1119 { |
1012 //Allocator type must be std::pair<CONST Key, T> | 1120 //A type must be std::pair<CONST Key, T> |
1013 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 1121 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
1014 } | 1122 } |
1015 | 1123 |
1016 //! <b>Effects</b>: Move constructs a multimap using the specified allocator. | 1124 //! <b>Effects</b>: Move constructs a multimap using the specified allocator. |
1017 //! Constructs *this using x's resources. | 1125 //! Constructs *this using x's resources. |
1018 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. | 1126 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. |
1019 //! | 1127 //! |
1020 //! <b>Postcondition</b>: x is emptied. | 1128 //! <b>Postcondition</b>: x is emptied. |
1021 multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) | 1129 multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) |
1022 : m_tree(boost::move(x.m_tree), a) | 1130 : base_t(BOOST_MOVE_BASE(base_t, x), a) |
1023 { | 1131 { |
1024 //Allocator type must be std::pair<CONST Key, T> | 1132 //A type must be std::pair<CONST Key, T> |
1025 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); | 1133 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); |
1026 } | 1134 } |
1027 | 1135 |
1028 //! <b>Effects</b>: Makes *this a copy of x. | 1136 //! <b>Effects</b>: Makes *this a copy of x. |
1029 //! | 1137 //! |
1030 //! <b>Complexity</b>: Linear in x.size(). | 1138 //! <b>Complexity</b>: Linear in x.size(). |
1031 multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) | 1139 multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) |
1032 { m_tree = x.m_tree; return *this; } | 1140 { return static_cast<multimap&>(this->base_t::operator=(static_cast<const base_t&>(x))); } |
1033 | 1141 |
1034 //! <b>Effects</b>: this->swap(x.get()). | 1142 //! <b>Effects</b>: this->swap(x.get()). |
1035 //! | 1143 //! |
1036 //! <b>Complexity</b>: Constant. | 1144 //! <b>Complexity</b>: Constant. |
1037 multimap& operator=(BOOST_RV_REF(multimap) x) | 1145 multimap& operator=(BOOST_RV_REF(multimap) x) |
1038 { m_tree = boost::move(x.m_tree); return *this; } | 1146 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value |
1039 | 1147 && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value ) |
1040 //! <b>Effects</b>: Returns a copy of the Allocator that | 1148 { return static_cast<multimap&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } |
1041 //! was passed to the object's constructor. | 1149 |
1042 //! | 1150 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) |
1043 //! <b>Complexity</b>: Constant. | 1151 //! <b>Effects</b>: Assign content of il to *this. |
1044 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT | 1152 //! |
1045 { return m_tree.get_allocator(); } | 1153 multimap& operator=(std::initializer_list<value_type> il) |
1046 | 1154 { |
1047 //! <b>Effects</b>: Returns a reference to the internal allocator. | 1155 this->clear(); |
1048 //! | 1156 insert(il.begin(), il.end()); |
1049 //! <b>Throws</b>: Nothing | 1157 return *this; |
1050 //! | 1158 } |
1051 //! <b>Complexity</b>: Constant. | 1159 #endif |
1052 //! | 1160 |
1053 //! <b>Note</b>: Non-standard extension. | 1161 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) |
1054 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT | 1162 |
1055 { return m_tree.get_stored_allocator(); } | 1163 //! @copydoc ::boost::container::set::get_allocator() |
1056 | 1164 allocator_type get_allocator() const; |
1057 //! <b>Effects</b>: Returns a reference to the internal allocator. | 1165 |
1058 //! | 1166 //! @copydoc ::boost::container::set::get_stored_allocator() |
1059 //! <b>Throws</b>: Nothing | 1167 stored_allocator_type &get_stored_allocator(); |
1060 //! | 1168 |
1061 //! <b>Complexity</b>: Constant. | 1169 //! @copydoc ::boost::container::set::get_stored_allocator() const |
1062 //! | 1170 const stored_allocator_type &get_stored_allocator() const; |
1063 //! <b>Note</b>: Non-standard extension. | 1171 |
1064 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT | 1172 //! @copydoc ::boost::container::set::begin() |
1065 { return m_tree.get_stored_allocator(); } | 1173 iterator begin(); |
1066 | 1174 |
1067 ////////////////////////////////////////////// | 1175 //! @copydoc ::boost::container::set::begin() const |
1068 // | 1176 const_iterator begin() const; |
1069 // iterators | 1177 |
1070 // | 1178 //! @copydoc ::boost::container::set::cbegin() const |
1071 ////////////////////////////////////////////// | 1179 const_iterator cbegin() const; |
1072 | 1180 |
1073 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. | 1181 //! @copydoc ::boost::container::set::end() |
1074 //! | 1182 iterator end() BOOST_NOEXCEPT_OR_NOTHROW; |
1075 //! <b>Throws</b>: Nothing. | 1183 |
1076 //! | 1184 //! @copydoc ::boost::container::set::end() const |
1077 //! <b>Complexity</b>: Constant. | 1185 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; |
1078 iterator begin() BOOST_CONTAINER_NOEXCEPT | 1186 |
1079 { return m_tree.begin(); } | 1187 //! @copydoc ::boost::container::set::cend() const |
1080 | 1188 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; |
1081 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | 1189 |
1082 //! | 1190 //! @copydoc ::boost::container::set::rbegin() |
1083 //! <b>Throws</b>: Nothing. | 1191 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; |
1084 //! | 1192 |
1085 //! <b>Complexity</b>: Constant. | 1193 //! @copydoc ::boost::container::set::rbegin() const |
1086 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT | 1194 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; |
1087 { return this->cbegin(); } | 1195 |
1088 | 1196 //! @copydoc ::boost::container::set::crbegin() const |
1089 //! <b>Effects</b>: Returns an iterator to the end of the container. | 1197 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; |
1090 //! | 1198 |
1091 //! <b>Throws</b>: Nothing. | 1199 //! @copydoc ::boost::container::set::rend() |
1092 //! | 1200 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; |
1093 //! <b>Complexity</b>: Constant. | 1201 |
1094 iterator end() BOOST_CONTAINER_NOEXCEPT | 1202 //! @copydoc ::boost::container::set::rend() const |
1095 { return m_tree.end(); } | 1203 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; |
1096 | 1204 |
1097 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | 1205 //! @copydoc ::boost::container::set::crend() const |
1098 //! | 1206 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; |
1099 //! <b>Throws</b>: Nothing. | 1207 |
1100 //! | 1208 //! @copydoc ::boost::container::set::empty() const |
1101 //! <b>Complexity</b>: Constant. | 1209 bool empty() const; |
1102 const_iterator end() const BOOST_CONTAINER_NOEXCEPT | 1210 |
1103 { return this->cend(); } | 1211 //! @copydoc ::boost::container::set::size() const |
1104 | 1212 size_type size() const; |
1105 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning | 1213 |
1106 //! of the reversed container. | 1214 //! @copydoc ::boost::container::set::max_size() const |
1107 //! | 1215 size_type max_size() const; |
1108 //! <b>Throws</b>: Nothing. | 1216 |
1109 //! | 1217 #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) |
1110 //! <b>Complexity</b>: Constant. | 1218 |
1111 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT | 1219 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) |
1112 { return m_tree.rbegin(); } | |
1113 | |
1114 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
1115 //! of the reversed container. | |
1116 //! | |
1117 //! <b>Throws</b>: Nothing. | |
1118 //! | |
1119 //! <b>Complexity</b>: Constant. | |
1120 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT | |
1121 { return this->crbegin(); } | |
1122 | |
1123 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end | |
1124 //! of the reversed container. | |
1125 //! | |
1126 //! <b>Throws</b>: Nothing. | |
1127 //! | |
1128 //! <b>Complexity</b>: Constant. | |
1129 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT | |
1130 { return m_tree.rend(); } | |
1131 | |
1132 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
1133 //! of the reversed container. | |
1134 //! | |
1135 //! <b>Throws</b>: Nothing. | |
1136 //! | |
1137 //! <b>Complexity</b>: Constant. | |
1138 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT | |
1139 { return this->crend(); } | |
1140 | |
1141 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
1142 //! | |
1143 //! <b>Throws</b>: Nothing. | |
1144 //! | |
1145 //! <b>Complexity</b>: Constant. | |
1146 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT | |
1147 { return m_tree.begin(); } | |
1148 | |
1149 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
1150 //! | |
1151 //! <b>Throws</b>: Nothing. | |
1152 //! | |
1153 //! <b>Complexity</b>: Constant. | |
1154 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT | |
1155 { return m_tree.end(); } | |
1156 | |
1157 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
1158 //! of the reversed container. | |
1159 //! | |
1160 //! <b>Throws</b>: Nothing. | |
1161 //! | |
1162 //! <b>Complexity</b>: Constant. | |
1163 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT | |
1164 { return m_tree.rbegin(); } | |
1165 | |
1166 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
1167 //! of the reversed container. | |
1168 //! | |
1169 //! <b>Throws</b>: Nothing. | |
1170 //! | |
1171 //! <b>Complexity</b>: Constant. | |
1172 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT | |
1173 { return m_tree.rend(); } | |
1174 | |
1175 ////////////////////////////////////////////// | |
1176 // | |
1177 // capacity | |
1178 // | |
1179 ////////////////////////////////////////////// | |
1180 | |
1181 //! <b>Effects</b>: Returns true if the container contains no elements. | |
1182 //! | |
1183 //! <b>Throws</b>: Nothing. | |
1184 //! | |
1185 //! <b>Complexity</b>: Constant. | |
1186 bool empty() const BOOST_CONTAINER_NOEXCEPT | |
1187 { return m_tree.empty(); } | |
1188 | |
1189 //! <b>Effects</b>: Returns the number of the elements contained in the container. | |
1190 //! | |
1191 //! <b>Throws</b>: Nothing. | |
1192 //! | |
1193 //! <b>Complexity</b>: Constant. | |
1194 size_type size() const BOOST_CONTAINER_NOEXCEPT | |
1195 { return m_tree.size(); } | |
1196 | |
1197 //! <b>Effects</b>: Returns the largest possible size of the container. | |
1198 //! | |
1199 //! <b>Throws</b>: Nothing. | |
1200 //! | |
1201 //! <b>Complexity</b>: Constant. | |
1202 size_type max_size() const BOOST_CONTAINER_NOEXCEPT | |
1203 { return m_tree.max_size(); } | |
1204 | |
1205 ////////////////////////////////////////////// | |
1206 // | |
1207 // modifiers | |
1208 // | |
1209 ////////////////////////////////////////////// | |
1210 | |
1211 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
1212 | 1220 |
1213 //! <b>Effects</b>: Inserts an object of type T constructed with | 1221 //! <b>Effects</b>: Inserts an object of type T constructed with |
1214 //! std::forward<Args>(args)... in the container. | 1222 //! std::forward<Args>(args)... in the container. |
1215 //! p is a hint pointing to where the insert should start to search. | 1223 //! p is a hint pointing to where the insert should start to search. |
1216 //! | 1224 //! |
1218 //! to the key of x. | 1226 //! to the key of x. |
1219 //! | 1227 //! |
1220 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | 1228 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t |
1221 //! is inserted right before p. | 1229 //! is inserted right before p. |
1222 template <class... Args> | 1230 template <class... Args> |
1223 iterator emplace(Args&&... args) | 1231 iterator emplace(BOOST_FWD_REF(Args)... args) |
1224 { return m_tree.emplace_equal(boost::forward<Args>(args)...); } | 1232 { return this->base_t::emplace_equal(boost::forward<Args>(args)...); } |
1225 | 1233 |
1226 //! <b>Effects</b>: Inserts an object of type T constructed with | 1234 //! <b>Effects</b>: Inserts an object of type T constructed with |
1227 //! std::forward<Args>(args)... in the container. | 1235 //! std::forward<Args>(args)... in the container. |
1228 //! p is a hint pointing to where the insert should start to search. | 1236 //! p is a hint pointing to where the insert should start to search. |
1229 //! | 1237 //! |
1231 //! to the key of x. | 1239 //! to the key of x. |
1232 //! | 1240 //! |
1233 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | 1241 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t |
1234 //! is inserted right before p. | 1242 //! is inserted right before p. |
1235 template <class... Args> | 1243 template <class... Args> |
1236 iterator emplace_hint(const_iterator hint, Args&&... args) | 1244 iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) |
1237 { return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); } | 1245 { return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); } |
1238 | 1246 |
1239 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | 1247 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) |
1240 | 1248 |
1241 #define BOOST_PP_LOCAL_MACRO(n) \ | 1249 #define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \ |
1242 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | 1250 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ |
1243 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | 1251 iterator emplace(BOOST_MOVE_UREF##N)\ |
1244 { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | 1252 { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\ |
1245 \ | 1253 \ |
1246 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | 1254 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ |
1247 iterator emplace_hint(const_iterator hint \ | 1255 iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ |
1248 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | 1256 { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ |
1249 { return m_tree.emplace_hint_equal(hint \ | 1257 // |
1250 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ | 1258 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE) |
1251 //! | 1259 #undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE |
1252 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | 1260 |
1253 #include BOOST_PP_LOCAL_ITERATE() | 1261 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) |
1254 | |
1255 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
1256 | 1262 |
1257 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the | 1263 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the |
1258 //! newly inserted element. | 1264 //! newly inserted element. |
1259 //! | 1265 //! |
1260 //! <b>Complexity</b>: Logarithmic. | 1266 //! <b>Complexity</b>: Logarithmic. |
1261 iterator insert(const value_type& x) | 1267 iterator insert(const value_type& x) |
1262 { return m_tree.insert_equal(x); } | 1268 { return this->base_t::insert_equal(x); } |
1263 | 1269 |
1264 //! <b>Effects</b>: Inserts a new value constructed from x and returns | 1270 //! <b>Effects</b>: Inserts a new value constructed from x and returns |
1265 //! the iterator pointing to the newly inserted element. | 1271 //! the iterator pointing to the newly inserted element. |
1266 //! | 1272 //! |
1267 //! <b>Complexity</b>: Logarithmic. | 1273 //! <b>Complexity</b>: Logarithmic. |
1268 iterator insert(const nonconst_value_type& x) | 1274 iterator insert(const nonconst_value_type& x) |
1269 { return m_tree.insert_equal(x); } | 1275 { return this->base_t::insert_equal(x); } |
1270 | 1276 |
1271 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns | 1277 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns |
1272 //! the iterator pointing to the newly inserted element. | 1278 //! the iterator pointing to the newly inserted element. |
1273 //! | 1279 //! |
1274 //! <b>Complexity</b>: Logarithmic. | 1280 //! <b>Complexity</b>: Logarithmic. |
1275 iterator insert(BOOST_RV_REF(nonconst_value_type) x) | 1281 iterator insert(BOOST_RV_REF(nonconst_value_type) x) |
1276 { return m_tree.insert_equal(boost::move(x)); } | 1282 { return this->base_t::insert_equal(boost::move(x)); } |
1277 | 1283 |
1278 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns | 1284 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns |
1279 //! the iterator pointing to the newly inserted element. | 1285 //! the iterator pointing to the newly inserted element. |
1280 //! | 1286 //! |
1281 //! <b>Complexity</b>: Logarithmic. | 1287 //! <b>Complexity</b>: Logarithmic. |
1282 iterator insert(BOOST_RV_REF(movable_value_type) x) | 1288 iterator insert(BOOST_RV_REF(movable_value_type) x) |
1283 { return m_tree.insert_equal(boost::move(x)); } | 1289 { return this->base_t::insert_equal(boost::move(x)); } |
1284 | 1290 |
1285 //! <b>Effects</b>: Inserts a copy of x in the container. | 1291 //! <b>Effects</b>: Inserts a copy of x in the container. |
1286 //! p is a hint pointing to where the insert should start to search. | 1292 //! p is a hint pointing to where the insert should start to search. |
1287 //! | 1293 //! |
1288 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | 1294 //! <b>Returns</b>: An iterator pointing to the element with key equivalent |
1289 //! to the key of x. | 1295 //! to the key of x. |
1290 //! | 1296 //! |
1291 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | 1297 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t |
1292 //! is inserted right before p. | 1298 //! is inserted right before p. |
1293 iterator insert(const_iterator position, const value_type& x) | 1299 iterator insert(const_iterator p, const value_type& x) |
1294 { return m_tree.insert_equal(position, x); } | 1300 { return this->base_t::insert_equal(p, x); } |
1295 | 1301 |
1296 //! <b>Effects</b>: Inserts a new value constructed from x in the container. | 1302 //! <b>Effects</b>: Inserts a new value constructed from x in the container. |
1297 //! p is a hint pointing to where the insert should start to search. | 1303 //! p is a hint pointing to where the insert should start to search. |
1298 //! | 1304 //! |
1299 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | 1305 //! <b>Returns</b>: An iterator pointing to the element with key equivalent |
1300 //! to the key of x. | 1306 //! to the key of x. |
1301 //! | 1307 //! |
1302 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | 1308 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t |
1303 //! is inserted right before p. | 1309 //! is inserted right before p. |
1304 iterator insert(const_iterator position, const nonconst_value_type& x) | 1310 iterator insert(const_iterator p, const nonconst_value_type& x) |
1305 { return m_tree.insert_equal(position, x); } | 1311 { return this->base_t::insert_equal(p, x); } |
1306 | 1312 |
1307 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. | 1313 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. |
1308 //! p is a hint pointing to where the insert should start to search. | 1314 //! p is a hint pointing to where the insert should start to search. |
1309 //! | 1315 //! |
1310 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | 1316 //! <b>Returns</b>: An iterator pointing to the element with key equivalent |
1311 //! to the key of x. | 1317 //! to the key of x. |
1312 //! | 1318 //! |
1313 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | 1319 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t |
1314 //! is inserted right before p. | 1320 //! is inserted right before p. |
1315 iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) | 1321 iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x) |
1316 { return m_tree.insert_equal(position, boost::move(x)); } | 1322 { return this->base_t::insert_equal(p, boost::move(x)); } |
1317 | 1323 |
1318 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. | 1324 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. |
1319 //! p is a hint pointing to where the insert should start to search. | 1325 //! p is a hint pointing to where the insert should start to search. |
1320 //! | 1326 //! |
1321 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | 1327 //! <b>Returns</b>: An iterator pointing to the element with key equivalent |
1322 //! to the key of x. | 1328 //! to the key of x. |
1323 //! | 1329 //! |
1324 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | 1330 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t |
1325 //! is inserted right before p. | 1331 //! is inserted right before p. |
1326 iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) | 1332 iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x) |
1327 { return m_tree.insert_equal(position, boost::move(x)); } | 1333 { return this->base_t::insert_equal(p, boost::move(x)); } |
1328 | 1334 |
1329 //! <b>Requires</b>: first, last are not iterators into *this. | 1335 //! <b>Requires</b>: first, last are not iterators into *this. |
1330 //! | 1336 //! |
1331 //! <b>Effects</b>: inserts each element from the range [first,last) . | 1337 //! <b>Effects</b>: inserts each element from the range [first,last) . |
1332 //! | 1338 //! |
1333 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | 1339 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) |
1334 template <class InputIterator> | 1340 template <class InputIterator> |
1335 void insert(InputIterator first, InputIterator last) | 1341 void insert(InputIterator first, InputIterator last) |
1336 { m_tree.insert_equal(first, last); } | 1342 { this->base_t::insert_equal(first, last); } |
1337 | 1343 |
1338 //! <b>Effects</b>: Erases the element pointed to by position. | 1344 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) |
1339 //! | 1345 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end(). |
1340 //! <b>Returns</b>: Returns an iterator pointing to the element immediately | 1346 //! |
1341 //! following q prior to the element being erased. If no such element exists, | 1347 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end()) |
1342 //! returns end(). | 1348 void insert(std::initializer_list<value_type> il) |
1343 //! | 1349 { this->base_t::insert_equal(il.begin(), il.end()); } |
1344 //! <b>Complexity</b>: Amortized constant time | 1350 #endif |
1345 iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT | 1351 |
1346 { return m_tree.erase(position); } | 1352 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) |
1347 | 1353 |
1348 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. | 1354 //! @copydoc ::boost::container::set::erase(const_iterator) |
1349 //! | 1355 iterator erase(const_iterator p); |
1350 //! <b>Returns</b>: Returns the number of erased elements. | 1356 |
1351 //! | 1357 //! @copydoc ::boost::container::set::erase(const key_type&) |
1352 //! <b>Complexity</b>: log(size()) + count(k) | 1358 size_type erase(const key_type& x); |
1353 size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT | 1359 |
1354 { return m_tree.erase(x); } | 1360 //! @copydoc ::boost::container::set::erase(const_iterator,const_iterator) |
1355 | 1361 iterator erase(const_iterator first, const_iterator last); |
1356 //! <b>Effects</b>: Erases all the elements in the range [first, last). | 1362 |
1357 //! | 1363 //! @copydoc ::boost::container::set::swap |
1358 //! <b>Returns</b>: Returns last. | 1364 void swap(multiset& x) |
1359 //! | 1365 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value |
1360 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. | 1366 && boost::container::container_detail::is_nothrow_swappable<Compare>::value ); |
1361 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT | 1367 |
1362 { return m_tree.erase(first, last); } | 1368 //! @copydoc ::boost::container::set::clear |
1363 | 1369 void clear() BOOST_NOEXCEPT_OR_NOTHROW; |
1364 //! <b>Effects</b>: Swaps the contents of *this and x. | 1370 |
1365 //! | 1371 //! @copydoc ::boost::container::set::key_comp |
1366 //! <b>Throws</b>: Nothing. | 1372 key_compare key_comp() const; |
1367 //! | 1373 |
1368 //! <b>Complexity</b>: Constant. | 1374 //! @copydoc ::boost::container::set::value_comp |
1369 void swap(multimap& x) | 1375 value_compare value_comp() const; |
1370 { m_tree.swap(x.m_tree); } | |
1371 | |
1372 //! <b>Effects</b>: erase(a.begin(),a.end()). | |
1373 //! | |
1374 //! <b>Postcondition</b>: size() == 0. | |
1375 //! | |
1376 //! <b>Complexity</b>: linear in size(). | |
1377 void clear() BOOST_CONTAINER_NOEXCEPT | |
1378 { m_tree.clear(); } | |
1379 | |
1380 ////////////////////////////////////////////// | |
1381 // | |
1382 // observers | |
1383 // | |
1384 ////////////////////////////////////////////// | |
1385 | |
1386 //! <b>Effects</b>: Returns the comparison object out | |
1387 //! of which a was constructed. | |
1388 //! | |
1389 //! <b>Complexity</b>: Constant. | |
1390 key_compare key_comp() const | |
1391 { return m_tree.key_comp(); } | |
1392 | |
1393 //! <b>Effects</b>: Returns an object of value_compare constructed out | |
1394 //! of the comparison object. | |
1395 //! | |
1396 //! <b>Complexity</b>: Constant. | |
1397 value_compare value_comp() const | |
1398 { return value_compare(m_tree.key_comp()); } | |
1399 | |
1400 ////////////////////////////////////////////// | |
1401 // | |
1402 // map operations | |
1403 // | |
1404 ////////////////////////////////////////////// | |
1405 | 1376 |
1406 //! <b>Returns</b>: An iterator pointing to an element with the key | 1377 //! <b>Returns</b>: An iterator pointing to an element with the key |
1407 //! equivalent to x, or end() if such an element is not found. | 1378 //! equivalent to x, or end() if such an element is not found. |
1408 //! | 1379 //! |
1409 //! <b>Complexity</b>: Logarithmic. | 1380 //! <b>Complexity</b>: Logarithmic. |
1410 iterator find(const key_type& x) | 1381 iterator find(const key_type& x); |
1411 { return m_tree.find(x); } | 1382 |
1412 | 1383 //! <b>Returns</b>: A const iterator pointing to an element with the key |
1413 //! <b>Returns</b>: Allocator const iterator pointing to an element with the key | |
1414 //! equivalent to x, or end() if such an element is not found. | 1384 //! equivalent to x, or end() if such an element is not found. |
1415 //! | 1385 //! |
1416 //! <b>Complexity</b>: Logarithmic. | 1386 //! <b>Complexity</b>: Logarithmic. |
1417 const_iterator find(const key_type& x) const | 1387 const_iterator find(const key_type& x) const; |
1418 { return m_tree.find(x); } | |
1419 | 1388 |
1420 //! <b>Returns</b>: The number of elements with key equivalent to x. | 1389 //! <b>Returns</b>: The number of elements with key equivalent to x. |
1421 //! | 1390 //! |
1422 //! <b>Complexity</b>: log(size())+count(k) | 1391 //! <b>Complexity</b>: log(size())+count(k) |
1423 size_type count(const key_type& x) const | 1392 size_type count(const key_type& x) const; |
1424 { return m_tree.count(x); } | |
1425 | 1393 |
1426 //! <b>Returns</b>: An iterator pointing to the first element with key not less | 1394 //! <b>Returns</b>: An iterator pointing to the first element with key not less |
1427 //! than k, or a.end() if such an element is not found. | 1395 //! than k, or a.end() if such an element is not found. |
1428 //! | 1396 //! |
1429 //! <b>Complexity</b>: Logarithmic | 1397 //! <b>Complexity</b>: Logarithmic |
1430 iterator lower_bound(const key_type& x) | 1398 iterator lower_bound(const key_type& x); |
1431 {return m_tree.lower_bound(x); } | 1399 |
1432 | 1400 //! <b>Returns</b>: A const iterator pointing to the first element with key not |
1433 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
1434 //! less than k, or a.end() if such an element is not found. | 1401 //! less than k, or a.end() if such an element is not found. |
1435 //! | 1402 //! |
1436 //! <b>Complexity</b>: Logarithmic | 1403 //! <b>Complexity</b>: Logarithmic |
1437 const_iterator lower_bound(const key_type& x) const | 1404 const_iterator lower_bound(const key_type& x) const; |
1438 { return m_tree.lower_bound(x); } | |
1439 | 1405 |
1440 //! <b>Returns</b>: An iterator pointing to the first element with key not less | 1406 //! <b>Returns</b>: An iterator pointing to the first element with key not less |
1441 //! than x, or end() if such an element is not found. | 1407 //! than x, or end() if such an element is not found. |
1442 //! | 1408 //! |
1443 //! <b>Complexity</b>: Logarithmic | 1409 //! <b>Complexity</b>: Logarithmic |
1444 iterator upper_bound(const key_type& x) | 1410 iterator upper_bound(const key_type& x); |
1445 { return m_tree.upper_bound(x); } | 1411 |
1446 | 1412 //! <b>Returns</b>: A const iterator pointing to the first element with key not |
1447 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
1448 //! less than x, or end() if such an element is not found. | 1413 //! less than x, or end() if such an element is not found. |
1449 //! | 1414 //! |
1450 //! <b>Complexity</b>: Logarithmic | 1415 //! <b>Complexity</b>: Logarithmic |
1451 const_iterator upper_bound(const key_type& x) const | 1416 const_iterator upper_bound(const key_type& x) const; |
1452 { return m_tree.upper_bound(x); } | |
1453 | 1417 |
1454 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | 1418 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). |
1455 //! | 1419 //! |
1456 //! <b>Complexity</b>: Logarithmic | 1420 //! <b>Complexity</b>: Logarithmic |
1457 std::pair<iterator,iterator> equal_range(const key_type& x) | 1421 std::pair<iterator,iterator> equal_range(const key_type& x); |
1458 { return m_tree.equal_range(x); } | |
1459 | 1422 |
1460 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | 1423 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). |
1461 //! | 1424 //! |
1462 //! <b>Complexity</b>: Logarithmic | 1425 //! <b>Complexity</b>: Logarithmic |
1463 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const | 1426 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const; |
1464 { return m_tree.equal_range(x); } | 1427 |
1465 | 1428 //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees. |
1466 /// @cond | 1429 //! |
1467 template <class K1, class T1, class C1, class A1> | 1430 //! <b>Complexity</b>: Linear |
1468 friend bool operator== (const multimap<K1, T1, C1, A1>& x, | 1431 void rebalance(); |
1469 const multimap<K1, T1, C1, A1>& y); | 1432 |
1470 | 1433 //! <b>Effects</b>: Returns true if x and y are equal |
1471 template <class K1, class T1, class C1, class A1> | 1434 //! |
1472 friend bool operator< (const multimap<K1, T1, C1, A1>& x, | 1435 //! <b>Complexity</b>: Linear to the number of elements in the container. |
1473 const multimap<K1, T1, C1, A1>& y); | 1436 friend bool operator==(const multimap& x, const multimap& y); |
1474 /// @endcond | 1437 |
1438 //! <b>Effects</b>: Returns true if x and y are unequal | |
1439 //! | |
1440 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
1441 friend bool operator!=(const multimap& x, const multimap& y); | |
1442 | |
1443 //! <b>Effects</b>: Returns true if x is less than y | |
1444 //! | |
1445 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
1446 friend bool operator<(const multimap& x, const multimap& y); | |
1447 | |
1448 //! <b>Effects</b>: Returns true if x is greater than y | |
1449 //! | |
1450 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
1451 friend bool operator>(const multimap& x, const multimap& y); | |
1452 | |
1453 //! <b>Effects</b>: Returns true if x is equal or less than y | |
1454 //! | |
1455 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
1456 friend bool operator<=(const multimap& x, const multimap& y); | |
1457 | |
1458 //! <b>Effects</b>: Returns true if x is equal or greater than y | |
1459 //! | |
1460 //! <b>Complexity</b>: Linear to the number of elements in the container. | |
1461 friend bool operator>=(const multimap& x, const multimap& y); | |
1462 | |
1463 //! <b>Effects</b>: x.swap(y) | |
1464 //! | |
1465 //! <b>Complexity</b>: Constant. | |
1466 friend void swap(multimap& x, multimap& y); | |
1467 | |
1468 #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
1475 }; | 1469 }; |
1476 | 1470 |
1477 template <class Key, class T, class Compare, class Allocator> | 1471 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED |
1478 inline bool operator==(const multimap<Key,T,Compare,Allocator>& x, | |
1479 const multimap<Key,T,Compare,Allocator>& y) | |
1480 { return x.m_tree == y.m_tree; } | |
1481 | |
1482 template <class Key, class T, class Compare, class Allocator> | |
1483 inline bool operator<(const multimap<Key,T,Compare,Allocator>& x, | |
1484 const multimap<Key,T,Compare,Allocator>& y) | |
1485 { return x.m_tree < y.m_tree; } | |
1486 | |
1487 template <class Key, class T, class Compare, class Allocator> | |
1488 inline bool operator!=(const multimap<Key,T,Compare,Allocator>& x, | |
1489 const multimap<Key,T,Compare,Allocator>& y) | |
1490 { return !(x == y); } | |
1491 | |
1492 template <class Key, class T, class Compare, class Allocator> | |
1493 inline bool operator>(const multimap<Key,T,Compare,Allocator>& x, | |
1494 const multimap<Key,T,Compare,Allocator>& y) | |
1495 { return y < x; } | |
1496 | |
1497 template <class Key, class T, class Compare, class Allocator> | |
1498 inline bool operator<=(const multimap<Key,T,Compare,Allocator>& x, | |
1499 const multimap<Key,T,Compare,Allocator>& y) | |
1500 { return !(y < x); } | |
1501 | |
1502 template <class Key, class T, class Compare, class Allocator> | |
1503 inline bool operator>=(const multimap<Key,T,Compare,Allocator>& x, | |
1504 const multimap<Key,T,Compare,Allocator>& y) | |
1505 { return !(x < y); } | |
1506 | |
1507 template <class Key, class T, class Compare, class Allocator> | |
1508 inline void swap(multimap<Key,T,Compare,Allocator>& x, multimap<Key,T,Compare,Allocator>& y) | |
1509 { x.swap(y); } | |
1510 | |
1511 /// @cond | |
1512 | 1472 |
1513 } //namespace container { | 1473 } //namespace container { |
1514 | 1474 |
1515 //!has_trivial_destructor_after_move<> == true_type | 1475 //!has_trivial_destructor_after_move<> == true_type |
1516 //!specialization for optimizations | 1476 //!specialization for optimizations |
1517 template <class K, class T, class C, class Allocator> | 1477 template <class Key, class T, class Compare, class Allocator> |
1518 struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> > | 1478 struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator> > |
1519 { | 1479 { |
1520 static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value; | 1480 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; |
1481 static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && | |
1482 ::boost::has_trivial_destructor_after_move<pointer>::value && | |
1483 ::boost::has_trivial_destructor_after_move<Compare>::value; | |
1521 }; | 1484 }; |
1522 | 1485 |
1523 namespace container { | 1486 namespace container { |
1524 | 1487 |
1525 /// @endcond | 1488 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED |
1526 | 1489 |
1527 }} | 1490 }} |
1528 | 1491 |
1529 #include <boost/container/detail/config_end.hpp> | 1492 #include <boost/container/detail/config_end.hpp> |
1530 | 1493 |
1531 #endif /* BOOST_CONTAINER_MAP_HPP */ | 1494 #endif // BOOST_CONTAINER_MAP_HPP |
1532 | 1495 |