]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/container/flat_map.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / container / flat_map.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 #ifndef BOOST_CONTAINER_FLAT_MAP_HPP
11 #define BOOST_CONTAINER_FLAT_MAP_HPP
12
13 #ifndef BOOST_CONFIG_HPP
14 # include <boost/config.hpp>
15 #endif
16
17 #if defined(BOOST_HAS_PRAGMA_ONCE)
18 # pragma once
19 #endif
20
21 #include <boost/container/detail/config_begin.hpp>
22 #include <boost/container/detail/workaround.hpp>
23 // container
24 #include <boost/container/allocator_traits.hpp>
25 #include <boost/container/container_fwd.hpp>
26 #include <boost/container/new_allocator.hpp> //new_allocator
27 #include <boost/container/throw_exception.hpp>
28 // container/detail
29 #include <boost/container/detail/flat_tree.hpp>
30 #include <boost/container/detail/type_traits.hpp>
31 #include <boost/container/detail/mpl.hpp>
32 #include <boost/container/detail/algorithm.hpp> //equal()
33 #include <boost/container/detail/container_or_allocator_rebind.hpp>
34 // move
35 #include <boost/move/utility_core.hpp>
36 #include <boost/move/traits.hpp>
37 // move/detail
38 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
39 #include <boost/move/detail/fwd_macros.hpp>
40 #endif
41 #include <boost/move/detail/move_helpers.hpp>
42 // intrusive
43 #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
44 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
45 //others
46 #include <boost/core/no_exceptions_support.hpp>
47
48 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
49 #include <initializer_list>
50 #endif
51
52 namespace boost {
53 namespace container {
54
55 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
56
57 template <class Key, class T, class Compare, class AllocatorOrContainer>
58 class flat_multimap;
59
60 namespace container_detail{
61
62 template<class D, class S>
63 BOOST_CONTAINER_FORCEINLINE static D &force(S &s)
64 { return *reinterpret_cast<D*>(&s); }
65
66 template<class D, class S>
67 BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s)
68 {
69 const D *const vp = reinterpret_cast<const D *>(&s);
70 D ret_val(*vp);
71 return ret_val;
72 }
73
74 } //namespace container_detail{
75
76 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
77
78 //! A flat_map is a kind of associative container that supports unique keys (contains at
79 //! most one of each key value) and provides for fast retrieval of values of another
80 //! type T based on the keys.
81 //!
82 //! A flat_map satisfies all of the requirements of a container, a reversible
83 //! container and an associative container. A flat_map also provides
84 //! most operations described for unique keys. For a
85 //! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
86 //! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
87 //!
88 //! flat_map is similar to std::map but it's implemented by as an ordered sequence container.
89 //! The underlying sequence container is by default <i>vector</i> but it can also work
90 //! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
91 //!
92 //! Using vector-like sequence containers means that inserting a new element into a flat_map might invalidate
93 //! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
94 //! container that offers stable pointers and references). Similarly, erasing an element might invalidate
95 //! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
96 //!
97 //! This container provides random-access iterators.
98 //!
99 //! \tparam Key is the key_type of the map
100 //! \tparam Value is the <code>mapped_type</code>
101 //! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
102 //! \tparam AllocatorOrContainer is either:
103 //! - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
104 //! (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
105 //! - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
106 //! sequence container with random-access iterators..
107 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
108 template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
109 #else
110 template <class Key, class T, class Compare, class AllocatorOrContainer>
111 #endif
112 class flat_map
113 {
114 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
115 private:
116 BOOST_COPYABLE_AND_MOVABLE(flat_map)
117 //This is the tree that we should store if pair was movable
118 typedef container_detail::flat_tree<
119 std::pair<Key, T>,
120 container_detail::select1st<Key>,
121 Compare,
122 AllocatorOrContainer> tree_t;
123
124 //This is the real tree stored here. It's based on a movable pair
125 typedef container_detail::flat_tree<
126 container_detail::pair<Key, T>,
127 container_detail::select1st<Key>,
128 Compare,
129 typename container_detail::container_or_allocator_rebind<AllocatorOrContainer, container_detail::pair<Key, T> >::type
130 > impl_tree_t;
131 impl_tree_t m_flat_tree; // flat tree representing flat_map
132
133 typedef typename impl_tree_t::value_type impl_value_type;
134 typedef typename impl_tree_t::const_iterator impl_const_iterator;
135 typedef typename impl_tree_t::iterator impl_iterator;
136 typedef typename impl_tree_t::allocator_type impl_allocator_type;
137 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
138 typedef std::initializer_list<impl_value_type> impl_initializer_list;
139 #endif
140
141 typedef container_detail::flat_tree_value_compare
142 < Compare
143 , container_detail::select1st<Key>
144 , std::pair<Key, T> > value_compare_t;
145 typedef typename tree_t::iterator iterator_t;
146 typedef typename tree_t::const_iterator const_iterator_t;
147 typedef typename tree_t::reverse_iterator reverse_iterator_t;
148 typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t;
149
150 public:
151 typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
152 typedef typename impl_tree_t::sequence_type impl_sequence_type;
153
154 BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
155 { return m_flat_tree; }
156
157 BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
158 { return m_flat_tree; }
159
160 private:
161 typedef typename tree_t::get_stored_allocator_const_return_t get_stored_allocator_const_return_t;
162 typedef typename tree_t::get_stored_allocator_noconst_return_t get_stored_allocator_noconst_return_t;
163 typedef typename impl_tree_t::get_stored_allocator_const_return_t impl_get_stored_allocator_const_return_t;
164 typedef typename impl_tree_t::get_stored_allocator_noconst_return_t impl_get_stored_allocator_noconst_return_t;
165
166 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
167
168 public:
169
170 //////////////////////////////////////////////
171 //
172 // types
173 //
174 //////////////////////////////////////////////
175 typedef Key key_type;
176 typedef T mapped_type;
177 typedef Compare key_compare;
178 typedef std::pair<Key, T> value_type;
179 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
180 typedef typename sequence_type::allocator_type allocator_type;
181 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
182 typedef typename sequence_type::pointer pointer;
183 typedef typename sequence_type::const_pointer const_pointer;
184 typedef typename sequence_type::reference reference;
185 typedef typename sequence_type::const_reference const_reference;
186 typedef typename sequence_type::size_type size_type;
187 typedef typename sequence_type::difference_type difference_type;
188 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
189 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
190
191 typedef typename sequence_type::iterator iterator;
192 typedef typename sequence_type::const_iterator const_iterator;
193 typedef typename sequence_type::reverse_iterator reverse_iterator;
194 typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
195 typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
196
197 //AllocatorOrContainer::value_type must be std::pair<Key, T>
198 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename allocator_type::value_type>::value));
199
200 //////////////////////////////////////////////
201 //
202 // construct/copy/destroy
203 //
204 //////////////////////////////////////////////
205
206 //! <b>Effects</b>: Default constructs an empty flat_map.
207 //!
208 //! <b>Complexity</b>: Constant.
209 BOOST_CONTAINER_FORCEINLINE flat_map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
210 container_detail::is_nothrow_default_constructible<Compare>::value)
211 : m_flat_tree()
212 {}
213
214 //! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
215 //!
216 //! <b>Complexity</b>: Constant.
217 BOOST_CONTAINER_FORCEINLINE explicit flat_map(const allocator_type& a)
218 : m_flat_tree(container_detail::force<const impl_allocator_type>(a))
219 {}
220
221 //! <b>Effects</b>: Constructs an empty flat_map using the specified
222 //! comparison object.
223 //!
224 //! <b>Complexity</b>: Constant.
225 BOOST_CONTAINER_FORCEINLINE explicit flat_map(const Compare& comp)
226 : m_flat_tree(comp)
227 {}
228
229 //! <b>Effects</b>: Constructs an empty flat_map using the specified
230 //! comparison object and allocator.
231 //!
232 //! <b>Complexity</b>: Constant.
233 BOOST_CONTAINER_FORCEINLINE flat_map(const Compare& comp, const allocator_type& a)
234 : m_flat_tree(comp, container_detail::force<const impl_allocator_type>(a))
235 {}
236
237 //! <b>Effects</b>: Constructs an empty flat_map and
238 //! and inserts elements from the range [first ,last ).
239 //!
240 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
241 //! the predicate and otherwise N logN, where N is last - first.
242 template <class InputIterator>
243 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last)
244 : m_flat_tree(true, first, last)
245 {}
246
247 //! <b>Effects</b>: Constructs an empty flat_map using the specified
248 //! allocator, and inserts elements from the range [first ,last ).
249 //!
250 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
251 //! the predicate and otherwise N logN, where N is last - first.
252 template <class InputIterator>
253 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const allocator_type& a)
254 : m_flat_tree(true, first, last, container_detail::force<const impl_allocator_type>(a))
255 {}
256
257 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
258 //! and inserts elements from the range [first ,last ).
259 //!
260 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
261 //! the predicate and otherwise N logN, where N is last - first.
262 template <class InputIterator>
263 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp)
264 : m_flat_tree(true, first, last, comp)
265 {}
266
267 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
268 //! allocator, and inserts elements from the range [first ,last ).
269 //!
270 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
271 //! the predicate and otherwise N logN, where N is last - first.
272 template <class InputIterator>
273 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
274 : m_flat_tree(true, first, last, comp, container_detail::force<const impl_allocator_type>(a))
275 {}
276
277 //! <b>Effects</b>: Constructs an empty flat_map
278 //! and inserts elements from the ordered range [first ,last). This function
279 //! is more efficient than the normal range creation for ordered ranges.
280 //!
281 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
282 //!
283 //! <b>Complexity</b>: Linear in N.
284 //!
285 //! <b>Note</b>: Non-standard extension.
286 template <class InputIterator>
287 BOOST_CONTAINER_FORCEINLINE
288 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last)
289 : m_flat_tree(ordered_range, first, last)
290 {}
291
292 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
293 //! inserts elements from the ordered range [first ,last). This function
294 //! is more efficient than the normal range creation for ordered ranges.
295 //!
296 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
297 //!
298 //! <b>Complexity</b>: Linear in N.
299 //!
300 //! <b>Note</b>: Non-standard extension.
301 template <class InputIterator>
302 BOOST_CONTAINER_FORCEINLINE
303 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
304 : m_flat_tree(ordered_range, first, last, comp)
305 {}
306
307 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
308 //! allocator, and inserts elements from the ordered range [first ,last). This function
309 //! is more efficient than the normal range creation for ordered ranges.
310 //!
311 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
312 //!
313 //! <b>Complexity</b>: Linear in N.
314 //!
315 //! <b>Note</b>: Non-standard extension.
316 template <class InputIterator>
317 BOOST_CONTAINER_FORCEINLINE
318 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
319 : m_flat_tree(ordered_range, first, last, comp, container_detail::force<const impl_allocator_type>(a))
320 {}
321
322 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
323 //! <b>Effects</b>: Constructs an empty flat_map and
324 //! inserts elements from the range [il.begin() ,il.end()).
325 //!
326 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
327 //! the predicate and otherwise N logN, where N is last - first.
328 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il)
329 : m_flat_tree( true
330 , container_detail::force<impl_initializer_list>(il).begin()
331 , container_detail::force<impl_initializer_list>(il).end())
332 {}
333
334 //! <b>Effects</b>: Constructs an empty flat_map using the specified
335 //! allocator, and inserts elements from the range [il.begin() ,il.end()).
336 //!
337 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
338 //! the predicate and otherwise N logN, where N is last - first.
339 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const allocator_type& a)
340 : m_flat_tree( true
341 , container_detail::force<impl_initializer_list>(il).begin()
342 , container_detail::force<impl_initializer_list>(il).end()
343 , container_detail::force<const impl_allocator_type>(a))
344 {}
345
346 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
347 //! inserts elements from the range [il.begin() ,il.end()).
348 //!
349 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
350 //! the predicate and otherwise N logN, where N is last - first.
351 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp)
352 : m_flat_tree(true
353 , container_detail::force<impl_initializer_list>(il).begin()
354 , container_detail::force<impl_initializer_list>(il).end()
355 , comp)
356 {}
357
358 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
359 //! allocator, and inserts elements from the range [il.begin() ,il.end()).
360 //!
361 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
362 //! the predicate and otherwise N logN, where N is last - first.
363 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
364 : m_flat_tree(true
365 , container_detail::force<impl_initializer_list>(il).begin()
366 , container_detail::force<impl_initializer_list>(il).end()
367 , comp
368 , container_detail::force<const impl_allocator_type>(a))
369 {}
370
371 //! <b>Effects</b>: Constructs an empty flat_map using and
372 //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
373 //! is more efficient than the normal range creation for ordered ranges.
374 //!
375 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
376 //! unique values.
377 //!
378 //! <b>Complexity</b>: Linear in N.
379 //!
380 //! <b>Note</b>: Non-standard extension.
381 BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il)
382 : m_flat_tree(ordered_unique_range
383 , container_detail::force<impl_initializer_list>(il).begin()
384 , container_detail::force<impl_initializer_list>(il).end())
385 {}
386
387 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
388 //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
389 //! is more efficient than the normal range creation for ordered ranges.
390 //!
391 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
392 //! unique values.
393 //!
394 //! <b>Complexity</b>: Linear in N.
395 //!
396 //! <b>Note</b>: Non-standard extension.
397 BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
398 : m_flat_tree(ordered_unique_range
399 , container_detail::force<impl_initializer_list>(il).begin()
400 , container_detail::force<impl_initializer_list>(il).end()
401 , comp)
402 {}
403
404 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
405 //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
406 //! is more efficient than the normal range creation for ordered ranges.
407 //!
408 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
409 //! unique values.
410 //!
411 //! <b>Complexity</b>: Linear in N.
412 //!
413 //! <b>Note</b>: Non-standard extension.
414 BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
415 : m_flat_tree( ordered_unique_range
416 , container_detail::force<impl_initializer_list>(il).begin()
417 , container_detail::force<impl_initializer_list>(il).end()
418 , comp
419 , container_detail::force<const impl_allocator_type>(a))
420 {}
421 #endif
422
423 //! <b>Effects</b>: Copy constructs a flat_map.
424 //!
425 //! <b>Complexity</b>: Linear in x.size().
426 BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x)
427 : m_flat_tree(x.m_flat_tree)
428 {}
429
430 //! <b>Effects</b>: Move constructs a flat_map.
431 //! Constructs *this using x's resources.
432 //!
433 //! <b>Complexity</b>: Constant.
434 //!
435 //! <b>Postcondition</b>: x is emptied.
436 BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x)
437 BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
438 : m_flat_tree(boost::move(x.m_flat_tree))
439 {}
440
441 //! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
442 //!
443 //! <b>Complexity</b>: Linear in x.size().
444 BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x, const allocator_type &a)
445 : m_flat_tree(x.m_flat_tree, container_detail::force<const impl_allocator_type>(a))
446 {}
447
448 //! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
449 //! Constructs *this using x's resources.
450 //!
451 //! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
452 BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
453 : m_flat_tree(boost::move(x.m_flat_tree), container_detail::force<const impl_allocator_type>(a))
454 {}
455
456 //! <b>Effects</b>: Makes *this a copy of x.
457 //!
458 //! <b>Complexity</b>: Linear in x.size().
459 BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
460 { m_flat_tree = x.m_flat_tree; return *this; }
461
462 //! <b>Effects</b>: Move constructs a flat_map.
463 //! Constructs *this using x's resources.
464 //!
465 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
466 //! is false and (allocation throws or value_type's move constructor throws)
467 //!
468 //! <b>Complexity</b>: Constant if allocator_traits_type::
469 //! propagate_on_container_move_assignment is true or
470 //! this->get>allocator() == x.get_allocator(). Linear otherwise.
471 BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_RV_REF(flat_map) x)
472 BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
473 allocator_traits_type::is_always_equal::value) &&
474 boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
475 { m_flat_tree = boost::move(x.m_flat_tree); return *this; }
476
477 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
478 //! <b>Effects</b>: Assign elements from il to *this
479 flat_map& operator=(std::initializer_list<value_type> il)
480 {
481 this->clear();
482 this->insert(il.begin(), il.end());
483 return *this;
484 }
485 #endif
486
487 //! <b>Effects</b>: Returns a copy of the allocator that
488 //! was passed to the object's constructor.
489 //!
490 //! <b>Complexity</b>: Constant.
491 BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
492 { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
493
494 //! <b>Effects</b>: Returns a reference to the internal allocator.
495 //!
496 //! <b>Throws</b>: Nothing
497 //!
498 //! <b>Complexity</b>: Constant.
499 //!
500 //! <b>Note</b>: Non-standard extension.
501 BOOST_CONTAINER_FORCEINLINE get_stored_allocator_noconst_return_t get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
502 {
503 impl_get_stored_allocator_noconst_return_t r = m_flat_tree.get_stored_allocator();
504 return container_detail::force<stored_allocator_type>(r);
505 }
506
507 //! <b>Effects</b>: Returns a reference to the internal allocator.
508 //!
509 //! <b>Throws</b>: Nothing
510 //!
511 //! <b>Complexity</b>: Constant.
512 //!
513 //! <b>Note</b>: Non-standard extension.
514 BOOST_CONTAINER_FORCEINLINE get_stored_allocator_const_return_t get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
515 {
516 impl_get_stored_allocator_const_return_t r = m_flat_tree.get_stored_allocator();
517 return container_detail::force<const stored_allocator_type>(r);
518 }
519
520 //////////////////////////////////////////////
521 //
522 // iterators
523 //
524 //////////////////////////////////////////////
525
526 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
527 //!
528 //! <b>Throws</b>: Nothing.
529 //!
530 //! <b>Complexity</b>: Constant.
531 BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
532 { return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
533
534 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
535 //!
536 //! <b>Throws</b>: Nothing.
537 //!
538 //! <b>Complexity</b>: Constant.
539 BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
540 { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
541
542 //! <b>Effects</b>: Returns an iterator to the end of the container.
543 //!
544 //! <b>Throws</b>: Nothing.
545 //!
546 //! <b>Complexity</b>: Constant.
547 BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
548 { return container_detail::force_copy<iterator>(m_flat_tree.end()); }
549
550 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
551 //!
552 //! <b>Throws</b>: Nothing.
553 //!
554 //! <b>Complexity</b>: Constant.
555 BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
556 { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
557
558 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
559 //! of the reversed container.
560 //!
561 //! <b>Throws</b>: Nothing.
562 //!
563 //! <b>Complexity</b>: Constant.
564 BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
565 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
566
567 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
568 //! of the reversed container.
569 //!
570 //! <b>Throws</b>: Nothing.
571 //!
572 //! <b>Complexity</b>: Constant.
573 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
574 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
575
576 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
577 //! of the reversed container.
578 //!
579 //! <b>Throws</b>: Nothing.
580 //!
581 //! <b>Complexity</b>: Constant.
582 BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
583 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
584
585 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
586 //! of the reversed container.
587 //!
588 //! <b>Throws</b>: Nothing.
589 //!
590 //! <b>Complexity</b>: Constant.
591 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
592 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
593
594 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
595 //!
596 //! <b>Throws</b>: Nothing.
597 //!
598 //! <b>Complexity</b>: Constant.
599 BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
600 { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
601
602 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
603 //!
604 //! <b>Throws</b>: Nothing.
605 //!
606 //! <b>Complexity</b>: Constant.
607 BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
608 { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
609
610 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
611 //! of the reversed container.
612 //!
613 //! <b>Throws</b>: Nothing.
614 //!
615 //! <b>Complexity</b>: Constant.
616 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
617 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
618
619 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
620 //! of the reversed container.
621 //!
622 //! <b>Throws</b>: Nothing.
623 //!
624 //! <b>Complexity</b>: Constant.
625 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
626 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
627
628 //////////////////////////////////////////////
629 //
630 // capacity
631 //
632 //////////////////////////////////////////////
633
634 //! <b>Effects</b>: Returns true if the container contains no elements.
635 //!
636 //! <b>Throws</b>: Nothing.
637 //!
638 //! <b>Complexity</b>: Constant.
639 BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
640 { return m_flat_tree.empty(); }
641
642 //! <b>Effects</b>: Returns the number of the elements contained in the container.
643 //!
644 //! <b>Throws</b>: Nothing.
645 //!
646 //! <b>Complexity</b>: Constant.
647 BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
648 { return m_flat_tree.size(); }
649
650 //! <b>Effects</b>: Returns the largest possible size of the container.
651 //!
652 //! <b>Throws</b>: Nothing.
653 //!
654 //! <b>Complexity</b>: Constant.
655 BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
656 { return m_flat_tree.max_size(); }
657
658 //! <b>Effects</b>: Number of elements for which memory has been allocated.
659 //! capacity() is always greater than or equal to size().
660 //!
661 //! <b>Throws</b>: Nothing.
662 //!
663 //! <b>Complexity</b>: Constant.
664 BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
665 { return m_flat_tree.capacity(); }
666
667 //! <b>Effects</b>: If n is less than or equal to capacity(), or the
668 //! underlying container has no `reserve` member, this call has no
669 //! effect. Otherwise, it is a request for allocation of additional memory.
670 //! If the request is successful, then capacity() is greater than or equal to
671 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
672 //!
673 //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
674 //!
675 //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
676 //! to values might be invalidated.
677 BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
678 { m_flat_tree.reserve(cnt); }
679
680 //! <b>Effects</b>: Tries to deallocate the excess of memory created
681 // with previous allocations. The size of the vector is unchanged
682 //!
683 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
684 //!
685 //! <b>Complexity</b>: Linear to size().
686 BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
687 { m_flat_tree.shrink_to_fit(); }
688
689 //////////////////////////////////////////////
690 //
691 // element access
692 //
693 //////////////////////////////////////////////
694
695 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
696 //! Effects: If there is no key equivalent to x in the flat_map, inserts
697 //! value_type(x, T()) into the flat_map.
698 //!
699 //! Returns: A reference to the mapped_type corresponding to x in *this.
700 //!
701 //! Complexity: Logarithmic.
702 mapped_type &operator[](const key_type& k);
703
704 //! Effects: If there is no key equivalent to x in the flat_map, inserts
705 //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
706 //!
707 //! Returns: A reference to the mapped_type corresponding to x in *this.
708 //!
709 //! Complexity: Logarithmic.
710 mapped_type &operator[](key_type &&k) ;
711 #elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
712 //in compilers like GCC 3.4, we can't catch temporaries
713 BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); }
714 BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](BOOST_RV_REF(key_type) k) { return this->priv_subscript(::boost::move(k)); }
715 #else
716 BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
717 #endif
718
719 //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
720 //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
721 //! as if by insert, constructing it from value_type(k, forward<M>(obj)).
722 //!
723 //! No iterators or references are invalidated. If the insertion is successful, pointers and references
724 //! to the element obtained while it is held in the node handle are invalidated, and pointers and
725 //! references obtained to that element before it was extracted become valid.
726 //!
727 //! Returns: The bool component is true if the insertion took place and false if the assignment
728 //! took place. The iterator component is pointing at the element that was inserted or updated.
729 //!
730 //! Complexity: Logarithmic in the size of the container.
731 template <class M>
732 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
733 {
734 return container_detail::force_copy< std::pair<iterator, bool> >
735 (this->m_flat_tree.insert_or_assign
736 ( impl_const_iterator(), k, ::boost::forward<M>(obj))
737 );
738 }
739
740 //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
741 //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
742 //! as if by insert, constructing it from value_type(k, move(obj)).
743 //!
744 //! No iterators or references are invalidated. If the insertion is successful, pointers and references
745 //! to the element obtained while it is held in the node handle are invalidated, and pointers and
746 //! references obtained to that element before it was extracted become valid.
747 //!
748 //! Returns: The bool component is true if the insertion took place and false if the assignment
749 //! took place. The iterator component is pointing at the element that was inserted or updated.
750 //!
751 //! Complexity: Logarithmic in the size of the container.
752 template <class M>
753 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
754 {
755 return container_detail::force_copy< std::pair<iterator, bool> >
756 (this->m_flat_tree.insert_or_assign
757 ( impl_const_iterator(), ::boost::move(k), ::boost::forward<M>(obj))
758 );
759 }
760
761 //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
762 //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
763 //! as if by insert, constructing it from value_type(k, forward<M>(obj)) and the new element
764 //! to the container as close as possible to the position just before hint.
765 //!
766 //! No iterators or references are invalidated. If the insertion is successful, pointers and references
767 //! to the element obtained while it is held in the node handle are invalidated, and pointers and
768 //! references obtained to that element before it was extracted become valid.
769 //!
770 //! Returns: The bool component is true if the insertion took place and false if the assignment
771 //! took place. The iterator component is pointing at the element that was inserted or updated.
772 //!
773 //! Complexity: Logarithmic in the size of the container in general, but amortized constant if
774 //! the new element is inserted just before hint.
775 template <class M>
776 BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
777 {
778 return container_detail::force_copy< std::pair<iterator, bool> >
779 (this->m_flat_tree.insert_or_assign
780 ( container_detail::force_copy<impl_const_iterator>(hint)
781 , k, ::boost::forward<M>(obj))
782 );
783 }
784
785 //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
786 //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
787 //! as if by insert, constructing it from value_type(k, move(obj)) and the new element
788 //! to the container as close as possible to the position just before hint.
789 //!
790 //! No iterators or references are invalidated. If the insertion is successful, pointers and references
791 //! to the element obtained while it is held in the node handle are invalidated, and pointers and
792 //! references obtained to that element before it was extracted become valid.
793 //!
794 //! Returns: The bool component is true if the insertion took place and false if the assignment
795 //! took place. The iterator component is pointing at the element that was inserted or updated.
796 //!
797 //! Complexity: Logarithmic in the size of the container in general, but amortized constant if
798 //! the new element is inserted just before hint.
799 template <class M>
800 BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
801 {
802 return container_detail::force_copy< std::pair<iterator, bool> >
803 (this->m_flat_tree.insert_or_assign
804 ( container_detail::force_copy<impl_const_iterator>(hint)
805 , ::boost::move(k), ::boost::forward<M>(obj))
806 );
807 }
808
809 //! @copydoc ::boost::container::flat_set::nth(size_type)
810 BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
811 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
812
813 //! @copydoc ::boost::container::flat_set::nth(size_type) const
814 BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
815 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
816
817 //! @copydoc ::boost::container::flat_set::index_of(iterator)
818 BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
819 { return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
820
821 //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
822 BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
823 { return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
824
825 //! Returns: A reference to the element whose key is equivalent to x.
826 //!
827 //! Throws: An exception object of type out_of_range if no such element is present.
828 //!
829 //! Complexity: logarithmic.
830 T& at(const key_type& k)
831 {
832 iterator i = this->find(k);
833 if(i == this->end()){
834 throw_out_of_range("flat_map::at key not found");
835 }
836 return i->second;
837 }
838
839 //! Returns: A reference to the element whose key is equivalent to x.
840 //!
841 //! Throws: An exception object of type out_of_range if no such element is present.
842 //!
843 //! Complexity: logarithmic.
844 const T& at(const key_type& k) const
845 {
846 const_iterator i = this->find(k);
847 if(i == this->end()){
848 throw_out_of_range("flat_map::at key not found");
849 }
850 return i->second;
851 }
852
853 //////////////////////////////////////////////
854 //
855 // modifiers
856 //
857 //////////////////////////////////////////////
858
859 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
860
861 //! <b>Effects</b>: Inserts an object x of type T constructed with
862 //! std::forward<Args>(args)... if and only if there is no element in the container
863 //! with key equivalent to the key of x.
864 //!
865 //! <b>Returns</b>: The bool component of the returned pair is true if and only
866 //! if the insertion takes place, and the iterator component of the pair
867 //! points to the element with key equivalent to the key of x.
868 //!
869 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
870 //! to the elements with bigger keys than x.
871 //!
872 //! <b>Note</b>: If an element is inserted it might invalidate elements.
873 template <class... Args>
874 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
875 { return container_detail::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
876
877 //! <b>Effects</b>: Inserts an object of type T constructed with
878 //! std::forward<Args>(args)... in the container if and only if there is
879 //! no element in the container with key equivalent to the key of x.
880 //! p is a hint pointing to where the insert should start to search.
881 //!
882 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
883 //! to the key of x.
884 //!
885 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
886 //! right before p) plus insertion linear to the elements with bigger keys than x.
887 //!
888 //! <b>Note</b>: If an element is inserted it might invalidate elements.
889 template <class... Args>
890 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
891 {
892 return container_detail::force_copy<iterator>
893 (m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
894 , boost::forward<Args>(args)...));
895 }
896
897 //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
898 //! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
899 //!
900 //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
901 //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
902 //! forward_as_tuple(forward<Args>(args)...).
903 //!
904 //! <b>Returns</b>: The bool component of the returned pair is true if and only if the
905 //! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
906 //!
907 //! <b>Complexity</b>: Logarithmic.
908 template <class... Args>
909 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args)
910 {
911 return container_detail::force_copy< std::pair<iterator, bool> >(
912 m_flat_tree.try_emplace(impl_const_iterator(), k, boost::forward<Args>(args)...));
913 }
914
915 //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
916 //! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
917 //!
918 //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
919 //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
920 //! forward_as_tuple(forward<Args>(args)...).
921 //!
922 //! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
923 //!
924 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
925 //! is inserted right before p.
926 template <class... Args>
927 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args)
928 {
929 return container_detail::force_copy<iterator>(m_flat_tree.try_emplace
930 (container_detail::force_copy<impl_const_iterator>(hint), k, boost::forward<Args>(args)...).first);
931 }
932
933 //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
934 //! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
935 //!
936 //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
937 //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
938 //! forward_as_tuple(forward<Args>(args)...).
939 //!
940 //! <b>Returns</b>: The bool component of the returned pair is true if and only if the
941 //! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
942 //!
943 //! <b>Complexity</b>: Logarithmic.
944 template <class... Args>
945 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
946 {
947 return container_detail::force_copy< std::pair<iterator, bool> >
948 (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k), boost::forward<Args>(args)...));
949 }
950
951 //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
952 //! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
953 //!
954 //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
955 //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
956 //! forward_as_tuple(forward<Args>(args)...).
957 //!
958 //! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
959 //!
960 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
961 //! is inserted right before p.
962 template <class... Args>
963 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
964 {
965 return container_detail::force_copy<iterator>
966 (m_flat_tree.try_emplace(container_detail::force_copy
967 <impl_const_iterator>(hint), boost::move(k), boost::forward<Args>(args)...).first);
968 }
969
970 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
971
972 #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
973 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
974 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
975 {\
976 return container_detail::force_copy< std::pair<iterator, bool> >\
977 (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
978 }\
979 \
980 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
981 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
982 {\
983 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
984 (container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
985 }\
986 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
987 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
988 {\
989 return container_detail::force_copy< std::pair<iterator, bool> >\
990 (m_flat_tree.try_emplace(impl_const_iterator(), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
991 }\
992 \
993 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
994 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
995 { return container_detail::force_copy<iterator>(m_flat_tree.try_emplace\
996 (container_detail::force_copy<impl_const_iterator>(hint), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
997 \
998 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
999 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1000 {\
1001 return container_detail::force_copy< std::pair<iterator, bool> >\
1002 (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
1003 }\
1004 \
1005 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1006 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1007 { return container_detail::force_copy<iterator>(m_flat_tree.try_emplace\
1008 (container_detail::force_copy<impl_const_iterator>(hint), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
1009 //
1010 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
1011 #undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
1012
1013 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1014
1015 //! <b>Effects</b>: Inserts x if and only if there is no element in the container
1016 //! with key equivalent to the key of x.
1017 //!
1018 //! <b>Returns</b>: The bool component of the returned pair is true if and only
1019 //! if the insertion takes place, and the iterator component of the pair
1020 //! points to the element with key equivalent to the key of x.
1021 //!
1022 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1023 //! to the elements with bigger keys than x.
1024 //!
1025 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1026 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x)
1027 { return container_detail::force_copy<std::pair<iterator,bool> >(
1028 m_flat_tree.insert_unique(container_detail::force<const impl_value_type>(x))); }
1029
1030 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
1031 //! only if there is no element in the container with key equivalent to the key of x.
1032 //!
1033 //! <b>Returns</b>: The bool component of the returned pair is true if and only
1034 //! if the insertion takes place, and the iterator component of the pair
1035 //! points to the element with key equivalent to the key of x.
1036 //!
1037 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1038 //! to the elements with bigger keys than x.
1039 //!
1040 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1041 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
1042 { return container_detail::force_copy<std::pair<iterator,bool> >(
1043 m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); }
1044
1045 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
1046 //! only if there is no element in the container with key equivalent to the key of x.
1047 //!
1048 //! <b>Returns</b>: The bool component of the returned pair is true if and only
1049 //! if the insertion takes place, and the iterator component of the pair
1050 //! points to the element with key equivalent to the key of x.
1051 //!
1052 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1053 //! to the elements with bigger keys than x.
1054 //!
1055 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1056 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
1057 {
1058 return container_detail::force_copy<std::pair<iterator,bool> >
1059 (m_flat_tree.insert_unique(boost::move(x)));
1060 }
1061
1062 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
1063 //! no element in the container with key equivalent to the key of x.
1064 //! p is a hint pointing to where the insert should start to search.
1065 //!
1066 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1067 //! to the key of x.
1068 //!
1069 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
1070 //! right before p) plus insertion linear to the elements with bigger keys than x.
1071 //!
1072 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1073 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
1074 {
1075 return container_detail::force_copy<iterator>(
1076 m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(p)
1077 , container_detail::force<const impl_value_type>(x)));
1078 }
1079
1080 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
1081 //! p is a hint pointing to where the insert should start to search.
1082 //!
1083 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
1084 //!
1085 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
1086 //! right before p) plus insertion linear to the elements with bigger keys than x.
1087 //!
1088 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1089 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
1090 {
1091 return container_detail::force_copy<iterator>
1092 (m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(p)
1093 , boost::move(container_detail::force<impl_value_type>(x))));
1094 }
1095
1096 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
1097 //! p is a hint pointing to where the insert should start to search.
1098 //!
1099 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
1100 //!
1101 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
1102 //! right before p) plus insertion linear to the elements with bigger keys than x.
1103 //!
1104 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1105 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
1106 {
1107 return container_detail::force_copy<iterator>(
1108 m_flat_tree.insert_unique(container_detail::force_copy<impl_const_iterator>(p), boost::move(x)));
1109 }
1110
1111 //! <b>Requires</b>: first, last are not iterators into *this.
1112 //!
1113 //! <b>Effects</b>: inserts each element from the range [first,last) if and only
1114 //! if there is no element with key equivalent to the key of that element.
1115 //!
1116 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
1117 //! search time plus N*size() insertion time.
1118 //!
1119 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1120 template <class InputIterator>
1121 BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
1122 { m_flat_tree.insert_unique(first, last); }
1123
1124 //! <b>Requires</b>: first, last are not iterators into *this.
1125 //!
1126 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
1127 //! unique values.
1128 //!
1129 //! <b>Effects</b>: inserts each element from the range [first,last) if and only
1130 //! if there is no element with key equivalent to the key of that element. This
1131 //! function is more efficient than the normal range creation for ordered ranges.
1132 //!
1133 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
1134 //! search time plus N*size() insertion time.
1135 //!
1136 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1137 //!
1138 //! <b>Note</b>: Non-standard extension.
1139 template <class InputIterator>
1140 BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
1141 { m_flat_tree.insert_unique(ordered_unique_range, first, last); }
1142
1143 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1144 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
1145 //! if there is no element with key equivalent to the key of that element.
1146 //!
1147 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.first() to il.end())
1148 //! search time plus N*size() insertion time.
1149 //!
1150 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1151 BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
1152 {
1153 m_flat_tree.insert_unique( container_detail::force<impl_initializer_list>(il).begin()
1154 , container_detail::force<impl_initializer_list>(il).end());
1155 }
1156
1157 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
1158 //! unique values.
1159 //!
1160 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
1161 //! if there is no element with key equivalent to the key of that element. This
1162 //! function is more efficient than the normal range creation for ordered ranges.
1163 //!
1164 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
1165 //! search time plus N*size() insertion time.
1166 //!
1167 //! <b>Note</b>: If an element is inserted it might invalidate elements.
1168 //!
1169 //! <b>Note</b>: Non-standard extension.
1170 BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
1171 {
1172 m_flat_tree.insert_unique(ordered_unique_range
1173 , container_detail::force<impl_initializer_list>(il).begin()
1174 , container_detail::force<impl_initializer_list>(il).end());
1175 }
1176 #endif
1177
1178 //! <b>Requires</b>: this->get_allocator() == source.get_allocator().
1179 //!
1180 //! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
1181 //! the comparison object of *this. If there is an element in a with key equivalent to the
1182 //! key of an element from source, then that element is not extracted from source.
1183 //!
1184 //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
1185 //! to those same elements but as members of *this. Iterators referring to the transferred
1186 //! elements will continue to refer to their elements, but they now behave as iterators into *this,
1187 //! not into source.
1188 //!
1189 //! <b>Throws</b>: Nothing unless the comparison object throws.
1190 //!
1191 //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
1192 template<class C2>
1193 BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
1194 { m_flat_tree.merge_unique(source.tree()); }
1195
1196 //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
1197 template<class C2>
1198 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
1199 { return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
1200
1201 //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
1202 template<class C2>
1203 BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
1204 { m_flat_tree.merge_unique(source.tree()); }
1205
1206 //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
1207 template<class C2>
1208 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
1209 { return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
1210
1211 //! <b>Effects</b>: Erases the element pointed to by p.
1212 //!
1213 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
1214 //! following q prior to the element being erased. If no such element exists,
1215 //! returns end().
1216 //!
1217 //! <b>Complexity</b>: Linear to the elements with keys bigger than p
1218 //!
1219 //! <b>Note</b>: Invalidates elements with keys
1220 //! not less than the erased element.
1221 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
1222 {
1223 return container_detail::force_copy<iterator>
1224 (m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(p)));
1225 }
1226
1227 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
1228 //!
1229 //! <b>Returns</b>: Returns the number of erased elements.
1230 //!
1231 //! <b>Complexity</b>: Logarithmic search time plus erasure time
1232 //! linear to the elements with bigger keys.
1233 BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
1234 { return m_flat_tree.erase(x); }
1235
1236 //! <b>Effects</b>: Erases all the elements in the range [first, last).
1237 //!
1238 //! <b>Returns</b>: Returns last.
1239 //!
1240 //! <b>Complexity</b>: size()*N where N is the distance from first to last.
1241 //!
1242 //! <b>Complexity</b>: Logarithmic search time plus erasure time
1243 //! linear to the elements with bigger keys.
1244 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
1245 {
1246 return container_detail::force_copy<iterator>(
1247 m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
1248 , container_detail::force_copy<impl_const_iterator>(last)));
1249 }
1250
1251 //! <b>Effects</b>: Swaps the contents of *this and x.
1252 //!
1253 //! <b>Throws</b>: Nothing.
1254 //!
1255 //! <b>Complexity</b>: Constant.
1256 BOOST_CONTAINER_FORCEINLINE void swap(flat_map& x)
1257 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
1258 && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
1259 { m_flat_tree.swap(x.m_flat_tree); }
1260
1261 //! <b>Effects</b>: erase(a.begin(),a.end()).
1262 //!
1263 //! <b>Postcondition</b>: size() == 0.
1264 //!
1265 //! <b>Complexity</b>: linear in size().
1266 BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
1267 { m_flat_tree.clear(); }
1268
1269 //////////////////////////////////////////////
1270 //
1271 // observers
1272 //
1273 //////////////////////////////////////////////
1274
1275 //! <b>Effects</b>: Returns the comparison object out
1276 //! of which a was constructed.
1277 //!
1278 //! <b>Complexity</b>: Constant.
1279 BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
1280 { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
1281
1282 //! <b>Effects</b>: Returns an object of value_compare constructed out
1283 //! of the comparison object.
1284 //!
1285 //! <b>Complexity</b>: Constant.
1286 BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
1287 { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
1288
1289 //////////////////////////////////////////////
1290 //
1291 // map operations
1292 //
1293 //////////////////////////////////////////////
1294
1295 //! <b>Returns</b>: An iterator pointing to an element with the key
1296 //! equivalent to x, or end() if such an element is not found.
1297 //!
1298 //! <b>Complexity</b>: Logarithmic.
1299 BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& x)
1300 { return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
1301
1302 //! <b>Returns</b>: A const_iterator pointing to an element with the key
1303 //! equivalent to x, or end() if such an element is not found.
1304 //!
1305 //! <b>Complexity</b>: Logarithmic.
1306 BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& x) const
1307 { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
1308
1309 //! <b>Returns</b>: The number of elements with key equivalent to x.
1310 //!
1311 //! <b>Complexity</b>: log(size())+count(k)
1312 BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
1313 { return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
1314
1315 //! <b>Returns</b>: An iterator pointing to the first element with key not less
1316 //! than k, or a.end() if such an element is not found.
1317 //!
1318 //! <b>Complexity</b>: Logarithmic.
1319 BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
1320 { return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
1321
1322 //! <b>Returns</b>: A const iterator pointing to the first element with key not
1323 //! less than k, or a.end() if such an element is not found.
1324 //!
1325 //! <b>Complexity</b>: Logarithmic.
1326 BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
1327 { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
1328
1329 //! <b>Returns</b>: An iterator pointing to the first element with key not less
1330 //! than x, or end() if such an element is not found.
1331 //!
1332 //! <b>Complexity</b>: Logarithmic.
1333 BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
1334 { return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
1335
1336 //! <b>Returns</b>: A const iterator pointing to the first element with key not
1337 //! less than x, or end() if such an element is not found.
1338 //!
1339 //! <b>Complexity</b>: Logarithmic.
1340 BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
1341 { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
1342
1343 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1344 //!
1345 //! <b>Complexity</b>: Logarithmic.
1346 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
1347 { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
1348
1349 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1350 //!
1351 //! <b>Complexity</b>: Logarithmic.
1352 BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
1353 { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
1354
1355 //! <b>Effects</b>: Extracts the internal sequence container.
1356 //!
1357 //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
1358 //!
1359 //! <b>Postcondition</b>: this->empty()
1360 //!
1361 //! <b>Throws</b>: If secuence_type's move constructor throws
1362 BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
1363 {
1364 return boost::move(container_detail::force<sequence_type>(m_flat_tree.get_sequence_ref()));
1365 }
1366
1367 //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
1368 //! one passed externally using the move assignment. Erases non-unique elements.
1369 //!
1370 //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
1371 //!
1372 //! <b>Throws</b>: If the comparison or the move constructor throws
1373 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
1374 { this->m_flat_tree.adopt_sequence_unique(boost::move(container_detail::force<impl_sequence_type>(seq))); }
1375
1376 //! <b>Requires</b>: seq shall be ordered according to this->compare()
1377 //! and shall contain unique elements.
1378 //!
1379 //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
1380 //! one passed externally using the move assignment.
1381 //!
1382 //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
1383 //!
1384 //! <b>Throws</b>: If the move assignment throws
1385 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
1386 { this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(container_detail::force<impl_sequence_type>(seq))); }
1387
1388 //! <b>Effects</b>: Returns true if x and y are equal
1389 //!
1390 //! <b>Complexity</b>: Linear to the number of elements in the container.
1391 BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_map& x, const flat_map& y)
1392 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
1393
1394 //! <b>Effects</b>: Returns true if x and y are unequal
1395 //!
1396 //! <b>Complexity</b>: Linear to the number of elements in the container.
1397 BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_map& x, const flat_map& y)
1398 { return !(x == y); }
1399
1400 //! <b>Effects</b>: Returns true if x is less than y
1401 //!
1402 //! <b>Complexity</b>: Linear to the number of elements in the container.
1403 BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_map& x, const flat_map& y)
1404 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
1405
1406 //! <b>Effects</b>: Returns true if x is greater than y
1407 //!
1408 //! <b>Complexity</b>: Linear to the number of elements in the container.
1409 BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_map& x, const flat_map& y)
1410 { return y < x; }
1411
1412 //! <b>Effects</b>: Returns true if x is equal or less than y
1413 //!
1414 //! <b>Complexity</b>: Linear to the number of elements in the container.
1415 BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_map& x, const flat_map& y)
1416 { return !(y < x); }
1417
1418 //! <b>Effects</b>: Returns true if x is equal or greater than y
1419 //!
1420 //! <b>Complexity</b>: Linear to the number of elements in the container.
1421 BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_map& x, const flat_map& y)
1422 { return !(x < y); }
1423
1424 //! <b>Effects</b>: x.swap(y)
1425 //!
1426 //! <b>Complexity</b>: Constant.
1427 BOOST_CONTAINER_FORCEINLINE friend void swap(flat_map& x, flat_map& y)
1428 { x.swap(y); }
1429
1430 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1431 private:
1432 mapped_type &priv_subscript(const key_type& k)
1433 {
1434 iterator i = lower_bound(k);
1435 // i->first is greater than or equivalent to k.
1436 if (i == end() || key_comp()(k, (*i).first)){
1437 container_detail::value_init<mapped_type> m;
1438 i = insert(i, impl_value_type(k, ::boost::move(m.m_t)));
1439 }
1440 return (*i).second;
1441 }
1442 mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk)
1443 {
1444 key_type &k = mk;
1445 iterator i = lower_bound(k);
1446 // i->first is greater than or equivalent to k.
1447 if (i == end() || key_comp()(k, (*i).first)){
1448 container_detail::value_init<mapped_type> m;
1449 i = insert(i, impl_value_type(boost::move(k), ::boost::move(m.m_t)));
1450 }
1451 return (*i).second;
1452 }
1453 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1454 };
1455
1456 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1457
1458 } //namespace container {
1459
1460 //!has_trivial_destructor_after_move<> == true_type
1461 //!specialization for optimizations
1462 template <class Key, class T, class Compare, class AllocatorOrContainer>
1463 struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, AllocatorOrContainer> >
1464 {
1465 typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
1466 static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
1467 ::boost::has_trivial_destructor_after_move<pointer>::value &&
1468 ::boost::has_trivial_destructor_after_move<Compare>::value;
1469 };
1470
1471 namespace container {
1472
1473 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1474
1475 //! A flat_multimap is a kind of associative container that supports equivalent keys
1476 //! (possibly containing multiple copies of the same key value) and provides for
1477 //! fast retrieval of values of another type T based on the keys.
1478 //!
1479 //! A flat_multimap satisfies all of the requirements of a container and of a reversible
1480 //! container and of an associative container. For a
1481 //! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
1482 //! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
1483 //!
1484 //! flat_multimap is similar to std::multimap but it's implemented by as an ordered sequence container.
1485 //! The underlying sequence container is by default <i>vector</i> but it can also work
1486 //! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
1487 //!
1488 //! Using vector-like sequence containers means that inserting a new element into a flat_multimap might invalidate
1489 //! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
1490 //! container that offers stable pointers and references). Similarly, erasing an element might invalidate
1491 //! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
1492 //!
1493 //! This container provides random-access iterators.
1494 //!
1495 //! \tparam Key is the key_type of the map
1496 //! \tparam Value is the <code>mapped_type</code>
1497 //! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
1498 //! \tparam AllocatorOrContainer is either:
1499 //! - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
1500 //! (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
1501 //! - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
1502 //! sequence container with random-access iterators.
1503 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1504 template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
1505 #else
1506 template <class Key, class T, class Compare, class AllocatorOrContainer>
1507 #endif
1508 class flat_multimap
1509 {
1510 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1511 private:
1512 BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
1513 typedef container_detail::flat_tree<
1514 std::pair<Key, T>,
1515 container_detail::select1st<Key>,
1516 Compare,
1517 AllocatorOrContainer> tree_t;
1518 //This is the real tree stored here. It's based on a movable pair
1519 typedef container_detail::flat_tree<
1520 container_detail::pair<Key, T>,
1521 container_detail::select1st<Key>,
1522 Compare,
1523 typename container_detail::container_or_allocator_rebind<AllocatorOrContainer, container_detail::pair<Key, T> >::type
1524 > impl_tree_t;
1525 impl_tree_t m_flat_tree; // flat tree representing flat_map
1526
1527 typedef typename impl_tree_t::value_type impl_value_type;
1528 typedef typename impl_tree_t::const_iterator impl_const_iterator;
1529 typedef typename impl_tree_t::iterator impl_iterator;
1530 typedef typename impl_tree_t::allocator_type impl_allocator_type;
1531 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1532 typedef std::initializer_list<impl_value_type> impl_initializer_list;
1533 #endif
1534
1535 typedef container_detail::flat_tree_value_compare
1536 < Compare
1537 , container_detail::select1st<Key>
1538 , std::pair<Key, T> > value_compare_t;
1539 typedef typename tree_t::iterator iterator_t;
1540 typedef typename tree_t::const_iterator const_iterator_t;
1541 typedef typename tree_t::reverse_iterator reverse_iterator_t;
1542 typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t;
1543
1544 public:
1545 typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
1546 typedef typename impl_tree_t::sequence_type impl_sequence_type;
1547
1548 BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
1549 { return m_flat_tree; }
1550
1551 BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
1552 { return m_flat_tree; }
1553
1554 private:
1555 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1556
1557 public:
1558
1559 //////////////////////////////////////////////
1560 //
1561 // types
1562 //
1563 //////////////////////////////////////////////
1564 typedef Key key_type;
1565 typedef T mapped_type;
1566 typedef Compare key_compare;
1567 typedef std::pair<Key, T> value_type;
1568 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
1569 typedef typename sequence_type::allocator_type allocator_type;
1570 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
1571 typedef typename sequence_type::pointer pointer;
1572 typedef typename sequence_type::const_pointer const_pointer;
1573 typedef typename sequence_type::reference reference;
1574 typedef typename sequence_type::const_reference const_reference;
1575 typedef typename sequence_type::size_type size_type;
1576 typedef typename sequence_type::difference_type difference_type;
1577 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
1578 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
1579
1580 typedef typename sequence_type::iterator iterator;
1581 typedef typename sequence_type::const_iterator const_iterator;
1582 typedef typename sequence_type::reverse_iterator reverse_iterator;
1583 typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
1584 typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
1585
1586 //AllocatorOrContainer::value_type must be std::pair<Key, T>
1587 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename AllocatorOrContainer::value_type>::value));
1588
1589 //////////////////////////////////////////////
1590 //
1591 // construct/copy/destroy
1592 //
1593 //////////////////////////////////////////////
1594
1595 //! <b>Effects</b>: Default constructs an empty flat_map.
1596 //!
1597 //! <b>Complexity</b>: Constant.
1598 BOOST_CONTAINER_FORCEINLINE flat_multimap()
1599 BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
1600 container_detail::is_nothrow_default_constructible<Compare>::value)
1601 : m_flat_tree()
1602 {}
1603
1604 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
1605 //!
1606 //! <b>Complexity</b>: Constant.
1607 BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const allocator_type& a)
1608 : m_flat_tree(container_detail::force<const impl_allocator_type>(a))
1609 {}
1610
1611 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
1612 //! object .
1613 //!
1614 //! <b>Complexity</b>: Constant.
1615 BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const Compare& comp)
1616 : m_flat_tree(comp)
1617 {}
1618
1619 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
1620 //! object and allocator.
1621 //!
1622 //! <b>Complexity</b>: Constant.
1623 BOOST_CONTAINER_FORCEINLINE
1624 flat_multimap(const Compare& comp, const allocator_type& a)
1625 : m_flat_tree(comp, container_detail::force<const impl_allocator_type>(a))
1626 {}
1627
1628 //! <b>Effects</b>: Constructs an empty flat_multimap
1629 //! and inserts elements from the range [first ,last ).
1630 //!
1631 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
1632 //! the predicate and otherwise N logN, where N is last - first.
1633 template <class InputIterator>
1634 BOOST_CONTAINER_FORCEINLINE
1635 flat_multimap(InputIterator first, InputIterator last)
1636 : m_flat_tree(false, first, last)
1637 {}
1638
1639 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified
1640 //! allocator, and inserts elements from the range [first ,last ).
1641 //!
1642 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
1643 //! the predicate and otherwise N logN, where N is last - first.
1644 template <class InputIterator>
1645 BOOST_CONTAINER_FORCEINLINE
1646 flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
1647 : m_flat_tree(false, first, last, container_detail::force<const impl_allocator_type>(a))
1648 {}
1649
1650 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
1651 //! and inserts elements from the range [first ,last ).
1652 //!
1653 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
1654 //! the predicate and otherwise N logN, where N is last - first.
1655 template <class InputIterator>
1656 BOOST_CONTAINER_FORCEINLINE
1657 flat_multimap(InputIterator first, InputIterator last, const Compare& comp)
1658 : m_flat_tree(false, first, last, comp)
1659 {}
1660
1661 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
1662 //! and allocator, and inserts elements from the range [first ,last ).
1663 //!
1664 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
1665 //! the predicate and otherwise N logN, where N is last - first.
1666 template <class InputIterator>
1667 BOOST_CONTAINER_FORCEINLINE
1668 flat_multimap(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1669 : m_flat_tree(false, first, last, comp, container_detail::force<const impl_allocator_type>(a))
1670 {}
1671
1672 //! <b>Effects</b>: Constructs an empty flat_multimap
1673 //! and inserts elements from the ordered range [first ,last). This function
1674 //! is more efficient than the normal range creation for ordered ranges.
1675 //!
1676 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1677 //!
1678 //! <b>Complexity</b>: Linear in N.
1679 //!
1680 //! <b>Note</b>: Non-standard extension.
1681 template <class InputIterator>
1682 BOOST_CONTAINER_FORCEINLINE
1683 flat_multimap(ordered_range_t, InputIterator first, InputIterator last)
1684 : m_flat_tree(ordered_range, first, last)
1685 {}
1686
1687 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
1688 //! inserts elements from the ordered range [first ,last). This function
1689 //! is more efficient than the normal range creation for ordered ranges.
1690 //!
1691 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1692 //!
1693 //! <b>Complexity</b>: Linear in N.
1694 //!
1695 //! <b>Note</b>: Non-standard extension.
1696 template <class InputIterator>
1697 BOOST_CONTAINER_FORCEINLINE
1698 flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
1699 : m_flat_tree(ordered_range, first, last, comp)
1700 {}
1701
1702 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
1703 //! allocator, and inserts elements from the ordered range [first ,last). This function
1704 //! is more efficient than the normal range creation for ordered ranges.
1705 //!
1706 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1707 //!
1708 //! <b>Complexity</b>: Linear in N.
1709 //!
1710 //! <b>Note</b>: Non-standard extension.
1711 template <class InputIterator>
1712 BOOST_CONTAINER_FORCEINLINE
1713 flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1714 : m_flat_tree(ordered_range, first, last, comp, a)
1715 {}
1716
1717 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1718 //! <b>Effects</b>: Constructs an empty flat_map and
1719 //! inserts elements from the range [il.begin(), il.end()).
1720 //!
1721 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
1722 //! the predicate and otherwise N logN, where N is last - first.
1723 BOOST_CONTAINER_FORCEINLINE
1724 flat_multimap(std::initializer_list<value_type> il)
1725 : m_flat_tree( false
1726 , container_detail::force<impl_initializer_list>(il).begin()
1727 , container_detail::force<impl_initializer_list>(il).end())
1728 {}
1729
1730 //! <b>Effects</b>: Constructs an empty flat_map using the specified
1731 //! allocator, and inserts elements from the range [il.begin(), il.end()).
1732 //!
1733 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
1734 //! the predicate and otherwise N logN, where N is last - first.
1735 BOOST_CONTAINER_FORCEINLINE
1736 flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
1737 : m_flat_tree(false
1738 , container_detail::force<impl_initializer_list>(il).begin()
1739 , container_detail::force<impl_initializer_list>(il).end()
1740 , container_detail::force<const impl_allocator_type>(a))
1741 {}
1742
1743 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
1744 //! inserts elements from the range [il.begin(), il.end()).
1745 //!
1746 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
1747 //! the predicate and otherwise N logN, where N is last - first.
1748 BOOST_CONTAINER_FORCEINLINE
1749 flat_multimap(std::initializer_list<value_type> il, const Compare& comp)
1750 : m_flat_tree(false
1751 , container_detail::force<impl_initializer_list>(il).begin()
1752 , container_detail::force<impl_initializer_list>(il).end(), comp)
1753 {}
1754
1755 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
1756 //! allocator, and inserts elements from the range [il.begin(), il.end()).
1757 //!
1758 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
1759 //! the predicate and otherwise N logN, where N is last - first.
1760 BOOST_CONTAINER_FORCEINLINE
1761 flat_multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
1762 : m_flat_tree( false
1763 , container_detail::force<impl_initializer_list>(il).begin()
1764 , container_detail::force<impl_initializer_list>(il).end()
1765 , comp, container_detail::force<const impl_allocator_type>(a))
1766 {}
1767
1768 //! <b>Effects</b>: Constructs an empty flat_multimap and
1769 //! inserts elements from the ordered range [il.begin(), il.end()). This function
1770 //! is more efficient than the normal range creation for ordered ranges.
1771 //!
1772 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
1773 //!
1774 //! <b>Complexity</b>: Linear in N.
1775 //!
1776 //! <b>Note</b>: Non-standard extension.
1777 BOOST_CONTAINER_FORCEINLINE
1778 flat_multimap(ordered_range_t, std::initializer_list<value_type> il)
1779 : m_flat_tree( ordered_range
1780 , container_detail::force<impl_initializer_list>(il).begin()
1781 , container_detail::force<impl_initializer_list>(il).end())
1782 {}
1783
1784 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
1785 //! inserts elements from the ordered range [il.begin(), il.end()). This function
1786 //! is more efficient than the normal range creation for ordered ranges.
1787 //!
1788 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
1789 //!
1790 //! <b>Complexity</b>: Linear in N.
1791 //!
1792 //! <b>Note</b>: Non-standard extension.
1793 BOOST_CONTAINER_FORCEINLINE
1794 flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
1795 : m_flat_tree( ordered_range
1796 , container_detail::force<impl_initializer_list>(il).begin()
1797 , container_detail::force<impl_initializer_list>(il).end(), comp)
1798 {}
1799
1800 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
1801 //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function
1802 //! is more efficient than the normal range creation for ordered ranges.
1803 //!
1804 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
1805 //!
1806 //! <b>Complexity</b>: Linear in N.
1807 //!
1808 //! <b>Note</b>: Non-standard extension.
1809 BOOST_CONTAINER_FORCEINLINE
1810 flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
1811 : m_flat_tree( ordered_range
1812 , container_detail::force<impl_initializer_list>(il).begin()
1813 , container_detail::force<impl_initializer_list>(il).end()
1814 , comp, container_detail::force<const impl_allocator_type>(a))
1815 {}
1816 #endif
1817
1818 //! <b>Effects</b>: Copy constructs a flat_multimap.
1819 //!
1820 //! <b>Complexity</b>: Linear in x.size().
1821 BOOST_CONTAINER_FORCEINLINE
1822 flat_multimap(const flat_multimap& x)
1823 : m_flat_tree(x.m_flat_tree)
1824 {}
1825
1826 //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
1827 //!
1828 //! <b>Complexity</b>: Constant.
1829 //!
1830 //! <b>Postcondition</b>: x is emptied.
1831 BOOST_CONTAINER_FORCEINLINE
1832 flat_multimap(BOOST_RV_REF(flat_multimap) x)
1833 BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
1834 : m_flat_tree(boost::move(x.m_flat_tree))
1835 {}
1836
1837 //! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
1838 //!
1839 //! <b>Complexity</b>: Linear in x.size().
1840 BOOST_CONTAINER_FORCEINLINE
1841 flat_multimap(const flat_multimap& x, const allocator_type &a)
1842 : m_flat_tree(x.m_flat_tree, container_detail::force<const impl_allocator_type>(a))
1843 {}
1844
1845 //! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
1846 //! Constructs *this using x's resources.
1847 //!
1848 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
1849 BOOST_CONTAINER_FORCEINLINE
1850 flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
1851 : m_flat_tree(boost::move(x.m_flat_tree), container_detail::force<const impl_allocator_type>(a))
1852 {}
1853
1854 //! <b>Effects</b>: Makes *this a copy of x.
1855 //!
1856 //! <b>Complexity</b>: Linear in x.size().
1857 BOOST_CONTAINER_FORCEINLINE
1858 flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
1859 { m_flat_tree = x.m_flat_tree; return *this; }
1860
1861 //! <b>Effects</b>: this->swap(x.get()).
1862 //!
1863 //! <b>Complexity</b>: Constant.
1864 BOOST_CONTAINER_FORCEINLINE
1865 flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
1866 BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
1867 allocator_traits_type::is_always_equal::value) &&
1868 boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
1869 { m_flat_tree = boost::move(x.m_flat_tree); return *this; }
1870
1871 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1872 //! <b>Effects</b>: Assign content of il to *this
1873 //!
1874 //! <b>Complexity</b>: Linear in il.size().
1875 BOOST_CONTAINER_FORCEINLINE
1876 flat_multimap& operator=(std::initializer_list<value_type> il)
1877 {
1878 this->clear();
1879 this->insert(il.begin(), il.end());
1880 return *this;
1881 }
1882 #endif
1883
1884 //! <b>Effects</b>: Returns a copy of the allocator that
1885 //! was passed to the object's constructor.
1886 //!
1887 //! <b>Complexity</b>: Constant.
1888 BOOST_CONTAINER_FORCEINLINE
1889 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1890 { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
1891
1892 //! <b>Effects</b>: Returns a reference to the internal allocator.
1893 //!
1894 //! <b>Throws</b>: Nothing
1895 //!
1896 //! <b>Complexity</b>: Constant.
1897 //!
1898 //! <b>Note</b>: Non-standard extension.
1899 BOOST_CONTAINER_FORCEINLINE
1900 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
1901 { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
1902
1903 //! <b>Effects</b>: Returns a reference to the internal allocator.
1904 //!
1905 //! <b>Throws</b>: Nothing
1906 //!
1907 //! <b>Complexity</b>: Constant.
1908 //!
1909 //! <b>Note</b>: Non-standard extension.
1910 BOOST_CONTAINER_FORCEINLINE
1911 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1912 { return container_detail::force<const stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
1913
1914 //////////////////////////////////////////////
1915 //
1916 // iterators
1917 //
1918 //////////////////////////////////////////////
1919
1920 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
1921 //!
1922 //! <b>Throws</b>: Nothing.
1923 //!
1924 //! <b>Complexity</b>: Constant.
1925 BOOST_CONTAINER_FORCEINLINE
1926 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
1927 { return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
1928
1929 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
1930 //!
1931 //! <b>Throws</b>: Nothing.
1932 //!
1933 //! <b>Complexity</b>: Constant.
1934 BOOST_CONTAINER_FORCEINLINE
1935 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
1936 { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
1937
1938 //! <b>Effects</b>: Returns an iterator to the end of the container.
1939 //!
1940 //! <b>Throws</b>: Nothing.
1941 //!
1942 //! <b>Complexity</b>: Constant.
1943 BOOST_CONTAINER_FORCEINLINE
1944 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
1945 { return container_detail::force_copy<iterator>(m_flat_tree.end()); }
1946
1947 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
1948 //!
1949 //! <b>Throws</b>: Nothing.
1950 //!
1951 //! <b>Complexity</b>: Constant.
1952 BOOST_CONTAINER_FORCEINLINE
1953 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
1954 { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
1955
1956 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
1957 //! of the reversed container.
1958 //!
1959 //! <b>Throws</b>: Nothing.
1960 //!
1961 //! <b>Complexity</b>: Constant.
1962 BOOST_CONTAINER_FORCEINLINE
1963 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
1964 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
1965
1966 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1967 //! of the reversed container.
1968 //!
1969 //! <b>Throws</b>: Nothing.
1970 //!
1971 //! <b>Complexity</b>: Constant.
1972 BOOST_CONTAINER_FORCEINLINE
1973 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1974 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
1975
1976 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
1977 //! of the reversed container.
1978 //!
1979 //! <b>Throws</b>: Nothing.
1980 //!
1981 //! <b>Complexity</b>: Constant.
1982 BOOST_CONTAINER_FORCEINLINE
1983 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
1984 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
1985
1986 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1987 //! of the reversed container.
1988 //!
1989 //! <b>Throws</b>: Nothing.
1990 //!
1991 //! <b>Complexity</b>: Constant.
1992 BOOST_CONTAINER_FORCEINLINE
1993 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
1994 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
1995
1996 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
1997 //!
1998 //! <b>Throws</b>: Nothing.
1999 //!
2000 //! <b>Complexity</b>: Constant.
2001 BOOST_CONTAINER_FORCEINLINE
2002 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
2003 { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
2004
2005 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
2006 //!
2007 //! <b>Throws</b>: Nothing.
2008 //!
2009 //! <b>Complexity</b>: Constant.
2010 BOOST_CONTAINER_FORCEINLINE
2011 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
2012 { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
2013
2014 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
2015 //! of the reversed container.
2016 //!
2017 //! <b>Throws</b>: Nothing.
2018 //!
2019 //! <b>Complexity</b>: Constant.
2020 BOOST_CONTAINER_FORCEINLINE
2021 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
2022 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
2023
2024 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
2025 //! of the reversed container.
2026 //!
2027 //! <b>Throws</b>: Nothing.
2028 //!
2029 //! <b>Complexity</b>: Constant.
2030 BOOST_CONTAINER_FORCEINLINE
2031 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
2032 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
2033
2034 //////////////////////////////////////////////
2035 //
2036 // capacity
2037 //
2038 //////////////////////////////////////////////
2039
2040 //! <b>Effects</b>: Returns true if the container contains no elements.
2041 //!
2042 //! <b>Throws</b>: Nothing.
2043 //!
2044 //! <b>Complexity</b>: Constant.
2045 BOOST_CONTAINER_FORCEINLINE
2046 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
2047 { return m_flat_tree.empty(); }
2048
2049 //! <b>Effects</b>: Returns the number of the elements contained in the container.
2050 //!
2051 //! <b>Throws</b>: Nothing.
2052 //!
2053 //! <b>Complexity</b>: Constant.
2054 BOOST_CONTAINER_FORCEINLINE
2055 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
2056 { return m_flat_tree.size(); }
2057
2058 //! <b>Effects</b>: Returns the largest possible size of the container.
2059 //!
2060 //! <b>Throws</b>: Nothing.
2061 //!
2062 //! <b>Complexity</b>: Constant.
2063 BOOST_CONTAINER_FORCEINLINE
2064 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
2065 { return m_flat_tree.max_size(); }
2066
2067 //! <b>Effects</b>: Number of elements for which memory has been allocated.
2068 //! capacity() is always greater than or equal to size().
2069 //!
2070 //! <b>Throws</b>: Nothing.
2071 //!
2072 //! <b>Complexity</b>: Constant.
2073 BOOST_CONTAINER_FORCEINLINE
2074 size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
2075 { return m_flat_tree.capacity(); }
2076
2077 //! <b>Effects</b>: If n is less than or equal to capacity(), or the
2078 //! underlying container has no `reserve` member, this call has no
2079 //! effect. Otherwise, it is a request for allocation of additional memory.
2080 //! If the request is successful, then capacity() is greater than or equal to
2081 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
2082 //!
2083 //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
2084 //!
2085 //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
2086 //! to values might be invalidated.
2087 BOOST_CONTAINER_FORCEINLINE
2088 void reserve(size_type cnt)
2089 { m_flat_tree.reserve(cnt); }
2090
2091 //! <b>Effects</b>: Tries to deallocate the excess of memory created
2092 // with previous allocations. The size of the vector is unchanged
2093 //!
2094 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
2095 //!
2096 //! <b>Complexity</b>: Linear to size().
2097 BOOST_CONTAINER_FORCEINLINE
2098 void shrink_to_fit()
2099 { m_flat_tree.shrink_to_fit(); }
2100
2101 //! @copydoc ::boost::container::flat_set::nth(size_type)
2102 BOOST_CONTAINER_FORCEINLINE
2103 iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
2104 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
2105
2106 //! @copydoc ::boost::container::flat_set::nth(size_type) const
2107 BOOST_CONTAINER_FORCEINLINE
2108 const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
2109 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
2110
2111 //! @copydoc ::boost::container::flat_set::index_of(iterator)
2112 BOOST_CONTAINER_FORCEINLINE
2113 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
2114 { return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
2115
2116 //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
2117 BOOST_CONTAINER_FORCEINLINE
2118 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
2119 { return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
2120
2121 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2122
2123 //! <b>Effects</b>: Inserts an object of type T constructed with
2124 //! std::forward<Args>(args)... and returns the iterator pointing to the
2125 //! newly inserted element.
2126 //!
2127 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
2128 //! to the elements with bigger keys than x.
2129 //!
2130 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2131 template <class... Args>
2132 BOOST_CONTAINER_FORCEINLINE
2133 iterator emplace(BOOST_FWD_REF(Args)... args)
2134 { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
2135
2136 //! <b>Effects</b>: Inserts an object of type T constructed with
2137 //! std::forward<Args>(args)... in the container.
2138 //! p is a hint pointing to where the insert should start to search.
2139 //!
2140 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
2141 //! to the key of x.
2142 //!
2143 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
2144 //! is to be inserted before p) plus linear insertion
2145 //! to the elements with bigger keys than x.
2146 //!
2147 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2148 template <class... Args>
2149 BOOST_CONTAINER_FORCEINLINE
2150 iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
2151 {
2152 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
2153 (container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
2154 }
2155
2156 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2157
2158 #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
2159 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2160 BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
2161 { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
2162 \
2163 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2164 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2165 {\
2166 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
2167 (container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
2168 }\
2169 //
2170 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
2171 #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
2172
2173 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2174
2175 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
2176 //! newly inserted element.
2177 //!
2178 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
2179 //! to the elements with bigger keys than x.
2180 //!
2181 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2182 BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x)
2183 {
2184 return container_detail::force_copy<iterator>(
2185 m_flat_tree.insert_equal(container_detail::force<const impl_value_type>(x)));
2186 }
2187
2188 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
2189 //! the iterator pointing to the newly inserted element.
2190 //!
2191 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
2192 //! to the elements with bigger keys than x.
2193 //!
2194 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2195 BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(value_type) x)
2196 { return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
2197
2198 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
2199 //! the iterator pointing to the newly inserted element.
2200 //!
2201 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
2202 //! to the elements with bigger keys than x.
2203 //!
2204 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2205 BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(impl_value_type) x)
2206 { return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
2207
2208 //! <b>Effects</b>: Inserts a copy of x in the container.
2209 //! p is a hint pointing to where the insert should start to search.
2210 //!
2211 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
2212 //! to the key of x.
2213 //!
2214 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
2215 //! is to be inserted before p) plus linear insertion
2216 //! to the elements with bigger keys than x.
2217 //!
2218 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2219 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
2220 {
2221 return container_detail::force_copy<iterator>
2222 (m_flat_tree.insert_equal( container_detail::force_copy<impl_const_iterator>(p)
2223 , container_detail::force<const impl_value_type>(x)));
2224 }
2225
2226 //! <b>Effects</b>: Inserts a value move constructed from x in the container.
2227 //! p is a hint pointing to where the insert should start to search.
2228 //!
2229 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
2230 //! to the key of x.
2231 //!
2232 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
2233 //! is to be inserted before p) plus linear insertion
2234 //! to the elements with bigger keys than x.
2235 //!
2236 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2237 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
2238 {
2239 return container_detail::force_copy<iterator>
2240 (m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(p)
2241 , boost::move(x)));
2242 }
2243
2244 //! <b>Effects</b>: Inserts a value move constructed from x in the container.
2245 //! p is a hint pointing to where the insert should start to search.
2246 //!
2247 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
2248 //! to the key of x.
2249 //!
2250 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
2251 //! is to be inserted before p) plus linear insertion
2252 //! to the elements with bigger keys than x.
2253 //!
2254 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2255 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(impl_value_type) x)
2256 {
2257 return container_detail::force_copy<iterator>(
2258 m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(p), boost::move(x)));
2259 }
2260
2261 //! <b>Requires</b>: first, last are not iterators into *this.
2262 //!
2263 //! <b>Effects</b>: inserts each element from the range [first,last) .
2264 //!
2265 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
2266 //! search time plus N*size() insertion time.
2267 //!
2268 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2269 template <class InputIterator>
2270 BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
2271 { m_flat_tree.insert_equal(first, last); }
2272
2273 //! <b>Requires</b>: first, last are not iterators into *this.
2274 //!
2275 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
2276 //!
2277 //! <b>Effects</b>: inserts each element from the range [first,last) if and only
2278 //! if there is no element with key equivalent to the key of that element. This
2279 //! function is more efficient than the normal range creation for ordered ranges.
2280 //!
2281 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
2282 //! search time plus N*size() insertion time.
2283 //!
2284 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2285 //!
2286 //! <b>Note</b>: Non-standard extension.
2287 template <class InputIterator>
2288 BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
2289 { m_flat_tree.insert_equal(ordered_range, first, last); }
2290
2291 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
2292 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) .
2293 //!
2294 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
2295 //! search time plus N*size() insertion time.
2296 //!
2297 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2298 BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
2299 {
2300 m_flat_tree.insert_equal( container_detail::force<impl_initializer_list>(il).begin()
2301 , container_detail::force<impl_initializer_list>(il).end());
2302 }
2303
2304 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
2305 //!
2306 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
2307 //! if there is no element with key equivalent to the key of that element. This
2308 //! function is more efficient than the normal range creation for ordered ranges.
2309 //!
2310 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
2311 //! search time plus N*size() insertion time.
2312 //!
2313 //! <b>Note</b>: If an element is inserted it might invalidate elements.
2314 //!
2315 //! <b>Note</b>: Non-standard extension.
2316 BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
2317 {
2318 m_flat_tree.insert_equal( ordered_range
2319 , container_detail::force<impl_initializer_list>(il).begin()
2320 , container_detail::force<impl_initializer_list>(il).end());
2321 }
2322 #endif
2323
2324 //! <b>Requires</b>: this->get_allocator() == source.get_allocator().
2325 //!
2326 //! <b>Effects</b>: Extracts each element in source and insert it into a using
2327 //! the comparison object of *this.
2328 //!
2329 //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
2330 //! to those same elements but as members of *this. Iterators referring to the transferred
2331 //! elements will continue to refer to their elements, but they now behave as iterators into *this,
2332 //! not into source.
2333 //!
2334 //! <b>Throws</b>: Nothing unless the comparison object throws.
2335 //!
2336 //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
2337 template<class C2>
2338 BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
2339 { m_flat_tree.merge_equal(source.tree()); }
2340
2341 //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
2342 template<class C2>
2343 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
2344 { return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
2345
2346 //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
2347 template<class C2>
2348 BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
2349 { m_flat_tree.merge_equal(source.tree()); }
2350
2351 //! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
2352 template<class C2>
2353 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
2354 { return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
2355
2356 //! <b>Effects</b>: Erases the element pointed to by p.
2357 //!
2358 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
2359 //! following q prior to the element being erased. If no such element exists,
2360 //! returns end().
2361 //!
2362 //! <b>Complexity</b>: Linear to the elements with keys bigger than p
2363 //!
2364 //! <b>Note</b>: Invalidates elements with keys
2365 //! not less than the erased element.
2366 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
2367 {
2368 return container_detail::force_copy<iterator>(
2369 m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(p)));
2370 }
2371
2372 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
2373 //!
2374 //! <b>Returns</b>: Returns the number of erased elements.
2375 //!
2376 //! <b>Complexity</b>: Logarithmic search time plus erasure time
2377 //! linear to the elements with bigger keys.
2378 BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
2379 { return m_flat_tree.erase(x); }
2380
2381 //! <b>Effects</b>: Erases all the elements in the range [first, last).
2382 //!
2383 //! <b>Returns</b>: Returns last.
2384 //!
2385 //! <b>Complexity</b>: size()*N where N is the distance from first to last.
2386 //!
2387 //! <b>Complexity</b>: Logarithmic search time plus erasure time
2388 //! linear to the elements with bigger keys.
2389 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
2390 {
2391 return container_detail::force_copy<iterator>
2392 (m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
2393 , container_detail::force_copy<impl_const_iterator>(last)));
2394 }
2395
2396 //! <b>Effects</b>: Swaps the contents of *this and x.
2397 //!
2398 //! <b>Throws</b>: Nothing.
2399 //!
2400 //! <b>Complexity</b>: Constant.
2401 BOOST_CONTAINER_FORCEINLINE void swap(flat_multimap& x)
2402 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
2403 && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
2404 { m_flat_tree.swap(x.m_flat_tree); }
2405
2406 //! <b>Effects</b>: erase(a.begin(),a.end()).
2407 //!
2408 //! <b>Postcondition</b>: size() == 0.
2409 //!
2410 //! <b>Complexity</b>: linear in size().
2411 BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
2412 { m_flat_tree.clear(); }
2413
2414 //////////////////////////////////////////////
2415 //
2416 // observers
2417 //
2418 //////////////////////////////////////////////
2419
2420 //! <b>Effects</b>: Returns the comparison object out
2421 //! of which a was constructed.
2422 //!
2423 //! <b>Complexity</b>: Constant.
2424 BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
2425 { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
2426
2427 //! <b>Effects</b>: Returns an object of value_compare constructed out
2428 //! of the comparison object.
2429 //!
2430 //! <b>Complexity</b>: Constant.
2431 BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
2432 { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
2433
2434 //////////////////////////////////////////////
2435 //
2436 // map operations
2437 //
2438 //////////////////////////////////////////////
2439
2440 //! <b>Returns</b>: An iterator pointing to an element with the key
2441 //! equivalent to x, or end() if such an element is not found.
2442 //!
2443 //! <b>Complexity</b>: Logarithmic.
2444 BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& x)
2445 { return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
2446
2447 //! <b>Returns</b>: An const_iterator pointing to an element with the key
2448 //! equivalent to x, or end() if such an element is not found.
2449 //!
2450 //! <b>Complexity</b>: Logarithmic.
2451 BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& x) const
2452 { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
2453
2454 //! <b>Returns</b>: The number of elements with key equivalent to x.
2455 //!
2456 //! <b>Complexity</b>: log(size())+count(k)
2457 BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
2458 { return m_flat_tree.count(x); }
2459
2460 //! <b>Returns</b>: An iterator pointing to the first element with key not less
2461 //! than k, or a.end() if such an element is not found.
2462 //!
2463 //! <b>Complexity</b>: Logarithmic
2464 BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
2465 { return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
2466
2467 //! <b>Returns</b>: A const iterator pointing to the first element with key
2468 //! not less than k, or a.end() if such an element is not found.
2469 //!
2470 //! <b>Complexity</b>: Logarithmic
2471 BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
2472 { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
2473
2474 //! <b>Returns</b>: An iterator pointing to the first element with key not less
2475 //! than x, or end() if such an element is not found.
2476 //!
2477 //! <b>Complexity</b>: Logarithmic
2478 BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
2479 {return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
2480
2481 //! <b>Returns</b>: A const iterator pointing to the first element with key
2482 //! not less than x, or end() if such an element is not found.
2483 //!
2484 //! <b>Complexity</b>: Logarithmic
2485 BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
2486 { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
2487
2488 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
2489 //!
2490 //! <b>Complexity</b>: Logarithmic
2491 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
2492 { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
2493
2494 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
2495 //!
2496 //! <b>Complexity</b>: Logarithmic
2497 BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
2498 { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
2499
2500 //! <b>Effects</b>: Extracts the internal sequence container.
2501 //!
2502 //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
2503 //!
2504 //! <b>Postcondition</b>: this->empty()
2505 //!
2506 //! <b>Throws</b>: If secuence_type's move constructor throws
2507 BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
2508 {
2509 return boost::move(container_detail::force<sequence_type>(m_flat_tree.get_sequence_ref()));
2510 }
2511
2512 //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
2513 //! one passed externally using the move assignment.
2514 //!
2515 //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
2516 //!
2517 //! <b>Throws</b>: If the comparison or the move constructor throws
2518 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
2519 { this->m_flat_tree.adopt_sequence_equal(boost::move(container_detail::force<impl_sequence_type>(seq))); }
2520
2521 //! <b>Requires</b>: seq shall be ordered according to this->compare().
2522 //!
2523 //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
2524 //! one passed externally using the move assignment.
2525 //!
2526 //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
2527 //!
2528 //! <b>Throws</b>: If the move assignment throws
2529 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
2530 { this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(container_detail::force<impl_sequence_type>(seq))); }
2531
2532 //! <b>Effects</b>: Returns true if x and y are equal
2533 //!
2534 //! <b>Complexity</b>: Linear to the number of elements in the container.
2535 BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_multimap& x, const flat_multimap& y)
2536 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
2537
2538 //! <b>Effects</b>: Returns true if x and y are unequal
2539 //!
2540 //! <b>Complexity</b>: Linear to the number of elements in the container.
2541 BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
2542 { return !(x == y); }
2543
2544 //! <b>Effects</b>: Returns true if x is less than y
2545 //!
2546 //! <b>Complexity</b>: Linear to the number of elements in the container.
2547 BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_multimap& x, const flat_multimap& y)
2548 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2549
2550 //! <b>Effects</b>: Returns true if x is greater than y
2551 //!
2552 //! <b>Complexity</b>: Linear to the number of elements in the container.
2553 BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_multimap& x, const flat_multimap& y)
2554 { return y < x; }
2555
2556 //! <b>Effects</b>: Returns true if x is equal or less than y
2557 //!
2558 //! <b>Complexity</b>: Linear to the number of elements in the container.
2559 BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
2560 { return !(y < x); }
2561
2562 //! <b>Effects</b>: Returns true if x is equal or greater than y
2563 //!
2564 //! <b>Complexity</b>: Linear to the number of elements in the container.
2565 BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
2566 { return !(x < y); }
2567
2568 //! <b>Effects</b>: x.swap(y)
2569 //!
2570 //! <b>Complexity</b>: Constant.
2571 BOOST_CONTAINER_FORCEINLINE friend void swap(flat_multimap& x, flat_multimap& y)
2572 { x.swap(y); }
2573 };
2574
2575 }}
2576
2577 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2578
2579 namespace boost {
2580
2581 //!has_trivial_destructor_after_move<> == true_type
2582 //!specialization for optimizations
2583 template <class Key, class T, class Compare, class AllocatorOrContainer>
2584 struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, AllocatorOrContainer> >
2585 {
2586 typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
2587 static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
2588 ::boost::has_trivial_destructor_after_move<pointer>::value &&
2589 ::boost::has_trivial_destructor_after_move<Compare>::value;
2590 };
2591
2592 } //namespace boost {
2593
2594 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2595
2596 #include <boost/container/detail/config_end.hpp>
2597
2598 #endif // BOOST_CONTAINER_FLAT_MAP_HPP