Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:19

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/container for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_CONTAINER_SET_HPP
0012 #define BOOST_CONTAINER_SET_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024 // container
0025 #include <boost/container/container_fwd.hpp>
0026 // container/detail
0027 #include <boost/container/detail/mpl.hpp>
0028 #include <boost/container/detail/tree.hpp>
0029 #include <boost/container/new_allocator.hpp> //new_allocator
0030 // intrusive/detail
0031 #include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
0032 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
0033 // move
0034 #include <boost/move/traits.hpp>
0035 #include <boost/move/utility_core.hpp>
0036 // move/detail
0037 #include <boost/move/detail/move_helpers.hpp>
0038 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0039 #include <boost/move/detail/fwd_macros.hpp>
0040 #endif
0041 // std
0042 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0043 #include <initializer_list>
0044 #endif
0045 
0046 namespace boost {
0047 namespace container {
0048 
0049 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0050 
0051 //! A set is a kind of associative container that supports unique keys (contains at
0052 //! most one of each key value) and provides for fast retrieval of the keys themselves.
0053 //! Class set supports bidirectional iterators.
0054 //!
0055 //! A set satisfies all of the requirements of a container and of a reversible container
0056 //! , and of an associative container. A set also provides most operations described in
0057 //! for unique keys.
0058 //!
0059 //! \tparam Key is the type to be inserted in the set, which is also the key_type
0060 //! \tparam Compare is the comparison functor used to order keys
0061 //! \tparam Allocator is the allocator to be used to allocate memory for this container
0062 //! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
0063 template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = void>
0064 #else
0065 template <class Key, class Compare, class Allocator, class Options>
0066 #endif
0067 class set
0068    ///@cond
0069    : public dtl::tree
0070       < Key, void, Compare, Allocator, Options>
0071    ///@endcond
0072 {
0073    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0074    private:
0075    BOOST_COPYABLE_AND_MOVABLE(set)
0076    typedef dtl::tree
0077       < Key, void, Compare, Allocator, Options> base_t;
0078    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0079 
0080    public:
0081    //////////////////////////////////////////////
0082    //
0083    //                    types
0084    //
0085    //////////////////////////////////////////////
0086    typedef Key                                                                            key_type;
0087    typedef Key                                                                            value_type;
0088    typedef Compare                                                                        key_compare;
0089    typedef key_compare                                                                    value_compare;
0090    typedef typename base_t::allocator_type                                                allocator_type;
0091    typedef ::boost::container::allocator_traits<allocator_type>                           allocator_traits_type;
0092    typedef typename ::boost::container::allocator_traits<allocator_type>::pointer         pointer;
0093    typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer   const_pointer;
0094    typedef typename ::boost::container::allocator_traits<allocator_type>::reference       reference;
0095    typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference;
0096    typedef typename ::boost::container::allocator_traits<allocator_type>::size_type       size_type;
0097    typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type;
0098    typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type)                 stored_allocator_type;
0099    typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator)                              iterator;
0100    typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator)                        const_iterator;
0101    typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator)                      reverse_iterator;
0102    typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator)                const_reverse_iterator;
0103    typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type)                             node_type;
0104    typedef typename BOOST_CONTAINER_IMPDEF(base_t::insert_return_type)                    insert_return_type;
0105 
0106    //////////////////////////////////////////////
0107    //
0108    //          construct/copy/destroy
0109    //
0110    //////////////////////////////////////////////
0111 
0112    //! <b>Effects</b>: Default constructs an empty set.
0113    //!
0114    //! <b>Complexity</b>: Constant.
0115    
0116    BOOST_CONTAINER_FORCEINLINE set()
0117       BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value &&
0118                         dtl::is_nothrow_default_constructible<Compare>::value)
0119       : base_t()
0120    {}
0121 
0122    //! <b>Effects</b>: Constructs an empty set using the specified allocator object.
0123    //!
0124    //! <b>Complexity</b>: Constant.
0125    BOOST_CONTAINER_FORCEINLINE explicit set(const allocator_type& a)
0126       : base_t(a)
0127    {}
0128 
0129    //! <b>Effects</b>: Constructs an empty set using the specified comparison object.
0130    //!
0131    //! <b>Complexity</b>: Constant.
0132    BOOST_CONTAINER_FORCEINLINE explicit set(const Compare& comp)
0133       : base_t(comp)
0134    {}
0135 
0136    //! <b>Effects</b>: Constructs an empty set using the specified comparison object
0137    //! and allocator.
0138    //!
0139    //! <b>Complexity</b>: Constant.
0140    BOOST_CONTAINER_FORCEINLINE set(const Compare& comp, const allocator_type& a)
0141       : base_t(comp, a)
0142    {}
0143 
0144    //! <b>Effects</b>: Constructs an empty set using and
0145    //! inserts elements from the range [first ,last ).
0146    //!
0147    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
0148    //! the predicate and otherwise N logN, where N is last - first.
0149    template <class InputIterator>
0150    BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last)
0151       : base_t(true, first, last)
0152    {}
0153 
0154    //! <b>Effects</b>: Constructs an empty set using the specified
0155    //! allocator, and inserts elements from the range [first ,last ).
0156    //!
0157    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
0158    //! the predicate and otherwise N logN, where N is last - first.
0159    template <class InputIterator>
0160    BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const allocator_type& a)
0161       : base_t(true, first, last, key_compare(), a)
0162    {}
0163 
0164    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0165    //! inserts elements from the range [first ,last ).
0166    //!
0167    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
0168    //! the predicate and otherwise N logN, where N is last - first.
0169    template <class InputIterator>
0170    BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp)
0171       : base_t(true, first, last, comp)
0172    {}
0173 
0174    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0175    //! allocator, and inserts elements from the range [first ,last ).
0176    //!
0177    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
0178    //! the predicate and otherwise N logN, where N is last - first.
0179    template <class InputIterator>
0180    BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
0181       : base_t(true, first, last, comp, a)
0182    {}
0183 
0184    //! <b>Effects</b>: Constructs an empty set and
0185    //! inserts elements from the ordered unique range [first ,last). This function
0186    //! is more efficient than the normal range creation for ordered ranges.
0187    //!
0188    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
0189    //! unique values.
0190    //!
0191    //! <b>Complexity</b>: Linear in N.
0192    //!
0193    //! <b>Note</b>: Non-standard extension.
0194    template <class InputIterator>
0195    BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last)
0196       : base_t(ordered_range, first, last)
0197    {}
0198 
0199    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0200    //! inserts elements from the ordered unique range [first ,last). This function
0201    //! is more efficient than the normal range creation for ordered ranges.
0202    //!
0203    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
0204    //! unique values.
0205    //!
0206    //! <b>Complexity</b>: Linear in N.
0207    //!
0208    //! <b>Note</b>: Non-standard extension.
0209    template <class InputIterator>
0210    BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp )
0211       : base_t(ordered_range, first, last, comp)
0212    {}
0213 
0214    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0215    //! allocator, and inserts elements from the ordered unique range [first ,last). This function
0216    //! is more efficient than the normal range creation for ordered ranges.
0217    //!
0218    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
0219    //! unique values.
0220    //!
0221    //! <b>Complexity</b>: Linear in N.
0222    //!
0223    //! <b>Note</b>: Non-standard extension.
0224    template <class InputIterator>
0225    BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last
0226       , const Compare& comp, const allocator_type& a)
0227       : base_t(ordered_range, first, last, comp, a)
0228    {}
0229 
0230    //! <b>Effects</b>: Constructs an empty set using the specified allocator and
0231    //! inserts elements from the ordered unique range [first ,last). This function
0232    //! is more efficient than the normal range creation for ordered ranges.
0233    //!
0234    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
0235    //! unique values.
0236    //!
0237    //! <b>Complexity</b>: Linear in N.
0238    //!
0239    //! <b>Note</b>: Non-standard extension.
0240    template <class InputIterator>
0241    BOOST_CONTAINER_FORCEINLINE set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a)
0242       : base_t(ordered_range, first, last, Compare(), a)
0243    {}
0244 
0245 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0246    //! <b>Effects</b>: Constructs an empty set and
0247    //! inserts elements from the range [il.begin(), il.end()).
0248    //!
0249    //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
0250    //! the predicate and otherwise N logN, where N is il.begin() - il.end().
0251    BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il)
0252       : base_t(true, il.begin(), il.end())
0253    {}
0254 
0255    //! <b>Effects</b>: Constructs an empty set using the specified
0256    //! allocator, and inserts elements from the range [il.begin(), il.end()).
0257    //!
0258    //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
0259    //! the predicate and otherwise N logN, where N is il.begin() - il.end().
0260    BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const allocator_type& a)
0261       : base_t(true, il.begin(), il.end(), Compare(), a)
0262    {}
0263 
0264    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0265    //! inserts elements from the range [il.begin(), il.end()).
0266    //!
0267    //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
0268    //! the predicate and otherwise N logN, where N is il.begin() - il.end().
0269    BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp )
0270       : base_t(true, il.begin(), il.end(), comp)
0271    {}
0272 
0273    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0274    //! allocator, and inserts elements from the range [il.begin(), il.end()).
0275    //!
0276    //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
0277    //! the predicate and otherwise N logN, where N is il.begin() - il.end().
0278    BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
0279       : base_t(true, il.begin(), il.end(), comp, a)
0280    {}
0281 
0282    //! <b>Effects</b>: Constructs an empty set and
0283    //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
0284    //! is more efficient than the normal range creation for ordered ranges.
0285    //!
0286    //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
0287    //! unique values.
0288    //!
0289    //! <b>Complexity</b>: Linear in N.
0290    //!
0291    //! <b>Note</b>: Non-standard extension.
0292    BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il)
0293       : base_t(ordered_range, il.begin(), il.end())
0294    {}
0295 
0296    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0297    //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
0298    //! is more efficient than the normal range creation for ordered ranges.
0299    //!
0300    //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
0301    //! unique values.
0302    //!
0303    //! <b>Complexity</b>: Linear in N.
0304    //!
0305    //! <b>Note</b>: Non-standard extension.
0306    BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
0307       : base_t(ordered_range, il.begin(), il.end(), comp)
0308    {}
0309 
0310    //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
0311    //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
0312    //! is more efficient than the normal range creation for ordered ranges.
0313    //!
0314    //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
0315    //! unique values.
0316    //!
0317    //! <b>Complexity</b>: Linear in N.
0318    //!
0319    //! <b>Note</b>: Non-standard extension.
0320    BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
0321       : base_t(ordered_range, il.begin(), il.end(), comp, a)
0322    {}
0323 #endif
0324 
0325    //! <b>Effects</b>: Copy constructs a set.
0326    //!
0327    //! <b>Complexity</b>: Linear in x.size().
0328    BOOST_CONTAINER_FORCEINLINE set(const set& x)
0329       : base_t(static_cast<const base_t&>(x))
0330    {}
0331 
0332    //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
0333    //!
0334    //! <b>Complexity</b>: Constant.
0335    //!
0336    //! <b>Postcondition</b>: x is emptied.
0337    BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x)
0338       BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
0339       : base_t(BOOST_MOVE_BASE(base_t, x))
0340    {}
0341 
0342    //! <b>Effects</b>: Copy constructs a set using the specified allocator.
0343    //!
0344    //! <b>Complexity</b>: Linear in x.size().
0345    BOOST_CONTAINER_FORCEINLINE set(const set& x, const allocator_type &a)
0346       : base_t(static_cast<const base_t&>(x), a)
0347    {}
0348 
0349    //! <b>Effects</b>: Move constructs a set using the specified allocator.
0350    //!                 Constructs *this using x's resources.
0351    //!
0352    //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
0353    BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x, const allocator_type &a)
0354       : base_t(BOOST_MOVE_BASE(base_t, x), a)
0355    {}
0356 
0357    //! <b>Effects</b>: Makes *this a copy of x.
0358    //!
0359    //! <b>Complexity</b>: Linear in x.size().
0360    BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
0361    {  return static_cast<set&>(this->base_t::operator=(static_cast<const base_t&>(x)));  }
0362 
0363    //! <b>Effects</b>: this->swap(x.get()).
0364    //!
0365    //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
0366    //!   is false and (allocation throws or value_type's move constructor throws)
0367    //!
0368    //! <b>Complexity</b>: Constant if allocator_traits_type::
0369    //!   propagate_on_container_move_assignment is true or
0370    //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
0371    BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_RV_REF(set) x)
0372       BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
0373                           allocator_traits_type::is_always_equal::value) &&
0374                            boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
0375    {  return static_cast<set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x)));  }
0376 
0377 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0378    //! <b>Effects</b>: Copy all elements from il to *this.
0379    //!
0380    //! <b>Complexity</b>: Linear in il.size().
0381    set& operator=(std::initializer_list<value_type> il)
0382    {
0383       this->clear();
0384       insert(il.begin(), il.end());
0385       return *this;
0386    }
0387 #endif
0388 
0389    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0390 
0391    //! <b>Effects</b>: Returns a copy of the allocator that
0392    //!   was passed to the object's constructor.
0393    //!
0394    //! <b>Complexity</b>: Constant.
0395    allocator_type get_allocator() const;
0396 
0397    //! <b>Effects</b>: Returns a reference to the internal allocator.
0398    //!
0399    //! <b>Throws</b>: Nothing
0400    //!
0401    //! <b>Complexity</b>: Constant.
0402    //!
0403    //! <b>Note</b>: Non-standard extension.
0404    stored_allocator_type &get_stored_allocator();
0405 
0406    //! <b>Effects</b>: Returns a reference to the internal allocator.
0407    //!
0408    //! <b>Throws</b>: Nothing
0409    //!
0410    //! <b>Complexity</b>: Constant.
0411    //!
0412    //! <b>Note</b>: Non-standard extension.
0413    const stored_allocator_type &get_stored_allocator() const;
0414 
0415    //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
0416    //!
0417    //! <b>Throws</b>: Nothing.
0418    //!
0419    //! <b>Complexity</b>: Constant
0420    iterator begin();
0421 
0422    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
0423    //!
0424    //! <b>Throws</b>: Nothing.
0425    //!
0426    //! <b>Complexity</b>: Constant.
0427    const_iterator begin() const;
0428 
0429    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
0430    //!
0431    //! <b>Throws</b>: Nothing.
0432    //!
0433    //! <b>Complexity</b>: Constant.
0434    const_iterator cbegin() const;
0435 
0436    //! <b>Effects</b>: Returns an iterator to the end of the container.
0437    //!
0438    //! <b>Throws</b>: Nothing.
0439    //!
0440    //! <b>Complexity</b>: Constant.
0441    iterator end();
0442 
0443    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
0444    //!
0445    //! <b>Throws</b>: Nothing.
0446    //!
0447    //! <b>Complexity</b>: Constant.
0448    const_iterator end() const;
0449 
0450    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
0451    //!
0452    //! <b>Throws</b>: Nothing.
0453    //!
0454    //! <b>Complexity</b>: Constant.
0455    const_iterator cend() const;
0456 
0457    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
0458    //! of the reversed container.
0459    //!
0460    //! <b>Throws</b>: Nothing.
0461    //!
0462    //! <b>Complexity</b>: Constant.
0463    reverse_iterator rbegin();
0464 
0465    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0466    //! of the reversed container.
0467    //!
0468    //! <b>Throws</b>: Nothing.
0469    //!
0470    //! <b>Complexity</b>: Constant.
0471    const_reverse_iterator rbegin() const;
0472 
0473    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0474    //! of the reversed container.
0475    //!
0476    //! <b>Throws</b>: Nothing.
0477    //!
0478    //! <b>Complexity</b>: Constant.
0479    const_reverse_iterator crbegin() const;
0480 
0481    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
0482    //! of the reversed container.
0483    //!
0484    //! <b>Throws</b>: Nothing.
0485    //!
0486    //! <b>Complexity</b>: Constant.
0487    reverse_iterator rend();
0488 
0489    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0490    //! of the reversed container.
0491    //!
0492    //! <b>Throws</b>: Nothing.
0493    //!
0494    //! <b>Complexity</b>: Constant.
0495    const_reverse_iterator rend() const;
0496 
0497    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0498    //! of the reversed container.
0499    //!
0500    //! <b>Throws</b>: Nothing.
0501    //!
0502    //! <b>Complexity</b>: Constant.
0503    const_reverse_iterator crend() const;
0504 
0505    //! <b>Effects</b>: Returns true if the container contains no elements.
0506    //!
0507    //! <b>Throws</b>: Nothing.
0508    //!
0509    //! <b>Complexity</b>: Constant.
0510    bool empty() const;
0511 
0512    //! <b>Effects</b>: Returns the number of the elements contained in the container.
0513    //!
0514    //! <b>Throws</b>: Nothing.
0515    //!
0516    //! <b>Complexity</b>: Constant.
0517    size_type size() const;
0518 
0519    //! <b>Effects</b>: Returns the largest possible size of the container.
0520    //!
0521    //! <b>Throws</b>: Nothing.
0522    //!
0523    //! <b>Complexity</b>: Constant.
0524    size_type max_size() const;
0525    #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0526 
0527    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0528 
0529    //! <b>Effects</b>:  Inserts an object x of type Key constructed with
0530    //!   std::forward<Args>(args)... if and only if there is
0531    //!   no element in the container with equivalent value.
0532    //!   and returns the iterator pointing to the
0533    //!   newly inserted element.
0534    //!
0535    //! <b>Returns</b>: The bool component of the returned pair is true if and only
0536    //!   if the insertion takes place, and the iterator component of the pair
0537    //!   points to the element with key equivalent to the key of x.
0538    //!
0539    //! <b>Throws</b>: If memory allocation throws or
0540    //!   Key's in-place constructor throws.
0541    //!
0542    //! <b>Complexity</b>: Logarithmic.
0543    template <class... Args>
0544    BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
0545    {  return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
0546 
0547    //! <b>Effects</b>:  Inserts an object of type Key constructed with
0548    //!   std::forward<Args>(args)... if and only if there is
0549    //!   no element in the container with equivalent value.
0550    //!   p is a hint pointing to where the insert
0551    //!   should start to search.
0552    //!
0553    //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
0554    //!
0555    //! <b>Complexity</b>: Logarithmic.
0556    template <class... Args>
0557    BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
0558    {  return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
0559 
0560    #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0561 
0562    #define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \
0563    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0564    BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
0565    {  return this->base_t::emplace_unique(BOOST_MOVE_FWD##N);  }\
0566    \
0567    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0568    BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0569    {  return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
0570    //
0571    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE)
0572    #undef BOOST_CONTAINER_SET_EMPLACE_CODE
0573 
0574    #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0575 
0576    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0577    //! <b>Effects</b>: Inserts x if and only if there is no element in the container
0578    //!   with key equivalent to the key of x.
0579    //!
0580    //! <b>Returns</b>: The bool component of the returned pair is true if and only
0581    //!   if the insertion takes place, and the iterator component of the pair
0582    //!   points to the element with key equivalent to the key of x.
0583    //!
0584    //! <b>Complexity</b>: Logarithmic.
0585    std::pair<iterator, bool> insert(const value_type &x);
0586 
0587    //! <b>Effects</b>: Move constructs a new value from x if and only if there is
0588    //!   no element in the container with key equivalent to the key of x.
0589    //!
0590    //! <b>Returns</b>: The bool component of the returned pair is true if and only
0591    //!   if the insertion takes place, and the iterator component of the pair
0592    //!   points to the element with key equivalent to the key of x.
0593    //!
0594    //! <b>Complexity</b>: Logarithmic.
0595    std::pair<iterator, bool> insert(value_type &&x);
0596    #else
0597    private:
0598    typedef std::pair<iterator, bool> insert_return_pair;
0599    public:
0600    BOOST_MOVE_CONVERSION_AWARE_CATCH
0601       (insert, value_type, insert_return_pair, this->base_t::insert_unique_convertible)
0602    #endif
0603 
0604    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0605    //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
0606    //!   no element in the container with key equivalent to the key of x.
0607    //!   p is a hint pointing to where the insert should start to search.
0608    //!
0609    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
0610    //!   to the key of x.
0611    //!
0612    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
0613    //!   is inserted right before p.
0614    iterator insert(const_iterator p, const value_type &x);
0615 
0616    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
0617    //!   p is a hint pointing to where the insert should start to search.
0618    //!
0619    //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
0620    //!
0621    //! <b>Complexity</b>: Logarithmic.
0622    iterator insert(const_iterator p, value_type &&x);
0623    #else
0624    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG
0625       (insert, value_type, iterator, this->base_t::insert_unique_hint_convertible, const_iterator, const_iterator)
0626    #endif
0627 
0628    //! <b>Requires</b>: first, last are not iterators into *this.
0629    //!
0630    //! <b>Effects</b>: inserts each element from the range [first,last) if and only
0631    //!   if there is no element with key equivalent to the key of that element.
0632    //!
0633    //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
0634    template <class InputIterator>
0635    BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
0636    {  this->base_t::insert_unique_range(first, last);  }
0637 
0638 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0639    //! <b>Effects</b>: inserts each element from the range [il.begin(),il.end()) if and only
0640    //!   if there is no element with key equivalent to the key of that element.
0641    //!
0642    //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end())
0643    BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
0644    {  this->base_t::insert_unique_range(il.begin(), il.end()); }
0645 #endif
0646 
0647    //! @copydoc ::boost::container::map::insert(node_type&&)
0648    BOOST_CONTAINER_FORCEINLINE insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
0649    {  return this->base_t::insert_unique_node(boost::move(nh));  }
0650 
0651    //! @copydoc ::boost::container::map::insert(const_iterator, node_type&&)
0652    BOOST_CONTAINER_FORCEINLINE insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
0653    {  return this->base_t::insert_unique_node(hint, boost::move(nh));  }
0654 
0655    //! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
0656    template<class C2>
0657    BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
0658    {
0659       typedef dtl::tree
0660          <Key, void, C2, Allocator, Options> base2_t;
0661       this->base_t::merge_unique(static_cast<base2_t&>(source));
0662    }
0663 
0664    //! @copydoc ::boost::container::set::merge(set<Key, C2, Allocator, Options>&)
0665    template<class C2>
0666    BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
0667    {  return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source));   }
0668 
0669    //! @copydoc ::boost::container::map::merge(multimap<Key, T, C2, Allocator, Options>&)
0670    template<class C2>
0671    BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
0672    {
0673       typedef dtl::tree
0674          <Key, void, C2, Allocator, Options> base2_t;
0675       this->base_t::merge_unique(static_cast<base2_t&>(source));
0676    }
0677 
0678    //! @copydoc ::boost::container::set::merge(multiset<Key, C2, Allocator, Options>&)
0679    template<class C2>
0680    BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
0681    {  return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source));   }
0682 
0683    //! <b>Effects</b>: If present, erases the element in the container with key equivalent to x.
0684    //!
0685    //! <b>Returns</b>: Returns the number of erased elements (0/1).
0686    //!
0687    //! <b>Complexity</b>: log(size()) + count(k)
0688    BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
0689    {  return this->base_t::erase_unique(x);   }
0690 
0691    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0692 
0693    //! <b>Effects</b>: Erases the element pointed to by p.
0694    //!
0695    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
0696    //!   following q prior to the element being erased. If no such element exists,
0697    //!   returns end().
0698    //!
0699    //! <b>Complexity</b>: Amortized constant time
0700    iterator erase(const_iterator p);
0701 
0702    //! <b>Effects</b>: Erases all the elements in the range [first, last).
0703    //!
0704    //! <b>Returns</b>: Returns last.
0705    //!
0706    //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
0707    iterator erase(const_iterator first, const_iterator last);
0708 
0709    //! @copydoc ::boost::container::map::extract(const_iterator)
0710    node_type extract(const_iterator p);
0711 
0712    //! @copydoc ::boost::container::map::extract(const key_type&)
0713    node_type extract(const key_type& x);
0714 
0715    //! <b>Effects</b>: Swaps the contents of *this and x.
0716    //!
0717    //! <b>Throws</b>: Nothing.
0718    //!
0719    //! <b>Complexity</b>: Constant.
0720    void swap(set& x)
0721       BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
0722                                  && boost::container::dtl::is_nothrow_swappable<Compare>::value );
0723 
0724    //! <b>Effects</b>: erase(begin(),end()).
0725    //!
0726    //! <b>Postcondition</b>: size() == 0.
0727    //!
0728    //! <b>Complexity</b>: linear in size().
0729    void clear();
0730 
0731    //! <b>Effects</b>: Returns the comparison object out
0732    //!   of which a was constructed.
0733    //!
0734    //! <b>Complexity</b>: Constant.
0735    key_compare key_comp() const;
0736 
0737    //! <b>Effects</b>: Returns an object of value_compare constructed out
0738    //!   of the comparison object.
0739    //!
0740    //! <b>Complexity</b>: Constant.
0741    value_compare value_comp() const;
0742 
0743    //! <b>Returns</b>: An iterator pointing to an element with the key
0744    //!   equivalent to x, or end() if such an element is not found.
0745    //!
0746    //! <b>Complexity</b>: Logarithmic.
0747    iterator find(const key_type& x);
0748 
0749    //! <b>Returns</b>: A const_iterator pointing to an element with the key
0750    //!   equivalent to x, or end() if such an element is not found.
0751    //!
0752    //! <b>Complexity</b>: Logarithmic.
0753    const_iterator find(const key_type& x) const;
0754 
0755    //! <b>Requires</b>: This overload is available only if
0756    //! key_compare::is_transparent exists.
0757    //!
0758    //! <b>Returns</b>: An iterator pointing to an element with the key
0759    //!   equivalent to x, or end() if such an element is not found.
0760    //!
0761    //! <b>Complexity</b>: Logarithmic.
0762    template<typename K>
0763    iterator find(const K& x);
0764 
0765    //! <b>Requires</b>: This overload is available only if
0766    //! key_compare::is_transparent exists.
0767    //!
0768    //! <b>Returns</b>: A const_iterator pointing to an element with the key
0769    //!   equivalent to x, or end() if such an element is not found.
0770    //!
0771    //! <b>Complexity</b>: Logarithmic.
0772    template<typename K>
0773    const_iterator find(const K& x) const;
0774 
0775    #else
0776    using base_t::erase;
0777    #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0778 
0779    //! <b>Returns</b>: The number of elements with key equivalent to x.
0780    //!
0781    //! <b>Complexity</b>: log(size())+count(k)
0782    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0783       size_type count(const key_type& x) const
0784    {  return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend());  }
0785 
0786    //! <b>Requires</b>: This overload is available only if
0787    //! key_compare::is_transparent exists.
0788    //!
0789    //! <b>Returns</b>: The number of elements with key equivalent to x.
0790    //!
0791    //! <b>Complexity</b>: log(size())+count(k)
0792    template<typename K>
0793    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0794       size_type count(const K& x) const
0795    {  return static_cast<size_type>(this->find(x) != this->cend());  }
0796 
0797    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0798 
0799    //! <b>Returns</b>: Returns true if there is an element with key
0800    //!   equivalent to key in the container, otherwise false.
0801    //!
0802    //! <b>Complexity</b>: log(size()).
0803    bool contains(const key_type& x) const;
0804 
0805    //! <b>Requires</b>: This overload is available only if
0806    //! key_compare::is_transparent exists.
0807    //!
0808    //! <b>Returns</b>: Returns true if there is an element with key
0809    //!   equivalent to key in the container, otherwise false.
0810    //!
0811    //! <b>Complexity</b>: log(size()).
0812    template<typename K>
0813    bool contains(const K& x) const;
0814 
0815    //! <b>Returns</b>: An iterator pointing to the first element with key not less
0816    //!   than x, or end() if such an element is not found.
0817    //!
0818    //! <b>Complexity</b>: Logarithmic
0819    iterator lower_bound(const key_type& x);
0820 
0821    //! <b>Returns</b>: A const iterator pointing to the first element with key not
0822    //!   less than x, or end() if such an element is not found.
0823    //!
0824    //! <b>Complexity</b>: Logarithmic
0825    const_iterator lower_bound(const key_type& x) const;
0826 
0827    //! <b>Requires</b>: This overload is available only if
0828    //! key_compare::is_transparent exists.
0829    //!
0830    //! <b>Returns</b>: An iterator pointing to the first element with key not less
0831    //!   than x, or end() if such an element is not found.
0832    //!
0833    //! <b>Complexity</b>: Logarithmic
0834    template<typename K>
0835    iterator lower_bound(const K& x);
0836 
0837    //! <b>Requires</b>: This overload is available only if
0838    //! key_compare::is_transparent exists.
0839    //!
0840    //! <b>Returns</b>: A const iterator pointing to the first element with key not
0841    //!   less than x, or end() if such an element is not found.
0842    //!
0843    //! <b>Complexity</b>: Logarithmic
0844    template<typename K>
0845    const_iterator lower_bound(const K& x) const;
0846 
0847    //! <b>Returns</b>: An iterator pointing to the first element with key greater
0848    //!   than x, or end() if such an element is not found.
0849    //!
0850    //! <b>Complexity</b>: Logarithmic
0851    iterator upper_bound(const key_type& x);
0852 
0853    //! <b>Returns</b>: A const iterator pointing to the first element with key
0854    //!   greater than x, or end() if such an element is not found.
0855    //!
0856    //! <b>Complexity</b>: Logarithmic
0857    const_iterator upper_bound(const key_type& x) const;
0858 
0859    //! <b>Requires</b>: This overload is available only if
0860    //! key_compare::is_transparent exists.
0861    //!
0862    //! <b>Returns</b>: An iterator pointing to the first element with key greater
0863    //!   than x, or end() if such an element is not found.
0864    //!
0865    //! <b>Complexity</b>: Logarithmic
0866    template<typename K>
0867    iterator upper_bound(const K& x);
0868 
0869    //! <b>Requires</b>: This overload is available only if
0870    //! key_compare::is_transparent exists.
0871    //!
0872    //! <b>Returns</b>: A const iterator pointing to the first element with key
0873    //!   greater than x, or end() if such an element is not found.
0874    //!
0875    //! <b>Complexity</b>: Logarithmic
0876    template<typename K>
0877    const_iterator upper_bound(const K& x) const;
0878 
0879    #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0880 
0881    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
0882    //!
0883    //! <b>Complexity</b>: Logarithmic
0884    BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
0885    {  return this->base_t::lower_bound_range(x);  }
0886 
0887    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
0888    //!
0889    //! <b>Complexity</b>: Logarithmic
0890    BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
0891    {  return this->base_t::lower_bound_range(x);  }
0892 
0893    //! <b>Requires</b>: This overload is available only if
0894    //! key_compare::is_transparent exists.
0895    //!
0896    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
0897    //!
0898    //! <b>Complexity</b>: Logarithmic
0899    template<typename K>
0900    BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const K& x)
0901    {  return this->base_t::lower_bound_range(x);  }
0902 
0903    //! <b>Requires</b>: This overload is available only if
0904    //! key_compare::is_transparent exists.
0905    //!
0906    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
0907    //!
0908    //! <b>Complexity</b>: Logarithmic
0909    template<typename K>
0910    BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator,const_iterator> equal_range(const K& x) const
0911    {  return this->base_t::lower_bound_range(x);  }
0912 
0913    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0914 
0915    //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
0916    //!
0917    //! <b>Complexity</b>: Linear
0918    void rebalance();
0919 
0920    //! <b>Effects</b>: Returns true if x and y are equal
0921    //!
0922    //! <b>Complexity</b>: Linear to the number of elements in the container.
0923    friend bool operator==(const set& x, const set& y);
0924 
0925    //! <b>Effects</b>: Returns true if x and y are unequal
0926    //!
0927    //! <b>Complexity</b>: Linear to the number of elements in the container.
0928    friend bool operator!=(const set& x, const set& y);
0929 
0930    //! <b>Effects</b>: Returns true if x is less than y
0931    //!
0932    //! <b>Complexity</b>: Linear to the number of elements in the container.
0933    friend bool operator<(const set& x, const set& y);
0934 
0935    //! <b>Effects</b>: Returns true if x is greater than y
0936    //!
0937    //! <b>Complexity</b>: Linear to the number of elements in the container.
0938    friend bool operator>(const set& x, const set& y);
0939 
0940    //! <b>Effects</b>: Returns true if x is equal or less than y
0941    //!
0942    //! <b>Complexity</b>: Linear to the number of elements in the container.
0943    friend bool operator<=(const set& x, const set& y);
0944 
0945    //! <b>Effects</b>: Returns true if x is equal or greater than y
0946    //!
0947    //! <b>Complexity</b>: Linear to the number of elements in the container.
0948    friend bool operator>=(const set& x, const set& y);
0949 
0950    //! <b>Effects</b>: x.swap(y)
0951    //!
0952    //! <b>Complexity</b>: Constant.
0953    friend void swap(set& x, set& y)
0954       BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
0955                                  && boost::container::dtl::is_nothrow_swappable<Compare>::value );
0956 
0957    #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0958 };
0959 
0960 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
0961 
0962 template <typename InputIterator>
0963 set(InputIterator, InputIterator) ->
0964    set< it_based_value_type_t<InputIterator> >;
0965 
0966 template < typename InputIterator, typename AllocatorOrCompare>
0967     set(InputIterator, InputIterator, AllocatorOrCompare const&) ->
0968     set< it_based_value_type_t<InputIterator>
0969             , typename dtl::if_c< // Compare
0970                 dtl::is_allocator<AllocatorOrCompare>::value
0971                 , std::less<it_based_value_type_t<InputIterator>>
0972                 , AllocatorOrCompare
0973             >::type
0974             , typename dtl::if_c< // Allocator
0975                 dtl::is_allocator<AllocatorOrCompare>::value
0976                 , AllocatorOrCompare
0977                 , new_allocator<it_based_value_type_t<InputIterator>>
0978                 >::type
0979             >;
0980 
0981 template < typename InputIterator, typename Compare, typename Allocator
0982          , typename = dtl::require_nonallocator_t<Compare>
0983          , typename = dtl::require_allocator_t<Allocator>>
0984 set(InputIterator, InputIterator, Compare const&, Allocator const&) ->
0985    set< it_based_value_type_t<InputIterator>
0986            , Compare
0987            , Allocator>;
0988 
0989 template <typename InputIterator>
0990 set(ordered_unique_range_t, InputIterator, InputIterator) ->
0991    set< it_based_value_type_t<InputIterator>>;
0992 
0993 
0994 template < typename InputIterator, typename AllocatorOrCompare>
0995     set(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) ->
0996     set< it_based_value_type_t<InputIterator>
0997             , typename dtl::if_c< // Compare
0998                 dtl::is_allocator<AllocatorOrCompare>::value
0999                 , std::less<it_based_value_type_t<InputIterator>>
1000                 , AllocatorOrCompare
1001             >::type
1002             , typename dtl::if_c< // Allocator
1003                 dtl::is_allocator<AllocatorOrCompare>::value
1004                 , AllocatorOrCompare
1005                 , new_allocator<it_based_value_type_t<InputIterator>>
1006                 >::type
1007             >;
1008 
1009 template < typename InputIterator, typename Compare, typename Allocator
1010          , typename = dtl::require_nonallocator_t<Compare>
1011          , typename = dtl::require_allocator_t<Allocator>>
1012 set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
1013    set< it_based_value_type_t<InputIterator>
1014            , Compare
1015            , Allocator>;
1016 
1017 #endif
1018 
1019 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1020 
1021 }  //namespace container {
1022 
1023 //!has_trivial_destructor_after_move<> == true_type
1024 //!specialization for optimizations
1025 template <class Key, class Compare, class Allocator, class Options>
1026 struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> >
1027 {
1028    typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree;
1029    static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
1030 };
1031 
1032 namespace container {
1033 
1034 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1035 
1036 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1037 
1038 //! A multiset is a kind of associative container that supports equivalent keys
1039 //! (possibly contains multiple copies of the same key value) and provides for
1040 //! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
1041 //!
1042 //! A multiset satisfies all of the requirements of a container and of a reversible
1043 //! container, and of an associative container). multiset also provides most operations
1044 //! described for duplicate keys.
1045 //!
1046 //! \tparam Key is the type to be inserted in the set, which is also the key_type
1047 //! \tparam Compare is the comparison functor used to order keys
1048 //! \tparam Allocator is the allocator to be used to allocate memory for this container
1049 //! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
1050 template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
1051 #else
1052 template <class Key, class Compare, class Allocator, class Options>
1053 #endif
1054 class multiset
1055    /// @cond
1056    : public dtl::tree
1057       <Key, void, Compare, Allocator, Options>
1058    /// @endcond
1059 {
1060    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1061    private:
1062    BOOST_COPYABLE_AND_MOVABLE(multiset)
1063    typedef dtl::tree
1064       <Key, void, Compare, Allocator, Options> base_t;
1065    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1066 
1067    public:
1068 
1069    //////////////////////////////////////////////
1070    //
1071    //                    types
1072    //
1073    //////////////////////////////////////////////
1074    typedef Key                                                                            key_type;
1075    typedef Key                                                                            value_type;
1076    typedef Compare                                                                        key_compare;
1077    typedef key_compare                                                                    value_compare;
1078    typedef typename base_t::allocator_type                                                allocator_type;
1079    typedef ::boost::container::allocator_traits<allocator_type>                           allocator_traits_type;
1080    typedef typename ::boost::container::allocator_traits<allocator_type>::pointer         pointer;
1081    typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer   const_pointer;
1082    typedef typename ::boost::container::allocator_traits<allocator_type>::reference       reference;
1083    typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference;
1084    typedef typename ::boost::container::allocator_traits<allocator_type>::size_type       size_type;
1085    typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type;
1086    typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type)                 stored_allocator_type;
1087    typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator)                              iterator;
1088    typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator)                        const_iterator;
1089    typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator)                      reverse_iterator;
1090    typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator)                const_reverse_iterator;
1091    typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type)                             node_type;
1092 
1093    //////////////////////////////////////////////
1094    //
1095    //          construct/copy/destroy
1096    //
1097    //////////////////////////////////////////////
1098 
1099    //! @copydoc ::boost::container::set::set()
1100    BOOST_CONTAINER_FORCEINLINE multiset()
1101       BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value &&
1102                         dtl::is_nothrow_default_constructible<Compare>::value)
1103       : base_t()
1104    {}
1105 
1106    //! @copydoc ::boost::container::set::set(const allocator_type&)
1107    BOOST_CONTAINER_FORCEINLINE explicit multiset(const allocator_type& a)
1108       : base_t(a)
1109    {}
1110 
1111    //! @copydoc ::boost::container::set::set(const Compare&)
1112    BOOST_CONTAINER_FORCEINLINE explicit multiset(const Compare& comp)
1113       : base_t(comp)
1114    {}
1115 
1116    //! @copydoc ::boost::container::set::set(const Compare&, const allocator_type&)
1117    BOOST_CONTAINER_FORCEINLINE multiset(const Compare& comp, const allocator_type& a)
1118       : base_t(comp, a)
1119    {}
1120 
1121    //! @copydoc ::boost::container::set::set(InputIterator, InputIterator)
1122    template <class InputIterator>
1123    BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last)
1124       : base_t(false, first, last)
1125    {}
1126 
1127    //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const allocator_type&)
1128    template <class InputIterator>
1129    BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const allocator_type& a)
1130       : base_t(false, first, last, key_compare(), a)
1131    {}
1132 
1133    //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&)
1134    template <class InputIterator>
1135    BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp)
1136       : base_t(false, first, last, comp)
1137    {}
1138 
1139    //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&, const allocator_type&)
1140    template <class InputIterator>
1141    BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1142       : base_t(false, first, last, comp, a)
1143    {}
1144 
1145    //! <b>Effects</b>: Constructs an empty multiset and
1146    //! and inserts elements from the ordered range [first ,last ). This function
1147    //! is more efficient than the normal range creation for ordered ranges.
1148    //!
1149    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1150    //!
1151    //! <b>Complexity</b>: Linear in N.
1152    //!
1153    //! <b>Note</b>: Non-standard extension.
1154    template <class InputIterator>
1155    BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last )
1156       : base_t(ordered_range, first, last)
1157    {}
1158 
1159    //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
1160    //! inserts elements from the ordered range [first ,last ). This function
1161    //! is more efficient than the normal range creation for ordered ranges.
1162    //!
1163    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1164    //!
1165    //! <b>Complexity</b>: Linear in N.
1166    //!
1167    //! <b>Note</b>: Non-standard extension.
1168    template <class InputIterator>
1169    BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
1170       : base_t(ordered_range, first, last, comp)
1171    {}
1172 
1173    //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
1174    //! allocator, and inserts elements from the ordered range [first ,last ). This function
1175    //! is more efficient than the normal range creation for ordered ranges.
1176    //!
1177    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1178    //!
1179    //! <b>Complexity</b>: Linear in N.
1180    //!
1181    //! <b>Note</b>: Non-standard extension.
1182    template <class InputIterator>
1183    BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1184       : base_t(ordered_range, first, last, comp, a)
1185    {}
1186 
1187    //! <b>Effects</b>: Constructs an empty multiset using the specified allocator and
1188    //! inserts elements from the ordered range [first ,last ). This function
1189    //! is more efficient than the normal range creation for ordered ranges.
1190    //!
1191    //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
1192    //!
1193    //! <b>Complexity</b>: Linear in N.
1194    //!
1195    //! <b>Note</b>: Non-standard extension.
1196    template <class InputIterator>
1197    BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a)
1198       : base_t(ordered_range, first, last, Compare(), a)
1199    {}
1200 
1201 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1202    //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>)
1203    BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il)
1204       : base_t(false, il.begin(), il.end())
1205    {}
1206 
1207    //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const allocator_type&)
1208    BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const allocator_type& a)
1209       : base_t(false, il.begin(), il.end(), Compare(), a)
1210    {}
1211 
1212    //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare&)
1213    BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp)
1214       : base_t(false, il.begin(), il.end(), comp)
1215    {}
1216 
1217    //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare&, const allocator_type&)
1218    BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
1219       : base_t(false, il.begin(), il.end(), comp, a)
1220    {}
1221 
1222    //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>)
1223    BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il)
1224       : base_t(ordered_range, il.begin(), il.end())
1225    {}
1226 
1227    //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare&)
1228    BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
1229       : base_t(ordered_range, il.begin(), il.end(), comp)
1230    {}
1231 
1232    //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare&, const allocator_type&)
1233    BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
1234       : base_t(ordered_range, il.begin(), il.end(), comp, a)
1235    {}
1236 #endif
1237 
1238    //! @copydoc ::boost::container::set::set(const set &)
1239    BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x)
1240       : base_t(static_cast<const base_t&>(x))
1241    {}
1242 
1243    //! @copydoc ::boost::container::set::set(set &&)
1244    BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x)
1245       BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
1246       : base_t(BOOST_MOVE_BASE(base_t, x))
1247    {}
1248 
1249    //! @copydoc ::boost::container::set::set(const set &, const allocator_type &)
1250    BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x, const allocator_type &a)
1251       : base_t(static_cast<const base_t&>(x), a)
1252    {}
1253 
1254    //! @copydoc ::boost::container::set::set(set &&, const allocator_type &)
1255    BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
1256       : base_t(BOOST_MOVE_BASE(base_t, x), a)
1257    {}
1258 
1259    //! @copydoc ::boost::container::set::operator=(const set &)
1260    BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
1261    {  return static_cast<multiset&>(this->base_t::operator=(static_cast<const base_t&>(x)));  }
1262 
1263    //! @copydoc ::boost::container::set::operator=(set &&)
1264    BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_RV_REF(multiset) x)
1265       BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
1266                           allocator_traits_type::is_always_equal::value) &&
1267                            boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
1268    {  return static_cast<multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x)));  }
1269 
1270 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1271    //! @copydoc ::boost::container::set::operator=(std::initializer_list<value_type>)
1272    multiset& operator=(std::initializer_list<value_type> il)
1273    {
1274        this->clear();
1275        insert(il.begin(), il.end());
1276        return *this;
1277    }
1278 #endif
1279    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1280 
1281    //! @copydoc ::boost::container::set::get_allocator()
1282    allocator_type get_allocator() const;
1283 
1284    //! @copydoc ::boost::container::set::get_stored_allocator()
1285    stored_allocator_type &get_stored_allocator();
1286 
1287    //! @copydoc ::boost::container::set::get_stored_allocator() const
1288    const stored_allocator_type &get_stored_allocator() const;
1289 
1290    //! @copydoc ::boost::container::set::begin()
1291    iterator begin();
1292 
1293    //! @copydoc ::boost::container::set::begin() const
1294    const_iterator begin() const;
1295 
1296    //! @copydoc ::boost::container::set::cbegin() const
1297    const_iterator cbegin() const;
1298 
1299    //! @copydoc ::boost::container::set::end()
1300    iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
1301 
1302    //! @copydoc ::boost::container::set::end() const
1303    const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
1304 
1305    //! @copydoc ::boost::container::set::cend() const
1306    const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
1307 
1308    //! @copydoc ::boost::container::set::rbegin()
1309    reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
1310 
1311    //! @copydoc ::boost::container::set::rbegin() const
1312    const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1313 
1314    //! @copydoc ::boost::container::set::crbegin() const
1315    const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1316 
1317    //! @copydoc ::boost::container::set::rend()
1318    reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
1319 
1320    //! @copydoc ::boost::container::set::rend() const
1321    const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
1322 
1323    //! @copydoc ::boost::container::set::crend() const
1324    const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
1325 
1326    //! @copydoc ::boost::container::set::empty() const
1327    bool empty() const;
1328 
1329    //! @copydoc ::boost::container::set::size() const
1330    size_type size() const;
1331 
1332    //! @copydoc ::boost::container::set::max_size() const
1333    size_type max_size() const;
1334 
1335    #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1336 
1337    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1338 
1339    //! <b>Effects</b>: Inserts an object of type Key constructed with
1340    //!   std::forward<Args>(args)... and returns the iterator pointing to the
1341    //!   newly inserted element.
1342    //!
1343    //! <b>Complexity</b>: Logarithmic.
1344    template <class... Args>
1345    BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
1346    {  return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
1347 
1348    //! <b>Effects</b>: Inserts an object of type Key constructed with
1349    //!   std::forward<Args>(args)...
1350    //!
1351    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1352    //!   to the key of x.
1353    //!
1354    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1355    //!   is inserted right before p.
1356    template <class... Args>
1357    BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
1358    {  return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
1359 
1360    #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1361 
1362    #define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \
1363    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1364    BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
1365    {  return this->base_t::emplace_equal(BOOST_MOVE_FWD##N);  }\
1366    \
1367    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1368    BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1369    {  return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
1370    //
1371    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE)
1372    #undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE
1373 
1374    #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1375 
1376    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1377    //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
1378    //!   newly inserted element.
1379    //!
1380    //! <b>Complexity</b>: Logarithmic.
1381    iterator insert(const value_type &x);
1382 
1383    //! <b>Effects</b>: Inserts a copy of x in the container.
1384    //!
1385    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1386    //!   to the key of x.
1387    //!
1388    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1389    //!   is inserted right before p.
1390    iterator insert(value_type &&x);
1391    #else
1392    BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->base_t::insert_equal_convertible)
1393    #endif
1394 
1395    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1396    //! <b>Effects</b>: Inserts a copy of x in the container.
1397    //!   p is a hint pointing to where the insert should start to search.
1398    //!
1399    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1400    //!   to the key of x.
1401    //!
1402    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1403    //!   is inserted right before p.
1404    iterator insert(const_iterator p, const value_type &x);
1405 
1406    //! <b>Effects</b>: Inserts a value move constructed from x in the container.
1407    //!   p is a hint pointing to where the insert should start to search.
1408    //!
1409    //! <b>Returns</b>: An iterator pointing to the element with key equivalent
1410    //!   to the key of x.
1411    //!
1412    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
1413    //!   is inserted right before p.
1414    iterator insert(const_iterator p, value_type &&x);
1415    #else
1416    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG
1417       (insert, value_type, iterator, this->base_t::insert_equal_hint_convertible, const_iterator, const_iterator)
1418    #endif
1419 
1420    //! <b>Requires</b>: first, last are not iterators into *this.
1421    //!
1422    //! <b>Effects</b>: inserts each element from the range [first,last) .
1423    //!
1424    //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
1425    template <class InputIterator>
1426    BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
1427    {  this->base_t::insert_equal_range(first, last);  }
1428 
1429 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1430    //! @copydoc ::boost::container::set::insert(std::initializer_list<value_type>)
1431    BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
1432    {  this->base_t::insert_equal_range(il.begin(), il.end());  }
1433 #endif
1434 
1435    //! @copydoc ::boost::container::multimap::insert(node_type&&)
1436    BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
1437    {  return this->base_t::insert_equal_node(boost::move(nh));  }
1438 
1439    //! @copydoc ::boost::container::multimap::insert(const_iterator, node_type&&)
1440    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
1441    {  return this->base_t::insert_equal_node(hint, boost::move(nh));  }
1442 
1443    //! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
1444    template<class C2>
1445    BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
1446    {
1447       typedef dtl::tree
1448          <Key, void, C2, Allocator, Options> base2_t;
1449       this->base_t::merge_equal(static_cast<base2_t&>(source));
1450    }
1451 
1452    //! @copydoc ::boost::container::multiset::merge(multiset<Key, C2, Allocator, Options>&)
1453    template<class C2>
1454    BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
1455    {  return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source));   }
1456 
1457    //! @copydoc ::boost::container::multimap::merge(map<Key, T, C2, Allocator, Options>&)
1458    template<class C2>
1459    BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
1460    {
1461       typedef dtl::tree
1462          <Key, void, C2, Allocator, Options> base2_t;
1463       this->base_t::merge_equal(static_cast<base2_t&>(source));
1464    }
1465 
1466    //! @copydoc ::boost::container::multiset::merge(set<Key, C2, Allocator, Options>&)
1467    template<class C2>
1468    BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
1469    {  return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source));   }
1470 
1471    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1472 
1473    //! @copydoc ::boost::container::set::erase(const_iterator)
1474    iterator erase(const_iterator p);
1475 
1476    //! @copydoc ::boost::container::set::erase(const key_type&)
1477    size_type erase(const key_type& x);
1478 
1479    //! @copydoc ::boost::container::set::erase(const_iterator,const_iterator)
1480    iterator erase(const_iterator first, const_iterator last);
1481 
1482    //! @copydoc ::boost::container::multimap::extract(const_iterator)
1483    node_type extract(const_iterator p);
1484 
1485    //! @copydoc ::boost::container::multimap::extract(const key_type&)
1486    node_type extract(const key_type& x);
1487 
1488    //! @copydoc ::boost::container::set::swap
1489    void swap(multiset& x)
1490       BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
1491                                  && boost::container::dtl::is_nothrow_swappable<Compare>::value );
1492 
1493    //! @copydoc ::boost::container::set::clear
1494    void clear() BOOST_NOEXCEPT_OR_NOTHROW;
1495 
1496    //! @copydoc ::boost::container::set::key_comp
1497    key_compare key_comp() const;
1498 
1499    //! @copydoc ::boost::container::set::value_comp
1500    value_compare value_comp() const;
1501 
1502    //! @copydoc ::boost::container::set::find(const key_type& )
1503    iterator find(const key_type& x);
1504 
1505    //! @copydoc ::boost::container::set::find(const key_type& ) const
1506    const_iterator find(const key_type& x) const;
1507 
1508    //! @copydoc ::boost::container::set::find(const K& )
1509    template<typename K>
1510    iterator find(const K& x);
1511 
1512    //! @copydoc ::boost::container::set::find(const K& )
1513    template<typename K>
1514    const_iterator find(const K& x) const;
1515 
1516    //! @copydoc ::boost::container::set::count(const key_type& ) const
1517    size_type count(const key_type& x) const;
1518 
1519    //! @copydoc ::boost::container::set::count(const K& ) const
1520    template<typename K>
1521    size_type count(const K& x) const;
1522 
1523    //! @copydoc ::boost::container::set::contains(const key_type& ) const
1524    bool contains(const key_type& x) const;
1525 
1526    //! @copydoc ::boost::container::set::contains(const K& ) const
1527    template<typename K>
1528    bool contains(const K& x) const;
1529 
1530    //! @copydoc ::boost::container::set::lower_bound(const key_type& )
1531    iterator lower_bound(const key_type& x);
1532 
1533    //! @copydoc ::boost::container::set::lower_bound(const key_type& ) const
1534    const_iterator lower_bound(const key_type& x) const;
1535 
1536    //! @copydoc ::boost::container::set::lower_bound(const K& )
1537    template<typename K>
1538    iterator lower_bound(const K& x);
1539 
1540    //! @copydoc ::boost::container::set::lower_bound(const K& ) const
1541    template<typename K>
1542    const_iterator lower_bound(const K& x) const;
1543 
1544    //! @copydoc ::boost::container::set::upper_bound(const key_type& )
1545    iterator upper_bound(const key_type& x);
1546 
1547    //! @copydoc ::boost::container::set::upper_bound(const key_type& ) const
1548    const_iterator upper_bound(const key_type& x) const;
1549 
1550    //! @copydoc ::boost::container::set::upper_bound(const K& )
1551    template<typename K>
1552    iterator upper_bound(const K& x);
1553 
1554    //! @copydoc ::boost::container::set::upper_bound(const K& ) const
1555    template<typename K>
1556    const_iterator upper_bound(const K& x) const;
1557 
1558    //! @copydoc ::boost::container::set::equal_range(const key_type& ) const
1559    std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
1560 
1561    //! @copydoc ::boost::container::set::equal_range(const key_type& )
1562    std::pair<iterator,iterator> equal_range(const key_type& x);
1563 
1564    //! @copydoc ::boost::container::set::equal_range(const K& ) const
1565    template<typename K>
1566    std::pair<const_iterator, const_iterator> equal_range(const K& x) const;
1567 
1568    //! @copydoc ::boost::container::set::equal_range(const K& )
1569    template<typename K>
1570    std::pair<iterator,iterator> equal_range(const K& x);
1571 
1572    //! @copydoc ::boost::container::set::rebalance()
1573    void rebalance();
1574 
1575    //! <b>Effects</b>: Returns true if x and y are equal
1576    //!
1577    //! <b>Complexity</b>: Linear to the number of elements in the container.
1578    friend bool operator==(const multiset& x, const multiset& y);
1579 
1580    //! <b>Effects</b>: Returns true if x and y are unequal
1581    //!
1582    //! <b>Complexity</b>: Linear to the number of elements in the container.
1583    friend bool operator!=(const multiset& x, const multiset& y);
1584 
1585    //! <b>Effects</b>: Returns true if x is less than y
1586    //!
1587    //! <b>Complexity</b>: Linear to the number of elements in the container.
1588    friend bool operator<(const multiset& x, const multiset& y);
1589 
1590    //! <b>Effects</b>: Returns true if x is greater than y
1591    //!
1592    //! <b>Complexity</b>: Linear to the number of elements in the container.
1593    friend bool operator>(const multiset& x, const multiset& y);
1594 
1595    //! <b>Effects</b>: Returns true if x is equal or less than y
1596    //!
1597    //! <b>Complexity</b>: Linear to the number of elements in the container.
1598    friend bool operator<=(const multiset& x, const multiset& y);
1599 
1600    //! <b>Effects</b>: Returns true if x is equal or greater than y
1601    //!
1602    //! <b>Complexity</b>: Linear to the number of elements in the container.
1603    friend bool operator>=(const multiset& x, const multiset& y);
1604 
1605    //! <b>Effects</b>: x.swap(y)
1606    //!
1607    //! <b>Complexity</b>: Constant.
1608    friend void swap(multiset& x, multiset& y)
1609       BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
1610                                  && boost::container::dtl::is_nothrow_swappable<Compare>::value );
1611 
1612    #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1613 };
1614 
1615 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
1616 
1617 template <typename InputIterator>
1618 multiset(InputIterator, InputIterator) ->
1619    multiset< it_based_value_type_t<InputIterator> >;
1620 
1621 
1622 template < typename InputIterator, typename AllocatorOrCompare>
1623 multiset(InputIterator, InputIterator, AllocatorOrCompare const&) ->
1624     multiset < it_based_value_type_t<InputIterator>
1625                   , typename dtl::if_c< // Compare
1626                       dtl::is_allocator<AllocatorOrCompare>::value
1627                       , std::less<it_based_value_type_t<InputIterator>>
1628                       , AllocatorOrCompare
1629                   >::type
1630                   , typename dtl::if_c< // Allocator
1631                       dtl::is_allocator<AllocatorOrCompare>::value
1632                       , AllocatorOrCompare
1633                       , new_allocator<it_based_value_type_t<InputIterator>>
1634                       >::type
1635                   >;
1636 
1637 template < typename InputIterator, typename Compare, typename Allocator
1638          , typename = dtl::require_nonallocator_t<Compare>
1639          , typename = dtl::require_allocator_t<Allocator>>
1640 multiset(InputIterator, InputIterator, Compare const&, Allocator const&) ->
1641    multiset< it_based_value_type_t<InputIterator>
1642            , Compare
1643            , Allocator>;
1644 
1645 template <typename InputIterator>
1646 multiset(ordered_range_t, InputIterator, InputIterator) ->
1647    multiset< it_based_value_type_t<InputIterator>>;
1648 
1649 template < typename InputIterator, typename AllocatorOrCompare>
1650 multiset(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) ->
1651     multiset < it_based_value_type_t<InputIterator>
1652                   , typename dtl::if_c< // Compare
1653                       dtl::is_allocator<AllocatorOrCompare>::value
1654                       , std::less<it_based_value_type_t<InputIterator>>
1655                       , AllocatorOrCompare
1656                   >::type
1657                   , typename dtl::if_c< // Allocator
1658                       dtl::is_allocator<AllocatorOrCompare>::value
1659                       , AllocatorOrCompare
1660                       , new_allocator<it_based_value_type_t<InputIterator>>
1661                       >::type
1662                   >;
1663 
1664 template < typename InputIterator, typename Compare, typename Allocator
1665          , typename = dtl::require_nonallocator_t<Compare>
1666          , typename = dtl::require_allocator_t<Allocator>>
1667 multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
1668    multiset< it_based_value_type_t<InputIterator>
1669            , Compare
1670            , Allocator>;
1671 
1672 #endif
1673 
1674 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1675 
1676 }  //namespace container {
1677 
1678 //!has_trivial_destructor_after_move<> == true_type
1679 //!specialization for optimizations
1680 template <class Key, class Compare, class Allocator, class Options>
1681 struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> >
1682 {
1683    typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree;
1684    static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
1685 };
1686 
1687 namespace container {
1688 
1689 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1690 
1691 }}
1692 
1693 #include <boost/container/detail/config_end.hpp>
1694 
1695 #endif   // BOOST_CONTAINER_SET_HPP