]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/container/set.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / container / set.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2011. 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_CONTAINERS_SET_HPP
12 #define BOOST_CONTAINERS_SET_HPP
13
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
15 #  pragma once
16 #endif
17
18 #include <boost/container/detail/config_begin.hpp>
19 #include <boost/container/detail/workaround.hpp>
20 #include <boost/container/container_fwd.hpp>
21
22 #include <utility>
23 #include <functional>
24 #include <memory>
25
26 #include <boost/move/move.hpp>
27 #include <boost/container/detail/mpl.hpp>
28 #include <boost/container/detail/tree.hpp>
29 #include <boost/move/move.hpp>
30 #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
31 #include <boost/container/detail/preprocessor.hpp>
32 #endif
33
34 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
35 namespace boost {
36 namespace container {
37 #else
38 namespace boost {
39 namespace container {
40 #endif
41
42 /// @cond
43 // Forward declarations of operators < and ==, needed for friend declaration.
44 template <class T, class Pred, class A>
45 inline bool operator==(const set<T,Pred,A>& x, 
46                        const set<T,Pred,A>& y);
47
48 template <class T, class Pred, class A>
49 inline bool operator<(const set<T,Pred,A>& x, 
50                       const set<T,Pred,A>& y);
51 /// @endcond
52
53 //! A set is a kind of associative container that supports unique keys (contains at 
54 //! most one of each key value) and provides for fast retrieval of the keys themselves. 
55 //! Class set supports bidirectional iterators. 
56 //! 
57 //! A set satisfies all of the requirements of a container and of a reversible container 
58 //! , and of an associative container. A set also provides most operations described in 
59 //! for unique keys.
60 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
61 template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
62 #else
63 template <class T, class Pred, class A>
64 #endif
65 class set 
66 {
67    /// @cond
68    private:
69    BOOST_COPYABLE_AND_MOVABLE(set)
70    typedef containers_detail::rbtree<T, T, 
71                      containers_detail::identity<T>, Pred, A> tree_t;
72    tree_t m_tree;  // red-black tree representing set
73    typedef typename containers_detail::
74       move_const_ref_type<T>::type insert_const_ref_type;
75    /// @endcond
76
77    public:
78
79    // typedefs:
80    typedef typename tree_t::key_type               key_type;
81    typedef typename tree_t::value_type             value_type;
82    typedef typename tree_t::pointer                pointer;
83    typedef typename tree_t::const_pointer          const_pointer;
84    typedef typename tree_t::reference              reference;
85    typedef typename tree_t::const_reference        const_reference;
86    typedef Pred                                    key_compare;
87    typedef Pred                                    value_compare;
88    typedef typename tree_t::iterator               iterator;
89    typedef typename tree_t::const_iterator         const_iterator;
90    typedef typename tree_t::reverse_iterator       reverse_iterator;
91    typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
92    typedef typename tree_t::size_type              size_type;
93    typedef typename tree_t::difference_type        difference_type;
94    typedef typename tree_t::allocator_type         allocator_type;
95    typedef typename tree_t::stored_allocator_type  stored_allocator_type;
96
97    //! <b>Effects</b>: Constructs an empty set using the specified comparison object 
98    //! and allocator.
99    //! 
100    //! <b>Complexity</b>: Constant.
101    explicit set(const Pred& comp = Pred(),
102                 const allocator_type& a = allocator_type())
103       : m_tree(comp, a)
104    {}
105
106    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and 
107    //! allocator, and inserts elements from the range [first ,last ).
108    //! 
109    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using 
110    //! comp and otherwise N logN, where N is last - first.
111    template <class InputIterator>
112    set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
113          const allocator_type& a = allocator_type())
114       : m_tree(first, last, comp, a, true) 
115    {}
116
117    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and 
118    //! allocator, and inserts elements from the ordered unique range [first ,last). This function
119    //! is more efficient than the normal range creation for ordered ranges.
120    //!
121    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
122    //! unique values.
123    //! 
124    //! <b>Complexity</b>: Linear in N.
125    template <class InputIterator>
126    set( ordered_unique_range_t, InputIterator first, InputIterator last
127       , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
128       : m_tree(ordered_range, first, last, comp, a) 
129    {}
130
131    //! <b>Effects</b>: Copy constructs a set.
132    //! 
133    //! <b>Complexity</b>: Linear in x.size().
134    set(const set& x) 
135       : m_tree(x.m_tree)
136    {}
137
138    //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
139    //! 
140    //! <b>Complexity</b>: Construct.
141    //! 
142    //! <b>Postcondition</b>: x is emptied.
143    set(BOOST_RV_REF(set) x) 
144       : m_tree(boost::move(x.m_tree))
145    {}
146
147    //! <b>Effects</b>: Makes *this a copy of x.
148    //! 
149    //! <b>Complexity</b>: Linear in x.size().
150    set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
151    {  m_tree = x.m_tree;   return *this;  }
152
153    //! <b>Effects</b>: this->swap(x.get()).
154    //! 
155    //! <b>Complexity</b>: Constant.
156    set& operator=(BOOST_RV_REF(set) x)
157    {  m_tree = boost::move(x.m_tree);   return *this;  }
158
159    //! <b>Effects</b>: Returns the comparison object out
160    //!   of which a was constructed.
161    //! 
162    //! <b>Complexity</b>: Constant.
163    key_compare key_comp() const 
164    { return m_tree.key_comp(); }
165
166    //! <b>Effects</b>: Returns an object of value_compare constructed out
167    //!   of the comparison object.
168    //! 
169    //! <b>Complexity</b>: Constant.
170    value_compare value_comp() const 
171    { return m_tree.key_comp(); }
172
173    //! <b>Effects</b>: Returns a copy of the Allocator that
174    //!   was passed to the object's constructor.
175    //! 
176    //! <b>Complexity</b>: Constant.
177    allocator_type get_allocator() const 
178    { return m_tree.get_allocator(); }
179
180    const stored_allocator_type &get_stored_allocator() const 
181    { return m_tree.get_stored_allocator(); }
182
183    stored_allocator_type &get_stored_allocator()
184    { return m_tree.get_stored_allocator(); }
185
186    //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
187    //! 
188    //! <b>Throws</b>: Nothing.
189    //! 
190    //! <b>Complexity</b>: Constant
191    iterator begin() 
192    { return m_tree.begin(); }
193
194    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
195    //! 
196    //! <b>Throws</b>: Nothing.
197    //! 
198    //! <b>Complexity</b>: Constant.
199    const_iterator begin() const 
200    { return m_tree.begin(); }
201
202    //! <b>Effects</b>: Returns an iterator to the end of the container.
203    //! 
204    //! <b>Throws</b>: Nothing.
205    //! 
206    //! <b>Complexity</b>: Constant.
207    iterator end() 
208    { return m_tree.end(); }
209
210    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
211    //! 
212    //! <b>Throws</b>: Nothing.
213    //! 
214    //! <b>Complexity</b>: Constant.
215    const_iterator end() const 
216    { return m_tree.end(); }
217
218    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
219    //! of the reversed container. 
220    //! 
221    //! <b>Throws</b>: Nothing.
222    //! 
223    //! <b>Complexity</b>: Constant.
224    reverse_iterator rbegin() 
225    { return m_tree.rbegin(); } 
226
227    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
228    //! of the reversed container. 
229    //! 
230    //! <b>Throws</b>: Nothing.
231    //! 
232    //! <b>Complexity</b>: Constant.
233    const_reverse_iterator rbegin() const 
234    { return m_tree.rbegin(); } 
235
236    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
237    //! of the reversed container. 
238    //! 
239    //! <b>Throws</b>: Nothing.
240    //! 
241    //! <b>Complexity</b>: Constant.
242    reverse_iterator rend() 
243    { return m_tree.rend(); }
244
245    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
246    //! of the reversed container. 
247    //! 
248    //! <b>Throws</b>: Nothing.
249    //! 
250    //! <b>Complexity</b>: Constant.
251    const_reverse_iterator rend() const 
252    { return m_tree.rend(); }
253
254    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
255    //! 
256    //! <b>Throws</b>: Nothing.
257    //! 
258    //! <b>Complexity</b>: Constant.
259    const_iterator cbegin() const 
260    { return m_tree.cbegin(); }
261
262    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
263    //! 
264    //! <b>Throws</b>: Nothing.
265    //! 
266    //! <b>Complexity</b>: Constant.
267    const_iterator cend() const 
268    { return m_tree.cend(); }
269
270    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
271    //! of the reversed container. 
272    //! 
273    //! <b>Throws</b>: Nothing.
274    //! 
275    //! <b>Complexity</b>: Constant.
276    const_reverse_iterator crbegin() const 
277    { return m_tree.crbegin(); } 
278
279    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
280    //! of the reversed container. 
281    //! 
282    //! <b>Throws</b>: Nothing.
283    //! 
284    //! <b>Complexity</b>: Constant.
285    const_reverse_iterator crend() const 
286    { return m_tree.crend(); }
287
288    //! <b>Effects</b>: Returns true if the container contains no elements.
289    //! 
290    //! <b>Throws</b>: Nothing.
291    //! 
292    //! <b>Complexity</b>: Constant.
293    bool empty() const 
294    { return m_tree.empty(); }
295
296    //! <b>Effects</b>: Returns the number of the elements contained in the container.
297    //! 
298    //! <b>Throws</b>: Nothing.
299    //! 
300    //! <b>Complexity</b>: Constant.
301    size_type size() const 
302    { return m_tree.size(); }
303
304    //! <b>Effects</b>: Returns the largest possible size of the container.
305    //! 
306    //! <b>Throws</b>: Nothing.
307    //! 
308    //! <b>Complexity</b>: Constant.
309    size_type max_size() const 
310    { return m_tree.max_size(); }
311
312    //! <b>Effects</b>: Swaps the contents of *this and x.
313    //!   If this->allocator_type() != x.allocator_type() allocators are also swapped.
314    //!
315    //! <b>Throws</b>: Nothing.
316    //!
317    //! <b>Complexity</b>: Constant.
318    void swap(set& x)
319    { m_tree.swap(x.m_tree); }
320
321    //! <b>Effects</b>: Inserts x if and only if there is no element in the container 
322    //!   with key equivalent to the key of x.
323    //!
324    //! <b>Returns</b>: The bool component of the returned pair is true if and only 
325    //!   if the insertion takes place, and the iterator component of the pair
326    //!   points to the element with key equivalent to the key of x.
327    //!
328    //! <b>Complexity</b>: Logarithmic.
329    std::pair<iterator,bool> insert(insert_const_ref_type x) 
330    {  return priv_insert(x); }
331
332    #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
333    std::pair<iterator,bool> insert(T &x)
334    { return this->insert(const_cast<const T &>(x)); }
335
336    template<class U>
337    std::pair<iterator,bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
338    {  return priv_insert(u); }
339    #endif
340
341    //! <b>Effects</b>: Move constructs a new value from x if and only if there is 
342    //!   no element in the container with key equivalent to the key of x.
343    //!
344    //! <b>Returns</b>: The bool component of the returned pair is true if and only 
345    //!   if the insertion takes place, and the iterator component of the pair
346    //!   points to the element with key equivalent to the key of x.
347    //!
348    //! <b>Complexity</b>: Logarithmic.
349    std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) 
350    {  return m_tree.insert_unique(boost::move(x));  }
351
352    //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is 
353    //!   no element in the container with key equivalent to the key of x.
354    //!   p is a hint pointing to where the insert should start to search.
355    //!
356    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
357    //!   to the key of x.
358    //!
359    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
360    //!   is inserted right before p.
361    iterator insert(const_iterator p, insert_const_ref_type x) 
362    {  return priv_insert(p, x); }
363
364    #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
365    iterator insert(const_iterator position, T &x)
366    { return this->insert(position, const_cast<const T &>(x)); }
367
368    template<class U>
369    iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
370    {  return priv_insert(position, u); }
371    #endif
372
373    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
374    //!   p is a hint pointing to where the insert should start to search.
375    //!
376    //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
377    //!
378    //! <b>Complexity</b>: Logarithmic.
379    iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) 
380    {  return m_tree.insert_unique(p, boost::move(x)); }
381
382    //! <b>Requires</b>: first, last are not iterators into *this.
383    //!
384    //! <b>Effects</b>: inserts each element from the range [first,last) if and only 
385    //!   if there is no element with key equivalent to the key of that element.
386    //!
387    //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
388    template <class InputIterator>
389    void insert(InputIterator first, InputIterator last) 
390    {  m_tree.insert_unique(first, last);  }
391
392    #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
393
394    //! <b>Effects</b>:  Inserts an object of type T constructed with
395    //!   std::forward<Args>(args)... if and only if there is 
396    //!   no element in the container with equivalent value.
397    //!   and returns the iterator pointing to the
398    //!   newly inserted element. 
399    //!
400    //! <b>Throws</b>: If memory allocation throws or
401    //!   T's in-place constructor throws.
402    //!
403    //! <b>Complexity</b>: Logarithmic.
404    template <class... Args>
405    iterator emplace(Args&&... args)
406    {  return m_tree.emplace_unique(boost::forward<Args>(args)...); }
407
408    //! <b>Effects</b>:  Inserts an object of type T constructed with
409    //!   std::forward<Args>(args)... if and only if there is 
410    //!   no element in the container with equivalent value.
411    //!   p is a hint pointing to where the insert
412    //!   should start to search.
413    //!
414    //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
415    //!
416    //! <b>Complexity</b>: Logarithmic.
417    template <class... Args>
418    iterator emplace_hint(const_iterator hint, Args&&... args)
419    {  return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
420
421    #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
422
423    iterator emplace()
424    {  return m_tree.emplace_unique(); }
425
426    iterator emplace_hint(const_iterator hint)
427    {  return m_tree.emplace_hint_unique(hint); }
428
429    #define BOOST_PP_LOCAL_MACRO(n)                                                                       \
430    template<BOOST_PP_ENUM_PARAMS(n, class P)>                                                            \
431    iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _))                               \
432    {  return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }          \
433                                                                                                          \
434    template<BOOST_PP_ENUM_PARAMS(n, class P)>                                                            \
435    iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _))     \
436    {  return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
437    //!
438    #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
439    #include BOOST_PP_LOCAL_ITERATE()
440
441    #endif   //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
442
443    //! <b>Effects</b>: Erases the element pointed to by p.
444    //!
445    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
446    //!   following q prior to the element being erased. If no such element exists, 
447    //!   returns end().
448    //!
449    //! <b>Complexity</b>: Amortized constant time
450    iterator erase(const_iterator p) 
451    {  return m_tree.erase(p); }
452
453    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
454    //!
455    //! <b>Returns</b>: Returns the number of erased elements.
456    //!
457    //! <b>Complexity</b>: log(size()) + count(k)
458    size_type erase(const key_type& x) 
459    {  return m_tree.erase(x); }
460
461    //! <b>Effects</b>: Erases all the elements in the range [first, last).
462    //!
463    //! <b>Returns</b>: Returns last.
464    //!
465    //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
466    iterator erase(const_iterator first, const_iterator last) 
467    {  return m_tree.erase(first, last);  }
468
469    //! <b>Effects</b>: erase(a.begin(),a.end()).
470    //!
471    //! <b>Postcondition</b>: size() == 0.
472    //!
473    //! <b>Complexity</b>: linear in size().
474    void clear() 
475    { m_tree.clear(); }
476
477    //! <b>Returns</b>: An iterator pointing to an element with the key
478    //!   equivalent to x, or end() if such an element is not found.
479    //!
480    //! <b>Complexity</b>: Logarithmic.
481    iterator find(const key_type& x) 
482    { return m_tree.find(x); }
483
484    //! <b>Returns</b>: A const_iterator pointing to an element with the key
485    //!   equivalent to x, or end() if such an element is not found.
486    //!
487    //! <b>Complexity</b>: Logarithmic.
488    const_iterator find(const key_type& x) const 
489    { return m_tree.find(x); }
490
491    //! <b>Returns</b>: The number of elements with key equivalent to x.
492    //!
493    //! <b>Complexity</b>: log(size())+count(k)
494    size_type count(const key_type& x) const 
495    {  return m_tree.find(x) == m_tree.end() ? 0 : 1;  }
496
497    //! <b>Returns</b>: An iterator pointing to the first element with key not less
498    //!   than k, or a.end() if such an element is not found.
499    //!
500    //! <b>Complexity</b>: Logarithmic
501    iterator lower_bound(const key_type& x) 
502    {  return m_tree.lower_bound(x); }
503
504    //! <b>Returns</b>: A const iterator pointing to the first element with key not
505    //!   less than k, or a.end() if such an element is not found.
506    //!
507    //! <b>Complexity</b>: Logarithmic
508    const_iterator lower_bound(const key_type& x) const 
509    {  return m_tree.lower_bound(x); }
510
511    //! <b>Returns</b>: An iterator pointing to the first element with key not less
512    //!   than x, or end() if such an element is not found.
513    //!
514    //! <b>Complexity</b>: Logarithmic
515    iterator upper_bound(const key_type& x)
516    {  return m_tree.upper_bound(x);    }
517
518    //! <b>Returns</b>: A const iterator pointing to the first element with key not
519    //!   less than x, or end() if such an element is not found.
520    //!
521    //! <b>Complexity</b>: Logarithmic
522    const_iterator upper_bound(const key_type& x) const 
523    {  return m_tree.upper_bound(x);    }
524
525    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
526    //!
527    //! <b>Complexity</b>: Logarithmic
528    std::pair<iterator,iterator> 
529       equal_range(const key_type& x) 
530    {  return m_tree.equal_range(x); }
531
532    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
533    //!
534    //! <b>Complexity</b>: Logarithmic
535    std::pair<const_iterator, const_iterator> 
536       equal_range(const key_type& x) const 
537    {  return m_tree.equal_range(x); }
538
539    /// @cond
540    template <class K1, class C1, class A1>
541    friend bool operator== (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
542
543    template <class K1, class C1, class A1>
544    friend bool operator< (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
545
546    private:
547    std::pair<iterator, bool> priv_insert(const T &x) 
548    {  return m_tree.insert_unique(x);  }
549
550    iterator priv_insert(const_iterator p, const T &x) 
551    {  return m_tree.insert_unique(p, x); }
552
553    /// @endcond
554 };
555
556 template <class T, class Pred, class A>
557 inline bool operator==(const set<T,Pred,A>& x, 
558                        const set<T,Pred,A>& y) 
559 {  return x.m_tree == y.m_tree;  }
560
561 template <class T, class Pred, class A>
562 inline bool operator<(const set<T,Pred,A>& x, 
563                       const set<T,Pred,A>& y) 
564 {  return x.m_tree < y.m_tree;   }
565
566 template <class T, class Pred, class A>
567 inline bool operator!=(const set<T,Pred,A>& x, 
568                        const set<T,Pred,A>& y) 
569 {  return !(x == y);   }
570
571 template <class T, class Pred, class A>
572 inline bool operator>(const set<T,Pred,A>& x, 
573                       const set<T,Pred,A>& y) 
574 {  return y < x; }
575
576 template <class T, class Pred, class A>
577 inline bool operator<=(const set<T,Pred,A>& x, 
578                        const set<T,Pred,A>& y) 
579 {  return !(y < x); }
580
581 template <class T, class Pred, class A>
582 inline bool operator>=(const set<T,Pred,A>& x, 
583                        const set<T,Pred,A>& y) 
584 {  return !(x < y);  }
585
586 template <class T, class Pred, class A>
587 inline void swap(set<T,Pred,A>& x, set<T,Pred,A>& y) 
588 {  x.swap(y);  }
589
590 /// @cond
591
592 }  //namespace container {
593 /*
594 //!has_trivial_destructor_after_move<> == true_type
595 //!specialization for optimizations
596 template <class T, class C, class A>
597 struct has_trivial_destructor_after_move<boost::container::set<T, C, A> >
598 {
599    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
600 };
601 */
602 namespace container {
603
604 // Forward declaration of operators < and ==, needed for friend declaration.
605
606 template <class T, class Pred, class A>
607 inline bool operator==(const multiset<T,Pred,A>& x, 
608                        const multiset<T,Pred,A>& y);
609
610 template <class T, class Pred, class A>
611 inline bool operator<(const multiset<T,Pred,A>& x, 
612                       const multiset<T,Pred,A>& y);
613 /// @endcond
614
615 //! A multiset is a kind of associative container that supports equivalent keys 
616 //! (possibly contains multiple copies of the same key value) and provides for 
617 //! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
618 //! 
619 //! A multiset satisfies all of the requirements of a container and of a reversible 
620 //! container, and of an associative container). multiset also provides most operations 
621 //! described for duplicate keys.
622 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
623 template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
624 #else
625 template <class T, class Pred, class A>
626 #endif
627 class multiset 
628 {
629    /// @cond
630    private:
631    BOOST_COPYABLE_AND_MOVABLE(multiset)
632    typedef containers_detail::rbtree<T, T, 
633                      containers_detail::identity<T>, Pred, A> tree_t;
634    tree_t m_tree;  // red-black tree representing multiset
635    typedef typename containers_detail::
636       move_const_ref_type<T>::type insert_const_ref_type;
637    /// @endcond
638
639    public:
640
641    // typedefs:
642    typedef typename tree_t::key_type               key_type;
643    typedef typename tree_t::value_type             value_type;
644    typedef typename tree_t::pointer                pointer;
645    typedef typename tree_t::const_pointer          const_pointer;
646    typedef typename tree_t::reference              reference;
647    typedef typename tree_t::const_reference        const_reference;
648    typedef Pred                                    key_compare;
649    typedef Pred                                    value_compare;
650    typedef typename tree_t::iterator               iterator;
651    typedef typename tree_t::const_iterator         const_iterator;
652    typedef typename tree_t::reverse_iterator       reverse_iterator;
653    typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
654    typedef typename tree_t::size_type              size_type;
655    typedef typename tree_t::difference_type        difference_type;
656    typedef typename tree_t::allocator_type         allocator_type;
657    typedef typename tree_t::stored_allocator_type  stored_allocator_type;
658
659    //! <b>Effects</b>: Constructs an empty multiset using the specified comparison
660    //!   object and allocator.
661    //! 
662    //! <b>Complexity</b>: Constant.
663    explicit multiset(const Pred& comp = Pred(),
664                      const allocator_type& a = allocator_type())
665       : m_tree(comp, a)
666    {}
667
668    //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object
669    //!   and allocator, and inserts elements from the range [first ,last ).
670    //! 
671    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using 
672    //! comp and otherwise N logN, where N is last - first.
673    template <class InputIterator>
674    multiset(InputIterator first, InputIterator last,
675             const Pred& comp = Pred(),
676             const allocator_type& a = allocator_type())
677       : m_tree(first, last, comp, a, false) 
678    {}
679
680    //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and 
681    //! allocator, and inserts elements from the ordered range [first ,last ). This function
682    //! is more efficient than the normal range creation for ordered ranges.
683    //!
684    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
685    //! 
686    //! <b>Complexity</b>: Linear in N.
687    template <class InputIterator>
688    multiset( ordered_range_t ordered_range, InputIterator first, InputIterator last
689            , const Pred& comp = Pred()
690            , const allocator_type& a = allocator_type())
691       : m_tree(ordered_range, first, last, comp, a) 
692    {}
693
694    //! <b>Effects</b>: Copy constructs a multiset.
695    //! 
696    //! <b>Complexity</b>: Linear in x.size().
697    multiset(const multiset& x) 
698       : m_tree(x.m_tree)
699    {}
700
701    //! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
702    //! 
703    //! <b>Complexity</b>: Construct.
704    //! 
705    //! <b>Postcondition</b>: x is emptied.
706    multiset(BOOST_RV_REF(multiset) x) 
707       : m_tree(boost::move(x.m_tree))
708    {}
709
710    //! <b>Effects</b>: Makes *this a copy of x.
711    //! 
712    //! <b>Complexity</b>: Linear in x.size().
713    multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x) 
714    {  m_tree = x.m_tree;   return *this;  }
715
716    //! <b>Effects</b>: this->swap(x.get()).
717    //! 
718    //! <b>Complexity</b>: Constant.
719    multiset& operator=(BOOST_RV_REF(multiset) x) 
720    {  m_tree = boost::move(x.m_tree);   return *this;  }
721
722    //! <b>Effects</b>: Returns the comparison object out
723    //!   of which a was constructed.
724    //! 
725    //! <b>Complexity</b>: Constant.
726    key_compare key_comp() const 
727    { return m_tree.key_comp(); }
728
729    //! <b>Effects</b>: Returns an object of value_compare constructed out
730    //!   of the comparison object.
731    //! 
732    //! <b>Complexity</b>: Constant.
733    value_compare value_comp() const 
734    { return m_tree.key_comp(); }
735
736    //! <b>Effects</b>: Returns a copy of the Allocator that
737    //!   was passed to the object's constructor.
738    //! 
739    //! <b>Complexity</b>: Constant.
740    allocator_type get_allocator() const 
741    { return m_tree.get_allocator(); }
742
743    const stored_allocator_type &get_stored_allocator() const 
744    { return m_tree.get_stored_allocator(); }
745
746    stored_allocator_type &get_stored_allocator()
747    { return m_tree.get_stored_allocator(); }
748
749    //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
750    //! 
751    //! <b>Throws</b>: Nothing.
752    //! 
753    //! <b>Complexity</b>: Constant.
754    iterator begin() 
755    { return m_tree.begin(); }
756
757    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
758    //! 
759    //! <b>Throws</b>: Nothing.
760    //! 
761    //! <b>Complexity</b>: Constant.
762    const_iterator begin() const 
763    { return m_tree.begin(); }
764
765    //! <b>Effects</b>: Returns an iterator to the end of the container.
766    //! 
767    //! <b>Throws</b>: Nothing.
768    //! 
769    //! <b>Complexity</b>: Constant.
770    iterator end() 
771    { return m_tree.end(); }
772
773    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
774    //! 
775    //! <b>Throws</b>: Nothing.
776    //! 
777    //! <b>Complexity</b>: Constant.
778    const_iterator end() const 
779    { return m_tree.end(); }
780
781    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
782    //! of the reversed container. 
783    //! 
784    //! <b>Throws</b>: Nothing.
785    //! 
786    //! <b>Complexity</b>: Constant.
787    reverse_iterator rbegin() 
788    { return m_tree.rbegin(); } 
789
790    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
791    //! of the reversed container. 
792    //! 
793    //! <b>Throws</b>: Nothing.
794    //! 
795    //! <b>Complexity</b>: Constant.
796    const_reverse_iterator rbegin() const 
797    { return m_tree.rbegin(); } 
798
799    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
800    //! of the reversed container. 
801    //! 
802    //! <b>Throws</b>: Nothing.
803    //! 
804    //! <b>Complexity</b>: Constant.
805    reverse_iterator rend() 
806    { return m_tree.rend(); }
807
808    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
809    //! of the reversed container. 
810    //! 
811    //! <b>Throws</b>: Nothing.
812    //! 
813    //! <b>Complexity</b>: Constant.
814    const_reverse_iterator rend() const 
815    { return m_tree.rend(); }
816
817    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
818    //! 
819    //! <b>Throws</b>: Nothing.
820    //! 
821    //! <b>Complexity</b>: Constant.
822    const_iterator cbegin() const 
823    { return m_tree.cbegin(); }
824
825    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
826    //! 
827    //! <b>Throws</b>: Nothing.
828    //! 
829    //! <b>Complexity</b>: Constant.
830    const_iterator cend() const 
831    { return m_tree.cend(); }
832
833    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
834    //! of the reversed container. 
835    //! 
836    //! <b>Throws</b>: Nothing.
837    //! 
838    //! <b>Complexity</b>: Constant.
839    const_reverse_iterator crbegin() const 
840    { return m_tree.crbegin(); } 
841
842    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
843    //! of the reversed container. 
844    //! 
845    //! <b>Throws</b>: Nothing.
846    //! 
847    //! <b>Complexity</b>: Constant.
848    const_reverse_iterator crend() const 
849    { return m_tree.crend(); }
850
851    //! <b>Effects</b>: Returns true if the container contains no elements.
852    //! 
853    //! <b>Throws</b>: Nothing.
854    //! 
855    //! <b>Complexity</b>: Constant.
856    bool empty() const 
857    { return m_tree.empty(); }
858
859    //! <b>Effects</b>: Returns the number of the elements contained in the container.
860    //! 
861    //! <b>Throws</b>: Nothing.
862    //! 
863    //! <b>Complexity</b>: Constant.
864    size_type size() const 
865    { return m_tree.size(); }
866
867    //! <b>Effects</b>: Returns the largest possible size of the container.
868    //! 
869    //! <b>Throws</b>: Nothing.
870    //! 
871    //! <b>Complexity</b>: Constant.
872    size_type max_size() const 
873    { return m_tree.max_size(); }
874
875    //! <b>Effects</b>: Swaps the contents of *this and x.
876    //!   If this->allocator_type() != x.allocator_type() allocators are also swapped.
877    //!
878    //! <b>Throws</b>: Nothing.
879    //!
880    //! <b>Complexity</b>: Constant.
881    void swap(multiset& x)
882    { m_tree.swap(x.m_tree); }
883
884    //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
885    //!   newly inserted element. 
886    //!
887    //! <b>Complexity</b>: Logarithmic.
888    iterator insert(insert_const_ref_type x) 
889    {  return priv_insert(x); }
890
891    #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
892    iterator insert(T &x)
893    { return this->insert(const_cast<const T &>(x)); }
894
895    template<class U>
896    iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
897    {  return priv_insert(u); }
898    #endif
899
900    //! <b>Effects</b>: Inserts a copy of x in the container.
901    //!
902    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
903    //!   to the key of x.
904    //!
905    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
906    //!   is inserted right before p.
907    iterator insert(BOOST_RV_REF(value_type) x) 
908    {  return m_tree.insert_equal(boost::move(x));  }
909
910    //! <b>Effects</b>: Inserts a copy of x in the container.
911    //!   p is a hint pointing to where the insert should start to search.
912    //!
913    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
914    //!   to the key of x.
915    //!
916    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
917    //!   is inserted right before p.
918    iterator insert(const_iterator p, insert_const_ref_type x) 
919    {  return priv_insert(p, x); }
920
921    #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
922    iterator insert(const_iterator position, T &x)
923    { return this->insert(position, const_cast<const T &>(x)); }
924
925    template<class U>
926    iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
927    {  return priv_insert(position, u); }
928    #endif
929
930    //! <b>Effects</b>: Inserts a value move constructed from x in the container.
931    //!   p is a hint pointing to where the insert should start to search.
932    //!
933    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
934    //!   to the key of x.
935    //!
936    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
937    //!   is inserted right before p.
938    iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) 
939    {  return m_tree.insert_equal(p, boost::move(x));  }
940
941    //! <b>Requires</b>: first, last are not iterators into *this.
942    //!
943    //! <b>Effects</b>: inserts each element from the range [first,last) .
944    //!
945    //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
946    template <class InputIterator>
947    void insert(InputIterator first, InputIterator last) 
948    {  m_tree.insert_equal(first, last);  }
949
950    #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
951
952    //! <b>Effects</b>: Inserts an object of type T constructed with
953    //!   std::forward<Args>(args)... and returns the iterator pointing to the
954    //!   newly inserted element. 
955    //!
956    //! <b>Complexity</b>: Logarithmic.
957    template <class... Args>
958    iterator emplace(Args&&... args)
959    {  return m_tree.emplace_equal(boost::forward<Args>(args)...); }
960
961    //! <b>Effects</b>: Inserts an object of type T constructed with
962    //!   std::forward<Args>(args)...
963    //!
964    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
965    //!   to the key of x.
966    //!
967    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
968    //!   is inserted right before p.
969    template <class... Args>
970    iterator emplace_hint(const_iterator hint, Args&&... args)
971    {  return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
972
973    #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
974
975    iterator emplace()
976    {  return m_tree.emplace_equal(); }
977
978    iterator emplace_hint(const_iterator hint)
979    {  return m_tree.emplace_hint_equal(hint); }
980
981    #define BOOST_PP_LOCAL_MACRO(n)                                                                       \
982    template<BOOST_PP_ENUM_PARAMS(n, class P)>                                                            \
983    iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _))                               \
984    {  return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }           \
985                                                                                                          \
986    template<BOOST_PP_ENUM_PARAMS(n, class P)>                                                            \
987    iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _))     \
988    {  return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
989    //!
990    #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
991    #include BOOST_PP_LOCAL_ITERATE()
992
993    #endif   //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
994
995    //! <b>Effects</b>: Erases the element pointed to by p.
996    //!
997    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
998    //!   following q prior to the element being erased. If no such element exists, 
999    //!   returns end().
1000    //!
1001    //! <b>Complexity</b>: Amortized constant time
1002    iterator erase(const_iterator p) 
1003    {  return m_tree.erase(p); }
1004
1005    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
1006    //!
1007    //! <b>Returns</b>: Returns the number of erased elements.
1008    //!
1009    //! <b>Complexity</b>: log(size()) + count(k)
1010    size_type erase(const key_type& x) 
1011    {  return m_tree.erase(x); }
1012
1013    //! <b>Effects</b>: Erases all the elements in the range [first, last).
1014    //!
1015    //! <b>Returns</b>: Returns last.
1016    //!
1017    //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
1018    iterator erase(const_iterator first, const_iterator last)
1019    {  return m_tree.erase(first, last); }
1020
1021    //! <b>Effects</b>: erase(a.begin(),a.end()).
1022    //!
1023    //! <b>Postcondition</b>: size() == 0.
1024    //!
1025    //! <b>Complexity</b>: linear in size().
1026    void clear() 
1027    { m_tree.clear(); }
1028
1029    //! <b>Returns</b>: An iterator pointing to an element with the key
1030    //!   equivalent to x, or end() if such an element is not found.
1031    //!
1032    //! <b>Complexity</b>: Logarithmic.
1033    iterator find(const key_type& x) 
1034    { return m_tree.find(x); }
1035
1036    //! <b>Returns</b>: A const iterator pointing to an element with the key
1037    //!   equivalent to x, or end() if such an element is not found.
1038    //!
1039    //! <b>Complexity</b>: Logarithmic.
1040    const_iterator find(const key_type& x) const 
1041    { return m_tree.find(x); }
1042
1043    //! <b>Returns</b>: The number of elements with key equivalent to x.
1044    //!
1045    //! <b>Complexity</b>: log(size())+count(k)
1046    size_type count(const key_type& x) const 
1047    {  return m_tree.count(x);  }
1048
1049    //! <b>Returns</b>: An iterator pointing to the first element with key not less
1050    //!   than k, or a.end() if such an element is not found.
1051    //!
1052    //! <b>Complexity</b>: Logarithmic
1053    iterator lower_bound(const key_type& x) 
1054    {  return m_tree.lower_bound(x); }
1055
1056    //! <b>Returns</b>: A const iterator pointing to the first element with key not
1057    //!   less than k, or a.end() if such an element is not found.
1058    //!
1059    //! <b>Complexity</b>: Logarithmic
1060    const_iterator lower_bound(const key_type& x) const 
1061    {  return m_tree.lower_bound(x); }
1062
1063    //! <b>Returns</b>: An iterator pointing to the first element with key not less
1064    //!   than x, or end() if such an element is not found.
1065    //!
1066    //! <b>Complexity</b>: Logarithmic
1067    iterator upper_bound(const key_type& x)
1068    {  return m_tree.upper_bound(x);    }
1069
1070    //! <b>Returns</b>: A const iterator pointing to the first element with key not
1071    //!   less than x, or end() if such an element is not found.
1072    //!
1073    //! <b>Complexity</b>: Logarithmic
1074    const_iterator upper_bound(const key_type& x) const 
1075    {  return m_tree.upper_bound(x);    }
1076
1077    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1078    //!
1079    //! <b>Complexity</b>: Logarithmic
1080    std::pair<iterator,iterator> 
1081       equal_range(const key_type& x) 
1082    {  return m_tree.equal_range(x); }
1083
1084    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
1085    //!
1086    //! <b>Complexity</b>: Logarithmic
1087    std::pair<const_iterator, const_iterator> 
1088       equal_range(const key_type& x) const 
1089    {  return m_tree.equal_range(x); }
1090
1091    /// @cond
1092    template <class K1, class C1, class A1>
1093    friend bool operator== (const multiset<K1,C1,A1>&,
1094                            const multiset<K1,C1,A1>&);
1095    template <class K1, class C1, class A1>
1096    friend bool operator< (const multiset<K1,C1,A1>&,
1097                           const multiset<K1,C1,A1>&);
1098    private:
1099    iterator priv_insert(const T &x) 
1100    {  return m_tree.insert_equal(x);  }
1101
1102    iterator priv_insert(const_iterator p, const T &x) 
1103    {  return m_tree.insert_equal(p, x); }
1104
1105    /// @endcond
1106 };
1107
1108 template <class T, class Pred, class A>
1109 inline bool operator==(const multiset<T,Pred,A>& x, 
1110                        const multiset<T,Pred,A>& y) 
1111 {  return x.m_tree == y.m_tree;  }
1112
1113 template <class T, class Pred, class A>
1114 inline bool operator<(const multiset<T,Pred,A>& x, 
1115                       const multiset<T,Pred,A>& y) 
1116 {  return x.m_tree < y.m_tree;   }
1117
1118 template <class T, class Pred, class A>
1119 inline bool operator!=(const multiset<T,Pred,A>& x, 
1120                        const multiset<T,Pred,A>& y) 
1121 {  return !(x == y);  }
1122
1123 template <class T, class Pred, class A>
1124 inline bool operator>(const multiset<T,Pred,A>& x, 
1125                       const multiset<T,Pred,A>& y) 
1126 {  return y < x;  }
1127
1128 template <class T, class Pred, class A>
1129 inline bool operator<=(const multiset<T,Pred,A>& x, 
1130                        const multiset<T,Pred,A>& y) 
1131 {  return !(y < x);  }
1132
1133 template <class T, class Pred, class A>
1134 inline bool operator>=(const multiset<T,Pred,A>& x, 
1135                        const multiset<T,Pred,A>& y) 
1136 {  return !(x < y);  }
1137
1138 template <class T, class Pred, class A>
1139 inline void swap(multiset<T,Pred,A>& x, multiset<T,Pred,A>& y) 
1140 {  x.swap(y);  }
1141
1142 /// @cond
1143
1144 }  //namespace container {
1145 /*
1146 //!has_trivial_destructor_after_move<> == true_type
1147 //!specialization for optimizations
1148 template <class T, class C, class A>
1149 struct has_trivial_destructor_after_move<boost::container::multiset<T, C, A> >
1150 {
1151    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
1152 };
1153 */
1154 namespace container {
1155
1156 /// @endcond
1157
1158 }}
1159
1160 #include <boost/container/detail/config_end.hpp>
1161
1162 #endif /* BOOST_CONTAINERS_SET_HPP */
1163