Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:17:32

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