Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:47

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Olaf Krzikalla 2004-2006.
0004 // (C) Copyright Ion Gaztanaga  2006-2014
0005 //
0006 // Distributed under the Boost Software License, Version 1.0.
0007 //    (See accompanying file LICENSE_1_0.txt or copy at
0008 //          http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 // See http://www.boost.org/libs/intrusive for documentation.
0011 //
0012 /////////////////////////////////////////////////////////////////////////////
0013 #ifndef BOOST_INTRUSIVE_UNORDERED_SET_HPP
0014 #define BOOST_INTRUSIVE_UNORDERED_SET_HPP
0015 
0016 #include <boost/intrusive/detail/config_begin.hpp>
0017 #include <boost/intrusive/intrusive_fwd.hpp>
0018 #include <boost/intrusive/hashtable.hpp>
0019 #include <boost/move/utility_core.hpp>
0020 #include <boost/static_assert.hpp>
0021 
0022 #if defined(BOOST_HAS_PRAGMA_ONCE)
0023 #  pragma once
0024 #endif
0025 
0026 namespace boost {
0027 namespace intrusive {
0028 
0029 //! The class template unordered_set is an intrusive container, that mimics most of
0030 //! the interface of std::tr1::unordered_set as described in the C++ TR1.
0031 //!
0032 //! unordered_set is a semi-intrusive container: each object to be stored in the
0033 //! container must contain a proper hook, but the container also needs
0034 //! additional auxiliary memory to work: unordered_set needs a pointer to an array
0035 //! of type `bucket_type` to be passed in the constructor. This bucket array must
0036 //! have at least the same lifetime as the container. This makes the use of
0037 //! unordered_set more complicated than purely intrusive containers.
0038 //! `bucket_type` is default-constructible, copyable and assignable
0039 //!
0040 //! The template parameter \c T is the type to be managed by the container.
0041 //! The user can specify additional options and if no options are provided
0042 //! default options are used.
0043 //!
0044 //! The container supports the following options:
0045 //! \c base_hook<>/member_hook<>/value_traits<>,
0046 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
0047 //! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
0048 //!
0049 //! unordered_set only provides forward iterators but it provides 4 iterator types:
0050 //! iterator and const_iterator to navigate through the whole container and
0051 //! local_iterator and const_local_iterator to navigate through the values
0052 //! stored in a single bucket. Local iterators are faster and smaller.
0053 //!
0054 //! It's not recommended to use non constant-time size unordered_sets because several
0055 //! key functions, like "empty()", become non-constant time functions. Non
0056 //! constant-time size unordered_sets are mainly provided to support auto-unlink hooks.
0057 //!
0058 //! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor
0059 //! offers functions related to a load factor. Rehashing can be explicitly requested
0060 //! and the user must provide a new bucket array that will be used from that moment.
0061 //!
0062 //! Since no automatic rehashing is done, iterators are never invalidated when
0063 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
0064 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0065 template<class T, class ...Options>
0066 #else
0067 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
0068 #endif
0069 class unordered_set_impl
0070    #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0071    : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos>
0072    #endif
0073 {
0074    /// @cond
0075    private:
0076    typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos> table_type;
0077 
0078    template<class Iterator, class MaybeConstThis, class KeyType, class KeyHasher, class KeyEqual>
0079    static std::pair<Iterator,Iterator> priv_equal_range(MaybeConstThis &c, const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
0080    {
0081       Iterator const it = c.find(key, hash_func, equal_func);
0082       std::pair<Iterator,Iterator> ret(it, it);      
0083       if(it != c.end())
0084          ++ret.second;
0085       return ret;
0086    }
0087 
0088    //! This class is
0089    //! movable
0090    BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set_impl)
0091 
0092    typedef table_type implementation_defined;
0093    /// @endcond
0094 
0095    public:
0096    typedef typename implementation_defined::value_type                  value_type;
0097    typedef typename implementation_defined::key_type                    key_type;
0098    typedef typename implementation_defined::key_of_value                key_of_value;
0099    typedef typename implementation_defined::value_traits                value_traits;
0100    typedef typename implementation_defined::bucket_traits               bucket_traits;
0101    typedef typename implementation_defined::pointer                     pointer;
0102    typedef typename implementation_defined::const_pointer               const_pointer;
0103    typedef typename implementation_defined::reference                   reference;
0104    typedef typename implementation_defined::const_reference             const_reference;
0105    typedef typename implementation_defined::difference_type             difference_type;
0106    typedef typename implementation_defined::size_type                   size_type;
0107    typedef typename implementation_defined::key_equal                   key_equal;
0108    typedef typename implementation_defined::hasher                      hasher;
0109    typedef typename implementation_defined::bucket_type                 bucket_type;
0110    typedef typename implementation_defined::bucket_ptr                  bucket_ptr;
0111    typedef typename implementation_defined::iterator                    iterator;
0112    typedef typename implementation_defined::const_iterator              const_iterator;
0113    typedef typename implementation_defined::insert_commit_data          insert_commit_data;
0114    typedef typename implementation_defined::local_iterator              local_iterator;
0115    typedef typename implementation_defined::const_local_iterator        const_local_iterator;
0116    typedef typename implementation_defined::node_traits                 node_traits;
0117    typedef typename implementation_defined::node                        node;
0118    typedef typename implementation_defined::node_ptr                    node_ptr;
0119    typedef typename implementation_defined::const_node_ptr              const_node_ptr;
0120 
0121    public:
0122 
0123    //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
0124    BOOST_INTRUSIVE_FORCEINLINE explicit unordered_set_impl( const bucket_traits &b_traits
0125                               , const hasher & hash_func = hasher()
0126                               , const key_equal &equal_func = key_equal()
0127                               , const value_traits &v_traits = value_traits())
0128       :  table_type(b_traits, hash_func, equal_func, v_traits)
0129    {}
0130 
0131    //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
0132    template<class Iterator>
0133    BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl( Iterator b
0134                      , Iterator e
0135                      , const bucket_traits &b_traits
0136                      , const hasher & hash_func = hasher()
0137                      , const key_equal &equal_func = key_equal()
0138                      , const value_traits &v_traits = value_traits())
0139       :  table_type(true, b, e, b_traits, hash_func, equal_func, v_traits)
0140    {}
0141 
0142    //! @copydoc ::boost::intrusive::hashtable::hashtable(hashtable&&)
0143    BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x)
0144       :  table_type(BOOST_MOVE_BASE(table_type, x))
0145    {}
0146 
0147    //! @copydoc ::boost::intrusive::hashtable::operator=(hashtable&&)
0148    BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x)
0149    {  return static_cast<unordered_set_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
0150 
0151    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0152    //! @copydoc ::boost::intrusive::hashtable::~hashtable()
0153    ~unordered_set_impl();
0154 
0155    //! @copydoc ::boost::intrusive::hashtable::begin()
0156    iterator begin() BOOST_NOEXCEPT;
0157 
0158    //! @copydoc ::boost::intrusive::hashtable::begin()const
0159    const_iterator begin() const BOOST_NOEXCEPT;
0160 
0161    //! @copydoc ::boost::intrusive::hashtable::cbegin()const
0162    const_iterator cbegin() const BOOST_NOEXCEPT;
0163 
0164    //! @copydoc ::boost::intrusive::hashtable::end()
0165    iterator end() BOOST_NOEXCEPT;
0166 
0167    //! @copydoc ::boost::intrusive::hashtable::end()const
0168    const_iterator end() const BOOST_NOEXCEPT;
0169 
0170    //! @copydoc ::boost::intrusive::hashtable::cend()const
0171    const_iterator cend() const BOOST_NOEXCEPT;
0172 
0173    //! @copydoc ::boost::intrusive::hashtable::hash_function()const
0174    hasher hash_function() const;
0175 
0176    //! @copydoc ::boost::intrusive::hashtable::key_eq()const
0177    key_equal key_eq() const;
0178 
0179    //! @copydoc ::boost::intrusive::hashtable::empty()const
0180    bool empty() const BOOST_NOEXCEPT;
0181 
0182    //! @copydoc ::boost::intrusive::hashtable::size()const
0183    size_type size() const BOOST_NOEXCEPT;
0184 
0185    //! @copydoc ::boost::intrusive::hashtable::hashtable
0186    void swap(unordered_set_impl& other);
0187 
0188    //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
0189    template <class Cloner, class Disposer>
0190    void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer);
0191 
0192    #else
0193 
0194    using table_type::clone_from;
0195 
0196    #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0197 
0198    //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
0199    template <class Cloner, class Disposer>
0200    BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set_impl) src, Cloner cloner, Disposer disposer)
0201    {  table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer);  }
0202 
0203    //! @copydoc ::boost::intrusive::hashtable::insert_unique(reference)
0204    BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert(reference value)
0205    {  return table_type::insert_unique(value);  }
0206 
0207    //! @copydoc ::boost::intrusive::hashtable::insert_unique(Iterator,Iterator)
0208    template<class Iterator>
0209    BOOST_INTRUSIVE_FORCEINLINE void insert(Iterator b, Iterator e)
0210    {  table_type::insert_unique(b, e);  }
0211 
0212    //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const key_type&,insert_commit_data&)
0213    BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert_check(const key_type &key, insert_commit_data &commit_data)
0214    {  return table_type::insert_unique_check(key, commit_data); }
0215 
0216    //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const KeyType&,KeyHasher,KeyEqual,insert_commit_data&)
0217    template<class KeyType, class KeyHasher, class KeyEqual>
0218    BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert_check
0219       (const KeyType &key, KeyHasher hash_func, KeyEqual key_value_equal, insert_commit_data &commit_data)
0220    {  return table_type::insert_unique_check(key, hash_func, key_value_equal, commit_data); }
0221 
0222    //! @copydoc ::boost::intrusive::hashtable::insert_unique_commit
0223    BOOST_INTRUSIVE_FORCEINLINE iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
0224    {  return table_type::insert_unique_commit(value, commit_data); }
0225 
0226    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0227 
0228    //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
0229    void erase(const_iterator i);
0230 
0231    //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
0232    void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
0233 
0234    //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
0235    size_type erase(const key_type &key);
0236 
0237    //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
0238    template<class KeyType, class KeyHasher, class KeyEqual>
0239    size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
0240 
0241    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
0242    template<class Disposer>
0243    BOOST_INTRUSIVE_DOC1ST(void
0244       , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
0245       erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
0246 
0247    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
0248    template<class Disposer>
0249    void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
0250 
0251    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
0252    template<class Disposer>
0253    size_type erase_and_dispose(const key_type &key, Disposer disposer);
0254 
0255    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
0256    template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
0257    size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
0258 
0259    //! @copydoc ::boost::intrusive::hashtable::clear
0260    void clear() BOOST_NOEXCEPT;
0261 
0262    //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
0263    template<class Disposer>
0264    void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
0265 
0266    //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
0267    size_type count(const key_type &key) const;
0268 
0269    //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
0270    template<class KeyType, class KeyHasher, class KeyEqual>
0271    size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
0272 
0273    //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
0274    iterator find(const key_type &key);
0275 
0276    //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
0277    template<class KeyType, class KeyHasher, class KeyEqual>
0278    iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
0279 
0280    //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
0281    const_iterator find(const key_type &key) const;
0282 
0283    //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
0284    template<class KeyType, class KeyHasher, class KeyEqual>
0285    const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
0286    #endif
0287 
0288    //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
0289    std::pair<iterator,iterator> equal_range(const key_type &key)
0290    {  return this->equal_range(key, this->hash_function(), this->key_eq());  }
0291 
0292    //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
0293    template<class KeyType, class KeyHasher, class KeyEqual>
0294    std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
0295    {  return this->priv_equal_range<iterator>(*this, key, hash_func, equal_func); }
0296 
0297    //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
0298    std::pair<const_iterator, const_iterator>
0299       equal_range(const key_type &key) const
0300    {  return this->equal_range(key, this->hash_function(), this->key_eq());  }
0301 
0302    //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
0303    template<class KeyType, class KeyHasher, class KeyEqual>
0304    std::pair<const_iterator, const_iterator>
0305       equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const
0306    {  return this->priv_equal_range<const_iterator>(*this, key, hash_func, equal_func); }
0307 
0308    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0309    //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
0310    iterator iterator_to(reference value) BOOST_NOEXCEPT;
0311 
0312    //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
0313    const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
0314 
0315    //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
0316    static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT;
0317 
0318    //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
0319    static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT;
0320 
0321    //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
0322    local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT;
0323 
0324    //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
0325    const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT;
0326 
0327    //! @copydoc ::boost::intrusive::hashtable::bucket_count
0328    size_type bucket_count() const BOOST_NOEXCEPT;
0329 
0330    //! @copydoc ::boost::intrusive::hashtable::bucket_size
0331    size_type bucket_size(size_type n) const BOOST_NOEXCEPT;
0332 
0333    //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
0334    size_type bucket(const key_type& k) const;
0335 
0336    //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
0337    template<class KeyType, class KeyHasher>
0338    size_type bucket(const KeyType& k,  KeyHasher hash_func) const;
0339 
0340    //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
0341    bucket_ptr bucket_pointer() const BOOST_NOEXCEPT;
0342 
0343    //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
0344    local_iterator begin(size_type n) BOOST_NOEXCEPT;
0345 
0346    //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
0347    const_local_iterator begin(size_type n) const BOOST_NOEXCEPT;
0348 
0349    //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
0350    const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT;
0351 
0352    //! @copydoc ::boost::intrusive::hashtable::end(size_type)
0353    local_iterator end(size_type n) BOOST_NOEXCEPT;
0354 
0355    //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
0356    const_local_iterator end(size_type n) const BOOST_NOEXCEPT;
0357 
0358    //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
0359    const_local_iterator cend(size_type n) const BOOST_NOEXCEPT;
0360 
0361    //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
0362    void rehash(const bucket_traits &new_bucket_traits);
0363 
0364    //! @copydoc ::boost::intrusive::hashtable::full_rehash
0365    void full_rehash();
0366 
0367    //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
0368    bool incremental_rehash(bool grow = true);
0369 
0370    //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
0371    bool incremental_rehash(const bucket_traits &new_bucket_traits);
0372 
0373    //! @copydoc ::boost::intrusive::hashtable::split_count
0374    size_type split_count() const BOOST_NOEXCEPT;
0375 
0376    //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
0377    static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT;
0378 
0379    //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
0380    static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT;
0381 
0382    #endif   //   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0383 
0384    friend bool operator==(const unordered_set_impl &x, const unordered_set_impl &y)
0385    {
0386       if(table_type::constant_time_size && x.size() != y.size()){
0387          return false;
0388       }
0389       //Find each element of x in y
0390       for (const_iterator ix = x.cbegin(), ex = x.cend(), ey = y.cend(); ix != ex; ++ix){
0391          const_iterator iy = y.find(key_of_value()(*ix));
0392          if (iy == ey || !(*ix == *iy))
0393             return false;
0394       }
0395       return true;
0396    }
0397 
0398    friend bool operator!=(const unordered_set_impl &x, const unordered_set_impl &y)
0399    {  return !(x == y); }
0400 
0401    friend bool operator<(const unordered_set_impl &x, const unordered_set_impl &y)
0402    {  return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
0403 
0404    friend bool operator>(const unordered_set_impl &x, const unordered_set_impl &y)
0405    {  return y < x;  }
0406 
0407    friend bool operator<=(const unordered_set_impl &x, const unordered_set_impl &y)
0408    {  return !(y < x);  }
0409 
0410    friend bool operator>=(const unordered_set_impl &x, const unordered_set_impl &y)
0411    {  return !(x < y);  }
0412 };
0413 
0414 //! Helper metafunction to define an \c unordered_set that yields to the same type when the
0415 //! same options (either explicitly or implicitly) are used.
0416 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0417 template<class T, class ...Options>
0418 #else
0419 template<class T, class O1 = void, class O2 = void
0420                 , class O3 = void, class O4 = void
0421                 , class O5 = void, class O6 = void
0422                 , class O7 = void, class O8 = void
0423                 , class O9 = void, class O10= void
0424                 , class O11 = void
0425                 >
0426 #endif
0427 struct make_unordered_set
0428 {
0429    /// @cond
0430    typedef typename pack_options
0431       < hashtable_defaults,
0432          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0433          O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11
0434          #else
0435          Options...
0436          #endif
0437       >::type packed_options;
0438 
0439    typedef typename detail::get_value_traits
0440       <T, typename packed_options::proto_value_traits>::type value_traits;
0441 
0442    typedef typename make_bucket_traits
0443             <T, packed_options>::type bucket_traits;
0444 
0445    typedef unordered_set_impl
0446       < value_traits
0447       , typename packed_options::key_of_value
0448       , typename packed_options::hash
0449       , typename packed_options::equal
0450       , typename packed_options::size_type
0451       , bucket_traits
0452       ,  (std::size_t(true)*hash_bool_flags::unique_keys_pos)
0453       |  (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
0454       |  (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
0455       |  (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
0456       |  (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
0457       |  (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
0458       |  (std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos)
0459       |  (std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos)
0460       > implementation_defined;
0461 
0462    /// @endcond
0463    typedef implementation_defined type;
0464 };
0465 
0466 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0467 
0468 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0469 template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10, class O11>
0470 #else
0471 template<class T, class ...Options>
0472 #endif
0473 class unordered_set
0474    :  public make_unordered_set<T,
0475          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0476          O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11
0477          #else
0478          Options...
0479          #endif
0480       >::type
0481 {
0482    typedef typename make_unordered_set<T,
0483          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0484          O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11
0485          #else
0486          Options...
0487          #endif
0488       >::type Base;
0489 
0490    //Assert if passed value traits are compatible with the type
0491    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
0492    BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set)
0493 
0494    public:
0495    typedef typename Base::value_traits       value_traits;
0496    typedef typename Base::bucket_traits      bucket_traits;
0497    typedef typename Base::iterator           iterator;
0498    typedef typename Base::const_iterator     const_iterator;
0499    typedef typename Base::bucket_ptr         bucket_ptr;
0500    typedef typename Base::size_type          size_type;
0501    typedef typename Base::hasher             hasher;
0502    typedef typename Base::key_equal          key_equal;
0503 
0504    BOOST_INTRUSIVE_FORCEINLINE
0505    explicit unordered_set  ( const bucket_traits &b_traits
0506                            , const hasher & hash_func = hasher()
0507                            , const key_equal &equal_func = key_equal()
0508                            , const value_traits &v_traits = value_traits())
0509       :  Base(b_traits, hash_func, equal_func, v_traits)
0510    {}
0511 
0512    template<class Iterator>
0513    BOOST_INTRUSIVE_FORCEINLINE
0514    unordered_set
0515                   ( Iterator b, Iterator e
0516                   , const bucket_traits &b_traits
0517                   , const hasher & hash_func = hasher()
0518                   , const key_equal &equal_func = key_equal()
0519                   , const value_traits &v_traits = value_traits())
0520       :  Base(b, e, b_traits, hash_func, equal_func, v_traits)
0521    {}
0522 
0523    BOOST_INTRUSIVE_FORCEINLINE unordered_set(BOOST_RV_REF(unordered_set) x)
0524       :  Base(BOOST_MOVE_BASE(Base, x))
0525    {}
0526 
0527    BOOST_INTRUSIVE_FORCEINLINE unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
0528    {  return static_cast<unordered_set&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
0529 
0530    template <class Cloner, class Disposer>
0531    BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
0532    {  this->Base::clone_from(src, cloner, disposer);  }
0533 
0534    template <class Cloner, class Disposer>
0535    BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set) src, Cloner cloner, Disposer disposer)
0536    {  this->Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
0537 };
0538 
0539 #endif
0540 
0541 
0542 //! The class template unordered_multiset is an intrusive container, that mimics most of
0543 //! the interface of std::tr1::unordered_multiset as described in the C++ TR1.
0544 //!
0545 //! unordered_multiset is a semi-intrusive container: each object to be stored in the
0546 //! container must contain a proper hook, but the container also needs
0547 //! additional auxiliary memory to work: unordered_multiset needs a pointer to an array
0548 //! of type `bucket_type` to be passed in the constructor. This bucket array must
0549 //! have at least the same lifetime as the container. This makes the use of
0550 //! unordered_multiset more complicated than purely intrusive containers.
0551 //! `bucket_type` is default-constructible, copyable and assignable
0552 //!
0553 //! The template parameter \c T is the type to be managed by the container.
0554 //! The user can specify additional options and if no options are provided
0555 //! default options are used.
0556 //!
0557 //! The container supports the following options:
0558 //! \c base_hook<>/member_hook<>/value_traits<>,
0559 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
0560 //! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
0561 //!
0562 //! unordered_multiset only provides forward iterators but it provides 4 iterator types:
0563 //! iterator and const_iterator to navigate through the whole container and
0564 //! local_iterator and const_local_iterator to navigate through the values
0565 //! stored in a single bucket. Local iterators are faster and smaller.
0566 //!
0567 //! It's not recommended to use non constant-time size unordered_multisets because several
0568 //! key functions, like "empty()", become non-constant time functions. Non
0569 //! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks.
0570 //!
0571 //! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor
0572 //! offers functions related to a load factor. Rehashing can be explicitly requested
0573 //! and the user must provide a new bucket array that will be used from that moment.
0574 //!
0575 //! Since no automatic rehashing is done, iterators are never invalidated when
0576 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
0577 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0578 template<class T, class ...Options>
0579 #else
0580 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
0581 #endif
0582 class unordered_multiset_impl
0583    #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0584    : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>
0585    #endif
0586 {
0587    /// @cond
0588    private:
0589    typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags> table_type;
0590    /// @endcond
0591 
0592    //Movable
0593    BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset_impl)
0594 
0595    typedef table_type implementation_defined;
0596 
0597    public:
0598    typedef typename implementation_defined::value_type                  value_type;
0599    typedef typename implementation_defined::key_type                    key_type;
0600    typedef typename implementation_defined::value_traits                value_traits;
0601    typedef typename implementation_defined::bucket_traits               bucket_traits;
0602    typedef typename implementation_defined::pointer                     pointer;
0603    typedef typename implementation_defined::const_pointer               const_pointer;
0604    typedef typename implementation_defined::reference                   reference;
0605    typedef typename implementation_defined::const_reference             const_reference;
0606    typedef typename implementation_defined::difference_type             difference_type;
0607    typedef typename implementation_defined::size_type                   size_type;
0608    typedef typename implementation_defined::key_equal                   key_equal;
0609    typedef typename implementation_defined::hasher                      hasher;
0610    typedef typename implementation_defined::bucket_type                 bucket_type;
0611    typedef typename implementation_defined::bucket_ptr                  bucket_ptr;
0612    typedef typename implementation_defined::iterator                    iterator;
0613    typedef typename implementation_defined::const_iterator              const_iterator;
0614    typedef typename implementation_defined::insert_commit_data          insert_commit_data;
0615    typedef typename implementation_defined::local_iterator              local_iterator;
0616    typedef typename implementation_defined::const_local_iterator        const_local_iterator;
0617    typedef typename implementation_defined::node_traits                 node_traits;
0618    typedef typename implementation_defined::node                        node;
0619    typedef typename implementation_defined::node_ptr                    node_ptr;
0620    typedef typename implementation_defined::const_node_ptr              const_node_ptr;
0621 
0622    public:
0623 
0624    //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
0625    BOOST_INTRUSIVE_FORCEINLINE explicit unordered_multiset_impl ( const bucket_traits &b_traits
0626                                     , const hasher & hash_func = hasher()
0627                                     , const key_equal &equal_func = key_equal()
0628                                     , const value_traits &v_traits = value_traits())
0629       :  table_type(b_traits, hash_func, equal_func, v_traits)
0630    {}
0631 
0632    //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
0633    template<class Iterator>
0634    BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl ( Iterator b
0635                            , Iterator e
0636                            , const bucket_traits &b_traits
0637                            , const hasher & hash_func = hasher()
0638                            , const key_equal &equal_func = key_equal()
0639                            , const value_traits &v_traits = value_traits())
0640       :  table_type(false, b, e, b_traits, hash_func, equal_func, v_traits)
0641    {}
0642 
0643    //! <b>Effects</b>: to-do
0644    //!
0645    BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl(BOOST_RV_REF(unordered_multiset_impl) x)
0646       :  table_type(BOOST_MOVE_BASE(table_type, x))
0647    {}
0648 
0649    //! <b>Effects</b>: to-do
0650    //!
0651    BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl& operator=(BOOST_RV_REF(unordered_multiset_impl) x)
0652    {  return static_cast<unordered_multiset_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x)));  }
0653 
0654    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0655 
0656    //! @copydoc ::boost::intrusive::hashtable::~hashtable()
0657    ~unordered_multiset_impl();
0658 
0659    //! @copydoc ::boost::intrusive::hashtable::begin()
0660    iterator begin() BOOST_NOEXCEPT;
0661 
0662    //! @copydoc ::boost::intrusive::hashtable::begin()const
0663    const_iterator begin() const BOOST_NOEXCEPT;
0664 
0665    //! @copydoc ::boost::intrusive::hashtable::cbegin()const
0666    const_iterator cbegin() const BOOST_NOEXCEPT;
0667 
0668    //! @copydoc ::boost::intrusive::hashtable::end()
0669    iterator end() BOOST_NOEXCEPT;
0670 
0671    //! @copydoc ::boost::intrusive::hashtable::end()const
0672    const_iterator end() const BOOST_NOEXCEPT;
0673 
0674    //! @copydoc ::boost::intrusive::hashtable::cend()const
0675    const_iterator cend() const BOOST_NOEXCEPT;
0676 
0677    //! @copydoc ::boost::intrusive::hashtable::hash_function()const
0678    hasher hash_function() const;
0679 
0680    //! @copydoc ::boost::intrusive::hashtable::key_eq()const
0681    key_equal key_eq() const;
0682 
0683    //! @copydoc ::boost::intrusive::hashtable::empty()const
0684    bool empty() const BOOST_NOEXCEPT;
0685 
0686    //! @copydoc ::boost::intrusive::hashtable::size()const
0687    size_type size() const BOOST_NOEXCEPT;
0688 
0689    //! @copydoc ::boost::intrusive::hashtable::hashtable
0690    void swap(unordered_multiset_impl& other);
0691 
0692    //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
0693    template <class Cloner, class Disposer>
0694    void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer);
0695 
0696    #else
0697 
0698    using table_type::clone_from;
0699 
0700    #endif   //   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0701 
0702    //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
0703    template <class Cloner, class Disposer>
0704    BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset_impl) src, Cloner cloner, Disposer disposer)
0705    {  table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer);  }
0706 
0707    //! @copydoc ::boost::intrusive::hashtable::insert_equal(reference)
0708    BOOST_INTRUSIVE_FORCEINLINE iterator insert(reference value)
0709    {  return table_type::insert_equal(value);  }
0710 
0711    //! @copydoc ::boost::intrusive::hashtable::insert_equal(Iterator,Iterator)
0712    template<class Iterator>
0713    BOOST_INTRUSIVE_FORCEINLINE void insert(Iterator b, Iterator e)
0714    {  table_type::insert_equal(b, e);  }
0715 
0716    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0717 
0718    //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
0719    void erase(const_iterator i);
0720 
0721    //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
0722    void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
0723 
0724    //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
0725    size_type erase(const key_type &key);
0726 
0727    //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
0728    template<class KeyType, class KeyHasher, class KeyEqual>
0729    size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
0730 
0731    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
0732    template<class Disposer>
0733    BOOST_INTRUSIVE_DOC1ST(void
0734       , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
0735       erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
0736 
0737    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
0738    template<class Disposer>
0739    void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
0740 
0741    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
0742    template<class Disposer>
0743    size_type erase_and_dispose(const key_type &key, Disposer disposer);
0744 
0745    //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
0746    template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
0747    size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
0748 
0749    //! @copydoc ::boost::intrusive::hashtable::clear
0750    void clear() BOOST_NOEXCEPT;
0751 
0752    //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
0753    template<class Disposer>
0754    void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
0755 
0756    //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
0757    size_type count(const key_type &key) const;
0758 
0759    //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
0760    template<class KeyType, class KeyHasher, class KeyEqual>
0761    size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
0762 
0763    //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
0764    iterator find(const key_type &key);
0765 
0766    //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
0767    template<class KeyType, class KeyHasher, class KeyEqual>
0768    iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
0769 
0770    //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
0771    const_iterator find(const key_type &key) const;
0772 
0773    //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
0774    template<class KeyType, class KeyHasher, class KeyEqual>
0775    const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
0776 
0777    //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
0778    std::pair<iterator,iterator> equal_range(const key_type &key);
0779 
0780    //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
0781    template<class KeyType, class KeyHasher, class KeyEqual>
0782    std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
0783 
0784    //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
0785    std::pair<const_iterator, const_iterator>
0786       equal_range(const key_type &key) const;
0787 
0788    //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
0789    template<class KeyType, class KeyHasher, class KeyEqual>
0790    std::pair<const_iterator, const_iterator>
0791       equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
0792 
0793    //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
0794    iterator iterator_to(reference value) BOOST_NOEXCEPT;
0795 
0796    //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
0797    const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
0798 
0799    //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
0800    static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT;
0801 
0802    //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
0803    static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT;
0804 
0805    //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
0806    local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT;
0807 
0808    //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
0809    const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT;
0810 
0811    //! @copydoc ::boost::intrusive::hashtable::bucket_count
0812    size_type bucket_count() const BOOST_NOEXCEPT;
0813 
0814    //! @copydoc ::boost::intrusive::hashtable::bucket_size
0815    size_type bucket_size(size_type n) const BOOST_NOEXCEPT;
0816 
0817    //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
0818    size_type bucket(const key_type& k) const;
0819 
0820    //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
0821    template<class KeyType, class KeyHasher>
0822    size_type bucket(const KeyType& k, KeyHasher hash_func) const;
0823 
0824    //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
0825    bucket_ptr bucket_pointer() const BOOST_NOEXCEPT;
0826 
0827    //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
0828    local_iterator begin(size_type n) BOOST_NOEXCEPT;
0829 
0830    //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
0831    const_local_iterator begin(size_type n) const BOOST_NOEXCEPT;
0832 
0833    //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
0834    const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT;
0835 
0836    //! @copydoc ::boost::intrusive::hashtable::end(size_type)
0837    local_iterator end(size_type n) BOOST_NOEXCEPT;
0838 
0839    //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
0840    const_local_iterator end(size_type n) const BOOST_NOEXCEPT;
0841 
0842    //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
0843    const_local_iterator cend(size_type n) const BOOST_NOEXCEPT;
0844 
0845    //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
0846    void rehash(const bucket_traits &new_bucket_traits);
0847 
0848    //! @copydoc ::boost::intrusive::hashtable::full_rehash
0849    void full_rehash();
0850 
0851    //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
0852    bool incremental_rehash(bool grow = true);
0853 
0854    //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
0855    bool incremental_rehash(const bucket_traits &new_bucket_traits);
0856 
0857    //! @copydoc ::boost::intrusive::hashtable::split_count
0858    size_type split_count() const BOOST_NOEXCEPT;
0859 
0860    //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
0861    static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT;
0862 
0863    //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
0864    static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT;
0865 
0866    #endif   //   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0867 };
0868 
0869 //! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
0870 //! same options (either explicitly or implicitly) are used.
0871 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0872 template<class T, class ...Options>
0873 #else
0874 template<class T, class O1 = void, class O2 = void
0875                 , class O3 = void, class O4 = void
0876                 , class O5 = void, class O6 = void
0877                 , class O7 = void, class O8 = void
0878                 , class O9 = void, class O10= void
0879                 , class O11 = void
0880                 >
0881 #endif
0882 struct make_unordered_multiset
0883 {
0884    /// @cond
0885    typedef typename pack_options
0886       < hashtable_defaults,
0887          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0888          O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11
0889          #else
0890          Options...
0891          #endif
0892       >::type packed_options;
0893 
0894    typedef typename detail::get_value_traits
0895       <T, typename packed_options::proto_value_traits>::type value_traits;
0896 
0897    typedef typename make_bucket_traits
0898             <T, packed_options>::type bucket_traits;
0899 
0900    typedef unordered_multiset_impl
0901       < value_traits
0902       , typename packed_options::key_of_value
0903       , typename packed_options::hash
0904       , typename packed_options::equal
0905       , typename packed_options::size_type
0906       , bucket_traits
0907       ,  (std::size_t(false)*hash_bool_flags::unique_keys_pos)
0908       |  (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
0909       |  (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
0910       |  (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
0911       |  (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
0912       |  (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
0913       |  (std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos)
0914       |  (std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos)
0915       > implementation_defined;
0916 
0917    /// @endcond
0918    typedef implementation_defined type;
0919 };
0920 
0921 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0922 
0923 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0924 template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10, class O11>
0925 #else
0926 template<class T, class ...Options>
0927 #endif
0928 class unordered_multiset
0929    :  public make_unordered_multiset<T,
0930          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0931          O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11
0932          #else
0933          Options...
0934          #endif
0935       >::type
0936 {
0937    typedef typename make_unordered_multiset
0938       <T,
0939          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0940          O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
0941          #else
0942          Options...
0943          #endif
0944       >::type   Base;
0945    //Assert if passed value traits are compatible with the type
0946    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
0947    BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset)
0948 
0949    public:
0950    typedef typename Base::value_traits       value_traits;
0951    typedef typename Base::bucket_traits      bucket_traits;
0952    typedef typename Base::iterator           iterator;
0953    typedef typename Base::const_iterator     const_iterator;
0954    typedef typename Base::bucket_ptr         bucket_ptr;
0955    typedef typename Base::size_type          size_type;
0956    typedef typename Base::hasher             hasher;
0957    typedef typename Base::key_equal          key_equal;
0958 
0959    BOOST_INTRUSIVE_FORCEINLINE
0960    explicit unordered_multiset( const bucket_traits &b_traits
0961                               , const hasher & hash_func = hasher()
0962                               , const key_equal &equal_func = key_equal()
0963                               , const value_traits &v_traits = value_traits())
0964       :  Base(b_traits, hash_func, equal_func, v_traits)
0965    {}
0966 
0967    template<class Iterator>
0968    BOOST_INTRUSIVE_FORCEINLINE
0969    unordered_multiset( Iterator b
0970                      , Iterator e
0971                      , const bucket_traits &b_traits
0972                      , const hasher & hash_func = hasher()
0973                      , const key_equal &equal_func = key_equal()
0974                      , const value_traits &v_traits = value_traits())
0975       :  Base(b, e, b_traits, hash_func, equal_func, v_traits)
0976    {}
0977 
0978    BOOST_INTRUSIVE_FORCEINLINE unordered_multiset(BOOST_RV_REF(unordered_multiset) x)
0979       :  Base(BOOST_MOVE_BASE(Base, x))
0980    {}
0981 
0982    BOOST_INTRUSIVE_FORCEINLINE unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
0983    {  return static_cast<unordered_multiset&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
0984 
0985    template <class Cloner, class Disposer>
0986    BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
0987    {  this->Base::clone_from(src, cloner, disposer);  }
0988 
0989    template <class Cloner, class Disposer>
0990    BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset) src, Cloner cloner, Disposer disposer)
0991    {  this->Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
0992 };
0993 
0994 #endif
0995 
0996 } //namespace intrusive
0997 } //namespace boost
0998 
0999 #include <boost/intrusive/detail/config_end.hpp>
1000 
1001 #endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP