Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@101
|
3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/container for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10 #ifndef BOOST_CONTAINER_FLAT_MAP_HPP
|
Chris@16
|
11 #define BOOST_CONTAINER_FLAT_MAP_HPP
|
Chris@16
|
12
|
Chris@101
|
13 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
14 # include <boost/config.hpp>
|
Chris@101
|
15 #endif
|
Chris@101
|
16
|
Chris@101
|
17 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@16
|
18 # pragma once
|
Chris@16
|
19 #endif
|
Chris@16
|
20
|
Chris@16
|
21 #include <boost/container/detail/config_begin.hpp>
|
Chris@16
|
22 #include <boost/container/detail/workaround.hpp>
|
Chris@101
|
23 // container
|
Chris@101
|
24 #include <boost/container/allocator_traits.hpp>
|
Chris@101
|
25 #include <boost/container/container_fwd.hpp>
|
Chris@101
|
26 #include <boost/container/new_allocator.hpp> //new_allocator
|
Chris@101
|
27 #include <boost/container/throw_exception.hpp>
|
Chris@101
|
28 // container/detail
|
Chris@101
|
29 #include <boost/container/detail/flat_tree.hpp>
|
Chris@101
|
30 #include <boost/container/detail/type_traits.hpp>
|
Chris@101
|
31 #include <boost/container/detail/mpl.hpp>
|
Chris@101
|
32 #include <boost/container/detail/algorithm.hpp> //equal()
|
Chris@101
|
33 // move
|
Chris@101
|
34 #include <boost/move/utility_core.hpp>
|
Chris@101
|
35 #include <boost/move/traits.hpp>
|
Chris@101
|
36 // move/detail
|
Chris@101
|
37 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
38 #include <boost/move/detail/fwd_macros.hpp>
|
Chris@101
|
39 #endif
|
Chris@101
|
40 #include <boost/move/detail/move_helpers.hpp>
|
Chris@101
|
41 // intrusive
|
Chris@101
|
42 #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
Chris@101
|
43 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
|
Chris@101
|
44 //others
|
Chris@101
|
45 #include <boost/core/no_exceptions_support.hpp>
|
Chris@16
|
46
|
Chris@101
|
47 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
48 #include <initializer_list>
|
Chris@101
|
49 #endif
|
Chris@16
|
50
|
Chris@16
|
51 namespace boost {
|
Chris@16
|
52 namespace container {
|
Chris@16
|
53
|
Chris@101
|
54 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
55
|
Chris@16
|
56 namespace container_detail{
|
Chris@16
|
57
|
Chris@16
|
58 template<class D, class S>
|
Chris@16
|
59 static D &force(const S &s)
|
Chris@16
|
60 { return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
|
Chris@16
|
61
|
Chris@16
|
62 template<class D, class S>
|
Chris@16
|
63 static D force_copy(S s)
|
Chris@16
|
64 {
|
Chris@16
|
65 D *vp = reinterpret_cast<D *>(&s);
|
Chris@16
|
66 return D(*vp);
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 } //namespace container_detail{
|
Chris@16
|
70
|
Chris@101
|
71 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
72
|
Chris@16
|
73 //! A flat_map is a kind of associative container that supports unique keys (contains at
|
Chris@16
|
74 //! most one of each key value) and provides for fast retrieval of values of another
|
Chris@16
|
75 //! type T based on the keys. The flat_map class supports random-access iterators.
|
Chris@16
|
76 //!
|
Chris@16
|
77 //! A flat_map satisfies all of the requirements of a container and of a reversible
|
Chris@16
|
78 //! container and of an associative container. A flat_map also provides
|
Chris@16
|
79 //! most operations described for unique keys. For a
|
Chris@16
|
80 //! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
|
Chris@16
|
81 //! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
|
Chris@16
|
82 //!
|
Chris@16
|
83 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
Chris@16
|
84 //!
|
Chris@16
|
85 //! Allocator is the allocator to allocate the value_types
|
Chris@16
|
86 //! (e.g. <i>allocator< std::pair<Key, T> ></i>).
|
Chris@16
|
87 //!
|
Chris@16
|
88 //! flat_map is similar to std::map but it's implemented like an ordered vector.
|
Chris@16
|
89 //! This means that inserting a new element into a flat_map invalidates
|
Chris@16
|
90 //! previous iterators and references
|
Chris@16
|
91 //!
|
Chris@16
|
92 //! Erasing an element invalidates iterators and references
|
Chris@16
|
93 //! pointing to elements that come after (their keys are bigger) the erased element.
|
Chris@16
|
94 //!
|
Chris@16
|
95 //! This container provides random-access iterators.
|
Chris@101
|
96 //!
|
Chris@101
|
97 //! \tparam Key is the key_type of the map
|
Chris@101
|
98 //! \tparam Value is the <code>mapped_type</code>
|
Chris@101
|
99 //! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
Chris@101
|
100 //! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
Chris@101
|
101 //! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
Chris@16
|
102 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@101
|
103 template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
|
Chris@16
|
104 #else
|
Chris@16
|
105 template <class Key, class T, class Compare, class Allocator>
|
Chris@16
|
106 #endif
|
Chris@16
|
107 class flat_map
|
Chris@16
|
108 {
|
Chris@101
|
109 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
110 private:
|
Chris@16
|
111 BOOST_COPYABLE_AND_MOVABLE(flat_map)
|
Chris@16
|
112 //This is the tree that we should store if pair was movable
|
Chris@16
|
113 typedef container_detail::flat_tree<Key,
|
Chris@16
|
114 std::pair<Key, T>,
|
Chris@16
|
115 container_detail::select1st< std::pair<Key, T> >,
|
Chris@16
|
116 Compare,
|
Chris@16
|
117 Allocator> tree_t;
|
Chris@16
|
118
|
Chris@16
|
119 //This is the real tree stored here. It's based on a movable pair
|
Chris@16
|
120 typedef container_detail::flat_tree<Key,
|
Chris@16
|
121 container_detail::pair<Key, T>,
|
Chris@16
|
122 container_detail::select1st<container_detail::pair<Key, T> >,
|
Chris@16
|
123 Compare,
|
Chris@16
|
124 typename allocator_traits<Allocator>::template portable_rebind_alloc
|
Chris@16
|
125 <container_detail::pair<Key, T> >::type> impl_tree_t;
|
Chris@16
|
126 impl_tree_t m_flat_tree; // flat tree representing flat_map
|
Chris@16
|
127
|
Chris@16
|
128 typedef typename impl_tree_t::value_type impl_value_type;
|
Chris@16
|
129 typedef typename impl_tree_t::const_iterator impl_const_iterator;
|
Chris@101
|
130 typedef typename impl_tree_t::iterator impl_iterator;
|
Chris@16
|
131 typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
Chris@16
|
132 typedef container_detail::flat_tree_value_compare
|
Chris@16
|
133 < Compare
|
Chris@16
|
134 , container_detail::select1st< std::pair<Key, T> >
|
Chris@16
|
135 , std::pair<Key, T> > value_compare_impl;
|
Chris@16
|
136 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
137 <typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
|
Chris@16
|
138 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
139 <typename allocator_traits<Allocator>::pointer>::const_iterator const_iterator_impl;
|
Chris@16
|
140 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
141 <typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
Chris@16
|
142 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
143 <typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
Chris@101
|
144 public:
|
Chris@101
|
145 typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
Chris@101
|
146 private:
|
Chris@101
|
147 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
148
|
Chris@16
|
149 public:
|
Chris@16
|
150
|
Chris@16
|
151 //////////////////////////////////////////////
|
Chris@16
|
152 //
|
Chris@16
|
153 // types
|
Chris@16
|
154 //
|
Chris@16
|
155 //////////////////////////////////////////////
|
Chris@16
|
156 typedef Key key_type;
|
Chris@16
|
157 typedef T mapped_type;
|
Chris@16
|
158 typedef std::pair<Key, T> value_type;
|
Chris@101
|
159 typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
160 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
Chris@16
|
161 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
Chris@16
|
162 typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
Chris@16
|
163 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
|
Chris@16
|
164 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
Chris@16
|
165 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
|
Chris@16
|
166 typedef Allocator allocator_type;
|
Chris@16
|
167 typedef BOOST_CONTAINER_IMPDEF(Allocator) stored_allocator_type;
|
Chris@16
|
168 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
|
Chris@16
|
169 typedef Compare key_compare;
|
Chris@16
|
170 typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
|
Chris@16
|
171 typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
|
Chris@16
|
172 typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator;
|
Chris@16
|
173 typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
|
Chris@16
|
174 typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
|
Chris@16
|
175
|
Chris@16
|
176 public:
|
Chris@16
|
177 //////////////////////////////////////////////
|
Chris@16
|
178 //
|
Chris@16
|
179 // construct/copy/destroy
|
Chris@16
|
180 //
|
Chris@16
|
181 //////////////////////////////////////////////
|
Chris@16
|
182
|
Chris@16
|
183 //! <b>Effects</b>: Default constructs an empty flat_map.
|
Chris@16
|
184 //!
|
Chris@16
|
185 //! <b>Complexity</b>: Constant.
|
Chris@16
|
186 flat_map()
|
Chris@101
|
187 : m_flat_tree()
|
Chris@101
|
188 {
|
Chris@101
|
189 //A type must be std::pair<Key, T>
|
Chris@101
|
190 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
191 }
|
Chris@16
|
192
|
Chris@16
|
193 //! <b>Effects</b>: Constructs an empty flat_map using the specified
|
Chris@16
|
194 //! comparison object and allocator.
|
Chris@16
|
195 //!
|
Chris@16
|
196 //! <b>Complexity</b>: Constant.
|
Chris@16
|
197 explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type())
|
Chris@16
|
198 : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
199 {
|
Chris@101
|
200 //A type must be std::pair<Key, T>
|
Chris@101
|
201 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
202 }
|
Chris@16
|
203
|
Chris@16
|
204 //! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
|
Chris@16
|
205 //!
|
Chris@16
|
206 //! <b>Complexity</b>: Constant.
|
Chris@16
|
207 explicit flat_map(const allocator_type& a)
|
Chris@16
|
208 : m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
209 {
|
Chris@101
|
210 //A type must be std::pair<Key, T>
|
Chris@101
|
211 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
212 }
|
Chris@16
|
213
|
Chris@16
|
214 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
Chris@16
|
215 //! allocator, and inserts elements from the range [first ,last ).
|
Chris@16
|
216 //!
|
Chris@16
|
217 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
Chris@16
|
218 //! comp and otherwise N logN, where N is last - first.
|
Chris@16
|
219 template <class InputIterator>
|
Chris@16
|
220 flat_map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
Chris@16
|
221 const allocator_type& a = allocator_type())
|
Chris@16
|
222 : m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
223 {
|
Chris@101
|
224 //A type must be std::pair<Key, T>
|
Chris@101
|
225 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
226 }
|
Chris@101
|
227
|
Chris@101
|
228 //! <b>Effects</b>: Constructs an empty flat_map using the specified
|
Chris@101
|
229 //! allocator, and inserts elements from the range [first ,last ).
|
Chris@101
|
230 //!
|
Chris@101
|
231 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
Chris@101
|
232 //! comp and otherwise N logN, where N is last - first.
|
Chris@101
|
233 template <class InputIterator>
|
Chris@101
|
234 flat_map(InputIterator first, InputIterator last, const allocator_type& a)
|
Chris@101
|
235 : m_flat_tree(true, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
236 {
|
Chris@101
|
237 //A type must be std::pair<Key, T>
|
Chris@101
|
238 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
239 }
|
Chris@16
|
240
|
Chris@16
|
241 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
Chris@16
|
242 //! allocator, and inserts elements from the ordered unique range [first ,last). This function
|
Chris@16
|
243 //! is more efficient than the normal range creation for ordered ranges.
|
Chris@16
|
244 //!
|
Chris@16
|
245 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
|
Chris@16
|
246 //! unique values.
|
Chris@16
|
247 //!
|
Chris@16
|
248 //! <b>Complexity</b>: Linear in N.
|
Chris@16
|
249 //!
|
Chris@16
|
250 //! <b>Note</b>: Non-standard extension.
|
Chris@16
|
251 template <class InputIterator>
|
Chris@16
|
252 flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
|
Chris@16
|
253 , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
Chris@16
|
254 : m_flat_tree(ordered_range, first, last, comp, a)
|
Chris@101
|
255 {
|
Chris@101
|
256 //A type must be std::pair<Key, T>
|
Chris@101
|
257 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
258 }
|
Chris@101
|
259
|
Chris@101
|
260 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
261 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
Chris@101
|
262 //! allocator, and inserts elements from the range [il.begin() ,il.end()).
|
Chris@101
|
263 //!
|
Chris@101
|
264 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
Chris@101
|
265 //! comp and otherwise N logN, where N is last - first.
|
Chris@101
|
266 flat_map(std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
Chris@101
|
267 const allocator_type& a = allocator_type())
|
Chris@101
|
268 : m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
269 {
|
Chris@101
|
270 //A type must be std::pair<Key, T>
|
Chris@101
|
271 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
272 }
|
Chris@101
|
273
|
Chris@101
|
274 //! <b>Effects</b>: Constructs an empty flat_map using the specified
|
Chris@101
|
275 //! allocator, and inserts elements from the range [il.begin() ,il.end()).
|
Chris@101
|
276 //!
|
Chris@101
|
277 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
Chris@101
|
278 //! comp and otherwise N logN, where N is last - first.
|
Chris@101
|
279 flat_map(std::initializer_list<value_type> il, const allocator_type& a)
|
Chris@101
|
280 : m_flat_tree(true, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
281 {
|
Chris@101
|
282 //A type must be std::pair<Key, T>
|
Chris@101
|
283 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
284 }
|
Chris@101
|
285
|
Chris@101
|
286 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
Chris@101
|
287 //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
|
Chris@101
|
288 //! is more efficient than the normal range creation for ordered ranges.
|
Chris@101
|
289 //!
|
Chris@101
|
290 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
|
Chris@101
|
291 //! unique values.
|
Chris@101
|
292 //!
|
Chris@101
|
293 //! <b>Complexity</b>: Linear in N.
|
Chris@101
|
294 //!
|
Chris@101
|
295 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
296 flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
Chris@101
|
297 const allocator_type& a = allocator_type())
|
Chris@101
|
298 : m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
|
Chris@101
|
299 {
|
Chris@101
|
300 //A type must be std::pair<Key, T>
|
Chris@101
|
301 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
302 }
|
Chris@101
|
303 #endif
|
Chris@16
|
304
|
Chris@16
|
305 //! <b>Effects</b>: Copy constructs a flat_map.
|
Chris@16
|
306 //!
|
Chris@16
|
307 //! <b>Complexity</b>: Linear in x.size().
|
Chris@16
|
308 flat_map(const flat_map& x)
|
Chris@101
|
309 : m_flat_tree(x.m_flat_tree)
|
Chris@101
|
310 {
|
Chris@101
|
311 //A type must be std::pair<Key, T>
|
Chris@101
|
312 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
313 }
|
Chris@16
|
314
|
Chris@16
|
315 //! <b>Effects</b>: Move constructs a flat_map.
|
Chris@16
|
316 //! Constructs *this using x's resources.
|
Chris@16
|
317 //!
|
Chris@16
|
318 //! <b>Complexity</b>: Constant.
|
Chris@16
|
319 //!
|
Chris@16
|
320 //! <b>Postcondition</b>: x is emptied.
|
Chris@16
|
321 flat_map(BOOST_RV_REF(flat_map) x)
|
Chris@16
|
322 : m_flat_tree(boost::move(x.m_flat_tree))
|
Chris@101
|
323 {
|
Chris@101
|
324 //A type must be std::pair<Key, T>
|
Chris@101
|
325 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
326 }
|
Chris@16
|
327
|
Chris@16
|
328 //! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
|
Chris@16
|
329 //!
|
Chris@16
|
330 //! <b>Complexity</b>: Linear in x.size().
|
Chris@16
|
331 flat_map(const flat_map& x, const allocator_type &a)
|
Chris@16
|
332 : m_flat_tree(x.m_flat_tree, a)
|
Chris@101
|
333 {
|
Chris@101
|
334 //A type must be std::pair<Key, T>
|
Chris@101
|
335 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
336 }
|
Chris@16
|
337
|
Chris@16
|
338 //! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
|
Chris@16
|
339 //! Constructs *this using x's resources.
|
Chris@16
|
340 //!
|
Chris@16
|
341 //! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
|
Chris@16
|
342 flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
|
Chris@16
|
343 : m_flat_tree(boost::move(x.m_flat_tree), a)
|
Chris@101
|
344 {
|
Chris@101
|
345 //A type must be std::pair<Key, T>
|
Chris@101
|
346 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
347 }
|
Chris@16
|
348
|
Chris@16
|
349 //! <b>Effects</b>: Makes *this a copy of x.
|
Chris@16
|
350 //!
|
Chris@16
|
351 //! <b>Complexity</b>: Linear in x.size().
|
Chris@16
|
352 flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
|
Chris@16
|
353 { m_flat_tree = x.m_flat_tree; return *this; }
|
Chris@16
|
354
|
Chris@16
|
355 //! <b>Effects</b>: Move constructs a flat_map.
|
Chris@16
|
356 //! Constructs *this using x's resources.
|
Chris@16
|
357 //!
|
Chris@101
|
358 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
Chris@101
|
359 //! is false and (allocation throws or value_type's move constructor throws)
|
Chris@16
|
360 //!
|
Chris@101
|
361 //! <b>Complexity</b>: Constant if allocator_traits_type::
|
Chris@101
|
362 //! propagate_on_container_move_assignment is true or
|
Chris@101
|
363 //! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
Chris@101
|
364 flat_map& operator=(BOOST_RV_REF(flat_map) x)
|
Chris@101
|
365 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
Chris@101
|
366 && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
Chris@101
|
367 { m_flat_tree = boost::move(x.m_flat_tree); return *this; }
|
Chris@16
|
368
|
Chris@101
|
369 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
370 //! <b>Effects</b>: Assign elements from il to *this
|
Chris@101
|
371 flat_map& operator=(std::initializer_list<value_type> il)
|
Chris@101
|
372 {
|
Chris@101
|
373 this->clear();
|
Chris@101
|
374 this->insert(il.begin(), il.end());
|
Chris@101
|
375 return *this;
|
Chris@101
|
376 }
|
Chris@101
|
377 #endif
|
Chris@101
|
378
|
Chris@101
|
379 //! <b>Effects</b>: Returns a copy of the allocator that
|
Chris@16
|
380 //! was passed to the object's constructor.
|
Chris@16
|
381 //!
|
Chris@16
|
382 //! <b>Complexity</b>: Constant.
|
Chris@101
|
383 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
384 { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
|
Chris@16
|
385
|
Chris@16
|
386 //! <b>Effects</b>: Returns a reference to the internal allocator.
|
Chris@16
|
387 //!
|
Chris@16
|
388 //! <b>Throws</b>: Nothing
|
Chris@16
|
389 //!
|
Chris@16
|
390 //! <b>Complexity</b>: Constant.
|
Chris@16
|
391 //!
|
Chris@16
|
392 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
393 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
394 { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
|
Chris@16
|
395
|
Chris@16
|
396 //! <b>Effects</b>: Returns a reference to the internal allocator.
|
Chris@16
|
397 //!
|
Chris@16
|
398 //! <b>Throws</b>: Nothing
|
Chris@16
|
399 //!
|
Chris@16
|
400 //! <b>Complexity</b>: Constant.
|
Chris@16
|
401 //!
|
Chris@16
|
402 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
403 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
404 { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
|
Chris@16
|
405
|
Chris@16
|
406 //////////////////////////////////////////////
|
Chris@16
|
407 //
|
Chris@16
|
408 // iterators
|
Chris@16
|
409 //
|
Chris@16
|
410 //////////////////////////////////////////////
|
Chris@16
|
411
|
Chris@16
|
412 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
|
Chris@16
|
413 //!
|
Chris@16
|
414 //! <b>Throws</b>: Nothing.
|
Chris@16
|
415 //!
|
Chris@16
|
416 //! <b>Complexity</b>: Constant.
|
Chris@101
|
417 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
418 { return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
|
Chris@16
|
419
|
Chris@16
|
420 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
Chris@16
|
421 //!
|
Chris@16
|
422 //! <b>Throws</b>: Nothing.
|
Chris@16
|
423 //!
|
Chris@16
|
424 //! <b>Complexity</b>: Constant.
|
Chris@101
|
425 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
426 { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
|
Chris@16
|
427
|
Chris@16
|
428 //! <b>Effects</b>: Returns an iterator to the end of the container.
|
Chris@16
|
429 //!
|
Chris@16
|
430 //! <b>Throws</b>: Nothing.
|
Chris@16
|
431 //!
|
Chris@16
|
432 //! <b>Complexity</b>: Constant.
|
Chris@101
|
433 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
434 { return container_detail::force_copy<iterator>(m_flat_tree.end()); }
|
Chris@16
|
435
|
Chris@16
|
436 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
Chris@16
|
437 //!
|
Chris@16
|
438 //! <b>Throws</b>: Nothing.
|
Chris@16
|
439 //!
|
Chris@16
|
440 //! <b>Complexity</b>: Constant.
|
Chris@101
|
441 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
442 { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
|
Chris@16
|
443
|
Chris@16
|
444 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
Chris@16
|
445 //! of the reversed container.
|
Chris@16
|
446 //!
|
Chris@16
|
447 //! <b>Throws</b>: Nothing.
|
Chris@16
|
448 //!
|
Chris@16
|
449 //! <b>Complexity</b>: Constant.
|
Chris@101
|
450 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
451 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
|
Chris@16
|
452
|
Chris@16
|
453 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
Chris@16
|
454 //! of the reversed container.
|
Chris@16
|
455 //!
|
Chris@16
|
456 //! <b>Throws</b>: Nothing.
|
Chris@16
|
457 //!
|
Chris@16
|
458 //! <b>Complexity</b>: Constant.
|
Chris@101
|
459 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
460 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
|
Chris@16
|
461
|
Chris@16
|
462 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
Chris@16
|
463 //! of the reversed container.
|
Chris@16
|
464 //!
|
Chris@16
|
465 //! <b>Throws</b>: Nothing.
|
Chris@16
|
466 //!
|
Chris@16
|
467 //! <b>Complexity</b>: Constant.
|
Chris@101
|
468 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
469 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
|
Chris@16
|
470
|
Chris@16
|
471 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
Chris@16
|
472 //! of the reversed container.
|
Chris@16
|
473 //!
|
Chris@16
|
474 //! <b>Throws</b>: Nothing.
|
Chris@16
|
475 //!
|
Chris@16
|
476 //! <b>Complexity</b>: Constant.
|
Chris@101
|
477 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
478 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
|
Chris@16
|
479
|
Chris@16
|
480 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
Chris@16
|
481 //!
|
Chris@16
|
482 //! <b>Throws</b>: Nothing.
|
Chris@16
|
483 //!
|
Chris@16
|
484 //! <b>Complexity</b>: Constant.
|
Chris@101
|
485 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
486 { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
|
Chris@16
|
487
|
Chris@16
|
488 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
Chris@16
|
489 //!
|
Chris@16
|
490 //! <b>Throws</b>: Nothing.
|
Chris@16
|
491 //!
|
Chris@16
|
492 //! <b>Complexity</b>: Constant.
|
Chris@101
|
493 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
494 { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
|
Chris@16
|
495
|
Chris@16
|
496 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
Chris@16
|
497 //! of the reversed container.
|
Chris@16
|
498 //!
|
Chris@16
|
499 //! <b>Throws</b>: Nothing.
|
Chris@16
|
500 //!
|
Chris@16
|
501 //! <b>Complexity</b>: Constant.
|
Chris@101
|
502 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
503 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
|
Chris@16
|
504
|
Chris@16
|
505 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
Chris@16
|
506 //! of the reversed container.
|
Chris@16
|
507 //!
|
Chris@16
|
508 //! <b>Throws</b>: Nothing.
|
Chris@16
|
509 //!
|
Chris@16
|
510 //! <b>Complexity</b>: Constant.
|
Chris@101
|
511 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
512 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
|
Chris@16
|
513
|
Chris@16
|
514 //////////////////////////////////////////////
|
Chris@16
|
515 //
|
Chris@16
|
516 // capacity
|
Chris@16
|
517 //
|
Chris@16
|
518 //////////////////////////////////////////////
|
Chris@16
|
519
|
Chris@16
|
520 //! <b>Effects</b>: Returns true if the container contains no elements.
|
Chris@16
|
521 //!
|
Chris@16
|
522 //! <b>Throws</b>: Nothing.
|
Chris@16
|
523 //!
|
Chris@16
|
524 //! <b>Complexity</b>: Constant.
|
Chris@101
|
525 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
526 { return m_flat_tree.empty(); }
|
Chris@16
|
527
|
Chris@16
|
528 //! <b>Effects</b>: Returns the number of the elements contained in the container.
|
Chris@16
|
529 //!
|
Chris@16
|
530 //! <b>Throws</b>: Nothing.
|
Chris@16
|
531 //!
|
Chris@16
|
532 //! <b>Complexity</b>: Constant.
|
Chris@101
|
533 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
534 { return m_flat_tree.size(); }
|
Chris@16
|
535
|
Chris@16
|
536 //! <b>Effects</b>: Returns the largest possible size of the container.
|
Chris@16
|
537 //!
|
Chris@16
|
538 //! <b>Throws</b>: Nothing.
|
Chris@16
|
539 //!
|
Chris@16
|
540 //! <b>Complexity</b>: Constant.
|
Chris@101
|
541 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
542 { return m_flat_tree.max_size(); }
|
Chris@16
|
543
|
Chris@16
|
544 //! <b>Effects</b>: Number of elements for which memory has been allocated.
|
Chris@16
|
545 //! capacity() is always greater than or equal to size().
|
Chris@16
|
546 //!
|
Chris@16
|
547 //! <b>Throws</b>: Nothing.
|
Chris@16
|
548 //!
|
Chris@16
|
549 //! <b>Complexity</b>: Constant.
|
Chris@101
|
550 size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
551 { return m_flat_tree.capacity(); }
|
Chris@16
|
552
|
Chris@16
|
553 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
|
Chris@16
|
554 //! effect. Otherwise, it is a request for allocation of additional memory.
|
Chris@16
|
555 //! If the request is successful, then capacity() is greater than or equal to
|
Chris@16
|
556 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
Chris@16
|
557 //!
|
Chris@16
|
558 //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
|
Chris@16
|
559 //!
|
Chris@16
|
560 //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
|
Chris@16
|
561 //! to values might be invalidated.
|
Chris@101
|
562 void reserve(size_type cnt)
|
Chris@16
|
563 { m_flat_tree.reserve(cnt); }
|
Chris@16
|
564
|
Chris@16
|
565 //! <b>Effects</b>: Tries to deallocate the excess of memory created
|
Chris@16
|
566 // with previous allocations. The size of the vector is unchanged
|
Chris@16
|
567 //!
|
Chris@16
|
568 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
Chris@16
|
569 //!
|
Chris@16
|
570 //! <b>Complexity</b>: Linear to size().
|
Chris@16
|
571 void shrink_to_fit()
|
Chris@16
|
572 { m_flat_tree.shrink_to_fit(); }
|
Chris@16
|
573
|
Chris@16
|
574 //////////////////////////////////////////////
|
Chris@16
|
575 //
|
Chris@16
|
576 // element access
|
Chris@16
|
577 //
|
Chris@16
|
578 //////////////////////////////////////////////
|
Chris@16
|
579
|
Chris@16
|
580 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
581 //! Effects: If there is no key equivalent to x in the flat_map, inserts
|
Chris@16
|
582 //! value_type(x, T()) into the flat_map.
|
Chris@16
|
583 //!
|
Chris@101
|
584 //! Returns: A reference to the mapped_type corresponding to x in *this.
|
Chris@16
|
585 //!
|
Chris@16
|
586 //! Complexity: Logarithmic.
|
Chris@16
|
587 mapped_type &operator[](const key_type& k);
|
Chris@16
|
588
|
Chris@16
|
589 //! Effects: If there is no key equivalent to x in the flat_map, inserts
|
Chris@16
|
590 //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
|
Chris@16
|
591 //!
|
Chris@101
|
592 //! Returns: A reference to the mapped_type corresponding to x in *this.
|
Chris@16
|
593 //!
|
Chris@16
|
594 //! Complexity: Logarithmic.
|
Chris@16
|
595 mapped_type &operator[](key_type &&k) ;
|
Chris@16
|
596
|
Chris@16
|
597 #else
|
Chris@16
|
598 BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
|
Chris@16
|
599 #endif
|
Chris@16
|
600
|
Chris@101
|
601 //! @copydoc ::boost::container::flat_set::nth(size_type)
|
Chris@101
|
602 iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
603 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
|
Chris@101
|
604
|
Chris@101
|
605 //! @copydoc ::boost::container::flat_set::nth(size_type) const
|
Chris@101
|
606 const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
607 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
|
Chris@101
|
608
|
Chris@101
|
609 //! @copydoc ::boost::container::flat_set::index_of(iterator)
|
Chris@101
|
610 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
611 { return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
|
Chris@101
|
612
|
Chris@101
|
613 //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
|
Chris@101
|
614 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
615 { return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
|
Chris@101
|
616
|
Chris@101
|
617 //! Returns: A reference to the element whose key is equivalent to x.
|
Chris@16
|
618 //!
|
Chris@16
|
619 //! Throws: An exception object of type out_of_range if no such element is present.
|
Chris@16
|
620 //!
|
Chris@16
|
621 //! Complexity: logarithmic.
|
Chris@16
|
622 T& at(const key_type& k)
|
Chris@16
|
623 {
|
Chris@16
|
624 iterator i = this->find(k);
|
Chris@16
|
625 if(i == this->end()){
|
Chris@16
|
626 throw_out_of_range("flat_map::at key not found");
|
Chris@16
|
627 }
|
Chris@16
|
628 return i->second;
|
Chris@16
|
629 }
|
Chris@16
|
630
|
Chris@101
|
631 //! Returns: A reference to the element whose key is equivalent to x.
|
Chris@16
|
632 //!
|
Chris@16
|
633 //! Throws: An exception object of type out_of_range if no such element is present.
|
Chris@16
|
634 //!
|
Chris@16
|
635 //! Complexity: logarithmic.
|
Chris@16
|
636 const T& at(const key_type& k) const
|
Chris@16
|
637 {
|
Chris@16
|
638 const_iterator i = this->find(k);
|
Chris@16
|
639 if(i == this->end()){
|
Chris@16
|
640 throw_out_of_range("flat_map::at key not found");
|
Chris@16
|
641 }
|
Chris@16
|
642 return i->second;
|
Chris@16
|
643 }
|
Chris@16
|
644
|
Chris@16
|
645 //////////////////////////////////////////////
|
Chris@16
|
646 //
|
Chris@16
|
647 // modifiers
|
Chris@16
|
648 //
|
Chris@16
|
649 //////////////////////////////////////////////
|
Chris@16
|
650
|
Chris@101
|
651 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
652
|
Chris@16
|
653 //! <b>Effects</b>: Inserts an object x of type T constructed with
|
Chris@16
|
654 //! std::forward<Args>(args)... if and only if there is no element in the container
|
Chris@16
|
655 //! with key equivalent to the key of x.
|
Chris@16
|
656 //!
|
Chris@16
|
657 //! <b>Returns</b>: The bool component of the returned pair is true if and only
|
Chris@16
|
658 //! if the insertion takes place, and the iterator component of the pair
|
Chris@16
|
659 //! points to the element with key equivalent to the key of x.
|
Chris@16
|
660 //!
|
Chris@16
|
661 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
662 //! to the elements with bigger keys than x.
|
Chris@16
|
663 //!
|
Chris@16
|
664 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
665 template <class... Args>
|
Chris@101
|
666 std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
|
Chris@16
|
667 { return container_detail::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
|
Chris@16
|
668
|
Chris@16
|
669 //! <b>Effects</b>: Inserts an object of type T constructed with
|
Chris@16
|
670 //! std::forward<Args>(args)... in the container if and only if there is
|
Chris@16
|
671 //! no element in the container with key equivalent to the key of x.
|
Chris@16
|
672 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
673 //!
|
Chris@16
|
674 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
Chris@16
|
675 //! to the key of x.
|
Chris@16
|
676 //!
|
Chris@16
|
677 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
|
Chris@16
|
678 //! right before p) plus insertion linear to the elements with bigger keys than x.
|
Chris@16
|
679 //!
|
Chris@16
|
680 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
681 template <class... Args>
|
Chris@101
|
682 iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
Chris@16
|
683 {
|
Chris@16
|
684 return container_detail::force_copy<iterator>
|
Chris@16
|
685 (m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
|
Chris@16
|
686 , boost::forward<Args>(args)...));
|
Chris@16
|
687 }
|
Chris@16
|
688
|
Chris@101
|
689 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
690
|
Chris@101
|
691 #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
|
Chris@101
|
692 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
Chris@101
|
693 std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
|
Chris@101
|
694 {\
|
Chris@101
|
695 return container_detail::force_copy< std::pair<iterator, bool> >\
|
Chris@101
|
696 (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
|
Chris@101
|
697 }\
|
Chris@101
|
698 \
|
Chris@101
|
699 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
Chris@101
|
700 iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
Chris@101
|
701 {\
|
Chris@101
|
702 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
|
Chris@101
|
703 (container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
|
Chris@101
|
704 }\
|
Chris@101
|
705 //
|
Chris@101
|
706 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
|
Chris@101
|
707 #undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
|
Chris@16
|
708
|
Chris@101
|
709 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
710
|
Chris@16
|
711 //! <b>Effects</b>: Inserts x if and only if there is no element in the container
|
Chris@16
|
712 //! with key equivalent to the key of x.
|
Chris@16
|
713 //!
|
Chris@16
|
714 //! <b>Returns</b>: The bool component of the returned pair is true if and only
|
Chris@16
|
715 //! if the insertion takes place, and the iterator component of the pair
|
Chris@16
|
716 //! points to the element with key equivalent to the key of x.
|
Chris@16
|
717 //!
|
Chris@16
|
718 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
719 //! to the elements with bigger keys than x.
|
Chris@16
|
720 //!
|
Chris@16
|
721 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
722 std::pair<iterator,bool> insert(const value_type& x)
|
Chris@101
|
723 { return container_detail::force_copy<std::pair<iterator,bool> >(
|
Chris@16
|
724 m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
|
Chris@16
|
725
|
Chris@16
|
726 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
|
Chris@16
|
727 //! only if there is no element in the container with key equivalent to the key of x.
|
Chris@16
|
728 //!
|
Chris@16
|
729 //! <b>Returns</b>: The bool component of the returned pair is true if and only
|
Chris@16
|
730 //! if the insertion takes place, and the iterator component of the pair
|
Chris@16
|
731 //! points to the element with key equivalent to the key of x.
|
Chris@16
|
732 //!
|
Chris@16
|
733 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
734 //! to the elements with bigger keys than x.
|
Chris@16
|
735 //!
|
Chris@16
|
736 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
737 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
|
Chris@16
|
738 { return container_detail::force_copy<std::pair<iterator,bool> >(
|
Chris@16
|
739 m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); }
|
Chris@16
|
740
|
Chris@16
|
741 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
|
Chris@16
|
742 //! only if there is no element in the container with key equivalent to the key of x.
|
Chris@16
|
743 //!
|
Chris@16
|
744 //! <b>Returns</b>: The bool component of the returned pair is true if and only
|
Chris@16
|
745 //! if the insertion takes place, and the iterator component of the pair
|
Chris@16
|
746 //! points to the element with key equivalent to the key of x.
|
Chris@16
|
747 //!
|
Chris@16
|
748 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
749 //! to the elements with bigger keys than x.
|
Chris@16
|
750 //!
|
Chris@16
|
751 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
752 std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
|
Chris@16
|
753 {
|
Chris@16
|
754 return container_detail::force_copy<std::pair<iterator,bool> >
|
Chris@16
|
755 (m_flat_tree.insert_unique(boost::move(x)));
|
Chris@16
|
756 }
|
Chris@16
|
757
|
Chris@16
|
758 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
|
Chris@16
|
759 //! no element in the container with key equivalent to the key of x.
|
Chris@16
|
760 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
761 //!
|
Chris@16
|
762 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
Chris@16
|
763 //! to the key of x.
|
Chris@16
|
764 //!
|
Chris@16
|
765 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
|
Chris@16
|
766 //! right before p) plus insertion linear to the elements with bigger keys than x.
|
Chris@16
|
767 //!
|
Chris@16
|
768 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
769 iterator insert(const_iterator p, const value_type& x)
|
Chris@16
|
770 {
|
Chris@16
|
771 return container_detail::force_copy<iterator>(
|
Chris@101
|
772 m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(p)
|
Chris@16
|
773 , container_detail::force<impl_value_type>(x)));
|
Chris@16
|
774 }
|
Chris@16
|
775
|
Chris@16
|
776 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
|
Chris@16
|
777 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
778 //!
|
Chris@16
|
779 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
|
Chris@16
|
780 //!
|
Chris@16
|
781 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
|
Chris@16
|
782 //! right before p) plus insertion linear to the elements with bigger keys than x.
|
Chris@16
|
783 //!
|
Chris@16
|
784 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
785 iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
|
Chris@16
|
786 {
|
Chris@16
|
787 return container_detail::force_copy<iterator>
|
Chris@101
|
788 (m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(p)
|
Chris@16
|
789 , boost::move(container_detail::force<impl_value_type>(x))));
|
Chris@16
|
790 }
|
Chris@16
|
791
|
Chris@16
|
792 //! <b>Effects</b>: Inserts an element move constructed from x in the container.
|
Chris@16
|
793 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
794 //!
|
Chris@16
|
795 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
|
Chris@16
|
796 //!
|
Chris@16
|
797 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
|
Chris@16
|
798 //! right before p) plus insertion linear to the elements with bigger keys than x.
|
Chris@16
|
799 //!
|
Chris@16
|
800 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
801 iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
|
Chris@16
|
802 {
|
Chris@16
|
803 return container_detail::force_copy<iterator>(
|
Chris@101
|
804 m_flat_tree.insert_unique(container_detail::force_copy<impl_const_iterator>(p), boost::move(x)));
|
Chris@16
|
805 }
|
Chris@16
|
806
|
Chris@16
|
807 //! <b>Requires</b>: first, last are not iterators into *this.
|
Chris@16
|
808 //!
|
Chris@16
|
809 //! <b>Effects</b>: inserts each element from the range [first,last) if and only
|
Chris@16
|
810 //! if there is no element with key equivalent to the key of that element.
|
Chris@16
|
811 //!
|
Chris@16
|
812 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@16
|
813 //! search time plus N*size() insertion time.
|
Chris@16
|
814 //!
|
Chris@16
|
815 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
816 template <class InputIterator>
|
Chris@16
|
817 void insert(InputIterator first, InputIterator last)
|
Chris@16
|
818 { m_flat_tree.insert_unique(first, last); }
|
Chris@16
|
819
|
Chris@16
|
820 //! <b>Requires</b>: first, last are not iterators into *this.
|
Chris@16
|
821 //!
|
Chris@16
|
822 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
|
Chris@16
|
823 //! unique values.
|
Chris@16
|
824 //!
|
Chris@16
|
825 //! <b>Effects</b>: inserts each element from the range [first,last) if and only
|
Chris@16
|
826 //! if there is no element with key equivalent to the key of that element. This
|
Chris@16
|
827 //! function is more efficient than the normal range creation for ordered ranges.
|
Chris@16
|
828 //!
|
Chris@16
|
829 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@16
|
830 //! search time plus N*size() insertion time.
|
Chris@16
|
831 //!
|
Chris@16
|
832 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
833 //!
|
Chris@16
|
834 //! <b>Note</b>: Non-standard extension.
|
Chris@16
|
835 template <class InputIterator>
|
Chris@16
|
836 void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
|
Chris@16
|
837 { m_flat_tree.insert_unique(ordered_unique_range, first, last); }
|
Chris@16
|
838
|
Chris@101
|
839 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
840 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
|
Chris@101
|
841 //! if there is no element with key equivalent to the key of that element.
|
Chris@101
|
842 //!
|
Chris@101
|
843 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.first() to il.end())
|
Chris@101
|
844 //! search time plus N*size() insertion time.
|
Chris@101
|
845 //!
|
Chris@101
|
846 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
847 void insert(std::initializer_list<value_type> il)
|
Chris@101
|
848 { m_flat_tree.insert_unique(il.begin(), il.end()); }
|
Chris@101
|
849
|
Chris@101
|
850 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
|
Chris@101
|
851 //! unique values.
|
Chris@101
|
852 //!
|
Chris@101
|
853 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
|
Chris@101
|
854 //! if there is no element with key equivalent to the key of that element. This
|
Chris@101
|
855 //! function is more efficient than the normal range creation for ordered ranges.
|
Chris@101
|
856 //!
|
Chris@101
|
857 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@101
|
858 //! search time plus N*size() insertion time.
|
Chris@101
|
859 //!
|
Chris@101
|
860 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
861 //!
|
Chris@101
|
862 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
863 void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
|
Chris@101
|
864 { m_flat_tree.insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
Chris@101
|
865 #endif
|
Chris@101
|
866
|
Chris@101
|
867 //! <b>Effects</b>: Erases the element pointed to by p.
|
Chris@16
|
868 //!
|
Chris@16
|
869 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
|
Chris@16
|
870 //! following q prior to the element being erased. If no such element exists,
|
Chris@16
|
871 //! returns end().
|
Chris@16
|
872 //!
|
Chris@101
|
873 //! <b>Complexity</b>: Linear to the elements with keys bigger than p
|
Chris@16
|
874 //!
|
Chris@16
|
875 //! <b>Note</b>: Invalidates elements with keys
|
Chris@16
|
876 //! not less than the erased element.
|
Chris@101
|
877 iterator erase(const_iterator p)
|
Chris@16
|
878 {
|
Chris@16
|
879 return container_detail::force_copy<iterator>
|
Chris@101
|
880 (m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(p)));
|
Chris@16
|
881 }
|
Chris@16
|
882
|
Chris@16
|
883 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
|
Chris@16
|
884 //!
|
Chris@16
|
885 //! <b>Returns</b>: Returns the number of erased elements.
|
Chris@16
|
886 //!
|
Chris@16
|
887 //! <b>Complexity</b>: Logarithmic search time plus erasure time
|
Chris@16
|
888 //! linear to the elements with bigger keys.
|
Chris@16
|
889 size_type erase(const key_type& x)
|
Chris@16
|
890 { return m_flat_tree.erase(x); }
|
Chris@16
|
891
|
Chris@16
|
892 //! <b>Effects</b>: Erases all the elements in the range [first, last).
|
Chris@16
|
893 //!
|
Chris@16
|
894 //! <b>Returns</b>: Returns last.
|
Chris@16
|
895 //!
|
Chris@16
|
896 //! <b>Complexity</b>: size()*N where N is the distance from first to last.
|
Chris@16
|
897 //!
|
Chris@16
|
898 //! <b>Complexity</b>: Logarithmic search time plus erasure time
|
Chris@16
|
899 //! linear to the elements with bigger keys.
|
Chris@16
|
900 iterator erase(const_iterator first, const_iterator last)
|
Chris@16
|
901 {
|
Chris@16
|
902 return container_detail::force_copy<iterator>(
|
Chris@16
|
903 m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
|
Chris@16
|
904 , container_detail::force_copy<impl_const_iterator>(last)));
|
Chris@16
|
905 }
|
Chris@16
|
906
|
Chris@16
|
907 //! <b>Effects</b>: Swaps the contents of *this and x.
|
Chris@16
|
908 //!
|
Chris@16
|
909 //! <b>Throws</b>: Nothing.
|
Chris@16
|
910 //!
|
Chris@16
|
911 //! <b>Complexity</b>: Constant.
|
Chris@16
|
912 void swap(flat_map& x)
|
Chris@101
|
913 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
Chris@101
|
914 && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
|
Chris@16
|
915 { m_flat_tree.swap(x.m_flat_tree); }
|
Chris@16
|
916
|
Chris@16
|
917 //! <b>Effects</b>: erase(a.begin(),a.end()).
|
Chris@16
|
918 //!
|
Chris@16
|
919 //! <b>Postcondition</b>: size() == 0.
|
Chris@16
|
920 //!
|
Chris@16
|
921 //! <b>Complexity</b>: linear in size().
|
Chris@101
|
922 void clear() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
923 { m_flat_tree.clear(); }
|
Chris@16
|
924
|
Chris@16
|
925 //////////////////////////////////////////////
|
Chris@16
|
926 //
|
Chris@16
|
927 // observers
|
Chris@16
|
928 //
|
Chris@16
|
929 //////////////////////////////////////////////
|
Chris@16
|
930
|
Chris@16
|
931 //! <b>Effects</b>: Returns the comparison object out
|
Chris@16
|
932 //! of which a was constructed.
|
Chris@16
|
933 //!
|
Chris@16
|
934 //! <b>Complexity</b>: Constant.
|
Chris@16
|
935 key_compare key_comp() const
|
Chris@16
|
936 { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
|
Chris@16
|
937
|
Chris@16
|
938 //! <b>Effects</b>: Returns an object of value_compare constructed out
|
Chris@16
|
939 //! of the comparison object.
|
Chris@16
|
940 //!
|
Chris@16
|
941 //! <b>Complexity</b>: Constant.
|
Chris@16
|
942 value_compare value_comp() const
|
Chris@16
|
943 { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
|
Chris@16
|
944
|
Chris@16
|
945 //////////////////////////////////////////////
|
Chris@16
|
946 //
|
Chris@16
|
947 // map operations
|
Chris@16
|
948 //
|
Chris@16
|
949 //////////////////////////////////////////////
|
Chris@16
|
950
|
Chris@16
|
951 //! <b>Returns</b>: An iterator pointing to an element with the key
|
Chris@16
|
952 //! equivalent to x, or end() if such an element is not found.
|
Chris@16
|
953 //!
|
Chris@16
|
954 //! <b>Complexity</b>: Logarithmic.
|
Chris@16
|
955 iterator find(const key_type& x)
|
Chris@16
|
956 { return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
|
Chris@16
|
957
|
Chris@101
|
958 //! <b>Returns</b>: A const_iterator pointing to an element with the key
|
Chris@16
|
959 //! equivalent to x, or end() if such an element is not found.
|
Chris@16
|
960 //!
|
Chris@16
|
961 //! <b>Complexity</b>: Logarithmic.s
|
Chris@16
|
962 const_iterator find(const key_type& x) const
|
Chris@16
|
963 { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
|
Chris@16
|
964
|
Chris@16
|
965 //! <b>Returns</b>: The number of elements with key equivalent to x.
|
Chris@16
|
966 //!
|
Chris@16
|
967 //! <b>Complexity</b>: log(size())+count(k)
|
Chris@16
|
968 size_type count(const key_type& x) const
|
Chris@16
|
969 { return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
|
Chris@16
|
970
|
Chris@16
|
971 //! <b>Returns</b>: An iterator pointing to the first element with key not less
|
Chris@16
|
972 //! than k, or a.end() if such an element is not found.
|
Chris@16
|
973 //!
|
Chris@16
|
974 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
975 iterator lower_bound(const key_type& x)
|
Chris@16
|
976 { return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
|
Chris@16
|
977
|
Chris@101
|
978 //! <b>Returns</b>: A const iterator pointing to the first element with key not
|
Chris@16
|
979 //! less than k, or a.end() if such an element is not found.
|
Chris@16
|
980 //!
|
Chris@16
|
981 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
982 const_iterator lower_bound(const key_type& x) const
|
Chris@16
|
983 { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
|
Chris@16
|
984
|
Chris@16
|
985 //! <b>Returns</b>: An iterator pointing to the first element with key not less
|
Chris@16
|
986 //! than x, or end() if such an element is not found.
|
Chris@16
|
987 //!
|
Chris@16
|
988 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
989 iterator upper_bound(const key_type& x)
|
Chris@16
|
990 { return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
|
Chris@16
|
991
|
Chris@101
|
992 //! <b>Returns</b>: A const iterator pointing to the first element with key not
|
Chris@16
|
993 //! less than x, or end() if such an element is not found.
|
Chris@16
|
994 //!
|
Chris@16
|
995 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
996 const_iterator upper_bound(const key_type& x) const
|
Chris@16
|
997 { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
|
Chris@16
|
998
|
Chris@16
|
999 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
Chris@16
|
1000 //!
|
Chris@16
|
1001 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1002 std::pair<iterator,iterator> equal_range(const key_type& x)
|
Chris@101
|
1003 { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
|
Chris@16
|
1004
|
Chris@16
|
1005 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
Chris@16
|
1006 //!
|
Chris@16
|
1007 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1008 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
Chris@101
|
1009 { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
|
Chris@16
|
1010
|
Chris@101
|
1011 //! <b>Effects</b>: Returns true if x and y are equal
|
Chris@101
|
1012 //!
|
Chris@101
|
1013 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1014 friend bool operator==(const flat_map& x, const flat_map& y)
|
Chris@101
|
1015 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
|
Chris@16
|
1016
|
Chris@101
|
1017 //! <b>Effects</b>: Returns true if x and y are unequal
|
Chris@101
|
1018 //!
|
Chris@101
|
1019 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1020 friend bool operator!=(const flat_map& x, const flat_map& y)
|
Chris@101
|
1021 { return !(x == y); }
|
Chris@101
|
1022
|
Chris@101
|
1023 //! <b>Effects</b>: Returns true if x is less than y
|
Chris@101
|
1024 //!
|
Chris@101
|
1025 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1026 friend bool operator<(const flat_map& x, const flat_map& y)
|
Chris@101
|
1027 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
Chris@101
|
1028
|
Chris@101
|
1029 //! <b>Effects</b>: Returns true if x is greater than y
|
Chris@101
|
1030 //!
|
Chris@101
|
1031 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1032 friend bool operator>(const flat_map& x, const flat_map& y)
|
Chris@101
|
1033 { return y < x; }
|
Chris@101
|
1034
|
Chris@101
|
1035 //! <b>Effects</b>: Returns true if x is equal or less than y
|
Chris@101
|
1036 //!
|
Chris@101
|
1037 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1038 friend bool operator<=(const flat_map& x, const flat_map& y)
|
Chris@101
|
1039 { return !(y < x); }
|
Chris@101
|
1040
|
Chris@101
|
1041 //! <b>Effects</b>: Returns true if x is equal or greater than y
|
Chris@101
|
1042 //!
|
Chris@101
|
1043 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1044 friend bool operator>=(const flat_map& x, const flat_map& y)
|
Chris@101
|
1045 { return !(x < y); }
|
Chris@101
|
1046
|
Chris@101
|
1047 //! <b>Effects</b>: x.swap(y)
|
Chris@101
|
1048 //!
|
Chris@101
|
1049 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1050 friend void swap(flat_map& x, flat_map& y)
|
Chris@101
|
1051 { x.swap(y); }
|
Chris@101
|
1052
|
Chris@101
|
1053 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1054 private:
|
Chris@16
|
1055 mapped_type &priv_subscript(const key_type& k)
|
Chris@16
|
1056 {
|
Chris@16
|
1057 iterator i = lower_bound(k);
|
Chris@16
|
1058 // i->first is greater than or equivalent to k.
|
Chris@16
|
1059 if (i == end() || key_comp()(k, (*i).first)){
|
Chris@16
|
1060 container_detail::value_init<mapped_type> m;
|
Chris@16
|
1061 i = insert(i, impl_value_type(k, ::boost::move(m.m_t)));
|
Chris@16
|
1062 }
|
Chris@16
|
1063 return (*i).second;
|
Chris@16
|
1064 }
|
Chris@16
|
1065 mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk)
|
Chris@16
|
1066 {
|
Chris@16
|
1067 key_type &k = mk;
|
Chris@16
|
1068 iterator i = lower_bound(k);
|
Chris@16
|
1069 // i->first is greater than or equivalent to k.
|
Chris@16
|
1070 if (i == end() || key_comp()(k, (*i).first)){
|
Chris@16
|
1071 container_detail::value_init<mapped_type> m;
|
Chris@16
|
1072 i = insert(i, impl_value_type(boost::move(k), ::boost::move(m.m_t)));
|
Chris@16
|
1073 }
|
Chris@16
|
1074 return (*i).second;
|
Chris@16
|
1075 }
|
Chris@101
|
1076 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1077 };
|
Chris@16
|
1078
|
Chris@101
|
1079 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1080
|
Chris@16
|
1081 } //namespace container {
|
Chris@16
|
1082
|
Chris@16
|
1083 //!has_trivial_destructor_after_move<> == true_type
|
Chris@16
|
1084 //!specialization for optimizations
|
Chris@101
|
1085 template <class Key, class T, class Compare, class Allocator>
|
Chris@101
|
1086 struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, Allocator> >
|
Chris@16
|
1087 {
|
Chris@101
|
1088 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
Chris@101
|
1089 static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
Chris@101
|
1090 ::boost::has_trivial_destructor_after_move<pointer>::value &&
|
Chris@101
|
1091 ::boost::has_trivial_destructor_after_move<Compare>::value;
|
Chris@16
|
1092 };
|
Chris@16
|
1093
|
Chris@16
|
1094 namespace container {
|
Chris@16
|
1095
|
Chris@101
|
1096 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1097
|
Chris@16
|
1098 //! A flat_multimap is a kind of associative container that supports equivalent keys
|
Chris@16
|
1099 //! (possibly containing multiple copies of the same key value) and provides for
|
Chris@16
|
1100 //! fast retrieval of values of another type T based on the keys. The flat_multimap
|
Chris@16
|
1101 //! class supports random-access iterators.
|
Chris@16
|
1102 //!
|
Chris@16
|
1103 //! A flat_multimap satisfies all of the requirements of a container and of a reversible
|
Chris@16
|
1104 //! container and of an associative container. For a
|
Chris@16
|
1105 //! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
|
Chris@16
|
1106 //! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
|
Chris@16
|
1107 //!
|
Chris@16
|
1108 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
Chris@16
|
1109 //!
|
Chris@16
|
1110 //! Allocator is the allocator to allocate the value_types
|
Chris@16
|
1111 //! (e.g. <i>allocator< std::pair<Key, T> ></i>).
|
Chris@16
|
1112 //!
|
Chris@16
|
1113 //! flat_multimap is similar to std::multimap but it's implemented like an ordered vector.
|
Chris@16
|
1114 //! This means that inserting a new element into a flat_map invalidates
|
Chris@16
|
1115 //! previous iterators and references
|
Chris@16
|
1116 //!
|
Chris@16
|
1117 //! Erasing an element invalidates iterators and references
|
Chris@16
|
1118 //! pointing to elements that come after (their keys are bigger) the erased element.
|
Chris@16
|
1119 //!
|
Chris@16
|
1120 //! This container provides random-access iterators.
|
Chris@101
|
1121 //!
|
Chris@101
|
1122 //! \tparam Key is the key_type of the map
|
Chris@101
|
1123 //! \tparam Value is the <code>mapped_type</code>
|
Chris@101
|
1124 //! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
Chris@101
|
1125 //! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
Chris@101
|
1126 //! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
Chris@16
|
1127 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@101
|
1128 template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
|
Chris@16
|
1129 #else
|
Chris@16
|
1130 template <class Key, class T, class Compare, class Allocator>
|
Chris@16
|
1131 #endif
|
Chris@16
|
1132 class flat_multimap
|
Chris@16
|
1133 {
|
Chris@101
|
1134 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1135 private:
|
Chris@16
|
1136 BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
|
Chris@16
|
1137 typedef container_detail::flat_tree<Key,
|
Chris@16
|
1138 std::pair<Key, T>,
|
Chris@16
|
1139 container_detail::select1st< std::pair<Key, T> >,
|
Chris@16
|
1140 Compare,
|
Chris@16
|
1141 Allocator> tree_t;
|
Chris@16
|
1142 //This is the real tree stored here. It's based on a movable pair
|
Chris@16
|
1143 typedef container_detail::flat_tree<Key,
|
Chris@16
|
1144 container_detail::pair<Key, T>,
|
Chris@16
|
1145 container_detail::select1st<container_detail::pair<Key, T> >,
|
Chris@16
|
1146 Compare,
|
Chris@16
|
1147 typename allocator_traits<Allocator>::template portable_rebind_alloc
|
Chris@16
|
1148 <container_detail::pair<Key, T> >::type> impl_tree_t;
|
Chris@16
|
1149 impl_tree_t m_flat_tree; // flat tree representing flat_map
|
Chris@16
|
1150
|
Chris@16
|
1151 typedef typename impl_tree_t::value_type impl_value_type;
|
Chris@16
|
1152 typedef typename impl_tree_t::const_iterator impl_const_iterator;
|
Chris@101
|
1153 typedef typename impl_tree_t::iterator impl_iterator;
|
Chris@16
|
1154 typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
Chris@16
|
1155 typedef container_detail::flat_tree_value_compare
|
Chris@16
|
1156 < Compare
|
Chris@16
|
1157 , container_detail::select1st< std::pair<Key, T> >
|
Chris@16
|
1158 , std::pair<Key, T> > value_compare_impl;
|
Chris@16
|
1159 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
1160 <typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
|
Chris@16
|
1161 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
1162 <typename allocator_traits<Allocator>::pointer>::const_iterator const_iterator_impl;
|
Chris@16
|
1163 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
1164 <typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
Chris@16
|
1165 typedef typename container_detail::get_flat_tree_iterators
|
Chris@16
|
1166 <typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
Chris@101
|
1167 public:
|
Chris@101
|
1168 typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
Chris@101
|
1169 private:
|
Chris@101
|
1170 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1171
|
Chris@16
|
1172 public:
|
Chris@16
|
1173
|
Chris@16
|
1174 //////////////////////////////////////////////
|
Chris@16
|
1175 //
|
Chris@16
|
1176 // types
|
Chris@16
|
1177 //
|
Chris@16
|
1178 //////////////////////////////////////////////
|
Chris@16
|
1179 typedef Key key_type;
|
Chris@16
|
1180 typedef T mapped_type;
|
Chris@16
|
1181 typedef std::pair<Key, T> value_type;
|
Chris@101
|
1182 typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
1183 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
Chris@16
|
1184 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
Chris@16
|
1185 typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
Chris@16
|
1186 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
|
Chris@16
|
1187 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
Chris@16
|
1188 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
|
Chris@16
|
1189 typedef Allocator allocator_type;
|
Chris@16
|
1190 typedef BOOST_CONTAINER_IMPDEF(Allocator) stored_allocator_type;
|
Chris@16
|
1191 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
|
Chris@16
|
1192 typedef Compare key_compare;
|
Chris@16
|
1193 typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
|
Chris@16
|
1194 typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
|
Chris@16
|
1195 typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator;
|
Chris@16
|
1196 typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
|
Chris@16
|
1197 typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
|
Chris@16
|
1198
|
Chris@16
|
1199 //////////////////////////////////////////////
|
Chris@16
|
1200 //
|
Chris@16
|
1201 // construct/copy/destroy
|
Chris@16
|
1202 //
|
Chris@16
|
1203 //////////////////////////////////////////////
|
Chris@16
|
1204
|
Chris@16
|
1205 //! <b>Effects</b>: Default constructs an empty flat_map.
|
Chris@16
|
1206 //!
|
Chris@16
|
1207 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1208 flat_multimap()
|
Chris@101
|
1209 : m_flat_tree()
|
Chris@101
|
1210 {
|
Chris@101
|
1211 //A type must be std::pair<Key, T>
|
Chris@101
|
1212 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1213 }
|
Chris@16
|
1214
|
Chris@16
|
1215 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
|
Chris@16
|
1216 //! object and allocator.
|
Chris@16
|
1217 //!
|
Chris@16
|
1218 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1219 explicit flat_multimap(const Compare& comp,
|
Chris@16
|
1220 const allocator_type& a = allocator_type())
|
Chris@16
|
1221 : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
1222 {
|
Chris@101
|
1223 //A type must be std::pair<Key, T>
|
Chris@101
|
1224 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1225 }
|
Chris@16
|
1226
|
Chris@16
|
1227 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
|
Chris@16
|
1228 //!
|
Chris@16
|
1229 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1230 explicit flat_multimap(const allocator_type& a)
|
Chris@16
|
1231 : m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
1232 {
|
Chris@101
|
1233 //A type must be std::pair<Key, T>
|
Chris@101
|
1234 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1235 }
|
Chris@16
|
1236
|
Chris@16
|
1237 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
|
Chris@16
|
1238 //! and allocator, and inserts elements from the range [first ,last ).
|
Chris@16
|
1239 //!
|
Chris@16
|
1240 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
Chris@16
|
1241 //! comp and otherwise N logN, where N is last - first.
|
Chris@16
|
1242 template <class InputIterator>
|
Chris@16
|
1243 flat_multimap(InputIterator first, InputIterator last,
|
Chris@16
|
1244 const Compare& comp = Compare(),
|
Chris@16
|
1245 const allocator_type& a = allocator_type())
|
Chris@16
|
1246 : m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
1247 {
|
Chris@101
|
1248 //A type must be std::pair<Key, T>
|
Chris@101
|
1249 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1250 }
|
Chris@101
|
1251
|
Chris@101
|
1252 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified
|
Chris@101
|
1253 //! allocator, and inserts elements from the range [first ,last ).
|
Chris@101
|
1254 //!
|
Chris@101
|
1255 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
Chris@101
|
1256 //! comp and otherwise N logN, where N is last - first.
|
Chris@101
|
1257 template <class InputIterator>
|
Chris@101
|
1258 flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
|
Chris@101
|
1259 : m_flat_tree(false, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
1260 {
|
Chris@101
|
1261 //A type must be std::pair<Key, T>
|
Chris@101
|
1262 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1263 }
|
Chris@16
|
1264
|
Chris@16
|
1265 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
|
Chris@16
|
1266 //! allocator, and inserts elements from the ordered range [first ,last). This function
|
Chris@16
|
1267 //! is more efficient than the normal range creation for ordered ranges.
|
Chris@16
|
1268 //!
|
Chris@16
|
1269 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
|
Chris@16
|
1270 //!
|
Chris@16
|
1271 //! <b>Complexity</b>: Linear in N.
|
Chris@16
|
1272 //!
|
Chris@16
|
1273 //! <b>Note</b>: Non-standard extension.
|
Chris@16
|
1274 template <class InputIterator>
|
Chris@16
|
1275 flat_multimap(ordered_range_t, InputIterator first, InputIterator last,
|
Chris@16
|
1276 const Compare& comp = Compare(),
|
Chris@16
|
1277 const allocator_type& a = allocator_type())
|
Chris@16
|
1278 : m_flat_tree(ordered_range, first, last, comp, a)
|
Chris@101
|
1279 {
|
Chris@101
|
1280 //A type must be std::pair<Key, T>
|
Chris@101
|
1281 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1282 }
|
Chris@101
|
1283
|
Chris@101
|
1284 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
1285 //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
Chris@101
|
1286 //! allocator, and inserts elements from the range [il.begin(), il.end()).
|
Chris@101
|
1287 //!
|
Chris@101
|
1288 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
Chris@101
|
1289 //! comp and otherwise N logN, where N is last - first.
|
Chris@101
|
1290 flat_multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
Chris@101
|
1291 : m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
1292 {
|
Chris@101
|
1293 //A type must be std::pair<Key, T>
|
Chris@101
|
1294 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1295 }
|
Chris@101
|
1296
|
Chris@101
|
1297 //! <b>Effects</b>: Constructs an empty flat_map using the specified
|
Chris@101
|
1298 //! allocator, and inserts elements from the range [il.begin(), il.end()).
|
Chris@101
|
1299 //!
|
Chris@101
|
1300 //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
Chris@101
|
1301 //! comp and otherwise N logN, where N is last - first.
|
Chris@101
|
1302 flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
|
Chris@101
|
1303 : m_flat_tree(false, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
|
Chris@101
|
1304 {
|
Chris@101
|
1305 //A type must be std::pair<Key, T>
|
Chris@101
|
1306 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1307 }
|
Chris@101
|
1308
|
Chris@101
|
1309 //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
|
Chris@101
|
1310 //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function
|
Chris@101
|
1311 //! is more efficient than the normal range creation for ordered ranges.
|
Chris@101
|
1312 //!
|
Chris@101
|
1313 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
|
Chris@101
|
1314 //!
|
Chris@101
|
1315 //! <b>Complexity</b>: Linear in N.
|
Chris@101
|
1316 //!
|
Chris@101
|
1317 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
1318 flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
Chris@101
|
1319 const allocator_type& a = allocator_type())
|
Chris@101
|
1320 : m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
|
Chris@101
|
1321 {
|
Chris@101
|
1322 //A type must be std::pair<Key, T>
|
Chris@101
|
1323 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1324 }
|
Chris@101
|
1325 #endif
|
Chris@16
|
1326
|
Chris@16
|
1327 //! <b>Effects</b>: Copy constructs a flat_multimap.
|
Chris@16
|
1328 //!
|
Chris@16
|
1329 //! <b>Complexity</b>: Linear in x.size().
|
Chris@16
|
1330 flat_multimap(const flat_multimap& x)
|
Chris@101
|
1331 : m_flat_tree(x.m_flat_tree)
|
Chris@101
|
1332 {
|
Chris@101
|
1333 //A type must be std::pair<Key, T>
|
Chris@101
|
1334 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1335 }
|
Chris@16
|
1336
|
Chris@16
|
1337 //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
|
Chris@16
|
1338 //!
|
Chris@16
|
1339 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1340 //!
|
Chris@16
|
1341 //! <b>Postcondition</b>: x is emptied.
|
Chris@16
|
1342 flat_multimap(BOOST_RV_REF(flat_multimap) x)
|
Chris@16
|
1343 : m_flat_tree(boost::move(x.m_flat_tree))
|
Chris@101
|
1344 {
|
Chris@101
|
1345 //A type must be std::pair<Key, T>
|
Chris@101
|
1346 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1347 }
|
Chris@16
|
1348
|
Chris@16
|
1349 //! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
|
Chris@16
|
1350 //!
|
Chris@16
|
1351 //! <b>Complexity</b>: Linear in x.size().
|
Chris@16
|
1352 flat_multimap(const flat_multimap& x, const allocator_type &a)
|
Chris@16
|
1353 : m_flat_tree(x.m_flat_tree, a)
|
Chris@101
|
1354 {
|
Chris@101
|
1355 //A type must be std::pair<Key, T>
|
Chris@101
|
1356 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1357 }
|
Chris@16
|
1358
|
Chris@16
|
1359 //! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
|
Chris@16
|
1360 //! Constructs *this using x's resources.
|
Chris@16
|
1361 //!
|
Chris@16
|
1362 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
Chris@16
|
1363 flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
Chris@16
|
1364 : m_flat_tree(boost::move(x.m_flat_tree), a)
|
Chris@101
|
1365 {
|
Chris@101
|
1366 //A type must be std::pair<Key, T>
|
Chris@101
|
1367 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
Chris@101
|
1368 }
|
Chris@16
|
1369
|
Chris@16
|
1370 //! <b>Effects</b>: Makes *this a copy of x.
|
Chris@16
|
1371 //!
|
Chris@16
|
1372 //! <b>Complexity</b>: Linear in x.size().
|
Chris@16
|
1373 flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
|
Chris@16
|
1374 { m_flat_tree = x.m_flat_tree; return *this; }
|
Chris@16
|
1375
|
Chris@16
|
1376 //! <b>Effects</b>: this->swap(x.get()).
|
Chris@16
|
1377 //!
|
Chris@16
|
1378 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1379 flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
|
Chris@101
|
1380 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
Chris@101
|
1381 && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
Chris@101
|
1382 { m_flat_tree = boost::move(x.m_flat_tree); return *this; }
|
Chris@16
|
1383
|
Chris@101
|
1384 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
1385 //! <b>Effects</b>: Assign content of il to *this
|
Chris@101
|
1386 //!
|
Chris@101
|
1387 //! <b>Complexity</b>: Linear in il.size().
|
Chris@101
|
1388 flat_multimap& operator=(std::initializer_list<value_type> il)
|
Chris@101
|
1389 {
|
Chris@101
|
1390 this->clear();
|
Chris@101
|
1391 this->insert(il.begin(), il.end());
|
Chris@101
|
1392 return *this;
|
Chris@101
|
1393 }
|
Chris@101
|
1394 #endif
|
Chris@101
|
1395
|
Chris@101
|
1396 //! <b>Effects</b>: Returns a copy of the allocator that
|
Chris@16
|
1397 //! was passed to the object's constructor.
|
Chris@16
|
1398 //!
|
Chris@16
|
1399 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1400 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1401 { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
|
Chris@16
|
1402
|
Chris@16
|
1403 //! <b>Effects</b>: Returns a reference to the internal allocator.
|
Chris@16
|
1404 //!
|
Chris@16
|
1405 //! <b>Throws</b>: Nothing
|
Chris@16
|
1406 //!
|
Chris@16
|
1407 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1408 //!
|
Chris@16
|
1409 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
1410 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1411 { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
|
Chris@16
|
1412
|
Chris@16
|
1413 //! <b>Effects</b>: Returns a reference to the internal allocator.
|
Chris@16
|
1414 //!
|
Chris@16
|
1415 //! <b>Throws</b>: Nothing
|
Chris@16
|
1416 //!
|
Chris@16
|
1417 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1418 //!
|
Chris@16
|
1419 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
1420 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1421 { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
|
Chris@16
|
1422
|
Chris@16
|
1423 //////////////////////////////////////////////
|
Chris@16
|
1424 //
|
Chris@16
|
1425 // iterators
|
Chris@16
|
1426 //
|
Chris@16
|
1427 //////////////////////////////////////////////
|
Chris@16
|
1428
|
Chris@16
|
1429 //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
|
Chris@16
|
1430 //!
|
Chris@16
|
1431 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1432 //!
|
Chris@16
|
1433 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1434 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1435 { return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
|
Chris@16
|
1436
|
Chris@16
|
1437 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
Chris@16
|
1438 //!
|
Chris@16
|
1439 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1440 //!
|
Chris@16
|
1441 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1442 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1443 { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
|
Chris@16
|
1444
|
Chris@16
|
1445 //! <b>Effects</b>: Returns an iterator to the end of the container.
|
Chris@16
|
1446 //!
|
Chris@16
|
1447 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1448 //!
|
Chris@16
|
1449 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1450 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1451 { return container_detail::force_copy<iterator>(m_flat_tree.end()); }
|
Chris@16
|
1452
|
Chris@16
|
1453 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
Chris@16
|
1454 //!
|
Chris@16
|
1455 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1456 //!
|
Chris@16
|
1457 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1458 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1459 { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
|
Chris@16
|
1460
|
Chris@16
|
1461 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
Chris@16
|
1462 //! of the reversed container.
|
Chris@16
|
1463 //!
|
Chris@16
|
1464 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1465 //!
|
Chris@16
|
1466 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1467 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1468 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
|
Chris@16
|
1469
|
Chris@16
|
1470 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
Chris@16
|
1471 //! of the reversed container.
|
Chris@16
|
1472 //!
|
Chris@16
|
1473 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1474 //!
|
Chris@16
|
1475 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1476 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1477 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
|
Chris@16
|
1478
|
Chris@16
|
1479 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
Chris@16
|
1480 //! of the reversed container.
|
Chris@16
|
1481 //!
|
Chris@16
|
1482 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1483 //!
|
Chris@16
|
1484 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1485 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1486 { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
|
Chris@16
|
1487
|
Chris@16
|
1488 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
Chris@16
|
1489 //! of the reversed container.
|
Chris@16
|
1490 //!
|
Chris@16
|
1491 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1492 //!
|
Chris@16
|
1493 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1494 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1495 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
|
Chris@16
|
1496
|
Chris@16
|
1497 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
Chris@16
|
1498 //!
|
Chris@16
|
1499 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1500 //!
|
Chris@16
|
1501 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1502 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1503 { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
|
Chris@16
|
1504
|
Chris@16
|
1505 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
Chris@16
|
1506 //!
|
Chris@16
|
1507 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1508 //!
|
Chris@16
|
1509 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1510 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1511 { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
|
Chris@16
|
1512
|
Chris@16
|
1513 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
Chris@16
|
1514 //! of the reversed container.
|
Chris@16
|
1515 //!
|
Chris@16
|
1516 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1517 //!
|
Chris@16
|
1518 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1519 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1520 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
|
Chris@16
|
1521
|
Chris@16
|
1522 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
Chris@16
|
1523 //! of the reversed container.
|
Chris@16
|
1524 //!
|
Chris@16
|
1525 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1526 //!
|
Chris@16
|
1527 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1528 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1529 { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
|
Chris@16
|
1530
|
Chris@16
|
1531 //////////////////////////////////////////////
|
Chris@16
|
1532 //
|
Chris@16
|
1533 // capacity
|
Chris@16
|
1534 //
|
Chris@16
|
1535 //////////////////////////////////////////////
|
Chris@16
|
1536
|
Chris@16
|
1537 //! <b>Effects</b>: Returns true if the container contains no elements.
|
Chris@16
|
1538 //!
|
Chris@16
|
1539 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1540 //!
|
Chris@16
|
1541 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1542 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1543 { return m_flat_tree.empty(); }
|
Chris@16
|
1544
|
Chris@16
|
1545 //! <b>Effects</b>: Returns the number of the elements contained in the container.
|
Chris@16
|
1546 //!
|
Chris@16
|
1547 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1548 //!
|
Chris@16
|
1549 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1550 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1551 { return m_flat_tree.size(); }
|
Chris@16
|
1552
|
Chris@16
|
1553 //! <b>Effects</b>: Returns the largest possible size of the container.
|
Chris@16
|
1554 //!
|
Chris@16
|
1555 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1556 //!
|
Chris@16
|
1557 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1558 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1559 { return m_flat_tree.max_size(); }
|
Chris@16
|
1560
|
Chris@16
|
1561 //! <b>Effects</b>: Number of elements for which memory has been allocated.
|
Chris@16
|
1562 //! capacity() is always greater than or equal to size().
|
Chris@16
|
1563 //!
|
Chris@16
|
1564 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1565 //!
|
Chris@16
|
1566 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1567 size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1568 { return m_flat_tree.capacity(); }
|
Chris@16
|
1569
|
Chris@16
|
1570 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
|
Chris@16
|
1571 //! effect. Otherwise, it is a request for allocation of additional memory.
|
Chris@16
|
1572 //! If the request is successful, then capacity() is greater than or equal to
|
Chris@16
|
1573 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
Chris@16
|
1574 //!
|
Chris@16
|
1575 //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
|
Chris@16
|
1576 //!
|
Chris@16
|
1577 //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
|
Chris@16
|
1578 //! to values might be invalidated.
|
Chris@101
|
1579 void reserve(size_type cnt)
|
Chris@16
|
1580 { m_flat_tree.reserve(cnt); }
|
Chris@16
|
1581
|
Chris@16
|
1582 //! <b>Effects</b>: Tries to deallocate the excess of memory created
|
Chris@16
|
1583 // with previous allocations. The size of the vector is unchanged
|
Chris@16
|
1584 //!
|
Chris@16
|
1585 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
Chris@16
|
1586 //!
|
Chris@16
|
1587 //! <b>Complexity</b>: Linear to size().
|
Chris@16
|
1588 void shrink_to_fit()
|
Chris@16
|
1589 { m_flat_tree.shrink_to_fit(); }
|
Chris@16
|
1590
|
Chris@101
|
1591 //! @copydoc ::boost::container::flat_set::nth(size_type)
|
Chris@101
|
1592 iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
1593 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
|
Chris@16
|
1594
|
Chris@101
|
1595 //! @copydoc ::boost::container::flat_set::nth(size_type) const
|
Chris@101
|
1596 const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
1597 { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
|
Chris@101
|
1598
|
Chris@101
|
1599 //! @copydoc ::boost::container::flat_set::index_of(iterator)
|
Chris@101
|
1600 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
1601 { return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
|
Chris@101
|
1602
|
Chris@101
|
1603 //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
|
Chris@101
|
1604 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
1605 { return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
|
Chris@101
|
1606
|
Chris@101
|
1607 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1608
|
Chris@16
|
1609 //! <b>Effects</b>: Inserts an object of type T constructed with
|
Chris@16
|
1610 //! std::forward<Args>(args)... and returns the iterator pointing to the
|
Chris@16
|
1611 //! newly inserted element.
|
Chris@16
|
1612 //!
|
Chris@16
|
1613 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
1614 //! to the elements with bigger keys than x.
|
Chris@16
|
1615 //!
|
Chris@16
|
1616 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1617 template <class... Args>
|
Chris@101
|
1618 iterator emplace(BOOST_FWD_REF(Args)... args)
|
Chris@16
|
1619 { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
|
Chris@16
|
1620
|
Chris@16
|
1621 //! <b>Effects</b>: Inserts an object of type T constructed with
|
Chris@16
|
1622 //! std::forward<Args>(args)... in the container.
|
Chris@16
|
1623 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
1624 //!
|
Chris@16
|
1625 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
Chris@16
|
1626 //! to the key of x.
|
Chris@16
|
1627 //!
|
Chris@16
|
1628 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
|
Chris@16
|
1629 //! is to be inserted before p) plus linear insertion
|
Chris@16
|
1630 //! to the elements with bigger keys than x.
|
Chris@16
|
1631 //!
|
Chris@16
|
1632 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1633 template <class... Args>
|
Chris@101
|
1634 iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
Chris@16
|
1635 {
|
Chris@16
|
1636 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
|
Chris@16
|
1637 (container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
|
Chris@16
|
1638 }
|
Chris@16
|
1639
|
Chris@101
|
1640 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
1641
|
Chris@101
|
1642 #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
|
Chris@101
|
1643 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
Chris@101
|
1644 iterator emplace(BOOST_MOVE_UREF##N)\
|
Chris@101
|
1645 { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
|
Chris@101
|
1646 \
|
Chris@101
|
1647 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
Chris@101
|
1648 iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
Chris@101
|
1649 {\
|
Chris@101
|
1650 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
|
Chris@101
|
1651 (container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
|
Chris@101
|
1652 }\
|
Chris@101
|
1653 //
|
Chris@101
|
1654 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
|
Chris@101
|
1655 #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
|
Chris@16
|
1656
|
Chris@101
|
1657 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
1658
|
Chris@16
|
1659 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
|
Chris@16
|
1660 //! newly inserted element.
|
Chris@16
|
1661 //!
|
Chris@16
|
1662 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
1663 //! to the elements with bigger keys than x.
|
Chris@16
|
1664 //!
|
Chris@16
|
1665 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1666 iterator insert(const value_type& x)
|
Chris@16
|
1667 {
|
Chris@16
|
1668 return container_detail::force_copy<iterator>(
|
Chris@16
|
1669 m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x)));
|
Chris@16
|
1670 }
|
Chris@16
|
1671
|
Chris@16
|
1672 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
|
Chris@16
|
1673 //! the iterator pointing to the newly inserted element.
|
Chris@16
|
1674 //!
|
Chris@16
|
1675 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
1676 //! to the elements with bigger keys than x.
|
Chris@16
|
1677 //!
|
Chris@16
|
1678 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1679 iterator insert(BOOST_RV_REF(value_type) x)
|
Chris@16
|
1680 { return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
|
Chris@16
|
1681
|
Chris@16
|
1682 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
|
Chris@16
|
1683 //! the iterator pointing to the newly inserted element.
|
Chris@16
|
1684 //!
|
Chris@16
|
1685 //! <b>Complexity</b>: Logarithmic search time plus linear insertion
|
Chris@16
|
1686 //! to the elements with bigger keys than x.
|
Chris@16
|
1687 //!
|
Chris@16
|
1688 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1689 iterator insert(BOOST_RV_REF(impl_value_type) x)
|
Chris@16
|
1690 { return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
|
Chris@16
|
1691
|
Chris@16
|
1692 //! <b>Effects</b>: Inserts a copy of x in the container.
|
Chris@16
|
1693 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
1694 //!
|
Chris@16
|
1695 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
Chris@16
|
1696 //! to the key of x.
|
Chris@16
|
1697 //!
|
Chris@16
|
1698 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
|
Chris@16
|
1699 //! is to be inserted before p) plus linear insertion
|
Chris@16
|
1700 //! to the elements with bigger keys than x.
|
Chris@16
|
1701 //!
|
Chris@16
|
1702 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
1703 iterator insert(const_iterator p, const value_type& x)
|
Chris@16
|
1704 {
|
Chris@16
|
1705 return container_detail::force_copy<iterator>
|
Chris@101
|
1706 (m_flat_tree.insert_equal( container_detail::force_copy<impl_const_iterator>(p)
|
Chris@16
|
1707 , container_detail::force<impl_value_type>(x)));
|
Chris@16
|
1708 }
|
Chris@16
|
1709
|
Chris@16
|
1710 //! <b>Effects</b>: Inserts a value move constructed from x in the container.
|
Chris@16
|
1711 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
1712 //!
|
Chris@16
|
1713 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
Chris@16
|
1714 //! to the key of x.
|
Chris@16
|
1715 //!
|
Chris@16
|
1716 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
|
Chris@16
|
1717 //! is to be inserted before p) plus linear insertion
|
Chris@16
|
1718 //! to the elements with bigger keys than x.
|
Chris@16
|
1719 //!
|
Chris@16
|
1720 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
1721 iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
|
Chris@16
|
1722 {
|
Chris@16
|
1723 return container_detail::force_copy<iterator>
|
Chris@101
|
1724 (m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(p)
|
Chris@16
|
1725 , boost::move(x)));
|
Chris@16
|
1726 }
|
Chris@16
|
1727
|
Chris@16
|
1728 //! <b>Effects</b>: Inserts a value move constructed from x in the container.
|
Chris@16
|
1729 //! p is a hint pointing to where the insert should start to search.
|
Chris@16
|
1730 //!
|
Chris@16
|
1731 //! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
Chris@16
|
1732 //! to the key of x.
|
Chris@16
|
1733 //!
|
Chris@16
|
1734 //! <b>Complexity</b>: Logarithmic search time (constant time if the value
|
Chris@16
|
1735 //! is to be inserted before p) plus linear insertion
|
Chris@16
|
1736 //! to the elements with bigger keys than x.
|
Chris@16
|
1737 //!
|
Chris@16
|
1738 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
1739 iterator insert(const_iterator p, BOOST_RV_REF(impl_value_type) x)
|
Chris@16
|
1740 {
|
Chris@16
|
1741 return container_detail::force_copy<iterator>(
|
Chris@101
|
1742 m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(p), boost::move(x)));
|
Chris@16
|
1743 }
|
Chris@16
|
1744
|
Chris@16
|
1745 //! <b>Requires</b>: first, last are not iterators into *this.
|
Chris@16
|
1746 //!
|
Chris@16
|
1747 //! <b>Effects</b>: inserts each element from the range [first,last) .
|
Chris@16
|
1748 //!
|
Chris@16
|
1749 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@16
|
1750 //! search time plus N*size() insertion time.
|
Chris@16
|
1751 //!
|
Chris@16
|
1752 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1753 template <class InputIterator>
|
Chris@16
|
1754 void insert(InputIterator first, InputIterator last)
|
Chris@16
|
1755 { m_flat_tree.insert_equal(first, last); }
|
Chris@16
|
1756
|
Chris@16
|
1757 //! <b>Requires</b>: first, last are not iterators into *this.
|
Chris@16
|
1758 //!
|
Chris@16
|
1759 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
|
Chris@16
|
1760 //!
|
Chris@16
|
1761 //! <b>Effects</b>: inserts each element from the range [first,last) if and only
|
Chris@16
|
1762 //! if there is no element with key equivalent to the key of that element. This
|
Chris@16
|
1763 //! function is more efficient than the normal range creation for ordered ranges.
|
Chris@16
|
1764 //!
|
Chris@16
|
1765 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@16
|
1766 //! search time plus N*size() insertion time.
|
Chris@16
|
1767 //!
|
Chris@16
|
1768 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@16
|
1769 //!
|
Chris@16
|
1770 //! <b>Note</b>: Non-standard extension.
|
Chris@16
|
1771 template <class InputIterator>
|
Chris@16
|
1772 void insert(ordered_range_t, InputIterator first, InputIterator last)
|
Chris@16
|
1773 { m_flat_tree.insert_equal(ordered_range, first, last); }
|
Chris@16
|
1774
|
Chris@101
|
1775 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@101
|
1776 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) .
|
Chris@101
|
1777 //!
|
Chris@101
|
1778 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@101
|
1779 //! search time plus N*size() insertion time.
|
Chris@101
|
1780 //!
|
Chris@101
|
1781 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
1782 void insert(std::initializer_list<value_type> il)
|
Chris@101
|
1783 { m_flat_tree.insert_equal(il.begin(), il.end()); }
|
Chris@101
|
1784
|
Chris@101
|
1785 //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
|
Chris@101
|
1786 //!
|
Chris@101
|
1787 //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
|
Chris@101
|
1788 //! if there is no element with key equivalent to the key of that element. This
|
Chris@101
|
1789 //! function is more efficient than the normal range creation for ordered ranges.
|
Chris@101
|
1790 //!
|
Chris@101
|
1791 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
|
Chris@101
|
1792 //! search time plus N*size() insertion time.
|
Chris@101
|
1793 //!
|
Chris@101
|
1794 //! <b>Note</b>: If an element is inserted it might invalidate elements.
|
Chris@101
|
1795 //!
|
Chris@101
|
1796 //! <b>Note</b>: Non-standard extension.
|
Chris@101
|
1797 void insert(ordered_range_t, std::initializer_list<value_type> il)
|
Chris@101
|
1798 { m_flat_tree.insert_equal(ordered_range, il.begin(), il.end()); }
|
Chris@101
|
1799 #endif
|
Chris@101
|
1800
|
Chris@101
|
1801 //! <b>Effects</b>: Erases the element pointed to by p.
|
Chris@16
|
1802 //!
|
Chris@16
|
1803 //! <b>Returns</b>: Returns an iterator pointing to the element immediately
|
Chris@16
|
1804 //! following q prior to the element being erased. If no such element exists,
|
Chris@16
|
1805 //! returns end().
|
Chris@16
|
1806 //!
|
Chris@101
|
1807 //! <b>Complexity</b>: Linear to the elements with keys bigger than p
|
Chris@16
|
1808 //!
|
Chris@16
|
1809 //! <b>Note</b>: Invalidates elements with keys
|
Chris@16
|
1810 //! not less than the erased element.
|
Chris@101
|
1811 iterator erase(const_iterator p)
|
Chris@16
|
1812 {
|
Chris@16
|
1813 return container_detail::force_copy<iterator>(
|
Chris@101
|
1814 m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(p)));
|
Chris@16
|
1815 }
|
Chris@16
|
1816
|
Chris@16
|
1817 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
|
Chris@16
|
1818 //!
|
Chris@16
|
1819 //! <b>Returns</b>: Returns the number of erased elements.
|
Chris@16
|
1820 //!
|
Chris@16
|
1821 //! <b>Complexity</b>: Logarithmic search time plus erasure time
|
Chris@16
|
1822 //! linear to the elements with bigger keys.
|
Chris@16
|
1823 size_type erase(const key_type& x)
|
Chris@16
|
1824 { return m_flat_tree.erase(x); }
|
Chris@16
|
1825
|
Chris@16
|
1826 //! <b>Effects</b>: Erases all the elements in the range [first, last).
|
Chris@16
|
1827 //!
|
Chris@16
|
1828 //! <b>Returns</b>: Returns last.
|
Chris@16
|
1829 //!
|
Chris@16
|
1830 //! <b>Complexity</b>: size()*N where N is the distance from first to last.
|
Chris@16
|
1831 //!
|
Chris@16
|
1832 //! <b>Complexity</b>: Logarithmic search time plus erasure time
|
Chris@16
|
1833 //! linear to the elements with bigger keys.
|
Chris@16
|
1834 iterator erase(const_iterator first, const_iterator last)
|
Chris@16
|
1835 {
|
Chris@16
|
1836 return container_detail::force_copy<iterator>
|
Chris@16
|
1837 (m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
|
Chris@16
|
1838 , container_detail::force_copy<impl_const_iterator>(last)));
|
Chris@16
|
1839 }
|
Chris@16
|
1840
|
Chris@16
|
1841 //! <b>Effects</b>: Swaps the contents of *this and x.
|
Chris@16
|
1842 //!
|
Chris@16
|
1843 //! <b>Throws</b>: Nothing.
|
Chris@16
|
1844 //!
|
Chris@16
|
1845 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1846 void swap(flat_multimap& x)
|
Chris@101
|
1847 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
Chris@101
|
1848 && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
|
Chris@16
|
1849 { m_flat_tree.swap(x.m_flat_tree); }
|
Chris@16
|
1850
|
Chris@16
|
1851 //! <b>Effects</b>: erase(a.begin(),a.end()).
|
Chris@16
|
1852 //!
|
Chris@16
|
1853 //! <b>Postcondition</b>: size() == 0.
|
Chris@16
|
1854 //!
|
Chris@16
|
1855 //! <b>Complexity</b>: linear in size().
|
Chris@101
|
1856 void clear() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1857 { m_flat_tree.clear(); }
|
Chris@16
|
1858
|
Chris@16
|
1859 //////////////////////////////////////////////
|
Chris@16
|
1860 //
|
Chris@16
|
1861 // observers
|
Chris@16
|
1862 //
|
Chris@16
|
1863 //////////////////////////////////////////////
|
Chris@16
|
1864
|
Chris@16
|
1865 //! <b>Effects</b>: Returns the comparison object out
|
Chris@16
|
1866 //! of which a was constructed.
|
Chris@16
|
1867 //!
|
Chris@16
|
1868 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1869 key_compare key_comp() const
|
Chris@16
|
1870 { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
|
Chris@16
|
1871
|
Chris@16
|
1872 //! <b>Effects</b>: Returns an object of value_compare constructed out
|
Chris@16
|
1873 //! of the comparison object.
|
Chris@16
|
1874 //!
|
Chris@16
|
1875 //! <b>Complexity</b>: Constant.
|
Chris@16
|
1876 value_compare value_comp() const
|
Chris@16
|
1877 { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
|
Chris@16
|
1878
|
Chris@16
|
1879 //////////////////////////////////////////////
|
Chris@16
|
1880 //
|
Chris@16
|
1881 // map operations
|
Chris@16
|
1882 //
|
Chris@16
|
1883 //////////////////////////////////////////////
|
Chris@16
|
1884
|
Chris@16
|
1885 //! <b>Returns</b>: An iterator pointing to an element with the key
|
Chris@16
|
1886 //! equivalent to x, or end() if such an element is not found.
|
Chris@16
|
1887 //!
|
Chris@16
|
1888 //! <b>Complexity</b>: Logarithmic.
|
Chris@16
|
1889 iterator find(const key_type& x)
|
Chris@16
|
1890 { return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
|
Chris@16
|
1891
|
Chris@16
|
1892 //! <b>Returns</b>: An const_iterator pointing to an element with the key
|
Chris@16
|
1893 //! equivalent to x, or end() if such an element is not found.
|
Chris@16
|
1894 //!
|
Chris@16
|
1895 //! <b>Complexity</b>: Logarithmic.
|
Chris@16
|
1896 const_iterator find(const key_type& x) const
|
Chris@16
|
1897 { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
|
Chris@16
|
1898
|
Chris@16
|
1899 //! <b>Returns</b>: The number of elements with key equivalent to x.
|
Chris@16
|
1900 //!
|
Chris@16
|
1901 //! <b>Complexity</b>: log(size())+count(k)
|
Chris@16
|
1902 size_type count(const key_type& x) const
|
Chris@16
|
1903 { return m_flat_tree.count(x); }
|
Chris@16
|
1904
|
Chris@16
|
1905 //! <b>Returns</b>: An iterator pointing to the first element with key not less
|
Chris@16
|
1906 //! than k, or a.end() if such an element is not found.
|
Chris@16
|
1907 //!
|
Chris@16
|
1908 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1909 iterator lower_bound(const key_type& x)
|
Chris@16
|
1910 { return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
|
Chris@16
|
1911
|
Chris@101
|
1912 //! <b>Returns</b>: A const iterator pointing to the first element with key
|
Chris@16
|
1913 //! not less than k, or a.end() if such an element is not found.
|
Chris@16
|
1914 //!
|
Chris@16
|
1915 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1916 const_iterator lower_bound(const key_type& x) const
|
Chris@16
|
1917 { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
|
Chris@16
|
1918
|
Chris@16
|
1919 //! <b>Returns</b>: An iterator pointing to the first element with key not less
|
Chris@16
|
1920 //! than x, or end() if such an element is not found.
|
Chris@16
|
1921 //!
|
Chris@16
|
1922 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1923 iterator upper_bound(const key_type& x)
|
Chris@16
|
1924 {return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
|
Chris@16
|
1925
|
Chris@101
|
1926 //! <b>Returns</b>: A const iterator pointing to the first element with key
|
Chris@16
|
1927 //! not less than x, or end() if such an element is not found.
|
Chris@16
|
1928 //!
|
Chris@16
|
1929 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1930 const_iterator upper_bound(const key_type& x) const
|
Chris@16
|
1931 { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
|
Chris@16
|
1932
|
Chris@16
|
1933 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
Chris@16
|
1934 //!
|
Chris@16
|
1935 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1936 std::pair<iterator,iterator> equal_range(const key_type& x)
|
Chris@16
|
1937 { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
|
Chris@16
|
1938
|
Chris@16
|
1939 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
Chris@16
|
1940 //!
|
Chris@16
|
1941 //! <b>Complexity</b>: Logarithmic
|
Chris@16
|
1942 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
Chris@16
|
1943 { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
|
Chris@16
|
1944
|
Chris@101
|
1945 //! <b>Effects</b>: Returns true if x and y are equal
|
Chris@101
|
1946 //!
|
Chris@101
|
1947 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1948 friend bool operator==(const flat_multimap& x, const flat_multimap& y)
|
Chris@101
|
1949 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
|
Chris@16
|
1950
|
Chris@101
|
1951 //! <b>Effects</b>: Returns true if x and y are unequal
|
Chris@101
|
1952 //!
|
Chris@101
|
1953 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1954 friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
|
Chris@101
|
1955 { return !(x == y); }
|
Chris@16
|
1956
|
Chris@101
|
1957 //! <b>Effects</b>: Returns true if x is less than y
|
Chris@101
|
1958 //!
|
Chris@101
|
1959 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1960 friend bool operator<(const flat_multimap& x, const flat_multimap& y)
|
Chris@101
|
1961 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
Chris@16
|
1962
|
Chris@101
|
1963 //! <b>Effects</b>: Returns true if x is greater than y
|
Chris@101
|
1964 //!
|
Chris@101
|
1965 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1966 friend bool operator>(const flat_multimap& x, const flat_multimap& y)
|
Chris@16
|
1967 { return y < x; }
|
Chris@16
|
1968
|
Chris@101
|
1969 //! <b>Effects</b>: Returns true if x is equal or less than y
|
Chris@101
|
1970 //!
|
Chris@101
|
1971 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1972 friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
|
Chris@16
|
1973 { return !(y < x); }
|
Chris@16
|
1974
|
Chris@101
|
1975 //! <b>Effects</b>: Returns true if x is equal or greater than y
|
Chris@101
|
1976 //!
|
Chris@101
|
1977 //! <b>Complexity</b>: Linear to the number of elements in the container.
|
Chris@101
|
1978 friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
|
Chris@16
|
1979 { return !(x < y); }
|
Chris@16
|
1980
|
Chris@101
|
1981 //! <b>Effects</b>: x.swap(y)
|
Chris@101
|
1982 //!
|
Chris@101
|
1983 //! <b>Complexity</b>: Constant.
|
Chris@101
|
1984 friend void swap(flat_multimap& x, flat_multimap& y)
|
Chris@16
|
1985 { x.swap(y); }
|
Chris@101
|
1986 };
|
Chris@16
|
1987
|
Chris@16
|
1988 }}
|
Chris@16
|
1989
|
Chris@101
|
1990 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1991
|
Chris@16
|
1992 namespace boost {
|
Chris@16
|
1993
|
Chris@16
|
1994 //!has_trivial_destructor_after_move<> == true_type
|
Chris@16
|
1995 //!specialization for optimizations
|
Chris@101
|
1996 template <class Key, class T, class Compare, class Allocator>
|
Chris@101
|
1997 struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, Allocator> >
|
Chris@16
|
1998 {
|
Chris@101
|
1999 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
Chris@101
|
2000 static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
Chris@101
|
2001 ::boost::has_trivial_destructor_after_move<pointer>::value &&
|
Chris@101
|
2002 ::boost::has_trivial_destructor_after_move<Compare>::value;
|
Chris@16
|
2003 };
|
Chris@16
|
2004
|
Chris@16
|
2005 } //namespace boost {
|
Chris@16
|
2006
|
Chris@101
|
2007 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
2008
|
Chris@16
|
2009 #include <boost/container/detail/config_end.hpp>
|
Chris@16
|
2010
|
Chris@101
|
2011 #endif // BOOST_CONTAINER_FLAT_MAP_HPP
|