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 */