Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/container/flat_set.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 ////////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost | |
4 // Software License, Version 1.0. (See accompanying file | |
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 // | |
7 // See http://www.boost.org/libs/container for documentation. | |
8 // | |
9 ////////////////////////////////////////////////////////////////////////////// | |
10 | |
11 #ifndef BOOST_CONTAINER_FLAT_SET_HPP | |
12 #define BOOST_CONTAINER_FLAT_SET_HPP | |
13 | |
14 #if defined(_MSC_VER) | |
15 # pragma once | |
16 #endif | |
17 | |
18 #include <boost/container/detail/config_begin.hpp> | |
19 #include <boost/container/detail/workaround.hpp> | |
20 | |
21 #include <boost/container/container_fwd.hpp> | |
22 #include <utility> | |
23 #include <functional> | |
24 #include <memory> | |
25 #include <boost/container/detail/flat_tree.hpp> | |
26 #include <boost/container/detail/mpl.hpp> | |
27 #include <boost/container/allocator_traits.hpp> | |
28 #include <boost/move/utility.hpp> | |
29 #include <boost/move/detail/move_helpers.hpp> | |
30 | |
31 namespace boost { | |
32 namespace container { | |
33 | |
34 /// @cond | |
35 // Forward declarations of operators < and ==, needed for friend declaration. | |
36 | |
37 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
38 template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> > | |
39 #else | |
40 template <class Key, class Compare, class Allocator> | |
41 #endif | |
42 class flat_set; | |
43 | |
44 template <class Key, class Compare, class Allocator> | |
45 inline bool operator==(const flat_set<Key,Compare,Allocator>& x, | |
46 const flat_set<Key,Compare,Allocator>& y); | |
47 | |
48 template <class Key, class Compare, class Allocator> | |
49 inline bool operator<(const flat_set<Key,Compare,Allocator>& x, | |
50 const flat_set<Key,Compare,Allocator>& y); | |
51 /// @endcond | |
52 | |
53 //! flat_set is a Sorted Associative Container that stores objects of type Key. | |
54 //! It is also a Unique Associative Container, meaning that no two elements are the same. | |
55 //! | |
56 //! flat_set is similar to std::set but it's implemented like an ordered vector. | |
57 //! This means that inserting a new element into a flat_set invalidates | |
58 //! previous iterators and references | |
59 //! | |
60 //! Erasing an element of a flat_set invalidates iterators and references | |
61 //! pointing to elements that come after (their keys are bigger) the erased element. | |
62 //! | |
63 //! This container provides random-access iterators. | |
64 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
65 template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> > | |
66 #else | |
67 template <class Key, class Compare, class Allocator> | |
68 #endif | |
69 class flat_set | |
70 { | |
71 /// @cond | |
72 private: | |
73 BOOST_COPYABLE_AND_MOVABLE(flat_set) | |
74 typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> tree_t; | |
75 tree_t m_flat_tree; // flat tree representing flat_set | |
76 /// @endcond | |
77 | |
78 public: | |
79 ////////////////////////////////////////////// | |
80 // | |
81 // types | |
82 // | |
83 ////////////////////////////////////////////// | |
84 typedef Key key_type; | |
85 typedef Key value_type; | |
86 typedef Compare key_compare; | |
87 typedef Compare value_compare; | |
88 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; | |
89 typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer; | |
90 typedef typename ::boost::container::allocator_traits<Allocator>::reference reference; | |
91 typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference; | |
92 typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type; | |
93 typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; | |
94 typedef Allocator allocator_type; | |
95 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; | |
96 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; | |
97 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; | |
98 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; | |
99 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; | |
100 | |
101 public: | |
102 ////////////////////////////////////////////// | |
103 // | |
104 // construct/copy/destroy | |
105 // | |
106 ////////////////////////////////////////////// | |
107 | |
108 //! <b>Effects</b>: Default constructs an empty flat_set. | |
109 //! | |
110 //! <b>Complexity</b>: Constant. | |
111 explicit flat_set() | |
112 : m_flat_tree() | |
113 {} | |
114 | |
115 //! <b>Effects</b>: Constructs an empty flat_set using the specified | |
116 //! comparison object and allocator. | |
117 //! | |
118 //! <b>Complexity</b>: Constant. | |
119 explicit flat_set(const Compare& comp, | |
120 const allocator_type& a = allocator_type()) | |
121 : m_flat_tree(comp, a) | |
122 {} | |
123 | |
124 //! <b>Effects</b>: Constructs an empty flat_set using the specified allocator. | |
125 //! | |
126 //! <b>Complexity</b>: Constant. | |
127 explicit flat_set(const allocator_type& a) | |
128 : m_flat_tree(a) | |
129 {} | |
130 | |
131 //! <b>Effects</b>: Constructs an empty set using the specified comparison object and | |
132 //! allocator, and inserts elements from the range [first ,last ). | |
133 //! | |
134 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using | |
135 //! comp and otherwise N logN, where N is last - first. | |
136 template <class InputIterator> | |
137 flat_set(InputIterator first, InputIterator last, | |
138 const Compare& comp = Compare(), | |
139 const allocator_type& a = allocator_type()) | |
140 : m_flat_tree(true, first, last, comp, a) | |
141 {} | |
142 | |
143 //! <b>Effects</b>: Constructs an empty flat_set using the specified comparison object and | |
144 //! allocator, and inserts elements from the ordered unique range [first ,last). This function | |
145 //! is more efficient than the normal range creation for ordered ranges. | |
146 //! | |
147 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be | |
148 //! unique values. | |
149 //! | |
150 //! <b>Complexity</b>: Linear in N. | |
151 //! | |
152 //! <b>Note</b>: Non-standard extension. | |
153 template <class InputIterator> | |
154 flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, | |
155 const Compare& comp = Compare(), | |
156 const allocator_type& a = allocator_type()) | |
157 : m_flat_tree(ordered_range, first, last, comp, a) | |
158 {} | |
159 | |
160 //! <b>Effects</b>: Copy constructs a set. | |
161 //! | |
162 //! <b>Complexity</b>: Linear in x.size(). | |
163 flat_set(const flat_set& x) | |
164 : m_flat_tree(x.m_flat_tree) | |
165 {} | |
166 | |
167 //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources. | |
168 //! | |
169 //! <b>Complexity</b>: Constant. | |
170 //! | |
171 //! <b>Postcondition</b>: x is emptied. | |
172 flat_set(BOOST_RV_REF(flat_set) mx) | |
173 : m_flat_tree(boost::move(mx.m_flat_tree)) | |
174 {} | |
175 | |
176 //! <b>Effects</b>: Copy constructs a set using the specified allocator. | |
177 //! | |
178 //! <b>Complexity</b>: Linear in x.size(). | |
179 flat_set(const flat_set& x, const allocator_type &a) | |
180 : m_flat_tree(x.m_flat_tree, a) | |
181 {} | |
182 | |
183 //! <b>Effects</b>: Move constructs a set using the specified allocator. | |
184 //! Constructs *this using x's resources. | |
185 //! | |
186 //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise | |
187 flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a) | |
188 : m_flat_tree(boost::move(mx.m_flat_tree), a) | |
189 {} | |
190 | |
191 //! <b>Effects</b>: Makes *this a copy of x. | |
192 //! | |
193 //! <b>Complexity</b>: Linear in x.size(). | |
194 flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x) | |
195 { m_flat_tree = x.m_flat_tree; return *this; } | |
196 | |
197 //! <b>Effects</b>: Makes *this a copy of the previous value of xx. | |
198 //! | |
199 //! <b>Complexity</b>: Linear in x.size(). | |
200 flat_set& operator=(BOOST_RV_REF(flat_set) mx) | |
201 { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } | |
202 | |
203 //! <b>Effects</b>: Returns a copy of the Allocator that | |
204 //! was passed to the object's constructor. | |
205 //! | |
206 //! <b>Complexity</b>: Constant. | |
207 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT | |
208 { return m_flat_tree.get_allocator(); } | |
209 | |
210 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
211 //! | |
212 //! <b>Throws</b>: Nothing | |
213 //! | |
214 //! <b>Complexity</b>: Constant. | |
215 //! | |
216 //! <b>Note</b>: Non-standard extension. | |
217 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT | |
218 { return m_flat_tree.get_stored_allocator(); } | |
219 | |
220 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
221 //! | |
222 //! <b>Throws</b>: Nothing | |
223 //! | |
224 //! <b>Complexity</b>: Constant. | |
225 //! | |
226 //! <b>Note</b>: Non-standard extension. | |
227 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT | |
228 { return m_flat_tree.get_stored_allocator(); } | |
229 | |
230 ////////////////////////////////////////////// | |
231 // | |
232 // iterators | |
233 // | |
234 ////////////////////////////////////////////// | |
235 | |
236 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. | |
237 //! | |
238 //! <b>Throws</b>: Nothing. | |
239 //! | |
240 //! <b>Complexity</b>: Constant. | |
241 iterator begin() BOOST_CONTAINER_NOEXCEPT | |
242 { return m_flat_tree.begin(); } | |
243 | |
244 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
245 //! | |
246 //! <b>Throws</b>: Nothing. | |
247 //! | |
248 //! <b>Complexity</b>: Constant. | |
249 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT | |
250 { return m_flat_tree.begin(); } | |
251 | |
252 //! <b>Effects</b>: Returns an iterator to the end of the container. | |
253 //! | |
254 //! <b>Throws</b>: Nothing. | |
255 //! | |
256 //! <b>Complexity</b>: Constant. | |
257 iterator end() BOOST_CONTAINER_NOEXCEPT | |
258 { return m_flat_tree.end(); } | |
259 | |
260 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
261 //! | |
262 //! <b>Throws</b>: Nothing. | |
263 //! | |
264 //! <b>Complexity</b>: Constant. | |
265 const_iterator end() const BOOST_CONTAINER_NOEXCEPT | |
266 { return m_flat_tree.end(); } | |
267 | |
268 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning | |
269 //! of the reversed container. | |
270 //! | |
271 //! <b>Throws</b>: Nothing. | |
272 //! | |
273 //! <b>Complexity</b>: Constant. | |
274 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT | |
275 { return m_flat_tree.rbegin(); } | |
276 | |
277 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
278 //! of the reversed container. | |
279 //! | |
280 //! <b>Throws</b>: Nothing. | |
281 //! | |
282 //! <b>Complexity</b>: Constant. | |
283 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT | |
284 { return m_flat_tree.rbegin(); } | |
285 | |
286 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end | |
287 //! of the reversed container. | |
288 //! | |
289 //! <b>Throws</b>: Nothing. | |
290 //! | |
291 //! <b>Complexity</b>: Constant. | |
292 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT | |
293 { return m_flat_tree.rend(); } | |
294 | |
295 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
296 //! of the reversed container. | |
297 //! | |
298 //! <b>Throws</b>: Nothing. | |
299 //! | |
300 //! <b>Complexity</b>: Constant. | |
301 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT | |
302 { return m_flat_tree.rend(); } | |
303 | |
304 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
305 //! | |
306 //! <b>Throws</b>: Nothing. | |
307 //! | |
308 //! <b>Complexity</b>: Constant. | |
309 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT | |
310 { return m_flat_tree.cbegin(); } | |
311 | |
312 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
313 //! | |
314 //! <b>Throws</b>: Nothing. | |
315 //! | |
316 //! <b>Complexity</b>: Constant. | |
317 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT | |
318 { return m_flat_tree.cend(); } | |
319 | |
320 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
321 //! of the reversed container. | |
322 //! | |
323 //! <b>Throws</b>: Nothing. | |
324 //! | |
325 //! <b>Complexity</b>: Constant. | |
326 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT | |
327 { return m_flat_tree.crbegin(); } | |
328 | |
329 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
330 //! of the reversed container. | |
331 //! | |
332 //! <b>Throws</b>: Nothing. | |
333 //! | |
334 //! <b>Complexity</b>: Constant. | |
335 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT | |
336 { return m_flat_tree.crend(); } | |
337 | |
338 | |
339 ////////////////////////////////////////////// | |
340 // | |
341 // capacity | |
342 // | |
343 ////////////////////////////////////////////// | |
344 | |
345 //! <b>Effects</b>: Returns true if the container contains no elements. | |
346 //! | |
347 //! <b>Throws</b>: Nothing. | |
348 //! | |
349 //! <b>Complexity</b>: Constant. | |
350 bool empty() const BOOST_CONTAINER_NOEXCEPT | |
351 { return m_flat_tree.empty(); } | |
352 | |
353 //! <b>Effects</b>: Returns the number of the elements contained in the container. | |
354 //! | |
355 //! <b>Throws</b>: Nothing. | |
356 //! | |
357 //! <b>Complexity</b>: Constant. | |
358 size_type size() const BOOST_CONTAINER_NOEXCEPT | |
359 { return m_flat_tree.size(); } | |
360 | |
361 //! <b>Effects</b>: Returns the largest possible size of the container. | |
362 //! | |
363 //! <b>Throws</b>: Nothing. | |
364 //! | |
365 //! <b>Complexity</b>: Constant. | |
366 size_type max_size() const BOOST_CONTAINER_NOEXCEPT | |
367 { return m_flat_tree.max_size(); } | |
368 | |
369 //! <b>Effects</b>: Number of elements for which memory has been allocated. | |
370 //! capacity() is always greater than or equal to size(). | |
371 //! | |
372 //! <b>Throws</b>: Nothing. | |
373 //! | |
374 //! <b>Complexity</b>: Constant. | |
375 size_type capacity() const BOOST_CONTAINER_NOEXCEPT | |
376 { return m_flat_tree.capacity(); } | |
377 | |
378 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no | |
379 //! effect. Otherwise, it is a request for allocation of additional memory. | |
380 //! If the request is successful, then capacity() is greater than or equal to | |
381 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. | |
382 //! | |
383 //! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws. | |
384 //! | |
385 //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to | |
386 //! to values might be invalidated. | |
387 void reserve(size_type cnt) | |
388 { m_flat_tree.reserve(cnt); } | |
389 | |
390 //! <b>Effects</b>: Tries to deallocate the excess of memory created | |
391 // with previous allocations. The size of the vector is unchanged | |
392 //! | |
393 //! <b>Throws</b>: If memory allocation throws, or Key's copy constructor throws. | |
394 //! | |
395 //! <b>Complexity</b>: Linear to size(). | |
396 void shrink_to_fit() | |
397 { m_flat_tree.shrink_to_fit(); } | |
398 | |
399 ////////////////////////////////////////////// | |
400 // | |
401 // modifiers | |
402 // | |
403 ////////////////////////////////////////////// | |
404 | |
405 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
406 | |
407 //! <b>Effects</b>: Inserts an object x of type Key constructed with | |
408 //! std::forward<Args>(args)... if and only if there is no element in the container | |
409 //! with key equivalent to the key of x. | |
410 //! | |
411 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
412 //! if the insertion takes place, and the iterator component of the pair | |
413 //! points to the element with key equivalent to the key of x. | |
414 //! | |
415 //! <b>Complexity</b>: Logarithmic search time plus linear insertion | |
416 //! to the elements with bigger keys than x. | |
417 //! | |
418 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
419 template <class... Args> | |
420 std::pair<iterator,bool> emplace(Args&&... args) | |
421 { return m_flat_tree.emplace_unique(boost::forward<Args>(args)...); } | |
422 | |
423 //! <b>Effects</b>: Inserts an object of type Key constructed with | |
424 //! std::forward<Args>(args)... in the container if and only if there is | |
425 //! no element in the container with key equivalent to the key of x. | |
426 //! p is a hint pointing to where the insert should start to search. | |
427 //! | |
428 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
429 //! to the key of x. | |
430 //! | |
431 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted | |
432 //! right before p) plus insertion linear to the elements with bigger keys than x. | |
433 //! | |
434 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
435 template <class... Args> | |
436 iterator emplace_hint(const_iterator hint, Args&&... args) | |
437 { return m_flat_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); } | |
438 | |
439 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
440 | |
441 #define BOOST_PP_LOCAL_MACRO(n) \ | |
442 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
443 std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
444 { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
445 \ | |
446 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
447 iterator emplace_hint(const_iterator hint \ | |
448 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
449 { return m_flat_tree.emplace_hint_unique \ | |
450 (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
451 //! | |
452 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
453 #include BOOST_PP_LOCAL_ITERATE() | |
454 | |
455 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
456 | |
457 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
458 //! <b>Effects</b>: Inserts x if and only if there is no element in the container | |
459 //! with key equivalent to the key of x. | |
460 //! | |
461 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
462 //! if the insertion takes place, and the iterator component of the pair | |
463 //! points to the element with key equivalent to the key of x. | |
464 //! | |
465 //! <b>Complexity</b>: Logarithmic search time plus linear insertion | |
466 //! to the elements with bigger keys than x. | |
467 //! | |
468 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
469 std::pair<iterator, bool> insert(const value_type &x); | |
470 | |
471 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and | |
472 //! only if there is no element in the container with key equivalent to the key of x. | |
473 //! | |
474 //! <b>Returns</b>: The bool component of the returned pair is true if and only | |
475 //! if the insertion takes place, and the iterator component of the pair | |
476 //! points to the element with key equivalent to the key of x. | |
477 //! | |
478 //! <b>Complexity</b>: Logarithmic search time plus linear insertion | |
479 //! to the elements with bigger keys than x. | |
480 //! | |
481 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
482 std::pair<iterator, bool> insert(value_type &&x); | |
483 #else | |
484 private: | |
485 typedef std::pair<iterator, bool> insert_return_pair; | |
486 public: | |
487 BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert) | |
488 #endif | |
489 | |
490 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
491 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is | |
492 //! no element in the container with key equivalent to the key of x. | |
493 //! p is a hint pointing to where the insert should start to search. | |
494 //! | |
495 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
496 //! to the key of x. | |
497 //! | |
498 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted | |
499 //! right before p) plus insertion linear to the elements with bigger keys than x. | |
500 //! | |
501 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
502 iterator insert(const_iterator p, const value_type &x); | |
503 | |
504 //! <b>Effects</b>: Inserts an element move constructed from x in the container. | |
505 //! p is a hint pointing to where the insert should start to search. | |
506 //! | |
507 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. | |
508 //! | |
509 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted | |
510 //! right before p) plus insertion linear to the elements with bigger keys than x. | |
511 //! | |
512 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
513 iterator insert(const_iterator position, value_type &&x); | |
514 #else | |
515 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator) | |
516 #endif | |
517 | |
518 //! <b>Requires</b>: first, last are not iterators into *this. | |
519 //! | |
520 //! <b>Effects</b>: inserts each element from the range [first,last) if and only | |
521 //! if there is no element with key equivalent to the key of that element. | |
522 //! | |
523 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
524 //! search time plus N*size() insertion time. | |
525 //! | |
526 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
527 template <class InputIterator> | |
528 void insert(InputIterator first, InputIterator last) | |
529 { m_flat_tree.insert_unique(first, last); } | |
530 | |
531 //! <b>Requires</b>: first, last are not iterators into *this and | |
532 //! must be ordered according to the predicate and must be | |
533 //! unique values. | |
534 //! | |
535 //! <b>Effects</b>: inserts each element from the range [first,last) .This function | |
536 //! is more efficient than the normal range creation for ordered ranges. | |
537 //! | |
538 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
539 //! search time plus N*size() insertion time. | |
540 //! | |
541 //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements. | |
542 template <class InputIterator> | |
543 void insert(ordered_unique_range_t, InputIterator first, InputIterator last) | |
544 { m_flat_tree.insert_unique(ordered_unique_range, first, last); } | |
545 | |
546 //! <b>Effects</b>: Erases the element pointed to by position. | |
547 //! | |
548 //! <b>Returns</b>: Returns an iterator pointing to the element immediately | |
549 //! following q prior to the element being erased. If no such element exists, | |
550 //! returns end(). | |
551 //! | |
552 //! <b>Complexity</b>: Linear to the elements with keys bigger than position | |
553 //! | |
554 //! <b>Note</b>: Invalidates elements with keys | |
555 //! not less than the erased element. | |
556 iterator erase(const_iterator position) | |
557 { return m_flat_tree.erase(position); } | |
558 | |
559 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. | |
560 //! | |
561 //! <b>Returns</b>: Returns the number of erased elements. | |
562 //! | |
563 //! <b>Complexity</b>: Logarithmic search time plus erasure time | |
564 //! linear to the elements with bigger keys. | |
565 size_type erase(const key_type& x) | |
566 { return m_flat_tree.erase(x); } | |
567 | |
568 //! <b>Effects</b>: Erases all the elements in the range [first, last). | |
569 //! | |
570 //! <b>Returns</b>: Returns last. | |
571 //! | |
572 //! <b>Complexity</b>: size()*N where N is the distance from first to last. | |
573 //! | |
574 //! <b>Complexity</b>: Logarithmic search time plus erasure time | |
575 //! linear to the elements with bigger keys. | |
576 iterator erase(const_iterator first, const_iterator last) | |
577 { return m_flat_tree.erase(first, last); } | |
578 | |
579 //! <b>Effects</b>: Swaps the contents of *this and x. | |
580 //! | |
581 //! <b>Throws</b>: Nothing. | |
582 //! | |
583 //! <b>Complexity</b>: Constant. | |
584 void swap(flat_set& x) | |
585 { m_flat_tree.swap(x.m_flat_tree); } | |
586 | |
587 //! <b>Effects</b>: erase(a.begin(),a.end()). | |
588 //! | |
589 //! <b>Postcondition</b>: size() == 0. | |
590 //! | |
591 //! <b>Complexity</b>: linear in size(). | |
592 void clear() BOOST_CONTAINER_NOEXCEPT | |
593 { m_flat_tree.clear(); } | |
594 | |
595 ////////////////////////////////////////////// | |
596 // | |
597 // observers | |
598 // | |
599 ////////////////////////////////////////////// | |
600 | |
601 //! <b>Effects</b>: Returns the comparison object out | |
602 //! of which a was constructed. | |
603 //! | |
604 //! <b>Complexity</b>: Constant. | |
605 key_compare key_comp() const | |
606 { return m_flat_tree.key_comp(); } | |
607 | |
608 //! <b>Effects</b>: Returns an object of value_compare constructed out | |
609 //! of the comparison object. | |
610 //! | |
611 //! <b>Complexity</b>: Constant. | |
612 value_compare value_comp() const | |
613 { return m_flat_tree.key_comp(); } | |
614 | |
615 ////////////////////////////////////////////// | |
616 // | |
617 // set operations | |
618 // | |
619 ////////////////////////////////////////////// | |
620 | |
621 //! <b>Returns</b>: An iterator pointing to an element with the key | |
622 //! equivalent to x, or end() if such an element is not found. | |
623 //! | |
624 //! <b>Complexity</b>: Logarithmic. | |
625 iterator find(const key_type& x) | |
626 { return m_flat_tree.find(x); } | |
627 | |
628 //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key | |
629 //! equivalent to x, or end() if such an element is not found. | |
630 //! | |
631 //! <b>Complexity</b>: Logarithmic.s | |
632 const_iterator find(const key_type& x) const | |
633 { return m_flat_tree.find(x); } | |
634 | |
635 //! <b>Returns</b>: The number of elements with key equivalent to x. | |
636 //! | |
637 //! <b>Complexity</b>: log(size())+count(k) | |
638 size_type count(const key_type& x) const | |
639 { return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); } | |
640 | |
641 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
642 //! than k, or a.end() if such an element is not found. | |
643 //! | |
644 //! <b>Complexity</b>: Logarithmic | |
645 iterator lower_bound(const key_type& x) | |
646 { return m_flat_tree.lower_bound(x); } | |
647 | |
648 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
649 //! less than k, or a.end() if such an element is not found. | |
650 //! | |
651 //! <b>Complexity</b>: Logarithmic | |
652 const_iterator lower_bound(const key_type& x) const | |
653 { return m_flat_tree.lower_bound(x); } | |
654 | |
655 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
656 //! than x, or end() if such an element is not found. | |
657 //! | |
658 //! <b>Complexity</b>: Logarithmic | |
659 iterator upper_bound(const key_type& x) | |
660 { return m_flat_tree.upper_bound(x); } | |
661 | |
662 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
663 //! less than x, or end() if such an element is not found. | |
664 //! | |
665 //! <b>Complexity</b>: Logarithmic | |
666 const_iterator upper_bound(const key_type& x) const | |
667 { return m_flat_tree.upper_bound(x); } | |
668 | |
669 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
670 //! | |
671 //! <b>Complexity</b>: Logarithmic | |
672 std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const | |
673 { return m_flat_tree.equal_range(x); } | |
674 | |
675 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
676 //! | |
677 //! <b>Complexity</b>: Logarithmic | |
678 std::pair<iterator,iterator> equal_range(const key_type& x) | |
679 { return m_flat_tree.equal_range(x); } | |
680 | |
681 /// @cond | |
682 template <class K1, class C1, class A1> | |
683 friend bool operator== (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&); | |
684 | |
685 template <class K1, class C1, class A1> | |
686 friend bool operator< (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&); | |
687 | |
688 private: | |
689 template<class KeyType> | |
690 std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x) | |
691 { return m_flat_tree.insert_unique(::boost::forward<KeyType>(x)); } | |
692 | |
693 template<class KeyType> | |
694 iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) | |
695 { return m_flat_tree.insert_unique(p, ::boost::forward<KeyType>(x)); } | |
696 /// @endcond | |
697 }; | |
698 | |
699 template <class Key, class Compare, class Allocator> | |
700 inline bool operator==(const flat_set<Key,Compare,Allocator>& x, | |
701 const flat_set<Key,Compare,Allocator>& y) | |
702 { return x.m_flat_tree == y.m_flat_tree; } | |
703 | |
704 template <class Key, class Compare, class Allocator> | |
705 inline bool operator<(const flat_set<Key,Compare,Allocator>& x, | |
706 const flat_set<Key,Compare,Allocator>& y) | |
707 { return x.m_flat_tree < y.m_flat_tree; } | |
708 | |
709 template <class Key, class Compare, class Allocator> | |
710 inline bool operator!=(const flat_set<Key,Compare,Allocator>& x, | |
711 const flat_set<Key,Compare,Allocator>& y) | |
712 { return !(x == y); } | |
713 | |
714 template <class Key, class Compare, class Allocator> | |
715 inline bool operator>(const flat_set<Key,Compare,Allocator>& x, | |
716 const flat_set<Key,Compare,Allocator>& y) | |
717 { return y < x; } | |
718 | |
719 template <class Key, class Compare, class Allocator> | |
720 inline bool operator<=(const flat_set<Key,Compare,Allocator>& x, | |
721 const flat_set<Key,Compare,Allocator>& y) | |
722 { return !(y < x); } | |
723 | |
724 template <class Key, class Compare, class Allocator> | |
725 inline bool operator>=(const flat_set<Key,Compare,Allocator>& x, | |
726 const flat_set<Key,Compare,Allocator>& y) | |
727 { return !(x < y); } | |
728 | |
729 template <class Key, class Compare, class Allocator> | |
730 inline void swap(flat_set<Key,Compare,Allocator>& x, flat_set<Key,Compare,Allocator>& y) | |
731 { x.swap(y); } | |
732 | |
733 /// @cond | |
734 | |
735 } //namespace container { | |
736 | |
737 //!has_trivial_destructor_after_move<> == true_type | |
738 //!specialization for optimizations | |
739 template <class Key, class C, class Allocator> | |
740 struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, Allocator> > | |
741 { | |
742 static const bool value = has_trivial_destructor_after_move<Allocator>::value &&has_trivial_destructor_after_move<C>::value; | |
743 }; | |
744 | |
745 namespace container { | |
746 | |
747 // Forward declaration of operators < and ==, needed for friend declaration. | |
748 | |
749 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
750 template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> > | |
751 #else | |
752 template <class Key, class Compare, class Allocator> | |
753 #endif | |
754 class flat_multiset; | |
755 | |
756 template <class Key, class Compare, class Allocator> | |
757 inline bool operator==(const flat_multiset<Key,Compare,Allocator>& x, | |
758 const flat_multiset<Key,Compare,Allocator>& y); | |
759 | |
760 template <class Key, class Compare, class Allocator> | |
761 inline bool operator<(const flat_multiset<Key,Compare,Allocator>& x, | |
762 const flat_multiset<Key,Compare,Allocator>& y); | |
763 /// @endcond | |
764 | |
765 //! flat_multiset is a Sorted Associative Container that stores objects of type Key. | |
766 //! | |
767 //! flat_multiset can store multiple copies of the same key value. | |
768 //! | |
769 //! flat_multiset is similar to std::multiset but it's implemented like an ordered vector. | |
770 //! This means that inserting a new element into a flat_multiset invalidates | |
771 //! previous iterators and references | |
772 //! | |
773 //! Erasing an element invalidates iterators and references | |
774 //! pointing to elements that come after (their keys are bigger) the erased element. | |
775 //! | |
776 //! This container provides random-access iterators. | |
777 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
778 template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> > | |
779 #else | |
780 template <class Key, class Compare, class Allocator> | |
781 #endif | |
782 class flat_multiset | |
783 { | |
784 /// @cond | |
785 private: | |
786 BOOST_COPYABLE_AND_MOVABLE(flat_multiset) | |
787 typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> tree_t; | |
788 tree_t m_flat_tree; // flat tree representing flat_multiset | |
789 /// @endcond | |
790 | |
791 public: | |
792 ////////////////////////////////////////////// | |
793 // | |
794 // types | |
795 // | |
796 ////////////////////////////////////////////// | |
797 typedef Key key_type; | |
798 typedef Key value_type; | |
799 typedef Compare key_compare; | |
800 typedef Compare value_compare; | |
801 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; | |
802 typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer; | |
803 typedef typename ::boost::container::allocator_traits<Allocator>::reference reference; | |
804 typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference; | |
805 typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type; | |
806 typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; | |
807 typedef Allocator allocator_type; | |
808 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; | |
809 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; | |
810 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; | |
811 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; | |
812 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; | |
813 | |
814 //! <b>Effects</b>: Default constructs an empty flat_multiset. | |
815 //! | |
816 //! <b>Complexity</b>: Constant. | |
817 explicit flat_multiset() | |
818 : m_flat_tree() | |
819 {} | |
820 | |
821 //! <b>Effects</b>: Constructs an empty flat_multiset using the specified | |
822 //! comparison object and allocator. | |
823 //! | |
824 //! <b>Complexity</b>: Constant. | |
825 explicit flat_multiset(const Compare& comp, | |
826 const allocator_type& a = allocator_type()) | |
827 : m_flat_tree(comp, a) | |
828 {} | |
829 | |
830 //! <b>Effects</b>: Constructs an empty flat_multiset using the specified allocator. | |
831 //! | |
832 //! <b>Complexity</b>: Constant. | |
833 explicit flat_multiset(const allocator_type& a) | |
834 : m_flat_tree(a) | |
835 {} | |
836 | |
837 template <class InputIterator> | |
838 flat_multiset(InputIterator first, InputIterator last, | |
839 const Compare& comp = Compare(), | |
840 const allocator_type& a = allocator_type()) | |
841 : m_flat_tree(false, first, last, comp, a) | |
842 {} | |
843 | |
844 //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and | |
845 //! allocator, and inserts elements from the ordered range [first ,last ). This function | |
846 //! is more efficient than the normal range creation for ordered ranges. | |
847 //! | |
848 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate. | |
849 //! | |
850 //! <b>Complexity</b>: Linear in N. | |
851 //! | |
852 //! <b>Note</b>: Non-standard extension. | |
853 template <class InputIterator> | |
854 flat_multiset(ordered_range_t, InputIterator first, InputIterator last, | |
855 const Compare& comp = Compare(), | |
856 const allocator_type& a = allocator_type()) | |
857 : m_flat_tree(ordered_range, first, last, comp, a) | |
858 {} | |
859 | |
860 //! <b>Effects</b>: Copy constructs a flat_multiset. | |
861 //! | |
862 //! <b>Complexity</b>: Linear in x.size(). | |
863 flat_multiset(const flat_multiset& x) | |
864 : m_flat_tree(x.m_flat_tree) | |
865 {} | |
866 | |
867 //! <b>Effects</b>: Move constructs a flat_multiset. Constructs *this using x's resources. | |
868 //! | |
869 //! <b>Complexity</b>: Constant. | |
870 //! | |
871 //! <b>Postcondition</b>: x is emptied. | |
872 flat_multiset(BOOST_RV_REF(flat_multiset) mx) | |
873 : m_flat_tree(boost::move(mx.m_flat_tree)) | |
874 {} | |
875 | |
876 //! <b>Effects</b>: Copy constructs a flat_multiset using the specified allocator. | |
877 //! | |
878 //! <b>Complexity</b>: Linear in x.size(). | |
879 flat_multiset(const flat_multiset& x, const allocator_type &a) | |
880 : m_flat_tree(x.m_flat_tree, a) | |
881 {} | |
882 | |
883 //! <b>Effects</b>: Move constructs a flat_multiset using the specified allocator. | |
884 //! Constructs *this using x's resources. | |
885 //! | |
886 //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise | |
887 flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a) | |
888 : m_flat_tree(boost::move(mx.m_flat_tree), a) | |
889 {} | |
890 | |
891 //! <b>Effects</b>: Makes *this a copy of x. | |
892 //! | |
893 //! <b>Complexity</b>: Linear in x.size(). | |
894 flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x) | |
895 { m_flat_tree = x.m_flat_tree; return *this; } | |
896 | |
897 //! <b>Effects</b>: Makes *this a copy of x. | |
898 //! | |
899 //! <b>Complexity</b>: Linear in x.size(). | |
900 flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) | |
901 { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } | |
902 | |
903 //! <b>Effects</b>: Returns a copy of the Allocator that | |
904 //! was passed to the object's constructor. | |
905 //! | |
906 //! <b>Complexity</b>: Constant. | |
907 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT | |
908 { return m_flat_tree.get_allocator(); } | |
909 | |
910 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
911 //! | |
912 //! <b>Throws</b>: Nothing | |
913 //! | |
914 //! <b>Complexity</b>: Constant. | |
915 //! | |
916 //! <b>Note</b>: Non-standard extension. | |
917 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT | |
918 { return m_flat_tree.get_stored_allocator(); } | |
919 | |
920 //! <b>Effects</b>: Returns a reference to the internal allocator. | |
921 //! | |
922 //! <b>Throws</b>: Nothing | |
923 //! | |
924 //! <b>Complexity</b>: Constant. | |
925 //! | |
926 //! <b>Note</b>: Non-standard extension. | |
927 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT | |
928 { return m_flat_tree.get_stored_allocator(); } | |
929 | |
930 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. | |
931 //! | |
932 //! <b>Throws</b>: Nothing. | |
933 //! | |
934 //! <b>Complexity</b>: Constant. | |
935 iterator begin() BOOST_CONTAINER_NOEXCEPT | |
936 { return m_flat_tree.begin(); } | |
937 | |
938 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
939 //! | |
940 //! <b>Throws</b>: Nothing. | |
941 //! | |
942 //! <b>Complexity</b>: Constant. | |
943 const_iterator begin() const | |
944 { return m_flat_tree.begin(); } | |
945 | |
946 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. | |
947 //! | |
948 //! <b>Throws</b>: Nothing. | |
949 //! | |
950 //! <b>Complexity</b>: Constant. | |
951 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT | |
952 { return m_flat_tree.cbegin(); } | |
953 | |
954 //! <b>Effects</b>: Returns an iterator to the end of the container. | |
955 //! | |
956 //! <b>Throws</b>: Nothing. | |
957 //! | |
958 //! <b>Complexity</b>: Constant. | |
959 iterator end() BOOST_CONTAINER_NOEXCEPT | |
960 { return m_flat_tree.end(); } | |
961 | |
962 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
963 //! | |
964 //! <b>Throws</b>: Nothing. | |
965 //! | |
966 //! <b>Complexity</b>: Constant. | |
967 const_iterator end() const BOOST_CONTAINER_NOEXCEPT | |
968 { return m_flat_tree.end(); } | |
969 | |
970 //! <b>Effects</b>: Returns a const_iterator to the end of the container. | |
971 //! | |
972 //! <b>Throws</b>: Nothing. | |
973 //! | |
974 //! <b>Complexity</b>: Constant. | |
975 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT | |
976 { return m_flat_tree.cend(); } | |
977 | |
978 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning | |
979 //! of the reversed container. | |
980 //! | |
981 //! <b>Throws</b>: Nothing. | |
982 //! | |
983 //! <b>Complexity</b>: Constant. | |
984 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT | |
985 { return m_flat_tree.rbegin(); } | |
986 | |
987 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
988 //! of the reversed container. | |
989 //! | |
990 //! <b>Throws</b>: Nothing. | |
991 //! | |
992 //! <b>Complexity</b>: Constant. | |
993 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT | |
994 { return m_flat_tree.rbegin(); } | |
995 | |
996 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning | |
997 //! of the reversed container. | |
998 //! | |
999 //! <b>Throws</b>: Nothing. | |
1000 //! | |
1001 //! <b>Complexity</b>: Constant. | |
1002 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT | |
1003 { return m_flat_tree.crbegin(); } | |
1004 | |
1005 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end | |
1006 //! of the reversed container. | |
1007 //! | |
1008 //! <b>Throws</b>: Nothing. | |
1009 //! | |
1010 //! <b>Complexity</b>: Constant. | |
1011 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT | |
1012 { return m_flat_tree.rend(); } | |
1013 | |
1014 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
1015 //! of the reversed container. | |
1016 //! | |
1017 //! <b>Throws</b>: Nothing. | |
1018 //! | |
1019 //! <b>Complexity</b>: Constant. | |
1020 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT | |
1021 { return m_flat_tree.rend(); } | |
1022 | |
1023 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end | |
1024 //! of the reversed container. | |
1025 //! | |
1026 //! <b>Throws</b>: Nothing. | |
1027 //! | |
1028 //! <b>Complexity</b>: Constant. | |
1029 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT | |
1030 { return m_flat_tree.crend(); } | |
1031 | |
1032 ////////////////////////////////////////////// | |
1033 // | |
1034 // capacity | |
1035 // | |
1036 ////////////////////////////////////////////// | |
1037 | |
1038 //! <b>Effects</b>: Returns true if the container contains no elements. | |
1039 //! | |
1040 //! <b>Throws</b>: Nothing. | |
1041 //! | |
1042 //! <b>Complexity</b>: Constant. | |
1043 bool empty() const BOOST_CONTAINER_NOEXCEPT | |
1044 { return m_flat_tree.empty(); } | |
1045 | |
1046 //! <b>Effects</b>: Returns the number of the elements contained in the container. | |
1047 //! | |
1048 //! <b>Throws</b>: Nothing. | |
1049 //! | |
1050 //! <b>Complexity</b>: Constant. | |
1051 size_type size() const BOOST_CONTAINER_NOEXCEPT | |
1052 { return m_flat_tree.size(); } | |
1053 | |
1054 //! <b>Effects</b>: Returns the largest possible size of the container. | |
1055 //! | |
1056 //! <b>Throws</b>: Nothing. | |
1057 //! | |
1058 //! <b>Complexity</b>: Constant. | |
1059 size_type max_size() const BOOST_CONTAINER_NOEXCEPT | |
1060 { return m_flat_tree.max_size(); } | |
1061 | |
1062 //! <b>Effects</b>: Number of elements for which memory has been allocated. | |
1063 //! capacity() is always greater than or equal to size(). | |
1064 //! | |
1065 //! <b>Throws</b>: Nothing. | |
1066 //! | |
1067 //! <b>Complexity</b>: Constant. | |
1068 size_type capacity() const BOOST_CONTAINER_NOEXCEPT | |
1069 { return m_flat_tree.capacity(); } | |
1070 | |
1071 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no | |
1072 //! effect. Otherwise, it is a request for allocation of additional memory. | |
1073 //! If the request is successful, then capacity() is greater than or equal to | |
1074 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. | |
1075 //! | |
1076 //! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws. | |
1077 //! | |
1078 //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to | |
1079 //! to values might be invalidated. | |
1080 void reserve(size_type cnt) | |
1081 { m_flat_tree.reserve(cnt); } | |
1082 | |
1083 //! <b>Effects</b>: Tries to deallocate the excess of memory created | |
1084 // with previous allocations. The size of the vector is unchanged | |
1085 //! | |
1086 //! <b>Throws</b>: If memory allocation throws, or Key's copy constructor throws. | |
1087 //! | |
1088 //! <b>Complexity</b>: Linear to size(). | |
1089 void shrink_to_fit() | |
1090 { m_flat_tree.shrink_to_fit(); } | |
1091 | |
1092 ////////////////////////////////////////////// | |
1093 // | |
1094 // modifiers | |
1095 // | |
1096 ////////////////////////////////////////////// | |
1097 | |
1098 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
1099 | |
1100 //! <b>Effects</b>: Inserts an object of type Key constructed with | |
1101 //! std::forward<Args>(args)... and returns the iterator pointing to the | |
1102 //! newly inserted element. | |
1103 //! | |
1104 //! <b>Complexity</b>: Logarithmic search time plus linear insertion | |
1105 //! to the elements with bigger keys than x. | |
1106 //! | |
1107 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1108 template <class... Args> | |
1109 iterator emplace(Args&&... args) | |
1110 { return m_flat_tree.emplace_equal(boost::forward<Args>(args)...); } | |
1111 | |
1112 //! <b>Effects</b>: Inserts an object of type Key constructed with | |
1113 //! std::forward<Args>(args)... in the container. | |
1114 //! p is a hint pointing to where the insert should start to search. | |
1115 //! | |
1116 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1117 //! to the key of x. | |
1118 //! | |
1119 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted | |
1120 //! right before p) plus insertion linear to the elements with bigger keys than x. | |
1121 //! | |
1122 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1123 template <class... Args> | |
1124 iterator emplace_hint(const_iterator hint, Args&&... args) | |
1125 { return m_flat_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); } | |
1126 | |
1127 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
1128 | |
1129 #define BOOST_PP_LOCAL_MACRO(n) \ | |
1130 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
1131 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
1132 { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
1133 \ | |
1134 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
1135 iterator emplace_hint(const_iterator hint \ | |
1136 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
1137 { return m_flat_tree.emplace_hint_equal \ | |
1138 (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
1139 //! | |
1140 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
1141 #include BOOST_PP_LOCAL_ITERATE() | |
1142 | |
1143 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING | |
1144 | |
1145 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
1146 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the | |
1147 //! newly inserted element. | |
1148 //! | |
1149 //! <b>Complexity</b>: Logarithmic search time plus linear insertion | |
1150 //! to the elements with bigger keys than x. | |
1151 //! | |
1152 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1153 iterator insert(const value_type &x); | |
1154 | |
1155 //! <b>Effects</b>: Inserts a new value_type move constructed from x | |
1156 //! and returns the iterator pointing to the newly inserted element. | |
1157 //! | |
1158 //! <b>Complexity</b>: Logarithmic search time plus linear insertion | |
1159 //! to the elements with bigger keys than x. | |
1160 //! | |
1161 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1162 iterator insert(value_type &&x); | |
1163 #else | |
1164 BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert) | |
1165 #endif | |
1166 | |
1167 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
1168 //! <b>Effects</b>: Inserts a copy of x in the container. | |
1169 //! p is a hint pointing to where the insert should start to search. | |
1170 //! | |
1171 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1172 //! to the key of x. | |
1173 //! | |
1174 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted | |
1175 //! right before p) plus insertion linear to the elements with bigger keys than x. | |
1176 //! | |
1177 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1178 iterator insert(const_iterator p, const value_type &x); | |
1179 | |
1180 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. | |
1181 //! p is a hint pointing to where the insert should start to search. | |
1182 //! | |
1183 //! <b>Returns</b>: An iterator pointing to the element with key equivalent | |
1184 //! to the key of x. | |
1185 //! | |
1186 //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted | |
1187 //! right before p) plus insertion linear to the elements with bigger keys than x. | |
1188 //! | |
1189 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1190 iterator insert(const_iterator position, value_type &&x); | |
1191 #else | |
1192 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator) | |
1193 #endif | |
1194 | |
1195 //! <b>Requires</b>: first, last are not iterators into *this. | |
1196 //! | |
1197 //! <b>Effects</b>: inserts each element from the range [first,last) . | |
1198 //! | |
1199 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
1200 //! search time plus N*size() insertion time. | |
1201 //! | |
1202 //! <b>Note</b>: If an element is inserted it might invalidate elements. | |
1203 template <class InputIterator> | |
1204 void insert(InputIterator first, InputIterator last) | |
1205 { m_flat_tree.insert_equal(first, last); } | |
1206 | |
1207 //! <b>Requires</b>: first, last are not iterators into *this and | |
1208 //! must be ordered according to the predicate. | |
1209 //! | |
1210 //! <b>Effects</b>: inserts each element from the range [first,last) .This function | |
1211 //! is more efficient than the normal range creation for ordered ranges. | |
1212 //! | |
1213 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) | |
1214 //! search time plus N*size() insertion time. | |
1215 //! | |
1216 //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements. | |
1217 template <class InputIterator> | |
1218 void insert(ordered_range_t, InputIterator first, InputIterator last) | |
1219 { m_flat_tree.insert_equal(ordered_range, first, last); } | |
1220 | |
1221 //! <b>Effects</b>: Erases the element pointed to by position. | |
1222 //! | |
1223 //! <b>Returns</b>: Returns an iterator pointing to the element immediately | |
1224 //! following q prior to the element being erased. If no such element exists, | |
1225 //! returns end(). | |
1226 //! | |
1227 //! <b>Complexity</b>: Linear to the elements with keys bigger than position | |
1228 //! | |
1229 //! <b>Note</b>: Invalidates elements with keys | |
1230 //! not less than the erased element. | |
1231 iterator erase(const_iterator position) | |
1232 { return m_flat_tree.erase(position); } | |
1233 | |
1234 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. | |
1235 //! | |
1236 //! <b>Returns</b>: Returns the number of erased elements. | |
1237 //! | |
1238 //! <b>Complexity</b>: Logarithmic search time plus erasure time | |
1239 //! linear to the elements with bigger keys. | |
1240 size_type erase(const key_type& x) | |
1241 { return m_flat_tree.erase(x); } | |
1242 | |
1243 //! <b>Effects</b>: Erases all the elements in the range [first, last). | |
1244 //! | |
1245 //! <b>Returns</b>: Returns last. | |
1246 //! | |
1247 //! <b>Complexity</b>: size()*N where N is the distance from first to last. | |
1248 //! | |
1249 //! <b>Complexity</b>: Logarithmic search time plus erasure time | |
1250 //! linear to the elements with bigger keys. | |
1251 iterator erase(const_iterator first, const_iterator last) | |
1252 { return m_flat_tree.erase(first, last); } | |
1253 | |
1254 //! <b>Effects</b>: Swaps the contents of *this and x. | |
1255 //! | |
1256 //! <b>Throws</b>: Nothing. | |
1257 //! | |
1258 //! <b>Complexity</b>: Constant. | |
1259 void swap(flat_multiset& x) | |
1260 { m_flat_tree.swap(x.m_flat_tree); } | |
1261 | |
1262 //! <b>Effects</b>: erase(a.begin(),a.end()). | |
1263 //! | |
1264 //! <b>Postcondition</b>: size() == 0. | |
1265 //! | |
1266 //! <b>Complexity</b>: linear in size(). | |
1267 void clear() BOOST_CONTAINER_NOEXCEPT | |
1268 { m_flat_tree.clear(); } | |
1269 | |
1270 ////////////////////////////////////////////// | |
1271 // | |
1272 // observers | |
1273 // | |
1274 ////////////////////////////////////////////// | |
1275 | |
1276 //! <b>Effects</b>: Returns the comparison object out | |
1277 //! of which a was constructed. | |
1278 //! | |
1279 //! <b>Complexity</b>: Constant. | |
1280 key_compare key_comp() const | |
1281 { return m_flat_tree.key_comp(); } | |
1282 | |
1283 //! <b>Effects</b>: Returns an object of value_compare constructed out | |
1284 //! of the comparison object. | |
1285 //! | |
1286 //! <b>Complexity</b>: Constant. | |
1287 value_compare value_comp() const | |
1288 { return m_flat_tree.key_comp(); } | |
1289 | |
1290 ////////////////////////////////////////////// | |
1291 // | |
1292 // set operations | |
1293 // | |
1294 ////////////////////////////////////////////// | |
1295 | |
1296 //! <b>Returns</b>: An iterator pointing to an element with the key | |
1297 //! equivalent to x, or end() if such an element is not found. | |
1298 //! | |
1299 //! <b>Complexity</b>: Logarithmic. | |
1300 iterator find(const key_type& x) | |
1301 { return m_flat_tree.find(x); } | |
1302 | |
1303 //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key | |
1304 //! equivalent to x, or end() if such an element is not found. | |
1305 //! | |
1306 //! <b>Complexity</b>: Logarithmic.s | |
1307 const_iterator find(const key_type& x) const | |
1308 { return m_flat_tree.find(x); } | |
1309 | |
1310 //! <b>Returns</b>: The number of elements with key equivalent to x. | |
1311 //! | |
1312 //! <b>Complexity</b>: log(size())+count(k) | |
1313 size_type count(const key_type& x) const | |
1314 { return m_flat_tree.count(x); } | |
1315 | |
1316 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
1317 //! than k, or a.end() if such an element is not found. | |
1318 //! | |
1319 //! <b>Complexity</b>: Logarithmic | |
1320 iterator lower_bound(const key_type& x) | |
1321 { return m_flat_tree.lower_bound(x); } | |
1322 | |
1323 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
1324 //! less than k, or a.end() if such an element is not found. | |
1325 //! | |
1326 //! <b>Complexity</b>: Logarithmic | |
1327 const_iterator lower_bound(const key_type& x) const | |
1328 { return m_flat_tree.lower_bound(x); } | |
1329 | |
1330 //! <b>Returns</b>: An iterator pointing to the first element with key not less | |
1331 //! than x, or end() if such an element is not found. | |
1332 //! | |
1333 //! <b>Complexity</b>: Logarithmic | |
1334 iterator upper_bound(const key_type& x) | |
1335 { return m_flat_tree.upper_bound(x); } | |
1336 | |
1337 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not | |
1338 //! less than x, or end() if such an element is not found. | |
1339 //! | |
1340 //! <b>Complexity</b>: Logarithmic | |
1341 const_iterator upper_bound(const key_type& x) const | |
1342 { return m_flat_tree.upper_bound(x); } | |
1343 | |
1344 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
1345 //! | |
1346 //! <b>Complexity</b>: Logarithmic | |
1347 std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const | |
1348 { return m_flat_tree.equal_range(x); } | |
1349 | |
1350 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). | |
1351 //! | |
1352 //! <b>Complexity</b>: Logarithmic | |
1353 std::pair<iterator,iterator> equal_range(const key_type& x) | |
1354 { return m_flat_tree.equal_range(x); } | |
1355 | |
1356 /// @cond | |
1357 template <class K1, class C1, class A1> | |
1358 friend bool operator== (const flat_multiset<K1,C1,A1>&, | |
1359 const flat_multiset<K1,C1,A1>&); | |
1360 template <class K1, class C1, class A1> | |
1361 friend bool operator< (const flat_multiset<K1,C1,A1>&, | |
1362 const flat_multiset<K1,C1,A1>&); | |
1363 private: | |
1364 template <class KeyType> | |
1365 iterator priv_insert(BOOST_FWD_REF(KeyType) x) | |
1366 { return m_flat_tree.insert_equal(::boost::forward<KeyType>(x)); } | |
1367 | |
1368 template <class KeyType> | |
1369 iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) | |
1370 { return m_flat_tree.insert_equal(p, ::boost::forward<KeyType>(x)); } | |
1371 /// @endcond | |
1372 }; | |
1373 | |
1374 template <class Key, class Compare, class Allocator> | |
1375 inline bool operator==(const flat_multiset<Key,Compare,Allocator>& x, | |
1376 const flat_multiset<Key,Compare,Allocator>& y) | |
1377 { return x.m_flat_tree == y.m_flat_tree; } | |
1378 | |
1379 template <class Key, class Compare, class Allocator> | |
1380 inline bool operator<(const flat_multiset<Key,Compare,Allocator>& x, | |
1381 const flat_multiset<Key,Compare,Allocator>& y) | |
1382 { return x.m_flat_tree < y.m_flat_tree; } | |
1383 | |
1384 template <class Key, class Compare, class Allocator> | |
1385 inline bool operator!=(const flat_multiset<Key,Compare,Allocator>& x, | |
1386 const flat_multiset<Key,Compare,Allocator>& y) | |
1387 { return !(x == y); } | |
1388 | |
1389 template <class Key, class Compare, class Allocator> | |
1390 inline bool operator>(const flat_multiset<Key,Compare,Allocator>& x, | |
1391 const flat_multiset<Key,Compare,Allocator>& y) | |
1392 { return y < x; } | |
1393 | |
1394 template <class Key, class Compare, class Allocator> | |
1395 inline bool operator<=(const flat_multiset<Key,Compare,Allocator>& x, | |
1396 const flat_multiset<Key,Compare,Allocator>& y) | |
1397 { return !(y < x); } | |
1398 | |
1399 template <class Key, class Compare, class Allocator> | |
1400 inline bool operator>=(const flat_multiset<Key,Compare,Allocator>& x, | |
1401 const flat_multiset<Key,Compare,Allocator>& y) | |
1402 { return !(x < y); } | |
1403 | |
1404 template <class Key, class Compare, class Allocator> | |
1405 inline void swap(flat_multiset<Key,Compare,Allocator>& x, flat_multiset<Key,Compare,Allocator>& y) | |
1406 { x.swap(y); } | |
1407 | |
1408 /// @cond | |
1409 | |
1410 } //namespace container { | |
1411 | |
1412 //!has_trivial_destructor_after_move<> == true_type | |
1413 //!specialization for optimizations | |
1414 template <class Key, class C, class Allocator> | |
1415 struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, Allocator> > | |
1416 { | |
1417 static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value; | |
1418 }; | |
1419 | |
1420 namespace container { | |
1421 | |
1422 /// @endcond | |
1423 | |
1424 }} | |
1425 | |
1426 #include <boost/container/detail/config_end.hpp> | |
1427 | |
1428 #endif /* BOOST_CONTAINER_FLAT_SET_HPP */ |