Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/container/map.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 ////////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost | |
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) | |
6 // | |
7 // See http://www.boost.org/libs/container for documentation. | |
8 // | |
9 ////////////////////////////////////////////////////////////////////////////// | |
10 | |
11 #ifndef BOOST_CONTAINER_MAP_HPP | |
12 #define BOOST_CONTAINER_MAP_HPP | |
13 | |
14 #if defined(_MSC_VER) | |
15 # pragma once | |
16 #endif | |
17 | |
18 #include <boost/container/detail/config_begin.hpp> | |
19 #include <boost/container/detail/workaround.hpp> | |
20 | |
21 #include <boost/container/container_fwd.hpp> | |
22 #include <utility> | |
23 #include <functional> | |
24 #include <memory> | |
25 #include <boost/container/detail/tree.hpp> | |
26 #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> | |
31 #include <boost/container/detail/type_traits.hpp> | |
32 #include <boost/container/throw_exception.hpp> | |
33 #include <boost/move/utility.hpp> | |
34 #include <boost/move/detail/move_helpers.hpp> | |
35 #include <boost/static_assert.hpp> | |
36 #include <boost/container/detail/value_init.hpp> | |
37 #include <boost/detail/no_exceptions_support.hpp> | |
38 | |
39 namespace boost { | |
40 namespace container { | |
41 | |
42 /// @cond | |
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 | |
53 //! 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 | |
55 //! type T based on the keys. The map class supports bidirectional iterators. | |
56 //! | |
57 //! A map satisfies all of the requirements of a container and of a reversible | |
58 //! container and of an associative container. For a | |
59 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>. | |
60 //! | |
61 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). | |
62 //! | |
63 //! Allocator is the allocator to allocate the value_types | |
64 //! (e.g. <i>allocator< std::pair<const Key, T> > </i>). | |
65 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
66 template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > > | |
67 #else | |
68 template <class Key, class T, class Compare, class Allocator> | |
69 #endif | |
70 class map | |
71 { | |
72 /// @cond | |
73 private: | |
74 BOOST_COPYABLE_AND_MOVABLE(map) | |
75 | |
76 typedef std::pair<const Key, T> value_type_impl; | |
77 typedef container_detail::rbtree | |
78 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t; | |
79 typedef container_detail::pair <Key, T> movable_value_type_impl; | |
80 typedef container_detail::tree_value_compare | |
81 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> | |
82 > value_compare_impl; | |
83 tree_t m_tree; // red-black tree representing map | |
84 /// @endcond | |
85 | |
86 public: | |
87 ////////////////////////////////////////////// | |
88 // | |
89 // types | |
90 // | |
91 ////////////////////////////////////////////// | |
92 | |
93 typedef Key key_type; | |
94 typedef T mapped_type; | |
95 typedef std::pair<const Key, T> value_type; | |
96 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; | |
97 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; | |
98 typedef typename boost::container::allocator_traits<Allocator>::reference reference; | |
99 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; | |
100 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; | |
101 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; | |
102 typedef Allocator allocator_type; | |
103 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; | |
104 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; | |
105 typedef Compare key_compare; | |
106 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; | |
107 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; | |
108 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; | |
109 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; | |
110 typedef std::pair<key_type, mapped_type> nonconst_value_type; | |
111 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; | |
112 | |
113 ////////////////////////////////////////////// | |
114 // | |
115 // construct/copy/destroy | |
116 // | |
117 ////////////////////////////////////////////// | |
118 | |
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. | |
924 //! | |
925 //! <b>Complexity</b>: Constant. | |
926 multimap() | |
927 : m_tree() | |
928 { | |
929 //Allocator 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)); | |
931 } | |
932 | |
933 //! <b>Effects</b>: Constructs an empty multimap using the specified allocator. | |
934 //! | |
935 //! <b>Complexity</b>: Constant. | |
936 explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) | |
937 : m_tree(comp, a) | |
938 { | |
939 //Allocator 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)); | |
941 } | |
942 | |
943 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison | |
944 //! object and allocator. | |
945 //! | |
946 //! <b>Complexity</b>: Constant. | |
947 explicit multimap(const allocator_type& a) | |
948 : m_tree(a) | |
949 { | |
950 //Allocator 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)); | |
952 } | |
953 | |
954 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object | |
955 //! and allocator, and inserts elements from the range [first ,last ). | |
956 //! | |
957 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
958 //! comp and otherwise N logN, where N is last - first. | |
959 template <class InputIterator> | |
960 multimap(InputIterator first, InputIterator last, | |
961 const Compare& comp = Compare(), | |
962 const allocator_type& a = allocator_type()) | |
963 : m_tree(false, first, last, comp, a) | |
964 { | |
965 //Allocator 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)); | |
967 } | |
968 | |
969 //! <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 | |
971 //! is more efficient than the normal range creation for ordered ranges. | |
972 //! | |
973 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate. | |
974 //! | |
975 //! <b>Complexity</b>: Linear in N. | |
976 //! | |
977 //! <b>Note</b>: Non-standard extension. | |
978 template <class InputIterator> | |
979 multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), | |
980 const allocator_type& a = allocator_type()) | |
981 : m_tree(ordered_range, first, last, comp, a) | |
982 {} | |
983 | |
984 //! <b>Effects</b>: Copy constructs a multimap. | |
985 //! | |
986 //! <b>Complexity</b>: Linear in x.size(). | |
987 multimap(const multimap& x) | |
988 : m_tree(x.m_tree) | |
989 { | |
990 //Allocator 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)); | |
992 } | |
993 | |
994 //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources. | |
995 //! | |
996 //! <b>Complexity</b>: Constant. | |
997 //! | |
998 //! <b>Postcondition</b>: x is emptied. | |
999 multimap(BOOST_RV_REF(multimap) x) | |
1000 : m_tree(boost::move(x.m_tree)) | |
1001 { | |
1002 //Allocator 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)); | |
1004 } | |
1005 | |
1006 //! <b>Effects</b>: Copy constructs a multimap. | |
1007 //! | |
1008 //! <b>Complexity</b>: Linear in x.size(). | |
1009 multimap(const multimap& x, const allocator_type &a) | |
1010 : m_tree(x.m_tree, a) | |
1011 { | |
1012 //Allocator 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)); | |
1014 } | |
1015 | |
1016 //! <b>Effects</b>: Move constructs a multimap using the specified allocator. | |
1017 //! Constructs *this using x's resources. | |
1018 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. | |
1019 //! | |
1020 //! <b>Postcondition</b>: x is emptied. | |
1021 multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) | |
1022 : m_tree(boost::move(x.m_tree), a) | |
1023 { | |
1024 //Allocator 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)); | |
1026 } | |
1027 | |
1028 //! <b>Effects</b>: Makes *this a copy of x. | |
1029 //! | |
1030 //! <b>Complexity</b>: Linear in x.size(). | |
1031 multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) | |
1032 { m_tree = x.m_tree; return *this; } | |
1033 | |
1034 //! <b>Effects</b>: this->swap(x.get()). | |
1035 //! | |
1036 //! <b>Complexity</b>: Constant. | |
1037 multimap& operator=(BOOST_RV_REF(multimap) x) | |
1038 { m_tree = boost::move(x.m_tree); return *this; } | |
1039 | |
1040 //! <b>Effects</b>: Returns a copy of the Allocator that | |
1041 //! was passed to the object's constructor. | |
1042 //! | |
1043 //! <b>Complexity</b>: Constant. | |
1044 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT | |
1045 { return m_tree.get_allocator(); } | |
1046 | |
1047 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
1048 //! | |
1049 //! <b>Throws</b>: Nothing | |
1050 //! | |
1051 //! <b>Complexity</b>: Constant. | |
1052 //! | |
1053 //! <b>Note</b>: Non-standard extension. | |
1054 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT | |
1055 { return m_tree.get_stored_allocator(); } | |
1056 | |
1057 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
1058 //! | |
1059 //! <b>Throws</b>: Nothing | |
1060 //! | |
1061 //! <b>Complexity</b>: Constant. | |
1062 //! | |
1063 //! <b>Note</b>: Non-standard extension. | |
1064 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT | |
1065 { return m_tree.get_stored_allocator(); } | |
1066 | |
1067 ////////////////////////////////////////////// | |
1068 // | |
1069 // iterators | |
1070 // | |
1071 ////////////////////////////////////////////// | |
1072 | |
1073 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. | |
1074 //! | |
1075 //! <b>Throws</b>: Nothing. | |
1076 //! | |
1077 //! <b>Complexity</b>: Constant. | |
1078 iterator begin() BOOST_CONTAINER_NOEXCEPT | |
1079 { return m_tree.begin(); } | |
1080 | |
1081 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
1082 //! | |
1083 //! <b>Throws</b>: Nothing. | |
1084 //! | |
1085 //! <b>Complexity</b>: Constant. | |
1086 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT | |
1087 { return this->cbegin(); } | |
1088 | |
1089 //! <b>Effects</b>: Returns an iterator to the end of the container. | |
1090 //! | |
1091 //! <b>Throws</b>: Nothing. | |
1092 //! | |
1093 //! <b>Complexity</b>: Constant. | |
1094 iterator end() BOOST_CONTAINER_NOEXCEPT | |
1095 { return m_tree.end(); } | |
1096 | |
1097 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
1098 //! | |
1099 //! <b>Throws</b>: Nothing. | |
1100 //! | |
1101 //! <b>Complexity</b>: Constant. | |
1102 const_iterator end() const BOOST_CONTAINER_NOEXCEPT | |
1103 { return this->cend(); } | |
1104 | |
1105 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning | |
1106 //! of the reversed container. | |
1107 //! | |
1108 //! <b>Throws</b>: Nothing. | |
1109 //! | |
1110 //! <b>Complexity</b>: Constant. | |
1111 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT | |
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 | |
1213 //! <b>Effects</b>: Inserts an object of type T constructed with | |
1214 //! std::forward<Args>(args)... in the container. | |
1215 //! p is a hint pointing to where the insert should start to search. | |
1216 //! | |
1217 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1218 //! to the key of x. | |
1219 //! | |
1220 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
1221 //! is inserted right before p. | |
1222 template <class... Args> | |
1223 iterator emplace(Args&&... args) | |
1224 { return m_tree.emplace_equal(boost::forward<Args>(args)...); } | |
1225 | |
1226 //! <b>Effects</b>: Inserts an object of type T constructed with | |
1227 //! std::forward<Args>(args)... in the container. | |
1228 //! p is a hint pointing to where the insert should start to search. | |
1229 //! | |
1230 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1231 //! to the key of x. | |
1232 //! | |
1233 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
1234 //! is inserted right before p. | |
1235 template <class... Args> | |
1236 iterator emplace_hint(const_iterator hint, Args&&... args) | |
1237 { return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); } | |
1238 | |
1239 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
1240 | |
1241 #define BOOST_PP_LOCAL_MACRO(n) \ | |
1242 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
1243 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
1244 { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
1245 \ | |
1246 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
1247 iterator emplace_hint(const_iterator hint \ | |
1248 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
1249 { return m_tree.emplace_hint_equal(hint \ | |
1250 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ | |
1251 //! | |
1252 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
1253 #include BOOST_PP_LOCAL_ITERATE() | |
1254 | |
1255 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
1256 | |
1257 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the | |
1258 //! newly inserted element. | |
1259 //! | |
1260 //! <b>Complexity</b>: Logarithmic. | |
1261 iterator insert(const value_type& x) | |
1262 { return m_tree.insert_equal(x); } | |
1263 | |
1264 //! <b>Effects</b>: Inserts a new value constructed from x and returns | |
1265 //! the iterator pointing to the newly inserted element. | |
1266 //! | |
1267 //! <b>Complexity</b>: Logarithmic. | |
1268 iterator insert(const nonconst_value_type& x) | |
1269 { return m_tree.insert_equal(x); } | |
1270 | |
1271 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns | |
1272 //! the iterator pointing to the newly inserted element. | |
1273 //! | |
1274 //! <b>Complexity</b>: Logarithmic. | |
1275 iterator insert(BOOST_RV_REF(nonconst_value_type) x) | |
1276 { return m_tree.insert_equal(boost::move(x)); } | |
1277 | |
1278 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns | |
1279 //! the iterator pointing to the newly inserted element. | |
1280 //! | |
1281 //! <b>Complexity</b>: Logarithmic. | |
1282 iterator insert(BOOST_RV_REF(movable_value_type) x) | |
1283 { return m_tree.insert_equal(boost::move(x)); } | |
1284 | |
1285 //! <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. | |
1287 //! | |
1288 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1289 //! to the key of x. | |
1290 //! | |
1291 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
1292 //! is inserted right before p. | |
1293 iterator insert(const_iterator position, const value_type& x) | |
1294 { return m_tree.insert_equal(position, x); } | |
1295 | |
1296 //! <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. | |
1298 //! | |
1299 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1300 //! to the key of x. | |
1301 //! | |
1302 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
1303 //! is inserted right before p. | |
1304 iterator insert(const_iterator position, const nonconst_value_type& x) | |
1305 { return m_tree.insert_equal(position, x); } | |
1306 | |
1307 //! <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. | |
1309 //! | |
1310 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1311 //! to the key of x. | |
1312 //! | |
1313 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
1314 //! is inserted right before p. | |
1315 iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) | |
1316 { return m_tree.insert_equal(position, boost::move(x)); } | |
1317 | |
1318 //! <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. | |
1320 //! | |
1321 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1322 //! to the key of x. | |
1323 //! | |
1324 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t | |
1325 //! is inserted right before p. | |
1326 iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) | |
1327 { return m_tree.insert_equal(position, boost::move(x)); } | |
1328 | |
1329 //! <b>Requires</b>: first, last are not iterators into *this. | |
1330 //! | |
1331 //! <b>Effects</b>: inserts each element from the range [first,last) . | |
1332 //! | |
1333 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
1334 template <class InputIterator> | |
1335 void insert(InputIterator first, InputIterator last) | |
1336 { m_tree.insert_equal(first, last); } | |
1337 | |
1338 //! <b>Effects</b>: Erases the element pointed to by position. | |
1339 //! | |
1340 //! <b>Returns</b>: Returns an iterator pointing to the element immediately | |
1341 //! following q prior to the element being erased. If no such element exists, | |
1342 //! returns end(). | |
1343 //! | |
1344 //! <b>Complexity</b>: Amortized constant time | |
1345 iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT | |
1346 { return m_tree.erase(position); } | |
1347 | |
1348 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. | |
1349 //! | |
1350 //! <b>Returns</b>: Returns the number of erased elements. | |
1351 //! | |
1352 //! <b>Complexity</b>: log(size()) + count(k) | |
1353 size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT | |
1354 { return m_tree.erase(x); } | |
1355 | |
1356 //! <b>Effects</b>: Erases all the elements in the range [first, last). | |
1357 //! | |
1358 //! <b>Returns</b>: Returns last. | |
1359 //! | |
1360 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. | |
1361 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT | |
1362 { return m_tree.erase(first, last); } | |
1363 | |
1364 //! <b>Effects</b>: Swaps the contents of *this and x. | |
1365 //! | |
1366 //! <b>Throws</b>: Nothing. | |
1367 //! | |
1368 //! <b>Complexity</b>: Constant. | |
1369 void swap(multimap& x) | |
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 | |
1406 //! <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. | |
1408 //! | |
1409 //! <b>Complexity</b>: Logarithmic. | |
1410 iterator find(const key_type& x) | |
1411 { return m_tree.find(x); } | |
1412 | |
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. | |
1415 //! | |
1416 //! <b>Complexity</b>: Logarithmic. | |
1417 const_iterator find(const key_type& x) const | |
1418 { return m_tree.find(x); } | |
1419 | |
1420 //! <b>Returns</b>: The number of elements with key equivalent to x. | |
1421 //! | |
1422 //! <b>Complexity</b>: log(size())+count(k) | |
1423 size_type count(const key_type& x) const | |
1424 { return m_tree.count(x); } | |
1425 | |
1426 //! <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. | |
1428 //! | |
1429 //! <b>Complexity</b>: Logarithmic | |
1430 iterator lower_bound(const key_type& x) | |
1431 {return m_tree.lower_bound(x); } | |
1432 | |
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. | |
1435 //! | |
1436 //! <b>Complexity</b>: Logarithmic | |
1437 const_iterator lower_bound(const key_type& x) const | |
1438 { return m_tree.lower_bound(x); } | |
1439 | |
1440 //! <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. | |
1442 //! | |
1443 //! <b>Complexity</b>: Logarithmic | |
1444 iterator upper_bound(const key_type& x) | |
1445 { return m_tree.upper_bound(x); } | |
1446 | |
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. | |
1449 //! | |
1450 //! <b>Complexity</b>: Logarithmic | |
1451 const_iterator upper_bound(const key_type& x) const | |
1452 { return m_tree.upper_bound(x); } | |
1453 | |
1454 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
1455 //! | |
1456 //! <b>Complexity</b>: Logarithmic | |
1457 std::pair<iterator,iterator> equal_range(const key_type& x) | |
1458 { return m_tree.equal_range(x); } | |
1459 | |
1460 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
1461 //! | |
1462 //! <b>Complexity</b>: Logarithmic | |
1463 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const | |
1464 { return m_tree.equal_range(x); } | |
1465 | |
1466 /// @cond | |
1467 template <class K1, class T1, class C1, class A1> | |
1468 friend bool operator== (const multimap<K1, T1, C1, A1>& x, | |
1469 const multimap<K1, T1, C1, A1>& y); | |
1470 | |
1471 template <class K1, class T1, class C1, class A1> | |
1472 friend bool operator< (const multimap<K1, T1, C1, A1>& x, | |
1473 const multimap<K1, T1, C1, A1>& y); | |
1474 /// @endcond | |
1475 }; | |
1476 | |
1477 template <class Key, class T, class Compare, class Allocator> | |
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 | |
1513 } //namespace container { | |
1514 | |
1515 //!has_trivial_destructor_after_move<> == true_type | |
1516 //!specialization for optimizations | |
1517 template <class K, class T, class C, class Allocator> | |
1518 struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> > | |
1519 { | |
1520 static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value; | |
1521 }; | |
1522 | |
1523 namespace container { | |
1524 | |
1525 /// @endcond | |
1526 | |
1527 }} | |
1528 | |
1529 #include <boost/container/detail/config_end.hpp> | |
1530 | |
1531 #endif /* BOOST_CONTAINER_MAP_HPP */ | |
1532 |