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