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 // This file comes from SGI's stl_map/stl_multimap files. Modified by Ion Gaztanaga.
12 // Renaming, isolating and porting to generic algorithms. Pointer typedef
13 // set to allocator::pointer to allow placing it in shared memory.
15 ///////////////////////////////////////////////////////////////////////////////
19 * Hewlett-Packard Company
21 * Permission to use, copy, modify, distribute and sell this software
22 * and its documentation for any purpose is hereby granted without fee,
23 * provided that the above copyright notice appear in all copies and
24 * that both that copyright notice and this permission notice appear
25 * in supporting documentation. Hewlett-Packard Company makes no
26 * representations about the suitability of this software for any
27 * purpose. It is provided "as is" without express or implied warranty.
31 * Silicon Graphics Computer Systems, Inc.
33 * Permission to use, copy, modify, distribute and sell this software
34 * and its documentation for any purpose is hereby granted without fee,
35 * provided that the above copyright notice appear in all copies and
36 * that both that copyright notice and this permission notice appear
37 * in supporting documentation. Silicon Graphics makes no
38 * representations about the suitability of this software for any
39 * purpose. It is provided "as is" without express or implied warranty.
43 #ifndef BOOST_CONTAINERS_MAP_HPP
44 #define BOOST_CONTAINERS_MAP_HPP
46 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
50 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
51 #include <boost/interprocess/containers/container/detail/workaround.hpp>
53 #include <boost/interprocess/containers/container/containers_fwd.hpp>
58 #include <boost/interprocess/containers/container/detail/tree.hpp>
59 #include <boost/interprocess/containers/container/detail/value_init.hpp>
60 #include <boost/type_traits/has_trivial_destructor.hpp>
61 #include <boost/interprocess/containers/container/detail/mpl.hpp>
62 #include <boost/interprocess/containers/container/detail/utilities.hpp>
63 #include <boost/interprocess/containers/container/detail/pair.hpp>
64 #include <boost/interprocess/detail/move.hpp>
66 #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
68 namespace interprocess
{
71 namespace interprocess_container
{
75 // Forward declarations of operators == and <, needed for friend declarations.
76 template <class Key
, class T
, class Pred
, class Alloc
>
77 inline bool operator==(const map
<Key
,T
,Pred
,Alloc
>& x
,
78 const map
<Key
,T
,Pred
,Alloc
>& y
);
80 template <class Key
, class T
, class Pred
, class Alloc
>
81 inline bool operator<(const map
<Key
,T
,Pred
,Alloc
>& x
,
82 const map
<Key
,T
,Pred
,Alloc
>& y
);
85 //! A map is a kind of associative container that supports unique keys (contains at
86 //! most one of each key value) and provides for fast retrieval of values of another
87 //! type T based on the keys. The map class supports bidirectional iterators.
89 //! A map satisfies all of the requirements of a container and of a reversible
90 //! container and of an associative container. For a
91 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
93 //! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
95 //! Alloc is the allocator to allocate the value_types
96 //! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
97 template <class Key
, class T
, class Pred
, class Alloc
>
102 typedef containers_detail::rbtree
<Key
,
103 std::pair
<const Key
, T
>,
104 containers_detail::select1st
< std::pair
<const Key
, T
> >,
107 tree_t m_tree
; // red-black tree representing map
111 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(map
)
114 typedef typename
tree_t::key_type key_type
;
115 typedef typename
tree_t::value_type value_type
;
116 typedef typename
tree_t::pointer pointer
;
117 typedef typename
tree_t::const_pointer const_pointer
;
118 typedef typename
tree_t::reference reference
;
119 typedef typename
tree_t::const_reference const_reference
;
120 typedef T mapped_type
;
121 typedef Pred key_compare
;
122 typedef typename
tree_t::iterator iterator
;
123 typedef typename
tree_t::const_iterator const_iterator
;
124 typedef typename
tree_t::reverse_iterator reverse_iterator
;
125 typedef typename
tree_t::const_reverse_iterator const_reverse_iterator
;
126 typedef typename
tree_t::size_type size_type
;
127 typedef typename
tree_t::difference_type difference_type
;
128 typedef typename
tree_t::allocator_type allocator_type
;
129 typedef typename
tree_t::stored_allocator_type stored_allocator_type
;
130 typedef std::pair
<key_type
, mapped_type
> nonconst_value_type
;
131 typedef containers_detail::pair
132 <key_type
, mapped_type
> nonconst_impl_value_type
;
135 class value_compare_impl
137 public std::binary_function
<value_type
, value_type
, bool>
139 friend class map
<Key
,T
,Pred
,Alloc
>;
141 value_compare_impl(const Pred
&c
) : Pred(c
) {}
143 bool operator()(const value_type
& x
, const value_type
& y
) const {
144 return Pred::operator()(x
.first
, y
.first
);
148 typedef value_compare_impl value_compare
;
150 //! <b>Effects</b>: Constructs an empty map using the specified comparison object
153 //! <b>Complexity</b>: Constant.
154 explicit map(const Pred
& comp
= Pred(),
155 const allocator_type
& a
= allocator_type())
159 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
160 //! allocator, and inserts elements from the range [first ,last ).
162 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
163 //! comp and otherwise N logN, where N is last - first.
164 template <class InputIterator
>
165 map(InputIterator first
, InputIterator last
, const Pred
& comp
= Pred(),
166 const allocator_type
& a
= allocator_type())
167 : m_tree(first
, last
, comp
, a
, true)
170 //! <b>Effects</b>: Copy constructs a map.
172 //! <b>Complexity</b>: Linear in x.size().
173 map(const map
<Key
,T
,Pred
,Alloc
>& x
)
177 //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
179 //! <b>Complexity</b>: Construct.
181 //! <b>Postcondition</b>: x is emptied.
182 map(BOOST_INTERPROCESS_RV_REF(map
) x
)
183 : m_tree(boost::interprocess::move(x
.m_tree
))
186 //! <b>Effects</b>: Makes *this a copy of x.
188 //! <b>Complexity</b>: Linear in x.size().
189 map
& operator=(const map
<Key
, T
, Pred
, Alloc
>& x
)
190 { m_tree
= x
.m_tree
; return *this; }
192 //! <b>Effects</b>: this->swap(x.get()).
194 //! <b>Complexity</b>: Constant.
195 map
& operator=(BOOST_INTERPROCESS_RV_REF(map
) x
)
196 { m_tree
= boost::interprocess::move(x
.m_tree
); return *this; }
198 //! <b>Effects</b>: Returns the comparison object out
199 //! of which a was constructed.
201 //! <b>Complexity</b>: Constant.
202 key_compare
key_comp() const
203 { return m_tree
.key_comp(); }
205 //! <b>Effects</b>: Returns an object of value_compare constructed out
206 //! of the comparison object.
208 //! <b>Complexity</b>: Constant.
209 value_compare
value_comp() const
210 { return value_compare(m_tree
.key_comp()); }
212 //! <b>Effects</b>: Returns a copy of the Allocator that
213 //! was passed to the object's constructor.
215 //! <b>Complexity</b>: Constant.
216 allocator_type
get_allocator() const
217 { return m_tree
.get_allocator(); }
219 const stored_allocator_type
&get_stored_allocator() const
220 { return m_tree
.get_stored_allocator(); }
222 stored_allocator_type
&get_stored_allocator()
223 { return m_tree
.get_stored_allocator(); }
225 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
227 //! <b>Throws</b>: Nothing.
229 //! <b>Complexity</b>: Constant.
231 { return m_tree
.begin(); }
233 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
235 //! <b>Throws</b>: Nothing.
237 //! <b>Complexity</b>: Constant.
238 const_iterator
begin() const
239 { return m_tree
.begin(); }
241 //! <b>Effects</b>: Returns an iterator to the end of the container.
243 //! <b>Throws</b>: Nothing.
245 //! <b>Complexity</b>: Constant.
247 { return m_tree
.end(); }
249 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
251 //! <b>Throws</b>: Nothing.
253 //! <b>Complexity</b>: Constant.
254 const_iterator
end() const
255 { return m_tree
.end(); }
257 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
258 //! of the reversed container.
260 //! <b>Throws</b>: Nothing.
262 //! <b>Complexity</b>: Constant.
263 reverse_iterator
rbegin()
264 { return m_tree
.rbegin(); }
266 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
267 //! of the reversed container.
269 //! <b>Throws</b>: Nothing.
271 //! <b>Complexity</b>: Constant.
272 const_reverse_iterator
rbegin() const
273 { return m_tree
.rbegin(); }
275 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
276 //! of the reversed container.
278 //! <b>Throws</b>: Nothing.
280 //! <b>Complexity</b>: Constant.
281 reverse_iterator
rend()
282 { return m_tree
.rend(); }
284 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
285 //! of the reversed container.
287 //! <b>Throws</b>: Nothing.
289 //! <b>Complexity</b>: Constant.
290 const_reverse_iterator
rend() const
291 { return m_tree
.rend(); }
293 //! <b>Effects</b>: Returns true if the container contains no elements.
295 //! <b>Throws</b>: Nothing.
297 //! <b>Complexity</b>: Constant.
299 { return m_tree
.empty(); }
301 //! <b>Effects</b>: Returns the number of the elements contained in the container.
303 //! <b>Throws</b>: Nothing.
305 //! <b>Complexity</b>: Constant.
306 size_type
size() const
307 { return m_tree
.size(); }
309 //! <b>Effects</b>: Returns the largest possible size of the container.
311 //! <b>Throws</b>: Nothing.
313 //! <b>Complexity</b>: Constant.
314 size_type
max_size() const
315 { return m_tree
.max_size(); }
317 //! Effects: If there is no key equivalent to x in the map, inserts
318 //! value_type(x, T()) into the map.
320 //! Returns: A reference to the mapped_type corresponding to x in *this.
322 //! Complexity: Logarithmic.
323 T
& operator[](const key_type
& k
)
325 //we can optimize this
326 iterator i
= lower_bound(k
);
327 // i->first is greater than or equivalent to k.
328 if (i
== end() || key_comp()(k
, (*i
).first
)){
329 containers_detail::value_init
<T
> v
;
330 value_type
val(k
, boost::interprocess::move(v
.m_t
));
331 i
= insert(i
, boost::interprocess::move(val
));
336 //! Effects: If there is no key equivalent to x in the map, inserts
337 //! value_type(boost::interprocess::move(x), T()) into the map (the key is move-constructed)
339 //! Returns: A reference to the mapped_type corresponding to x in *this.
341 //! Complexity: Logarithmic.
342 T
& operator[](BOOST_INTERPROCESS_RV_REF(key_type
) mk
)
345 //we can optimize this
346 iterator i
= lower_bound(k
);
347 // i->first is greater than or equivalent to k.
348 if (i
== end() || key_comp()(k
, (*i
).first
)){
349 value_type
val(boost::interprocess::move(k
), boost::interprocess::move(T()));
350 i
= insert(i
, boost::interprocess::move(val
));
355 //! Returns: A reference to the element whose key is equivalent to x.
356 //! Throws: An exception object of type out_of_range if no such element is present.
357 //! Complexity: logarithmic.
358 T
& at(const key_type
& k
)
360 iterator i
= this->find(k
);
361 if(i
== this->end()){
362 throw std::out_of_range("key not found");
367 //! Returns: A reference to the element whose key is equivalent to x.
368 //! Throws: An exception object of type out_of_range if no such element is present.
369 //! Complexity: logarithmic.
370 const T
& at(const key_type
& k
) const
372 const_iterator i
= this->find(k
);
373 if(i
== this->end()){
374 throw std::out_of_range("key not found");
379 //! <b>Effects</b>: Swaps the contents of *this and x.
380 //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
382 //! <b>Throws</b>: Nothing.
384 //! <b>Complexity</b>: Constant.
386 { m_tree
.swap(x
.m_tree
); }
388 //! <b>Effects</b>: Inserts x if and only if there is no element in the container
389 //! with key equivalent to the key of x.
391 //! <b>Returns</b>: The bool component of the returned pair is true if and only
392 //! if the insertion takes place, and the iterator component of the pair
393 //! points to the element with key equivalent to the key of x.
395 //! <b>Complexity</b>: Logarithmic.
396 std::pair
<iterator
,bool> insert(const value_type
& x
)
397 { return m_tree
.insert_unique(x
); }
399 //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
400 //! there is no element in the container with key equivalent to the key of x.
402 //! <b>Returns</b>: The bool component of the returned pair is true if and only
403 //! if the insertion takes place, and the iterator component of the pair
404 //! points to the element with key equivalent to the key of x.
406 //! <b>Complexity</b>: Logarithmic.
407 std::pair
<iterator
,bool> insert(const nonconst_value_type
& x
)
408 { return m_tree
.insert_unique(x
); }
410 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
411 //! only if there is no element in the container with key equivalent to the key of x.
413 //! <b>Returns</b>: The bool component of the returned pair is true if and only
414 //! if the insertion takes place, and the iterator component of the pair
415 //! points to the element with key equivalent to the key of x.
417 //! <b>Complexity</b>: Logarithmic.
418 std::pair
<iterator
,bool> insert(BOOST_INTERPROCESS_RV_REF(nonconst_value_type
) x
)
419 { return m_tree
.insert_unique(boost::interprocess::move(x
)); }
421 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
422 //! only if there is no element in the container with key equivalent to the key of x.
424 //! <b>Returns</b>: The bool component of the returned pair is true if and only
425 //! if the insertion takes place, and the iterator component of the pair
426 //! points to the element with key equivalent to the key of x.
428 //! <b>Complexity</b>: Logarithmic.
429 std::pair
<iterator
,bool> insert(BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type
) x
)
430 { return m_tree
.insert_unique(boost::interprocess::move(x
)); }
432 //! <b>Effects</b>: Move constructs a new value from x if and only if there is
433 //! no element in the container with key equivalent to the key of x.
435 //! <b>Returns</b>: The bool component of the returned pair is true if and only
436 //! if the insertion takes place, and the iterator component of the pair
437 //! points to the element with key equivalent to the key of x.
439 //! <b>Complexity</b>: Logarithmic.
440 std::pair
<iterator
,bool> insert(BOOST_INTERPROCESS_RV_REF(value_type
) x
)
441 { return m_tree
.insert_unique(boost::interprocess::move(x
)); }
443 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
444 //! no element in the container with key equivalent to the key of x.
445 //! p is a hint pointing to where the insert should start to search.
447 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
450 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
451 //! is inserted right before p.
452 iterator
insert(iterator position
, const value_type
& x
)
453 { return m_tree
.insert_unique(position
, x
); }
455 //! <b>Effects</b>: Move constructs a new value from x if and only if there is
456 //! no element in the container with key equivalent to the key of x.
457 //! p is a hint pointing to where the insert should start to search.
459 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
462 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
463 //! is inserted right before p.
464 iterator
insert(iterator position
, BOOST_INTERPROCESS_RV_REF(nonconst_value_type
) x
)
465 { return m_tree
.insert_unique(position
, boost::interprocess::move(x
)); }
467 //! <b>Effects</b>: Move constructs a new value from x if and only if there is
468 //! no element in the container with key equivalent to the key of x.
469 //! p is a hint pointing to where the insert should start to search.
471 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
474 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
475 //! is inserted right before p.
476 iterator
insert(iterator position
, BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type
) x
)
477 { return m_tree
.insert_unique(position
, boost::interprocess::move(x
)); }
479 //! <b>Effects</b>: Inserts a copy of x in the container.
480 //! p is a hint pointing to where the insert should start to search.
482 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
484 //! <b>Complexity</b>: Logarithmic.
485 iterator
insert(iterator position
, const nonconst_value_type
& x
)
486 { return m_tree
.insert_unique(position
, x
); }
488 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
489 //! p is a hint pointing to where the insert should start to search.
491 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
493 //! <b>Complexity</b>: Logarithmic.
494 iterator
insert(iterator position
, BOOST_INTERPROCESS_RV_REF(value_type
) x
)
495 { return m_tree
.insert_unique(position
, boost::interprocess::move(x
)); }
497 //! <b>Requires</b>: i, j are not iterators into *this.
499 //! <b>Effects</b>: inserts each element from the range [i,j) if and only
500 //! if there is no element with key equivalent to the key of that element.
502 //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
503 template <class InputIterator
>
504 void insert(InputIterator first
, InputIterator last
)
505 { m_tree
.insert_unique(first
, last
); }
507 #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
509 //! <b>Effects</b>: Inserts an object of type T constructed with
510 //! std::forward<Args>(args)... in the container if and only if there is
511 //! no element in the container with an equivalent key.
512 //! p is a hint pointing to where the insert should start to search.
514 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
517 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
518 //! is inserted right before p.
519 template <class... Args
>
520 iterator
emplace(Args
&&... args
)
521 { return m_tree
.emplace_unique(boost::interprocess::forward
<Args
>(args
)...); }
523 //! <b>Effects</b>: Inserts an object of type T constructed with
524 //! std::forward<Args>(args)... in the container if and only if there is
525 //! no element in the container with an equivalent key.
526 //! p is a hint pointing to where the insert should start to search.
528 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
531 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
532 //! is inserted right before p.
533 template <class... Args
>
534 iterator
emplace_hint(const_iterator hint
, Args
&&... args
)
535 { return m_tree
.emplace_hint_unique(hint
, boost::interprocess::forward
<Args
>(args
)...); }
537 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
540 { return m_tree
.emplace_unique(); }
542 iterator
emplace_hint(const_iterator hint
)
543 { return m_tree
.emplace_hint_unique(hint
); }
545 #define BOOST_PP_LOCAL_MACRO(n) \
546 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
547 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
548 { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
550 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
551 iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
552 { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
554 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
555 #include BOOST_PP_LOCAL_ITERATE()
557 #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
559 //! <b>Effects</b>: Erases the element pointed to by position.
561 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
562 //! following q prior to the element being erased. If no such element exists,
565 //! <b>Complexity</b>: Amortized constant time
566 iterator
erase(const_iterator position
)
567 { return m_tree
.erase(position
); }
569 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
571 //! <b>Returns</b>: Returns the number of erased elements.
573 //! <b>Complexity</b>: log(size()) + count(k)
574 size_type
erase(const key_type
& x
)
575 { return m_tree
.erase(x
); }
577 //! <b>Effects</b>: Erases all the elements in the range [first, last).
579 //! <b>Returns</b>: Returns last.
581 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
582 iterator
erase(const_iterator first
, const_iterator last
)
583 { return m_tree
.erase(first
, last
); }
585 //! <b>Effects</b>: erase(a.begin(),a.end()).
587 //! <b>Postcondition</b>: size() == 0.
589 //! <b>Complexity</b>: linear in size().
593 //! <b>Returns</b>: An iterator pointing to an element with the key
594 //! equivalent to x, or end() if such an element is not found.
596 //! <b>Complexity</b>: Logarithmic.
597 iterator
find(const key_type
& x
)
598 { return m_tree
.find(x
); }
600 //! <b>Returns</b>: A const_iterator pointing to an element with the key
601 //! equivalent to x, or end() if such an element is not found.
603 //! <b>Complexity</b>: Logarithmic.
604 const_iterator
find(const key_type
& x
) const
605 { return m_tree
.find(x
); }
607 //! <b>Returns</b>: The number of elements with key equivalent to x.
609 //! <b>Complexity</b>: log(size())+count(k)
610 size_type
count(const key_type
& x
) const
611 { return m_tree
.find(x
) == m_tree
.end() ? 0 : 1; }
613 //! <b>Returns</b>: An iterator pointing to the first element with key not less
614 //! than k, or a.end() if such an element is not found.
616 //! <b>Complexity</b>: Logarithmic
617 iterator
lower_bound(const key_type
& x
)
618 { return m_tree
.lower_bound(x
); }
620 //! <b>Returns</b>: A const iterator pointing to the first element with key not
621 //! less than k, or a.end() if such an element is not found.
623 //! <b>Complexity</b>: Logarithmic
624 const_iterator
lower_bound(const key_type
& x
) const
625 { return m_tree
.lower_bound(x
); }
627 //! <b>Returns</b>: An iterator pointing to the first element with key not less
628 //! than x, or end() if such an element is not found.
630 //! <b>Complexity</b>: Logarithmic
631 iterator
upper_bound(const key_type
& x
)
632 { return m_tree
.upper_bound(x
); }
634 //! <b>Returns</b>: A const iterator pointing to the first element with key not
635 //! less than x, or end() if such an element is not found.
637 //! <b>Complexity</b>: Logarithmic
638 const_iterator
upper_bound(const key_type
& x
) const
639 { return m_tree
.upper_bound(x
); }
641 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
643 //! <b>Complexity</b>: Logarithmic
644 std::pair
<iterator
,iterator
> equal_range(const key_type
& x
)
645 { return m_tree
.equal_range(x
); }
647 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
649 //! <b>Complexity</b>: Logarithmic
650 std::pair
<const_iterator
,const_iterator
> equal_range(const key_type
& x
) const
651 { return m_tree
.equal_range(x
); }
654 template <class K1
, class T1
, class C1
, class A1
>
655 friend bool operator== (const map
<K1
, T1
, C1
, A1
>&,
656 const map
<K1
, T1
, C1
, A1
>&);
657 template <class K1
, class T1
, class C1
, class A1
>
658 friend bool operator< (const map
<K1
, T1
, C1
, A1
>&,
659 const map
<K1
, T1
, C1
, A1
>&);
663 template <class Key
, class T
, class Pred
, class Alloc
>
664 inline bool operator==(const map
<Key
,T
,Pred
,Alloc
>& x
,
665 const map
<Key
,T
,Pred
,Alloc
>& y
)
666 { return x
.m_tree
== y
.m_tree
; }
668 template <class Key
, class T
, class Pred
, class Alloc
>
669 inline bool operator<(const map
<Key
,T
,Pred
,Alloc
>& x
,
670 const map
<Key
,T
,Pred
,Alloc
>& y
)
671 { return x
.m_tree
< y
.m_tree
; }
673 template <class Key
, class T
, class Pred
, class Alloc
>
674 inline bool operator!=(const map
<Key
,T
,Pred
,Alloc
>& x
,
675 const map
<Key
,T
,Pred
,Alloc
>& y
)
676 { return !(x
== y
); }
678 template <class Key
, class T
, class Pred
, class Alloc
>
679 inline bool operator>(const map
<Key
,T
,Pred
,Alloc
>& x
,
680 const map
<Key
,T
,Pred
,Alloc
>& y
)
683 template <class Key
, class T
, class Pred
, class Alloc
>
684 inline bool operator<=(const map
<Key
,T
,Pred
,Alloc
>& x
,
685 const map
<Key
,T
,Pred
,Alloc
>& y
)
688 template <class Key
, class T
, class Pred
, class Alloc
>
689 inline bool operator>=(const map
<Key
,T
,Pred
,Alloc
>& x
,
690 const map
<Key
,T
,Pred
,Alloc
>& y
)
693 template <class Key
, class T
, class Pred
, class Alloc
>
694 inline void swap(map
<Key
,T
,Pred
,Alloc
>& x
, map
<Key
,T
,Pred
,Alloc
>& y
)
699 // Forward declaration of operators < and ==, needed for friend declaration.
701 template <class Key
, class T
, class Pred
, class Alloc
>
702 inline bool operator==(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
703 const multimap
<Key
,T
,Pred
,Alloc
>& y
);
705 template <class Key
, class T
, class Pred
, class Alloc
>
706 inline bool operator<(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
707 const multimap
<Key
,T
,Pred
,Alloc
>& y
);
709 } //namespace interprocess_container {
711 namespace interprocess
{
713 //!has_trivial_destructor_after_move<> == true_type
714 //!specialization for optimizations
715 template <class K
, class T
, class C
, class A
>
716 struct has_trivial_destructor_after_move
<boost::interprocess_container::map
<K
, T
, C
, A
> >
718 static const bool value
= has_trivial_destructor
<A
>::value
&& has_trivial_destructor
<C
>::value
;
721 } //namespace interprocess {
723 namespace interprocess_container
{
727 //! A multimap is a kind of associative container that supports equivalent keys
728 //! (possibly containing multiple copies of the same key value) and provides for
729 //! fast retrieval of values of another type T based on the keys. The multimap class
730 //! supports bidirectional iterators.
732 //! A multimap satisfies all of the requirements of a container and of a reversible
733 //! container and of an associative container. For a
734 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
736 //! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
738 //! Alloc is the allocator to allocate the value_types
739 //!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
740 template <class Key
, class T
, class Pred
, class Alloc
>
745 typedef containers_detail::rbtree
<Key
,
746 std::pair
<const Key
, T
>,
747 containers_detail::select1st
< std::pair
<const Key
, T
> >,
750 tree_t m_tree
; // red-black tree representing map
754 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(multimap
)
757 typedef typename
tree_t::key_type key_type
;
758 typedef typename
tree_t::value_type value_type
;
759 typedef typename
tree_t::pointer pointer
;
760 typedef typename
tree_t::const_pointer const_pointer
;
761 typedef typename
tree_t::reference reference
;
762 typedef typename
tree_t::const_reference const_reference
;
763 typedef T mapped_type
;
764 typedef Pred key_compare
;
765 typedef typename
tree_t::iterator iterator
;
766 typedef typename
tree_t::const_iterator const_iterator
;
767 typedef typename
tree_t::reverse_iterator reverse_iterator
;
768 typedef typename
tree_t::const_reverse_iterator const_reverse_iterator
;
769 typedef typename
tree_t::size_type size_type
;
770 typedef typename
tree_t::difference_type difference_type
;
771 typedef typename
tree_t::allocator_type allocator_type
;
772 typedef typename
tree_t::stored_allocator_type stored_allocator_type
;
773 typedef std::pair
<key_type
, mapped_type
> nonconst_value_type
;
774 typedef containers_detail::pair
775 <key_type
, mapped_type
> nonconst_impl_value_type
;
778 class value_compare_impl
780 public std::binary_function
<value_type
, value_type
, bool>
782 friend class multimap
<Key
,T
,Pred
,Alloc
>;
784 value_compare_impl(const Pred
&c
) : Pred(c
) {}
786 bool operator()(const value_type
& x
, const value_type
& y
) const {
787 return Pred::operator()(x
.first
, y
.first
);
791 typedef value_compare_impl value_compare
;
793 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
794 //! object and allocator.
796 //! <b>Complexity</b>: Constant.
797 explicit multimap(const Pred
& comp
= Pred(),
798 const allocator_type
& a
= allocator_type())
802 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
803 //! and allocator, and inserts elements from the range [first ,last ).
805 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
806 //! comp and otherwise N logN, where N is last - first.
807 template <class InputIterator
>
808 multimap(InputIterator first
, InputIterator last
,
809 const Pred
& comp
= Pred(),
810 const allocator_type
& a
= allocator_type())
811 : m_tree(first
, last
, comp
, a
, false)
814 //! <b>Effects</b>: Copy constructs a multimap.
816 //! <b>Complexity</b>: Linear in x.size().
817 multimap(const multimap
<Key
,T
,Pred
,Alloc
>& x
)
821 //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
823 //! <b>Complexity</b>: Construct.
825 //! <b>Postcondition</b>: x is emptied.
826 multimap(BOOST_INTERPROCESS_RV_REF(multimap
) x
)
827 : m_tree(boost::interprocess::move(x
.m_tree
))
830 //! <b>Effects</b>: Makes *this a copy of x.
832 //! <b>Complexity</b>: Linear in x.size().
833 multimap
& operator=(const multimap
<Key
,T
,Pred
,Alloc
>& x
)
834 { m_tree
= x
.m_tree
; return *this; }
836 //! <b>Effects</b>: this->swap(x.get()).
838 //! <b>Complexity</b>: Constant.
839 multimap
& operator=(BOOST_INTERPROCESS_RV_REF(multimap
) x
)
840 { m_tree
= boost::interprocess::move(x
.m_tree
); return *this; }
842 //! <b>Effects</b>: Returns the comparison object out
843 //! of which a was constructed.
845 //! <b>Complexity</b>: Constant.
846 key_compare
key_comp() const
847 { return m_tree
.key_comp(); }
849 //! <b>Effects</b>: Returns an object of value_compare constructed out
850 //! of the comparison object.
852 //! <b>Complexity</b>: Constant.
853 value_compare
value_comp() const
854 { return value_compare(m_tree
.key_comp()); }
856 //! <b>Effects</b>: Returns a copy of the Allocator that
857 //! was passed to the object's constructor.
859 //! <b>Complexity</b>: Constant.
860 allocator_type
get_allocator() const
861 { return m_tree
.get_allocator(); }
863 const stored_allocator_type
&get_stored_allocator() const
864 { return m_tree
.get_stored_allocator(); }
866 stored_allocator_type
&get_stored_allocator()
867 { return m_tree
.get_stored_allocator(); }
869 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
871 //! <b>Throws</b>: Nothing.
873 //! <b>Complexity</b>: Constant.
875 { return m_tree
.begin(); }
877 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
879 //! <b>Throws</b>: Nothing.
881 //! <b>Complexity</b>: Constant.
882 const_iterator
begin() const
883 { return m_tree
.begin(); }
885 //! <b>Effects</b>: Returns an iterator to the end of the container.
887 //! <b>Throws</b>: Nothing.
889 //! <b>Complexity</b>: Constant.
891 { return m_tree
.end(); }
893 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
895 //! <b>Throws</b>: Nothing.
897 //! <b>Complexity</b>: Constant.
898 const_iterator
end() const
899 { return m_tree
.end(); }
901 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
902 //! of the reversed container.
904 //! <b>Throws</b>: Nothing.
906 //! <b>Complexity</b>: Constant.
907 reverse_iterator
rbegin()
908 { return m_tree
.rbegin(); }
910 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
911 //! of the reversed container.
913 //! <b>Throws</b>: Nothing.
915 //! <b>Complexity</b>: Constant.
916 const_reverse_iterator
rbegin() const
917 { return m_tree
.rbegin(); }
919 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
920 //! of the reversed container.
922 //! <b>Throws</b>: Nothing.
924 //! <b>Complexity</b>: Constant.
925 reverse_iterator
rend()
926 { return m_tree
.rend(); }
928 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
929 //! of the reversed container.
931 //! <b>Throws</b>: Nothing.
933 //! <b>Complexity</b>: Constant.
934 const_reverse_iterator
rend() const
935 { return m_tree
.rend(); }
937 //! <b>Effects</b>: Returns true if the container contains no elements.
939 //! <b>Throws</b>: Nothing.
941 //! <b>Complexity</b>: Constant.
943 { return m_tree
.empty(); }
945 //! <b>Effects</b>: Returns the number of the elements contained in the container.
947 //! <b>Throws</b>: Nothing.
949 //! <b>Complexity</b>: Constant.
950 size_type
size() const
951 { return m_tree
.size(); }
953 //! <b>Effects</b>: Returns the largest possible size of the container.
955 //! <b>Throws</b>: Nothing.
957 //! <b>Complexity</b>: Constant.
958 size_type
max_size() const
959 { return m_tree
.max_size(); }
961 //! <b>Effects</b>: Swaps the contents of *this and x.
962 //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
964 //! <b>Throws</b>: Nothing.
966 //! <b>Complexity</b>: Constant.
967 void swap(multimap
& x
)
968 { m_tree
.swap(x
.m_tree
); }
970 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
971 //! newly inserted element.
973 //! <b>Complexity</b>: Logarithmic.
974 iterator
insert(const value_type
& x
)
975 { return m_tree
.insert_equal(x
); }
977 //! <b>Effects</b>: Inserts a new value constructed from x and returns
978 //! the iterator pointing to the newly inserted element.
980 //! <b>Complexity</b>: Logarithmic.
981 iterator
insert(const nonconst_value_type
& x
)
982 { return m_tree
.insert_equal(x
); }
984 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
985 //! the iterator pointing to the newly inserted element.
987 //! <b>Complexity</b>: Logarithmic.
988 iterator
insert(BOOST_INTERPROCESS_RV_REF(nonconst_value_type
) x
)
989 { return m_tree
.insert_equal(boost::interprocess::move(x
)); }
991 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
992 //! the iterator pointing to the newly inserted element.
994 //! <b>Complexity</b>: Logarithmic.
995 iterator
insert(BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type
) x
)
996 { return m_tree
.insert_equal(boost::interprocess::move(x
)); }
998 //! <b>Effects</b>: Inserts a copy of x in the container.
999 //! p is a hint pointing to where the insert should start to search.
1001 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1002 //! to the key of x.
1004 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1005 //! is inserted right before p.
1006 iterator
insert(iterator position
, const value_type
& x
)
1007 { return m_tree
.insert_equal(position
, x
); }
1009 //! <b>Effects</b>: Inserts a new value constructed from x in the container.
1010 //! p is a hint pointing to where the insert should start to search.
1012 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1013 //! to the key of x.
1015 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1016 //! is inserted right before p.
1017 iterator
insert(iterator position
, const nonconst_value_type
& x
)
1018 { return m_tree
.insert_equal(position
, x
); }
1020 //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
1021 //! p is a hint pointing to where the insert should start to search.
1023 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1024 //! to the key of x.
1026 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1027 //! is inserted right before p.
1028 iterator
insert(iterator position
, BOOST_INTERPROCESS_RV_REF(nonconst_value_type
) x
)
1029 { return m_tree
.insert_equal(position
, boost::interprocess::move(x
)); }
1031 //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
1032 //! p is a hint pointing to where the insert should start to search.
1034 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1035 //! to the key of x.
1037 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1038 //! is inserted right before p.
1039 iterator
insert(iterator position
, BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type
) x
)
1040 { return m_tree
.insert_equal(position
, boost::interprocess::move(x
)); }
1042 //! <b>Requires</b>: i, j are not iterators into *this.
1044 //! <b>Effects</b>: inserts each element from the range [i,j) .
1046 //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
1047 template <class InputIterator
>
1048 void insert(InputIterator first
, InputIterator last
)
1049 { m_tree
.insert_equal(first
, last
); }
1051 #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
1053 //! <b>Effects</b>: Inserts an object of type T constructed with
1054 //! std::forward<Args>(args)... in the container.
1055 //! p is a hint pointing to where the insert should start to search.
1057 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1058 //! to the key of x.
1060 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1061 //! is inserted right before p.
1062 template <class... Args
>
1063 iterator
emplace(Args
&&... args
)
1064 { return m_tree
.emplace_equal(boost::interprocess::forward
<Args
>(args
)...); }
1066 //! <b>Effects</b>: Inserts an object of type T constructed with
1067 //! std::forward<Args>(args)... in the container.
1068 //! p is a hint pointing to where the insert should start to search.
1070 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1071 //! to the key of x.
1073 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1074 //! is inserted right before p.
1075 template <class... Args
>
1076 iterator
emplace_hint(const_iterator hint
, Args
&&... args
)
1077 { return m_tree
.emplace_hint_equal(hint
, boost::interprocess::forward
<Args
>(args
)...); }
1079 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
1082 { return m_tree
.emplace_equal(); }
1084 iterator
emplace_hint(const_iterator hint
)
1085 { return m_tree
.emplace_hint_equal(hint
); }
1087 #define BOOST_PP_LOCAL_MACRO(n) \
1088 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
1089 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
1090 { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
1092 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
1093 iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
1094 { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
1096 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
1097 #include BOOST_PP_LOCAL_ITERATE()
1099 #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
1101 //! <b>Effects</b>: Erases the element pointed to by position.
1103 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
1104 //! following q prior to the element being erased. If no such element exists,
1107 //! <b>Complexity</b>: Amortized constant time
1108 iterator
erase(const_iterator position
)
1109 { return m_tree
.erase(position
); }
1111 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
1113 //! <b>Returns</b>: Returns the number of erased elements.
1115 //! <b>Complexity</b>: log(size()) + count(k)
1116 size_type
erase(const key_type
& x
)
1117 { return m_tree
.erase(x
); }
1119 //! <b>Effects</b>: Erases all the elements in the range [first, last).
1121 //! <b>Returns</b>: Returns last.
1123 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
1124 iterator
erase(const_iterator first
, const_iterator last
)
1125 { return m_tree
.erase(first
, last
); }
1127 //! <b>Effects</b>: erase(a.begin(),a.end()).
1129 //! <b>Postcondition</b>: size() == 0.
1131 //! <b>Complexity</b>: linear in size().
1135 //! <b>Returns</b>: An iterator pointing to an element with the key
1136 //! equivalent to x, or end() if such an element is not found.
1138 //! <b>Complexity</b>: Logarithmic.
1139 iterator
find(const key_type
& x
)
1140 { return m_tree
.find(x
); }
1142 //! <b>Returns</b>: A const iterator pointing to an element with the key
1143 //! equivalent to x, or end() if such an element is not found.
1145 //! <b>Complexity</b>: Logarithmic.
1146 const_iterator
find(const key_type
& x
) const
1147 { return m_tree
.find(x
); }
1149 //! <b>Returns</b>: The number of elements with key equivalent to x.
1151 //! <b>Complexity</b>: log(size())+count(k)
1152 size_type
count(const key_type
& x
) const
1153 { return m_tree
.count(x
); }
1155 //! <b>Returns</b>: An iterator pointing to the first element with key not less
1156 //! than k, or a.end() if such an element is not found.
1158 //! <b>Complexity</b>: Logarithmic
1159 iterator
lower_bound(const key_type
& x
)
1160 {return m_tree
.lower_bound(x
); }
1162 //! <b>Returns</b>: A const iterator pointing to the first element with key not
1163 //! less than k, or a.end() if such an element is not found.
1165 //! <b>Complexity</b>: Logarithmic
1166 const_iterator
lower_bound(const key_type
& x
) const
1167 { return m_tree
.lower_bound(x
); }
1169 //! <b>Returns</b>: An iterator pointing to the first element with key not less
1170 //! than x, or end() if such an element is not found.
1172 //! <b>Complexity</b>: Logarithmic
1173 iterator
upper_bound(const key_type
& x
)
1174 { return m_tree
.upper_bound(x
); }
1176 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1178 //! <b>Complexity</b>: Logarithmic
1179 std::pair
<iterator
,iterator
> equal_range(const key_type
& x
)
1180 { return m_tree
.equal_range(x
); }
1182 //! <b>Returns</b>: A const iterator pointing to the first element with key not
1183 //! less than x, or end() if such an element is not found.
1185 //! <b>Complexity</b>: Logarithmic
1186 const_iterator
upper_bound(const key_type
& x
) const
1187 { return m_tree
.upper_bound(x
); }
1189 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1191 //! <b>Complexity</b>: Logarithmic
1192 std::pair
<const_iterator
,const_iterator
>
1193 equal_range(const key_type
& x
) const
1194 { return m_tree
.equal_range(x
); }
1197 template <class K1
, class T1
, class C1
, class A1
>
1198 friend bool operator== (const multimap
<K1
, T1
, C1
, A1
>& x
,
1199 const multimap
<K1
, T1
, C1
, A1
>& y
);
1201 template <class K1
, class T1
, class C1
, class A1
>
1202 friend bool operator< (const multimap
<K1
, T1
, C1
, A1
>& x
,
1203 const multimap
<K1
, T1
, C1
, A1
>& y
);
1207 template <class Key
, class T
, class Pred
, class Alloc
>
1208 inline bool operator==(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
1209 const multimap
<Key
,T
,Pred
,Alloc
>& y
)
1210 { return x
.m_tree
== y
.m_tree
; }
1212 template <class Key
, class T
, class Pred
, class Alloc
>
1213 inline bool operator<(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
1214 const multimap
<Key
,T
,Pred
,Alloc
>& y
)
1215 { return x
.m_tree
< y
.m_tree
; }
1217 template <class Key
, class T
, class Pred
, class Alloc
>
1218 inline bool operator!=(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
1219 const multimap
<Key
,T
,Pred
,Alloc
>& y
)
1220 { return !(x
== y
); }
1222 template <class Key
, class T
, class Pred
, class Alloc
>
1223 inline bool operator>(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
1224 const multimap
<Key
,T
,Pred
,Alloc
>& y
)
1227 template <class Key
, class T
, class Pred
, class Alloc
>
1228 inline bool operator<=(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
1229 const multimap
<Key
,T
,Pred
,Alloc
>& y
)
1230 { return !(y
< x
); }
1232 template <class Key
, class T
, class Pred
, class Alloc
>
1233 inline bool operator>=(const multimap
<Key
,T
,Pred
,Alloc
>& x
,
1234 const multimap
<Key
,T
,Pred
,Alloc
>& y
)
1235 { return !(x
< y
); }
1237 template <class Key
, class T
, class Pred
, class Alloc
>
1238 inline void swap(multimap
<Key
,T
,Pred
,Alloc
>& x
, multimap
<Key
,T
,Pred
,Alloc
>& y
)
1243 } //namespace interprocess_container {
1245 namespace interprocess
{
1247 //!has_trivial_destructor_after_move<> == true_type
1248 //!specialization for optimizations
1249 template <class K
, class T
, class C
, class A
>
1250 struct has_trivial_destructor_after_move
<boost::interprocess_container::multimap
<K
, T
, C
, A
> >
1252 static const bool value
= has_trivial_destructor
<A
>::value
&& has_trivial_destructor
<C
>::value
;
1255 } //namespace interprocess {
1257 namespace interprocess_container
{
1263 #include <boost/interprocess/containers/container/detail/config_end.hpp>
1265 #endif /* BOOST_CONTAINERS_MAP_HPP */