1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2008. 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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_CONTAINERS_FLAT_MAP_HPP
12 #define BOOST_CONTAINERS_FLAT_MAP_HPP
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
19 #include <boost/interprocess/containers/container/detail/workaround.hpp>
21 #include <boost/interprocess/containers/container/containers_fwd.hpp>
26 #include <boost/interprocess/containers/container/detail/flat_tree.hpp>
27 #include <boost/interprocess/containers/container/detail/utilities.hpp>
28 #include <boost/type_traits/has_trivial_destructor.hpp>
29 #include <boost/interprocess/containers/container/detail/mpl.hpp>
30 #include <boost/interprocess/detail/move.hpp>
32 #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
34 namespace interprocess
{
37 namespace interprocess_container
{
41 // Forward declarations of operators == and <, needed for friend declarations.
42 template <class Key
, class T
, class Pred
, class Alloc
>
45 template <class Key
, class T
, class Pred
, class Alloc
>
46 inline bool operator==(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
47 const flat_map
<Key
,T
,Pred
,Alloc
>& y
);
49 template <class Key
, class T
, class Pred
, class Alloc
>
50 inline bool operator<(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
51 const flat_map
<Key
,T
,Pred
,Alloc
>& y
);
54 //! A flat_map is a kind of associative container that supports unique keys (contains at
55 //! most one of each key value) and provides for fast retrieval of values of another
56 //! type T based on the keys. The flat_map class supports random-access iterators.
58 //! A flat_map satisfies all of the requirements of a container and of a reversible
59 //! container and of an associative container. A flat_map also provides
60 //! most operations described for unique keys. For a
61 //! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
62 //! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
64 //! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
66 //! Alloc is the allocator to allocate the value_types
67 //! (e.g. <i>allocator< std::pair<Key, T> ></i>).
69 //! flat_map is similar to std::map but it's implemented like an ordered vector.
70 //! This means that inserting a new element into a flat_map invalidates
71 //! previous iterators and references
73 //! Erasing an element of a flat_map invalidates iterators and references
74 //! pointing to elements that come after (their keys are bigger) the erased element.
75 template <class Key
, class T
, class Pred
, class Alloc
>
80 //This is the tree that we should store if pair was movable
81 typedef containers_detail::flat_tree
<Key
,
83 containers_detail::select1st
< std::pair
<Key
, T
> >,
87 //This is the real tree stored here. It's based on a movable pair
88 typedef containers_detail::flat_tree
<Key
,
89 containers_detail::pair
<Key
, T
>,
90 containers_detail::select1st
<containers_detail::pair
<Key
, T
> >,
92 typename
Alloc::template
93 rebind
<containers_detail::pair
<Key
, T
> >::other
> impl_tree_t
;
94 impl_tree_t m_flat_tree
; // flat tree representing flat_map
96 typedef typename
impl_tree_t::value_type impl_value_type
;
97 typedef typename
impl_tree_t::pointer impl_pointer
;
98 typedef typename
impl_tree_t::const_pointer impl_const_pointer
;
99 typedef typename
impl_tree_t::reference impl_reference
;
100 typedef typename
impl_tree_t::const_reference impl_const_reference
;
101 typedef typename
impl_tree_t::value_compare impl_value_compare
;
102 typedef typename
impl_tree_t::iterator impl_iterator
;
103 typedef typename
impl_tree_t::const_iterator impl_const_iterator
;
104 typedef typename
impl_tree_t::reverse_iterator impl_reverse_iterator
;
105 typedef typename
impl_tree_t::const_reverse_iterator impl_const_reverse_iterator
;
106 typedef typename
impl_tree_t::allocator_type impl_allocator_type
;
108 template<class D
, class S
>
109 static D
&force(const S
&s
)
110 { return *const_cast<D
*>(reinterpret_cast<const D
*>(&s
)); }
112 template<class D
, class S
>
113 static D
force_copy(S s
)
115 value_type
*vp
= reinterpret_cast<value_type
*>(&*s
);
122 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_map
)
125 typedef typename
tree_t::key_type key_type
;
126 typedef typename
tree_t::value_type value_type
;
127 typedef typename
tree_t::pointer pointer
;
128 typedef typename
tree_t::const_pointer const_pointer
;
129 typedef typename
tree_t::reference reference
;
130 typedef typename
tree_t::const_reference const_reference
;
131 typedef typename
tree_t::value_compare value_compare
;
132 typedef T mapped_type
;
133 typedef typename
tree_t::key_compare key_compare
;
134 typedef typename
tree_t::iterator iterator
;
135 typedef typename
tree_t::const_iterator const_iterator
;
136 typedef typename
tree_t::reverse_iterator reverse_iterator
;
137 typedef typename
tree_t::const_reverse_iterator const_reverse_iterator
;
138 typedef typename
tree_t::size_type size_type
;
139 typedef typename
tree_t::difference_type difference_type
;
140 typedef typename
tree_t::allocator_type allocator_type
;
141 typedef typename
tree_t::stored_allocator_type stored_allocator_type
;
143 //! <b>Effects</b>: Constructs an empty flat_map using the specified
144 //! comparison object and allocator.
146 //! <b>Complexity</b>: Constant.
147 explicit flat_map(const Pred
& comp
= Pred(), const allocator_type
& a
= allocator_type())
148 : m_flat_tree(comp
, force
<impl_allocator_type
>(a
)) {}
150 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
151 //! allocator, and inserts elements from the range [first ,last ).
153 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
154 //! comp and otherwise N logN, where N is last - first.
155 template <class InputIterator
>
156 flat_map(InputIterator first
, InputIterator last
, const Pred
& comp
= Pred(),
157 const allocator_type
& a
= allocator_type())
158 : m_flat_tree(comp
, force
<impl_allocator_type
>(a
))
159 { m_flat_tree
.insert_unique(first
, last
); }
161 //! <b>Effects</b>: Copy constructs a flat_map.
163 //! <b>Complexity</b>: Linear in x.size().
164 flat_map(const flat_map
<Key
,T
,Pred
,Alloc
>& x
)
165 : m_flat_tree(x
.m_flat_tree
) {}
167 //! <b>Effects</b>: Move constructs a flat_map.
168 //! Constructs *this using x's resources.
170 //! <b>Complexity</b>: Construct.
172 //! <b>Postcondition</b>: x is emptied.
173 flat_map(BOOST_INTERPROCESS_RV_REF(flat_map
) x
)
174 : m_flat_tree(boost::interprocess::move(x
.m_flat_tree
))
177 //! <b>Effects</b>: Makes *this a copy of x.
179 //! <b>Complexity</b>: Linear in x.size().
180 flat_map
<Key
,T
,Pred
,Alloc
>& operator=(const flat_map
<Key
, T
, Pred
, Alloc
>& x
)
181 { m_flat_tree
= x
.m_flat_tree
; return *this; }
183 //! <b>Effects</b>: Move constructs a flat_map.
184 //! Constructs *this using x's resources.
186 //! <b>Complexity</b>: Construct.
188 //! <b>Postcondition</b>: x is emptied.
189 flat_map
<Key
,T
,Pred
,Alloc
>& operator=(BOOST_INTERPROCESS_RV_REF(flat_map
) mx
)
190 { m_flat_tree
= boost::interprocess::move(mx
.m_flat_tree
); return *this; }
192 //! <b>Effects</b>: Returns the comparison object out
193 //! of which a was constructed.
195 //! <b>Complexity</b>: Constant.
196 key_compare
key_comp() const
197 { return force
<key_compare
>(m_flat_tree
.key_comp()); }
199 //! <b>Effects</b>: Returns an object of value_compare constructed out
200 //! of the comparison object.
202 //! <b>Complexity</b>: Constant.
203 value_compare
value_comp() const
204 { return value_compare(force
<key_compare
>(m_flat_tree
.key_comp())); }
206 //! <b>Effects</b>: Returns a copy of the Allocator that
207 //! was passed to the object's constructor.
209 //! <b>Complexity</b>: Constant.
210 allocator_type
get_allocator() const
211 { return force
<allocator_type
>(m_flat_tree
.get_allocator()); }
213 const stored_allocator_type
&get_stored_allocator() const
214 { return force
<stored_allocator_type
>(m_flat_tree
.get_stored_allocator()); }
216 stored_allocator_type
&get_stored_allocator()
217 { return force
<stored_allocator_type
>(m_flat_tree
.get_stored_allocator()); }
219 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
221 //! <b>Throws</b>: Nothing.
223 //! <b>Complexity</b>: Constant.
225 { return force_copy
<iterator
>(m_flat_tree
.begin()); }
227 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
229 //! <b>Throws</b>: Nothing.
231 //! <b>Complexity</b>: Constant.
232 const_iterator
begin() const
233 { return force
<const_iterator
>(m_flat_tree
.begin()); }
235 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
237 //! <b>Throws</b>: Nothing.
239 //! <b>Complexity</b>: Constant.
240 const_iterator
cbegin() const
241 { return force
<const_iterator
>(m_flat_tree
.cbegin()); }
243 //! <b>Effects</b>: Returns an iterator to the end of the container.
245 //! <b>Throws</b>: Nothing.
247 //! <b>Complexity</b>: Constant.
249 { return force_copy
<iterator
>(m_flat_tree
.end()); }
251 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
253 //! <b>Throws</b>: Nothing.
255 //! <b>Complexity</b>: Constant.
256 const_iterator
end() const
257 { return force
<const_iterator
>(m_flat_tree
.end()); }
259 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
261 //! <b>Throws</b>: Nothing.
263 //! <b>Complexity</b>: Constant.
264 const_iterator
cend() const
265 { return force
<const_iterator
>(m_flat_tree
.cend()); }
267 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
268 //! of the reversed container.
270 //! <b>Throws</b>: Nothing.
272 //! <b>Complexity</b>: Constant.
273 reverse_iterator
rbegin()
274 { return force
<reverse_iterator
>(m_flat_tree
.rbegin()); }
276 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
277 //! of the reversed container.
279 //! <b>Throws</b>: Nothing.
281 //! <b>Complexity</b>: Constant.
282 const_reverse_iterator
rbegin() const
283 { return force
<const_reverse_iterator
>(m_flat_tree
.rbegin()); }
285 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
286 //! of the reversed container.
288 //! <b>Throws</b>: Nothing.
290 //! <b>Complexity</b>: Constant.
291 const_reverse_iterator
crbegin() const
292 { return force
<const_reverse_iterator
>(m_flat_tree
.crbegin()); }
294 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
295 //! of the reversed container.
297 //! <b>Throws</b>: Nothing.
299 //! <b>Complexity</b>: Constant.
300 reverse_iterator
rend()
301 { return force
<reverse_iterator
>(m_flat_tree
.rend()); }
303 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
304 //! of the reversed container.
306 //! <b>Throws</b>: Nothing.
308 //! <b>Complexity</b>: Constant.
309 const_reverse_iterator
rend() const
310 { return force
<const_reverse_iterator
>(m_flat_tree
.rend()); }
312 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
313 //! of the reversed container.
315 //! <b>Throws</b>: Nothing.
317 //! <b>Complexity</b>: Constant.
318 const_reverse_iterator
crend() const
319 { return force
<const_reverse_iterator
>(m_flat_tree
.crend()); }
321 //! <b>Effects</b>: Returns true if the container contains no elements.
323 //! <b>Throws</b>: Nothing.
325 //! <b>Complexity</b>: Constant.
327 { return m_flat_tree
.empty(); }
329 //! <b>Effects</b>: Returns the number of the elements contained in the container.
331 //! <b>Throws</b>: Nothing.
333 //! <b>Complexity</b>: Constant.
334 size_type
size() const
335 { return m_flat_tree
.size(); }
337 //! <b>Effects</b>: Returns the largest possible size of the container.
339 //! <b>Throws</b>: Nothing.
341 //! <b>Complexity</b>: Constant.
342 size_type
max_size() const
343 { return m_flat_tree
.max_size(); }
345 //! Effects: If there is no key equivalent to x in the flat_map, inserts
346 //! value_type(x, T()) into the flat_map.
348 //! Returns: A reference to the mapped_type corresponding to x in *this.
350 //! Complexity: Logarithmic.
351 T
&operator[](const key_type
& k
)
353 iterator i
= lower_bound(k
);
354 // i->first is greater than or equivalent to k.
355 if (i
== end() || key_comp()(k
, (*i
).first
))
356 i
= insert(i
, value_type(k
, T()));
360 //! Effects: If there is no key equivalent to x in the flat_map, inserts
361 //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
363 //! Returns: A reference to the mapped_type corresponding to x in *this.
365 //! Complexity: Logarithmic.
366 T
&operator[](BOOST_INTERPROCESS_RV_REF(key_type
) mk
)
369 iterator i
= lower_bound(k
);
370 // i->first is greater than or equivalent to k.
371 if (i
== end() || key_comp()(k
, (*i
).first
))
372 i
= insert(i
, value_type(boost::interprocess::move(k
), boost::interprocess::move(T())));
376 //! Returns: A reference to the element whose key is equivalent to x.
377 //! Throws: An exception object of type out_of_range if no such element is present.
378 //! Complexity: logarithmic.
379 T
& at(const key_type
& k
)
381 iterator i
= this->find(k
);
382 if(i
== this->end()){
383 throw std::out_of_range("key not found");
388 //! Returns: A reference to the element whose key is equivalent to x.
389 //! Throws: An exception object of type out_of_range if no such element is present.
390 //! Complexity: logarithmic.
391 const T
& at(const key_type
& k
) const
393 const_iterator i
= this->find(k
);
394 if(i
== this->end()){
395 throw std::out_of_range("key not found");
400 //! <b>Effects</b>: Swaps the contents of *this and x.
401 //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
403 //! <b>Throws</b>: Nothing.
405 //! <b>Complexity</b>: Constant.
406 void swap(flat_map
& x
)
407 { m_flat_tree
.swap(x
.m_flat_tree
); }
409 //! <b>Effects</b>: Inserts x if and only if there is no element in the container
410 //! with key equivalent to the key of x.
412 //! <b>Returns</b>: The bool component of the returned pair is true if and only
413 //! if the insertion takes place, and the iterator component of the pair
414 //! points to the element with key equivalent to the key of x.
416 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
417 //! to the elements with bigger keys than x.
419 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
420 std::pair
<iterator
,bool> insert(const value_type
& x
)
421 { return force
<std::pair
<iterator
,bool> >(
422 m_flat_tree
.insert_unique(force
<impl_value_type
>(x
))); }
424 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
425 //! only if there is no element in the container with key equivalent to the key of x.
427 //! <b>Returns</b>: The bool component of the returned pair is true if and only
428 //! if the insertion takes place, and the iterator component of the pair
429 //! points to the element with key equivalent to the key of x.
431 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
432 //! to the elements with bigger keys than x.
434 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
435 std::pair
<iterator
,bool> insert(BOOST_INTERPROCESS_RV_REF(value_type
) x
)
436 { return force
<std::pair
<iterator
,bool> >(
437 m_flat_tree
.insert_unique(boost::interprocess::move(force
<impl_value_type
>(x
)))); }
439 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
440 //! only if there is no element in the container with key equivalent to the key of x.
442 //! <b>Returns</b>: The bool component of the returned pair is true if and only
443 //! if the insertion takes place, and the iterator component of the pair
444 //! points to the element with key equivalent to the key of x.
446 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
447 //! to the elements with bigger keys than x.
449 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
450 std::pair
<iterator
,bool> insert(BOOST_INTERPROCESS_RV_REF(impl_value_type
) x
)
452 return force
<std::pair
<iterator
,bool> >
453 (m_flat_tree
.insert_unique(boost::interprocess::move(x
)));
456 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
457 //! no element in the container with key equivalent to the key of x.
458 //! p is a hint pointing to where the insert should start to search.
460 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
463 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
464 //! right before p) plus insertion linear to the elements with bigger keys than x.
466 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
467 iterator
insert(const_iterator position
, const value_type
& x
)
468 { return force_copy
<iterator
>(
469 m_flat_tree
.insert_unique(force
<impl_const_iterator
>(position
), force
<impl_value_type
>(x
))); }
471 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
472 //! p is a hint pointing to where the insert should start to search.
474 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
476 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
477 //! right before p) plus insertion linear to the elements with bigger keys than x.
479 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
480 iterator
insert(const_iterator position
, BOOST_INTERPROCESS_RV_REF(value_type
) x
)
481 { return force_copy
<iterator
>(
482 m_flat_tree
.insert_unique(force
<impl_const_iterator
>(position
), boost::interprocess::move(force
<impl_value_type
>(x
)))); }
484 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
485 //! p is a hint pointing to where the insert should start to search.
487 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
489 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
490 //! right before p) plus insertion linear to the elements with bigger keys than x.
492 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
493 iterator
insert(const_iterator position
, BOOST_INTERPROCESS_RV_REF(impl_value_type
) x
)
495 return force_copy
<iterator
>(
496 m_flat_tree
.insert_unique(force
<impl_const_iterator
>(position
), boost::interprocess::move(x
)));
499 //! <b>Requires</b>: i, j are not iterators into *this.
501 //! <b>Effects</b>: inserts each element from the range [i,j) if and only
502 //! if there is no element with key equivalent to the key of that element.
504 //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
505 //! search time plus N*size() insertion time.
507 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
508 template <class InputIterator
>
509 void insert(InputIterator first
, InputIterator last
)
510 { m_flat_tree
.insert_unique(first
, last
); }
512 #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
514 //! <b>Effects</b>: Inserts an object of type T constructed with
515 //! std::forward<Args>(args)... if and only if there is no element in the container
516 //! with key equivalent to the key of x.
518 //! <b>Returns</b>: The bool component of the returned pair is true if and only
519 //! if the insertion takes place, and the iterator component of the pair
520 //! points to the element with key equivalent to the key of x.
522 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
523 //! to the elements with bigger keys than x.
525 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
526 template <class... Args
>
527 iterator
emplace(Args
&&... args
)
528 { return force_copy
<iterator
>(m_flat_tree
.emplace_unique(boost::interprocess::forward
<Args
>(args
)...)); }
530 //! <b>Effects</b>: Inserts an object of type T constructed with
531 //! std::forward<Args>(args)... in the container if and only if there is
532 //! no element in the container with key equivalent to the key of x.
533 //! p is a hint pointing to where the insert should start to search.
535 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
538 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
539 //! right before p) plus insertion linear to the elements with bigger keys than x.
541 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
542 template <class... Args
>
543 iterator
emplace_hint(const_iterator hint
, Args
&&... args
)
544 { return force_copy
<iterator
>(m_flat_tree
.emplace_hint_unique(force
<impl_const_iterator
>(hint
), boost::interprocess::forward
<Args
>(args
)...)); }
546 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
549 { return force_copy
<iterator
>(m_flat_tree
.emplace_unique()); }
551 iterator
emplace_hint(const_iterator hint
)
552 { return force_copy
<iterator
>(m_flat_tree
.emplace_hint_unique(force
<impl_const_iterator
>(hint
))); }
554 #define BOOST_PP_LOCAL_MACRO(n) \
555 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
556 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
558 return force_copy<iterator>(m_flat_tree.emplace_unique \
559 (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
562 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
563 iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
565 return force_copy<iterator>(m_flat_tree.emplace_hint_unique \
566 (force<impl_const_iterator>(hint), \
567 BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
570 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
571 #include BOOST_PP_LOCAL_ITERATE()
573 #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
575 //! <b>Effects</b>: Erases the element pointed to by position.
577 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
578 //! following q prior to the element being erased. If no such element exists,
581 //! <b>Complexity</b>: Linear to the elements with keys bigger than position
583 //! <b>Note</b>: Invalidates elements with keys
584 //! not less than the erased element.
585 iterator
erase(const_iterator position
)
586 { return force_copy
<iterator
>(m_flat_tree
.erase(force
<impl_const_iterator
>(position
))); }
588 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
590 //! <b>Returns</b>: Returns the number of erased elements.
592 //! <b>Complexity</b>: Logarithmic search time plus erasure time
593 //! linear to the elements with bigger keys.
594 size_type
erase(const key_type
& x
)
595 { return m_flat_tree
.erase(x
); }
597 //! <b>Effects</b>: Erases all the elements in the range [first, last).
599 //! <b>Returns</b>: Returns last.
601 //! <b>Complexity</b>: size()*N where N is the distance from first to last.
603 //! <b>Complexity</b>: Logarithmic search time plus erasure time
604 //! linear to the elements with bigger keys.
605 iterator
erase(const_iterator first
, const_iterator last
)
606 { return force_copy
<iterator
>(m_flat_tree
.erase(force
<impl_const_iterator
>(first
), force
<impl_const_iterator
>(last
))); }
608 //! <b>Effects</b>: erase(a.begin(),a.end()).
610 //! <b>Postcondition</b>: size() == 0.
612 //! <b>Complexity</b>: linear in size().
614 { m_flat_tree
.clear(); }
616 //! <b>Effects</b>: Tries to deallocate the excess of memory created
617 // with previous allocations. The size of the vector is unchanged
619 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
621 //! <b>Complexity</b>: Linear to size().
623 { m_flat_tree
.shrink_to_fit(); }
625 //! <b>Returns</b>: An iterator pointing to an element with the key
626 //! equivalent to x, or end() if such an element is not found.
628 //! <b>Complexity</b>: Logarithmic.
629 iterator
find(const key_type
& x
)
630 { return force_copy
<iterator
>(m_flat_tree
.find(x
)); }
632 //! <b>Returns</b>: A const_iterator pointing to an element with the key
633 //! equivalent to x, or end() if such an element is not found.
635 //! <b>Complexity</b>: Logarithmic.s
636 const_iterator
find(const key_type
& x
) const
637 { return force
<const_iterator
>(m_flat_tree
.find(x
)); }
639 //! <b>Returns</b>: The number of elements with key equivalent to x.
641 //! <b>Complexity</b>: log(size())+count(k)
642 size_type
count(const key_type
& x
) const
643 { return m_flat_tree
.find(x
) == m_flat_tree
.end() ? 0 : 1; }
645 //! <b>Returns</b>: An iterator pointing to the first element with key not less
646 //! than k, or a.end() if such an element is not found.
648 //! <b>Complexity</b>: Logarithmic
649 iterator
lower_bound(const key_type
& x
)
650 { return force_copy
<iterator
>(m_flat_tree
.lower_bound(x
)); }
652 //! <b>Returns</b>: A const iterator pointing to the first element with key not
653 //! less than k, or a.end() if such an element is not found.
655 //! <b>Complexity</b>: Logarithmic
656 const_iterator
lower_bound(const key_type
& x
) const
657 { return force
<const_iterator
>(m_flat_tree
.lower_bound(x
)); }
659 //! <b>Returns</b>: An iterator pointing to the first element with key not less
660 //! than x, or end() if such an element is not found.
662 //! <b>Complexity</b>: Logarithmic
663 iterator
upper_bound(const key_type
& x
)
664 { return force_copy
<iterator
>(m_flat_tree
.upper_bound(x
)); }
666 //! <b>Returns</b>: A const iterator pointing to the first element with key not
667 //! less than x, or end() if such an element is not found.
669 //! <b>Complexity</b>: Logarithmic
670 const_iterator
upper_bound(const key_type
& x
) const
671 { return force
<const_iterator
>(m_flat_tree
.upper_bound(x
)); }
673 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
675 //! <b>Complexity</b>: Logarithmic
676 std::pair
<iterator
,iterator
> equal_range(const key_type
& x
)
677 { return force
<std::pair
<iterator
,iterator
> >(m_flat_tree
.equal_range(x
)); }
679 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
681 //! <b>Complexity</b>: Logarithmic
682 std::pair
<const_iterator
,const_iterator
> equal_range(const key_type
& x
) const
683 { return force
<std::pair
<const_iterator
,const_iterator
> >(m_flat_tree
.equal_range(x
)); }
685 //! <b>Effects</b>: Number of elements for which memory has been allocated.
686 //! capacity() is always greater than or equal to size().
688 //! <b>Throws</b>: Nothing.
690 //! <b>Complexity</b>: Constant.
691 size_type
capacity() const
692 { return m_flat_tree
.capacity(); }
694 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
695 //! effect. Otherwise, it is a request for allocation of additional memory.
696 //! If the request is successful, then capacity() is greater than or equal to
697 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
699 //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
701 //! <b>Note</b>: If capacity() is less than "count", iterators and references to
702 //! to values might be invalidated.
703 void reserve(size_type count
)
704 { m_flat_tree
.reserve(count
); }
707 template <class K1
, class T1
, class C1
, class A1
>
708 friend bool operator== (const flat_map
<K1
, T1
, C1
, A1
>&,
709 const flat_map
<K1
, T1
, C1
, A1
>&);
710 template <class K1
, class T1
, class C1
, class A1
>
711 friend bool operator< (const flat_map
<K1
, T1
, C1
, A1
>&,
712 const flat_map
<K1
, T1
, C1
, A1
>&);
716 template <class Key
, class T
, class Pred
, class Alloc
>
717 inline bool operator==(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
718 const flat_map
<Key
,T
,Pred
,Alloc
>& y
)
719 { return x
.m_flat_tree
== y
.m_flat_tree
; }
721 template <class Key
, class T
, class Pred
, class Alloc
>
722 inline bool operator<(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
723 const flat_map
<Key
,T
,Pred
,Alloc
>& y
)
724 { return x
.m_flat_tree
< y
.m_flat_tree
; }
726 template <class Key
, class T
, class Pred
, class Alloc
>
727 inline bool operator!=(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
728 const flat_map
<Key
,T
,Pred
,Alloc
>& y
)
729 { return !(x
== y
); }
731 template <class Key
, class T
, class Pred
, class Alloc
>
732 inline bool operator>(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
733 const flat_map
<Key
,T
,Pred
,Alloc
>& y
)
736 template <class Key
, class T
, class Pred
, class Alloc
>
737 inline bool operator<=(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
738 const flat_map
<Key
,T
,Pred
,Alloc
>& y
)
741 template <class Key
, class T
, class Pred
, class Alloc
>
742 inline bool operator>=(const flat_map
<Key
,T
,Pred
,Alloc
>& x
,
743 const flat_map
<Key
,T
,Pred
,Alloc
>& y
)
746 template <class Key
, class T
, class Pred
, class Alloc
>
747 inline void swap(flat_map
<Key
,T
,Pred
,Alloc
>& x
,
748 flat_map
<Key
,T
,Pred
,Alloc
>& y
)
753 } //namespace interprocess_container {
755 namespace interprocess
{
757 //!has_trivial_destructor_after_move<> == true_type
758 //!specialization for optimizations
759 template <class K
, class T
, class C
, class A
>
760 struct has_trivial_destructor_after_move
<boost::interprocess_container::flat_map
<K
, T
, C
, A
> >
762 static const bool value
= has_trivial_destructor
<A
>::value
&& has_trivial_destructor
<C
>::value
;
765 } //namespace interprocess {
767 namespace interprocess_container
{
769 // Forward declaration of operators < and ==, needed for friend declaration.
770 template <class Key
, class T
,
775 template <class Key
, class T
, class Pred
, class Alloc
>
776 inline bool operator==(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
777 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
);
779 template <class Key
, class T
, class Pred
, class Alloc
>
780 inline bool operator<(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
781 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
);
784 //! A flat_multimap is a kind of associative container that supports equivalent keys
785 //! (possibly containing multiple copies of the same key value) and provides for
786 //! fast retrieval of values of another type T based on the keys. The flat_multimap
787 //! class supports random-access iterators.
789 //! A flat_multimap satisfies all of the requirements of a container and of a reversible
790 //! container and of an associative container. For a
791 //! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
792 //! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
794 //! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
796 //! Alloc is the allocator to allocate the value_types
797 //! (e.g. <i>allocator< std::pair<Key, T> ></i>).
798 template <class Key
, class T
, class Pred
, class Alloc
>
803 typedef containers_detail::flat_tree
<Key
,
805 containers_detail::select1st
< std::pair
<Key
, T
> >,
808 //This is the real tree stored here. It's based on a movable pair
809 typedef containers_detail::flat_tree
<Key
,
810 containers_detail::pair
<Key
, T
>,
811 containers_detail::select1st
<containers_detail::pair
<Key
, T
> >,
813 typename
Alloc::template
814 rebind
<containers_detail::pair
<Key
, T
> >::other
> impl_tree_t
;
815 impl_tree_t m_flat_tree
; // flat tree representing flat_map
817 typedef typename
impl_tree_t::value_type impl_value_type
;
818 typedef typename
impl_tree_t::pointer impl_pointer
;
819 typedef typename
impl_tree_t::const_pointer impl_const_pointer
;
820 typedef typename
impl_tree_t::reference impl_reference
;
821 typedef typename
impl_tree_t::const_reference impl_const_reference
;
822 typedef typename
impl_tree_t::value_compare impl_value_compare
;
823 typedef typename
impl_tree_t::iterator impl_iterator
;
824 typedef typename
impl_tree_t::const_iterator impl_const_iterator
;
825 typedef typename
impl_tree_t::reverse_iterator impl_reverse_iterator
;
826 typedef typename
impl_tree_t::const_reverse_iterator impl_const_reverse_iterator
;
827 typedef typename
impl_tree_t::allocator_type impl_allocator_type
;
829 template<class D
, class S
>
830 static D
&force(const S
&s
)
831 { return *const_cast<D
*>((reinterpret_cast<const D
*>(&s
))); }
833 template<class D
, class S
>
834 static D
force_copy(S s
)
836 value_type
*vp
= reinterpret_cast<value_type
*>(&*s
);
842 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_multimap
)
845 typedef typename
tree_t::key_type key_type
;
846 typedef typename
tree_t::value_type value_type
;
847 typedef typename
tree_t::pointer pointer
;
848 typedef typename
tree_t::const_pointer const_pointer
;
849 typedef typename
tree_t::reference reference
;
850 typedef typename
tree_t::const_reference const_reference
;
851 typedef typename
tree_t::value_compare value_compare
;
852 typedef T mapped_type
;
853 typedef typename
tree_t::key_compare key_compare
;
854 typedef typename
tree_t::iterator iterator
;
855 typedef typename
tree_t::const_iterator const_iterator
;
856 typedef typename
tree_t::reverse_iterator reverse_iterator
;
857 typedef typename
tree_t::const_reverse_iterator const_reverse_iterator
;
858 typedef typename
tree_t::size_type size_type
;
859 typedef typename
tree_t::difference_type difference_type
;
860 typedef typename
tree_t::allocator_type allocator_type
;
861 typedef typename
tree_t::stored_allocator_type stored_allocator_type
;
863 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
864 //! object and allocator.
866 //! <b>Complexity</b>: Constant.
867 explicit flat_multimap(const Pred
& comp
= Pred(),
868 const allocator_type
& a
= allocator_type())
869 : m_flat_tree(comp
, force
<impl_allocator_type
>(a
)) { }
871 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
872 //! and allocator, and inserts elements from the range [first ,last ).
874 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
875 //! comp and otherwise N logN, where N is last - first.
876 template <class InputIterator
>
877 flat_multimap(InputIterator first
, InputIterator last
,
878 const Pred
& comp
= Pred(),
879 const allocator_type
& a
= allocator_type())
880 : m_flat_tree(comp
, force
<impl_allocator_type
>(a
))
881 { m_flat_tree
.insert_equal(first
, last
); }
883 //! <b>Effects</b>: Copy constructs a flat_multimap.
885 //! <b>Complexity</b>: Linear in x.size().
886 flat_multimap(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
)
887 : m_flat_tree(x
.m_flat_tree
) { }
889 //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
891 //! <b>Complexity</b>: Construct.
893 //! <b>Postcondition</b>: x is emptied.
894 flat_multimap(BOOST_INTERPROCESS_RV_REF(flat_multimap
) x
)
895 : m_flat_tree(boost::interprocess::move(x
.m_flat_tree
))
898 //! <b>Effects</b>: Makes *this a copy of x.
900 //! <b>Complexity</b>: Linear in x.size().
901 flat_multimap
<Key
,T
,Pred
,Alloc
>& operator=(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
)
902 { m_flat_tree
= x
.m_flat_tree
; return *this; }
904 //! <b>Effects</b>: this->swap(x.get()).
906 //! <b>Complexity</b>: Constant.
907 flat_multimap
<Key
,T
,Pred
,Alloc
>& operator=(BOOST_INTERPROCESS_RV_REF(flat_multimap
) mx
)
908 { m_flat_tree
= boost::interprocess::move(mx
.m_flat_tree
); return *this; }
910 //! <b>Effects</b>: Returns the comparison object out
911 //! of which a was constructed.
913 //! <b>Complexity</b>: Constant.
914 key_compare
key_comp() const
915 { return force
<key_compare
>(m_flat_tree
.key_comp()); }
917 //! <b>Effects</b>: Returns an object of value_compare constructed out
918 //! of the comparison object.
920 //! <b>Complexity</b>: Constant.
921 value_compare
value_comp() const
922 { return value_compare(force
<key_compare
>(m_flat_tree
.key_comp())); }
924 //! <b>Effects</b>: Returns a copy of the Allocator that
925 //! was passed to the object's constructor.
927 //! <b>Complexity</b>: Constant.
928 allocator_type
get_allocator() const
929 { return force
<allocator_type
>(m_flat_tree
.get_allocator()); }
931 const stored_allocator_type
&get_stored_allocator() const
932 { return force
<stored_allocator_type
>(m_flat_tree
.get_stored_allocator()); }
934 stored_allocator_type
&get_stored_allocator()
935 { return force
<stored_allocator_type
>(m_flat_tree
.get_stored_allocator()); }
937 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
939 //! <b>Throws</b>: Nothing.
941 //! <b>Complexity</b>: Constant.
943 { return force_copy
<iterator
>(m_flat_tree
.begin()); }
945 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
947 //! <b>Throws</b>: Nothing.
949 //! <b>Complexity</b>: Constant.
950 const_iterator
begin() const
951 { return force
<const_iterator
>(m_flat_tree
.begin()); }
953 //! <b>Effects</b>: Returns an iterator to the end of the container.
955 //! <b>Throws</b>: Nothing.
957 //! <b>Complexity</b>: Constant.
959 { return force_copy
<iterator
>(m_flat_tree
.end()); }
961 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
963 //! <b>Throws</b>: Nothing.
965 //! <b>Complexity</b>: Constant.
966 const_iterator
end() const
967 { return force
<const_iterator
>(m_flat_tree
.end()); }
969 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
970 //! of the reversed container.
972 //! <b>Throws</b>: Nothing.
974 //! <b>Complexity</b>: Constant.
975 reverse_iterator
rbegin()
976 { return force
<reverse_iterator
>(m_flat_tree
.rbegin()); }
978 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
979 //! of the reversed container.
981 //! <b>Throws</b>: Nothing.
983 //! <b>Complexity</b>: Constant.
984 const_reverse_iterator
rbegin() const
985 { return force
<const_reverse_iterator
>(m_flat_tree
.rbegin()); }
987 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
988 //! of the reversed container.
990 //! <b>Throws</b>: Nothing.
992 //! <b>Complexity</b>: Constant.
993 reverse_iterator
rend()
994 { return force
<reverse_iterator
>(m_flat_tree
.rend()); }
996 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
997 //! of the reversed container.
999 //! <b>Throws</b>: Nothing.
1001 //! <b>Complexity</b>: Constant.
1002 const_reverse_iterator
rend() const
1003 { return force
<const_reverse_iterator
>(m_flat_tree
.rend()); }
1005 //! <b>Effects</b>: Returns true if the container contains no elements.
1007 //! <b>Throws</b>: Nothing.
1009 //! <b>Complexity</b>: Constant.
1011 { return m_flat_tree
.empty(); }
1013 //! <b>Effects</b>: Returns the number of the elements contained in the container.
1015 //! <b>Throws</b>: Nothing.
1017 //! <b>Complexity</b>: Constant.
1018 size_type
size() const
1019 { return m_flat_tree
.size(); }
1021 //! <b>Effects</b>: Returns the largest possible size of the container.
1023 //! <b>Throws</b>: Nothing.
1025 //! <b>Complexity</b>: Constant.
1026 size_type
max_size() const
1027 { return m_flat_tree
.max_size(); }
1029 //! <b>Effects</b>: Swaps the contents of *this and x.
1030 //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
1032 //! <b>Throws</b>: Nothing.
1034 //! <b>Complexity</b>: Constant.
1035 void swap(flat_multimap
& x
)
1036 { m_flat_tree
.swap(x
.m_flat_tree
); }
1038 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
1039 //! newly inserted element.
1041 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1042 //! to the elements with bigger keys than x.
1044 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1045 iterator
insert(const value_type
& x
)
1046 { return force_copy
<iterator
>(m_flat_tree
.insert_equal(force
<impl_value_type
>(x
))); }
1048 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
1049 //! the iterator pointing to the newly inserted element.
1051 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1052 //! to the elements with bigger keys than x.
1054 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1055 iterator
insert(BOOST_INTERPROCESS_RV_REF(value_type
) x
)
1056 { return force_copy
<iterator
>(m_flat_tree
.insert_equal(boost::interprocess::move(x
))); }
1058 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
1059 //! the iterator pointing to the newly inserted element.
1061 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1062 //! to the elements with bigger keys than x.
1064 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1065 iterator
insert(BOOST_INTERPROCESS_RV_REF(impl_value_type
) x
)
1066 { return force_copy
<iterator
>(m_flat_tree
.insert_equal(boost::interprocess::move(x
))); }
1068 //! <b>Effects</b>: Inserts a copy of x in the container.
1069 //! p is a hint pointing to where the insert should start to search.
1071 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1072 //! to the key of x.
1074 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
1075 //! is to be inserted before p) plus linear insertion
1076 //! to the elements with bigger keys than x.
1078 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1079 iterator
insert(const_iterator position
, const value_type
& x
)
1080 { return force_copy
<iterator
>(m_flat_tree
.insert_equal(force
<impl_const_iterator
>(position
), force
<impl_value_type
>(x
))); }
1082 //! <b>Effects</b>: Inserts a value move constructed from x in the container.
1083 //! p is a hint pointing to where the insert should start to search.
1085 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1086 //! to the key of x.
1088 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
1089 //! is to be inserted before p) plus linear insertion
1090 //! to the elements with bigger keys than x.
1092 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1093 iterator
insert(const_iterator position
, BOOST_INTERPROCESS_RV_REF(value_type
) x
)
1095 return force_copy
<iterator
>
1096 (m_flat_tree
.insert_equal(force
<impl_const_iterator
>(position
)
1097 , boost::interprocess::move(x
)));
1100 //! <b>Effects</b>: Inserts a value move constructed from x in the container.
1101 //! p is a hint pointing to where the insert should start to search.
1103 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1104 //! to the key of x.
1106 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
1107 //! is to be inserted before p) plus linear insertion
1108 //! to the elements with bigger keys than x.
1110 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1111 iterator
insert(const_iterator position
, BOOST_INTERPROCESS_RV_REF(impl_value_type
) x
)
1113 return force_copy
<iterator
>(
1114 m_flat_tree
.insert_equal(force
<impl_const_iterator
>(position
), boost::interprocess::move(x
)));
1117 //! <b>Requires</b>: i, j are not iterators into *this.
1119 //! <b>Effects</b>: inserts each element from the range [i,j) .
1121 //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
1122 //! search time plus N*size() insertion time.
1124 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1125 template <class InputIterator
>
1126 void insert(InputIterator first
, InputIterator last
)
1127 { m_flat_tree
.insert_equal(first
, last
); }
1129 #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
1131 //! <b>Effects</b>: Inserts an object of type T constructed with
1132 //! std::forward<Args>(args)... and returns the iterator pointing to the
1133 //! newly inserted element.
1135 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
1136 //! to the elements with bigger keys than x.
1138 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1139 template <class... Args
>
1140 iterator
emplace(Args
&&... args
)
1141 { return force_copy
<iterator
>(m_flat_tree
.emplace_equal(boost::interprocess::forward
<Args
>(args
)...)); }
1143 //! <b>Effects</b>: Inserts an object of type T constructed with
1144 //! std::forward<Args>(args)... in the container.
1145 //! p is a hint pointing to where the insert should start to search.
1147 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1148 //! to the key of x.
1150 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
1151 //! is to be inserted before p) plus linear insertion
1152 //! to the elements with bigger keys than x.
1154 //! <b>Note</b>: If an element it's inserted it might invalidate elements.
1155 template <class... Args
>
1156 iterator
emplace_hint(const_iterator hint
, Args
&&... args
)
1158 return force_copy
<iterator
>(m_flat_tree
.emplace_hint_equal
1159 (force
<impl_const_iterator
>(hint
), boost::interprocess::forward
<Args
>(args
)...));
1162 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
1165 { return force_copy
<iterator
>(m_flat_tree
.emplace_equal()); }
1167 iterator
emplace_hint(const_iterator hint
)
1168 { return force_copy
<iterator
>(m_flat_tree
.emplace_hint_equal(force
<impl_const_iterator
>(hint
))); }
1170 #define BOOST_PP_LOCAL_MACRO(n) \
1171 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
1172 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
1174 return force_copy<iterator>(m_flat_tree.emplace_equal \
1175 (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
1178 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
1179 iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
1181 return force_copy<iterator>(m_flat_tree.emplace_hint_equal \
1182 (force<impl_const_iterator>(hint), \
1183 BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
1186 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
1187 #include BOOST_PP_LOCAL_ITERATE()
1189 #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
1191 //! <b>Effects</b>: Erases the element pointed to by position.
1193 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
1194 //! following q prior to the element being erased. If no such element exists,
1197 //! <b>Complexity</b>: Linear to the elements with keys bigger than position
1199 //! <b>Note</b>: Invalidates elements with keys
1200 //! not less than the erased element.
1201 iterator
erase(const_iterator position
)
1202 { return force_copy
<iterator
>(m_flat_tree
.erase(force
<impl_const_iterator
>(position
))); }
1204 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
1206 //! <b>Returns</b>: Returns the number of erased elements.
1208 //! <b>Complexity</b>: Logarithmic search time plus erasure time
1209 //! linear to the elements with bigger keys.
1210 size_type
erase(const key_type
& x
)
1211 { return m_flat_tree
.erase(x
); }
1213 //! <b>Effects</b>: Erases all the elements in the range [first, last).
1215 //! <b>Returns</b>: Returns last.
1217 //! <b>Complexity</b>: size()*N where N is the distance from first to last.
1219 //! <b>Complexity</b>: Logarithmic search time plus erasure time
1220 //! linear to the elements with bigger keys.
1221 iterator
erase(const_iterator first
, const_iterator last
)
1222 { return force_copy
<iterator
>(m_flat_tree
.erase(force
<impl_const_iterator
>(first
), force
<impl_const_iterator
>(last
))); }
1224 //! <b>Effects</b>: erase(a.begin(),a.end()).
1226 //! <b>Postcondition</b>: size() == 0.
1228 //! <b>Complexity</b>: linear in size().
1230 { m_flat_tree
.clear(); }
1232 //! <b>Effects</b>: Tries to deallocate the excess of memory created
1233 // with previous allocations. The size of the vector is unchanged
1235 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
1237 //! <b>Complexity</b>: Linear to size().
1238 void shrink_to_fit()
1239 { m_flat_tree
.shrink_to_fit(); }
1241 //! <b>Returns</b>: An iterator pointing to an element with the key
1242 //! equivalent to x, or end() if such an element is not found.
1244 //! <b>Complexity</b>: Logarithmic.
1245 iterator
find(const key_type
& x
)
1246 { return force_copy
<iterator
>(m_flat_tree
.find(x
)); }
1248 //! <b>Returns</b>: An const_iterator pointing to an element with the key
1249 //! equivalent to x, or end() if such an element is not found.
1251 //! <b>Complexity</b>: Logarithmic.
1252 const_iterator
find(const key_type
& x
) const
1253 { return force
<const_iterator
>(m_flat_tree
.find(x
)); }
1255 //! <b>Returns</b>: The number of elements with key equivalent to x.
1257 //! <b>Complexity</b>: log(size())+count(k)
1258 size_type
count(const key_type
& x
) const
1259 { return m_flat_tree
.count(x
); }
1261 //! <b>Returns</b>: An iterator pointing to the first element with key not less
1262 //! than k, or a.end() if such an element is not found.
1264 //! <b>Complexity</b>: Logarithmic
1265 iterator
lower_bound(const key_type
& x
)
1266 {return force_copy
<iterator
>(m_flat_tree
.lower_bound(x
)); }
1268 //! <b>Returns</b>: A const iterator pointing to the first element with key
1269 //! not less than k, or a.end() if such an element is not found.
1271 //! <b>Complexity</b>: Logarithmic
1272 const_iterator
lower_bound(const key_type
& x
) const
1273 { return force
<const_iterator
>(m_flat_tree
.lower_bound(x
)); }
1275 //! <b>Returns</b>: An iterator pointing to the first element with key not less
1276 //! than x, or end() if such an element is not found.
1278 //! <b>Complexity</b>: Logarithmic
1279 iterator
upper_bound(const key_type
& x
)
1280 {return force_copy
<iterator
>(m_flat_tree
.upper_bound(x
)); }
1282 //! <b>Returns</b>: A const iterator pointing to the first element with key
1283 //! not less than x, or end() if such an element is not found.
1285 //! <b>Complexity</b>: Logarithmic
1286 const_iterator
upper_bound(const key_type
& x
) const
1287 { return force
<const_iterator
>(m_flat_tree
.upper_bound(x
)); }
1289 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1291 //! <b>Complexity</b>: Logarithmic
1292 std::pair
<iterator
,iterator
> equal_range(const key_type
& x
)
1293 { return force_copy
<std::pair
<iterator
,iterator
> >(m_flat_tree
.equal_range(x
)); }
1295 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1297 //! <b>Complexity</b>: Logarithmic
1298 std::pair
<const_iterator
,const_iterator
>
1299 equal_range(const key_type
& x
) const
1300 { return force_copy
<std::pair
<const_iterator
,const_iterator
> >(m_flat_tree
.equal_range(x
)); }
1302 //! <b>Effects</b>: Number of elements for which memory has been allocated.
1303 //! capacity() is always greater than or equal to size().
1305 //! <b>Throws</b>: Nothing.
1307 //! <b>Complexity</b>: Constant.
1308 size_type
capacity() const
1309 { return m_flat_tree
.capacity(); }
1311 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
1312 //! effect. Otherwise, it is a request for allocation of additional memory.
1313 //! If the request is successful, then capacity() is greater than or equal to
1314 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
1316 //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
1318 //! <b>Note</b>: If capacity() is less than "count", iterators and references to
1319 //! to values might be invalidated.
1320 void reserve(size_type count
)
1321 { m_flat_tree
.reserve(count
); }
1324 template <class K1
, class T1
, class C1
, class A1
>
1325 friend bool operator== (const flat_multimap
<K1
, T1
, C1
, A1
>& x
,
1326 const flat_multimap
<K1
, T1
, C1
, A1
>& y
);
1328 template <class K1
, class T1
, class C1
, class A1
>
1329 friend bool operator< (const flat_multimap
<K1
, T1
, C1
, A1
>& x
,
1330 const flat_multimap
<K1
, T1
, C1
, A1
>& y
);
1334 template <class Key
, class T
, class Pred
, class Alloc
>
1335 inline bool operator==(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
1336 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1337 { return x
.m_flat_tree
== y
.m_flat_tree
; }
1339 template <class Key
, class T
, class Pred
, class Alloc
>
1340 inline bool operator<(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
1341 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1342 { return x
.m_flat_tree
< y
.m_flat_tree
; }
1344 template <class Key
, class T
, class Pred
, class Alloc
>
1345 inline bool operator!=(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
1346 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1347 { return !(x
== y
); }
1349 template <class Key
, class T
, class Pred
, class Alloc
>
1350 inline bool operator>(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
1351 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1354 template <class Key
, class T
, class Pred
, class Alloc
>
1355 inline bool operator<=(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
1356 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1357 { return !(y
< x
); }
1359 template <class Key
, class T
, class Pred
, class Alloc
>
1360 inline bool operator>=(const flat_multimap
<Key
,T
,Pred
,Alloc
>& x
,
1361 const flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1362 { return !(x
< y
); }
1364 template <class Key
, class T
, class Pred
, class Alloc
>
1365 inline void swap(flat_multimap
<Key
,T
,Pred
,Alloc
>& x
, flat_multimap
<Key
,T
,Pred
,Alloc
>& y
)
1373 namespace interprocess
{
1375 //!has_trivial_destructor_after_move<> == true_type
1376 //!specialization for optimizations
1377 template <class K
, class T
, class C
, class A
>
1378 struct has_trivial_destructor_after_move
< boost::interprocess_container::flat_multimap
<K
, T
, C
, A
> >
1380 static const bool value
= has_trivial_destructor
<A
>::value
&& has_trivial_destructor
<C
>::value
;
1383 } //namespace interprocess {
1384 } //namespace boost {
1388 #include <boost/interprocess/containers/container/detail/config_end.hpp>
1390 #endif /* BOOST_CONTAINERS_FLAT_MAP_HPP */