]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/intrusive/unordered_set.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / intrusive / unordered_set.hpp
CommitLineData
7c673cae
FG
1/////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Olaf Krzikalla 2004-2006.
4// (C) Copyright Ion Gaztanaga 2006-2014
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9//
10// See http://www.boost.org/libs/intrusive for documentation.
11//
12/////////////////////////////////////////////////////////////////////////////
13#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HPP
14#define BOOST_INTRUSIVE_UNORDERED_SET_HPP
15
16#include <boost/intrusive/detail/config_begin.hpp>
17#include <boost/intrusive/intrusive_fwd.hpp>
18#include <boost/intrusive/hashtable.hpp>
19#include <boost/move/utility_core.hpp>
20#include <boost/static_assert.hpp>
21
22#if defined(BOOST_HAS_PRAGMA_ONCE)
23# pragma once
24#endif
25
26namespace boost {
27namespace intrusive {
28
29//! The class template unordered_set is an intrusive container, that mimics most of
30//! the interface of std::tr1::unordered_set as described in the C++ TR1.
31//!
32//! unordered_set is a semi-intrusive container: each object to be stored in the
33//! container must contain a proper hook, but the container also needs
34//! additional auxiliary memory to work: unordered_set needs a pointer to an array
35//! of type `bucket_type` to be passed in the constructor. This bucket array must
36//! have at least the same lifetime as the container. This makes the use of
37//! unordered_set more complicated than purely intrusive containers.
38//! `bucket_type` is default-constructible, copyable and assignable
39//!
40//! The template parameter \c T is the type to be managed by the container.
41//! The user can specify additional options and if no options are provided
42//! default options are used.
43//!
44//! The container supports the following options:
45//! \c base_hook<>/member_hook<>/value_traits<>,
46//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
47//! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
48//!
49//! unordered_set only provides forward iterators but it provides 4 iterator types:
50//! iterator and const_iterator to navigate through the whole container and
51//! local_iterator and const_local_iterator to navigate through the values
52//! stored in a single bucket. Local iterators are faster and smaller.
53//!
54//! It's not recommended to use non constant-time size unordered_sets because several
55//! key functions, like "empty()", become non-constant time functions. Non
56//! constant-time size unordered_sets are mainly provided to support auto-unlink hooks.
57//!
58//! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor
59//! offers functions related to a load factor. Rehashing can be explicitly requested
60//! and the user must provide a new bucket array that will be used from that moment.
61//!
62//! Since no automatic rehashing is done, iterators are never invalidated when
63//! inserting or erasing elements. Iterators are only invalidated when rehasing.
64#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
65template<class T, class ...Options>
66#else
67template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
68#endif
69class unordered_set_impl
70 : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos>
71{
72 /// @cond
73 private:
74 typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos> table_type;
75
76 template<class Iterator, class MaybeConstThis, class KeyType, class KeyHasher, class KeyEqual>
77 static std::pair<Iterator,Iterator> priv_equal_range(MaybeConstThis &c, const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
78 {
79 Iterator const it = c.find(key, hash_func, equal_func);
80 std::pair<Iterator,Iterator> ret(it, it);
81 if(it != c.end())
82 ++ret.second;
83 return ret;
84 }
85
86 //! This class is
87 //! movable
88 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set_impl)
89
90 typedef table_type implementation_defined;
91 /// @endcond
92
93 public:
94 typedef typename implementation_defined::value_type value_type;
95 typedef typename implementation_defined::key_type key_type;
96 typedef typename implementation_defined::key_of_value key_of_value;
97 typedef typename implementation_defined::value_traits value_traits;
98 typedef typename implementation_defined::bucket_traits bucket_traits;
99 typedef typename implementation_defined::pointer pointer;
100 typedef typename implementation_defined::const_pointer const_pointer;
101 typedef typename implementation_defined::reference reference;
102 typedef typename implementation_defined::const_reference const_reference;
103 typedef typename implementation_defined::difference_type difference_type;
104 typedef typename implementation_defined::size_type size_type;
105 typedef typename implementation_defined::key_equal key_equal;
106 typedef typename implementation_defined::hasher hasher;
107 typedef typename implementation_defined::bucket_type bucket_type;
108 typedef typename implementation_defined::bucket_ptr bucket_ptr;
109 typedef typename implementation_defined::iterator iterator;
110 typedef typename implementation_defined::const_iterator const_iterator;
111 typedef typename implementation_defined::insert_commit_data insert_commit_data;
112 typedef typename implementation_defined::local_iterator local_iterator;
113 typedef typename implementation_defined::const_local_iterator const_local_iterator;
114 typedef typename implementation_defined::node_traits node_traits;
115 typedef typename implementation_defined::node node;
116 typedef typename implementation_defined::node_ptr node_ptr;
117 typedef typename implementation_defined::const_node_ptr const_node_ptr;
118 typedef typename implementation_defined::node_algorithms node_algorithms;
119
120 public:
121
122 //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
b32b8144 123 BOOST_INTRUSIVE_FORCEINLINE explicit unordered_set_impl( const bucket_traits &b_traits
7c673cae
FG
124 , const hasher & hash_func = hasher()
125 , const key_equal &equal_func = key_equal()
126 , const value_traits &v_traits = value_traits())
127 : table_type(b_traits, hash_func, equal_func, v_traits)
128 {}
129
130 //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
131 template<class Iterator>
b32b8144 132 BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl( Iterator b
7c673cae
FG
133 , Iterator e
134 , const bucket_traits &b_traits
135 , const hasher & hash_func = hasher()
136 , const key_equal &equal_func = key_equal()
137 , const value_traits &v_traits = value_traits())
138 : table_type(true, b, e, b_traits, hash_func, equal_func, v_traits)
139 {}
140
141 //! @copydoc ::boost::intrusive::hashtable::hashtable(hashtable&&)
b32b8144 142 BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x)
7c673cae
FG
143 : table_type(BOOST_MOVE_BASE(table_type, x))
144 {}
145
146 //! @copydoc ::boost::intrusive::hashtable::operator=(hashtable&&)
b32b8144 147 BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x)
7c673cae
FG
148 { return static_cast<unordered_set_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
149
150 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
151 //! @copydoc ::boost::intrusive::hashtable::~hashtable()
152 ~unordered_set_impl();
153
154 //! @copydoc ::boost::intrusive::hashtable::begin()
1e59de90 155 iterator begin() BOOST_NOEXCEPT;
7c673cae
FG
156
157 //! @copydoc ::boost::intrusive::hashtable::begin()const
1e59de90 158 const_iterator begin() const BOOST_NOEXCEPT;
7c673cae
FG
159
160 //! @copydoc ::boost::intrusive::hashtable::cbegin()const
1e59de90 161 const_iterator cbegin() const BOOST_NOEXCEPT;
7c673cae
FG
162
163 //! @copydoc ::boost::intrusive::hashtable::end()
1e59de90 164 iterator end() BOOST_NOEXCEPT;
7c673cae
FG
165
166 //! @copydoc ::boost::intrusive::hashtable::end()const
1e59de90 167 const_iterator end() const BOOST_NOEXCEPT;
7c673cae
FG
168
169 //! @copydoc ::boost::intrusive::hashtable::cend()const
1e59de90 170 const_iterator cend() const BOOST_NOEXCEPT;
7c673cae
FG
171
172 //! @copydoc ::boost::intrusive::hashtable::hash_function()const
173 hasher hash_function() const;
174
175 //! @copydoc ::boost::intrusive::hashtable::key_eq()const
176 key_equal key_eq() const;
177
178 //! @copydoc ::boost::intrusive::hashtable::empty()const
1e59de90 179 bool empty() const BOOST_NOEXCEPT;
7c673cae
FG
180
181 //! @copydoc ::boost::intrusive::hashtable::size()const
1e59de90 182 size_type size() const BOOST_NOEXCEPT;
7c673cae
FG
183
184 //! @copydoc ::boost::intrusive::hashtable::hashtable
185 void swap(unordered_set_impl& other);
186
187 //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
188 template <class Cloner, class Disposer>
189 void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer);
190
191 #else
192
193 using table_type::clone_from;
194
195 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
196
197 //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
198 template <class Cloner, class Disposer>
b32b8144 199 BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set_impl) src, Cloner cloner, Disposer disposer)
7c673cae
FG
200 { table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
201
202 //! @copydoc ::boost::intrusive::hashtable::insert_unique(reference)
b32b8144 203 BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert(reference value)
7c673cae
FG
204 { return table_type::insert_unique(value); }
205
206 //! @copydoc ::boost::intrusive::hashtable::insert_unique(Iterator,Iterator)
207 template<class Iterator>
b32b8144 208 BOOST_INTRUSIVE_FORCEINLINE void insert(Iterator b, Iterator e)
7c673cae
FG
209 { table_type::insert_unique(b, e); }
210
211 //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const key_type&,insert_commit_data&)
b32b8144 212 BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert_check(const key_type &key, insert_commit_data &commit_data)
7c673cae
FG
213 { return table_type::insert_unique_check(key, commit_data); }
214
215 //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const KeyType&,KeyHasher,KeyEqual,insert_commit_data&)
216 template<class KeyType, class KeyHasher, class KeyEqual>
b32b8144 217 BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert_check
1e59de90
TL
218 (const KeyType &key, KeyHasher hash_func, KeyEqual key_value_equal, insert_commit_data &commit_data)
219 { return table_type::insert_unique_check(key, hash_func, key_value_equal, commit_data); }
7c673cae
FG
220
221 //! @copydoc ::boost::intrusive::hashtable::insert_unique_commit
1e59de90 222 BOOST_INTRUSIVE_FORCEINLINE iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
7c673cae
FG
223 { return table_type::insert_unique_commit(value, commit_data); }
224
225 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
226
227 //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
228 void erase(const_iterator i);
229
230 //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
1e59de90 231 void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
7c673cae
FG
232
233 //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
234 size_type erase(const key_type &key);
235
236 //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
237 template<class KeyType, class KeyHasher, class KeyEqual>
238 size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
239
240 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
241 template<class Disposer>
242 BOOST_INTRUSIVE_DOC1ST(void
243 , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
1e59de90 244 erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
7c673cae
FG
245
246 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
247 template<class Disposer>
1e59de90 248 void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
7c673cae
FG
249
250 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
251 template<class Disposer>
252 size_type erase_and_dispose(const key_type &key, Disposer disposer);
253
254 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
255 template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
256 size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
257
258 //! @copydoc ::boost::intrusive::hashtable::clear
1e59de90 259 void clear() BOOST_NOEXCEPT;
7c673cae
FG
260
261 //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
262 template<class Disposer>
1e59de90 263 void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
7c673cae
FG
264
265 //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
266 size_type count(const key_type &key) const;
267
268 //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
269 template<class KeyType, class KeyHasher, class KeyEqual>
270 size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
271
272 //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
273 iterator find(const key_type &key);
274
275 //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
276 template<class KeyType, class KeyHasher, class KeyEqual>
277 iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
278
279 //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
280 const_iterator find(const key_type &key) const;
281
282 //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
283 template<class KeyType, class KeyHasher, class KeyEqual>
284 const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
285 #endif
286
287 //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
288 std::pair<iterator,iterator> equal_range(const key_type &key)
289 { return this->equal_range(key, this->hash_function(), this->key_eq()); }
290
291 //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
292 template<class KeyType, class KeyHasher, class KeyEqual>
293 std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
294 { return this->priv_equal_range<iterator>(*this, key, hash_func, equal_func); }
295
296 //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
297 std::pair<const_iterator, const_iterator>
298 equal_range(const key_type &key) const
299 { return this->equal_range(key, this->hash_function(), this->key_eq()); }
300
301 //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
302 template<class KeyType, class KeyHasher, class KeyEqual>
303 std::pair<const_iterator, const_iterator>
304 equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const
305 { return this->priv_equal_range<const_iterator>(*this, key, hash_func, equal_func); }
306
307 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
308 //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
1e59de90 309 iterator iterator_to(reference value) BOOST_NOEXCEPT;
7c673cae
FG
310
311 //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
1e59de90 312 const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
7c673cae
FG
313
314 //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
1e59de90 315 static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT;
7c673cae
FG
316
317 //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
1e59de90 318 static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT;
7c673cae
FG
319
320 //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
1e59de90 321 local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT;
7c673cae
FG
322
323 //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
1e59de90 324 const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT;
7c673cae
FG
325
326 //! @copydoc ::boost::intrusive::hashtable::bucket_count
1e59de90 327 size_type bucket_count() const BOOST_NOEXCEPT;
7c673cae
FG
328
329 //! @copydoc ::boost::intrusive::hashtable::bucket_size
1e59de90 330 size_type bucket_size(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
331
332 //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
333 size_type bucket(const key_type& k) const;
334
335 //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
336 template<class KeyType, class KeyHasher>
337 size_type bucket(const KeyType& k, KeyHasher hash_func) const;
338
339 //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
1e59de90 340 bucket_ptr bucket_pointer() const BOOST_NOEXCEPT;
7c673cae
FG
341
342 //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
1e59de90 343 local_iterator begin(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
344
345 //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
1e59de90 346 const_local_iterator begin(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
347
348 //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
1e59de90 349 const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
350
351 //! @copydoc ::boost::intrusive::hashtable::end(size_type)
1e59de90 352 local_iterator end(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
353
354 //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
1e59de90 355 const_local_iterator end(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
356
357 //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
1e59de90 358 const_local_iterator cend(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
359
360 //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
361 void rehash(const bucket_traits &new_bucket_traits);
362
363 //! @copydoc ::boost::intrusive::hashtable::full_rehash
364 void full_rehash();
365
366 //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
367 bool incremental_rehash(bool grow = true);
368
369 //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
370 bool incremental_rehash(const bucket_traits &new_bucket_traits);
371
372 //! @copydoc ::boost::intrusive::hashtable::split_count
1e59de90 373 size_type split_count() const BOOST_NOEXCEPT;
7c673cae
FG
374
375 //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
1e59de90 376 static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
377
378 //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
1e59de90 379 static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
380
381 #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
382
383 friend bool operator==(const unordered_set_impl &x, const unordered_set_impl &y)
384 {
385 if(table_type::constant_time_size && x.size() != y.size()){
386 return false;
387 }
388 //Find each element of x in y
389 for (const_iterator ix = x.cbegin(), ex = x.cend(), ey = y.cend(); ix != ex; ++ix){
390 const_iterator iy = y.find(key_of_value()(*ix));
391 if (iy == ey || !(*ix == *iy))
392 return false;
393 }
394 return true;
395 }
396
397 friend bool operator!=(const unordered_set_impl &x, const unordered_set_impl &y)
398 { return !(x == y); }
399
400 friend bool operator<(const unordered_set_impl &x, const unordered_set_impl &y)
401 { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
402
403 friend bool operator>(const unordered_set_impl &x, const unordered_set_impl &y)
404 { return y < x; }
405
406 friend bool operator<=(const unordered_set_impl &x, const unordered_set_impl &y)
407 { return !(y < x); }
408
409 friend bool operator>=(const unordered_set_impl &x, const unordered_set_impl &y)
410 { return !(x < y); }
411};
412
413//! Helper metafunction to define an \c unordered_set that yields to the same type when the
414//! same options (either explicitly or implicitly) are used.
415#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
416template<class T, class ...Options>
417#else
418template<class T, class O1 = void, class O2 = void
419 , class O3 = void, class O4 = void
420 , class O5 = void, class O6 = void
421 , class O7 = void, class O8 = void
422 , class O9 = void, class O10= void
423 >
424#endif
425struct make_unordered_set
426{
427 /// @cond
428 typedef typename pack_options
429 < hashtable_defaults,
430 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
431 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
432 #else
433 Options...
434 #endif
435 >::type packed_options;
436
437 typedef typename detail::get_value_traits
438 <T, typename packed_options::proto_value_traits>::type value_traits;
439
440 typedef typename make_bucket_traits
441 <T, true, packed_options>::type bucket_traits;
442
443 typedef unordered_set_impl
444 < value_traits
445 , typename packed_options::key_of_value
446 , typename packed_options::hash
447 , typename packed_options::equal
448 , typename packed_options::size_type
449 , bucket_traits
450 , (std::size_t(true)*hash_bool_flags::unique_keys_pos)
451 | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
452 | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
453 | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
454 | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
455 | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
456 > implementation_defined;
457
458 /// @endcond
459 typedef implementation_defined type;
460};
461
462#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
463
464#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
465template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
466#else
467template<class T, class ...Options>
468#endif
469class unordered_set
470 : public make_unordered_set<T,
471 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
472 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
473 #else
474 Options...
475 #endif
476 >::type
477{
478 typedef typename make_unordered_set
479 <T,
480 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
481 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
482 #else
483 Options...
484 #endif
485 >::type Base;
486
487 //Assert if passed value traits are compatible with the type
488 BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
489 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set)
490
491 public:
492 typedef typename Base::value_traits value_traits;
493 typedef typename Base::bucket_traits bucket_traits;
494 typedef typename Base::iterator iterator;
495 typedef typename Base::const_iterator const_iterator;
496 typedef typename Base::bucket_ptr bucket_ptr;
497 typedef typename Base::size_type size_type;
498 typedef typename Base::hasher hasher;
499 typedef typename Base::key_equal key_equal;
500
92f5a8d4 501 BOOST_INTRUSIVE_FORCEINLINE
7c673cae
FG
502 explicit unordered_set ( const bucket_traits &b_traits
503 , const hasher & hash_func = hasher()
504 , const key_equal &equal_func = key_equal()
505 , const value_traits &v_traits = value_traits())
506 : Base(b_traits, hash_func, equal_func, v_traits)
507 {}
508
509 template<class Iterator>
92f5a8d4
TL
510 BOOST_INTRUSIVE_FORCEINLINE
511 unordered_set
b32b8144 512 ( Iterator b, Iterator e
7c673cae
FG
513 , const bucket_traits &b_traits
514 , const hasher & hash_func = hasher()
515 , const key_equal &equal_func = key_equal()
516 , const value_traits &v_traits = value_traits())
517 : Base(b, e, b_traits, hash_func, equal_func, v_traits)
518 {}
519
b32b8144 520 BOOST_INTRUSIVE_FORCEINLINE unordered_set(BOOST_RV_REF(unordered_set) x)
7c673cae
FG
521 : Base(BOOST_MOVE_BASE(Base, x))
522 {}
523
b32b8144 524 BOOST_INTRUSIVE_FORCEINLINE unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
7c673cae
FG
525 { return static_cast<unordered_set&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
526
527 template <class Cloner, class Disposer>
b32b8144 528 BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
7c673cae
FG
529 { Base::clone_from(src, cloner, disposer); }
530
531 template <class Cloner, class Disposer>
b32b8144 532 BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set) src, Cloner cloner, Disposer disposer)
7c673cae
FG
533 { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
534};
535
536#endif
537
538
539//! The class template unordered_multiset is an intrusive container, that mimics most of
540//! the interface of std::tr1::unordered_multiset as described in the C++ TR1.
541//!
542//! unordered_multiset is a semi-intrusive container: each object to be stored in the
543//! container must contain a proper hook, but the container also needs
544//! additional auxiliary memory to work: unordered_multiset needs a pointer to an array
545//! of type `bucket_type` to be passed in the constructor. This bucket array must
546//! have at least the same lifetime as the container. This makes the use of
547//! unordered_multiset more complicated than purely intrusive containers.
548//! `bucket_type` is default-constructible, copyable and assignable
549//!
550//! The template parameter \c T is the type to be managed by the container.
551//! The user can specify additional options and if no options are provided
552//! default options are used.
553//!
554//! The container supports the following options:
555//! \c base_hook<>/member_hook<>/value_traits<>,
556//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
557//! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
558//!
559//! unordered_multiset only provides forward iterators but it provides 4 iterator types:
560//! iterator and const_iterator to navigate through the whole container and
561//! local_iterator and const_local_iterator to navigate through the values
562//! stored in a single bucket. Local iterators are faster and smaller.
563//!
564//! It's not recommended to use non constant-time size unordered_multisets because several
565//! key functions, like "empty()", become non-constant time functions. Non
566//! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks.
567//!
568//! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor
569//! offers functions related to a load factor. Rehashing can be explicitly requested
570//! and the user must provide a new bucket array that will be used from that moment.
571//!
572//! Since no automatic rehashing is done, iterators are never invalidated when
573//! inserting or erasing elements. Iterators are only invalidated when rehasing.
574#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
575template<class T, class ...Options>
576#else
577template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
578#endif
579class unordered_multiset_impl
580 : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>
581{
582 /// @cond
583 private:
584 typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags> table_type;
585 /// @endcond
586
587 //Movable
588 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset_impl)
589
590 typedef table_type implementation_defined;
591
592 public:
593 typedef typename implementation_defined::value_type value_type;
594 typedef typename implementation_defined::key_type key_type;
595 typedef typename implementation_defined::value_traits value_traits;
596 typedef typename implementation_defined::bucket_traits bucket_traits;
597 typedef typename implementation_defined::pointer pointer;
598 typedef typename implementation_defined::const_pointer const_pointer;
599 typedef typename implementation_defined::reference reference;
600 typedef typename implementation_defined::const_reference const_reference;
601 typedef typename implementation_defined::difference_type difference_type;
602 typedef typename implementation_defined::size_type size_type;
603 typedef typename implementation_defined::key_equal key_equal;
604 typedef typename implementation_defined::hasher hasher;
605 typedef typename implementation_defined::bucket_type bucket_type;
606 typedef typename implementation_defined::bucket_ptr bucket_ptr;
607 typedef typename implementation_defined::iterator iterator;
608 typedef typename implementation_defined::const_iterator const_iterator;
609 typedef typename implementation_defined::insert_commit_data insert_commit_data;
610 typedef typename implementation_defined::local_iterator local_iterator;
611 typedef typename implementation_defined::const_local_iterator const_local_iterator;
612 typedef typename implementation_defined::node_traits node_traits;
613 typedef typename implementation_defined::node node;
614 typedef typename implementation_defined::node_ptr node_ptr;
615 typedef typename implementation_defined::const_node_ptr const_node_ptr;
616 typedef typename implementation_defined::node_algorithms node_algorithms;
617
618 public:
619
620 //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
b32b8144 621 BOOST_INTRUSIVE_FORCEINLINE explicit unordered_multiset_impl ( const bucket_traits &b_traits
7c673cae
FG
622 , const hasher & hash_func = hasher()
623 , const key_equal &equal_func = key_equal()
624 , const value_traits &v_traits = value_traits())
625 : table_type(b_traits, hash_func, equal_func, v_traits)
626 {}
627
628 //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
629 template<class Iterator>
b32b8144 630 BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl ( Iterator b
7c673cae
FG
631 , Iterator e
632 , const bucket_traits &b_traits
633 , const hasher & hash_func = hasher()
634 , const key_equal &equal_func = key_equal()
635 , const value_traits &v_traits = value_traits())
636 : table_type(false, b, e, b_traits, hash_func, equal_func, v_traits)
637 {}
638
639 //! <b>Effects</b>: to-do
640 //!
b32b8144 641 BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl(BOOST_RV_REF(unordered_multiset_impl) x)
7c673cae
FG
642 : table_type(BOOST_MOVE_BASE(table_type, x))
643 {}
644
645 //! <b>Effects</b>: to-do
646 //!
b32b8144 647 BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl& operator=(BOOST_RV_REF(unordered_multiset_impl) x)
7c673cae
FG
648 { return static_cast<unordered_multiset_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
649
650 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
651
652 //! @copydoc ::boost::intrusive::hashtable::~hashtable()
653 ~unordered_multiset_impl();
654
655 //! @copydoc ::boost::intrusive::hashtable::begin()
1e59de90 656 iterator begin() BOOST_NOEXCEPT;
7c673cae
FG
657
658 //! @copydoc ::boost::intrusive::hashtable::begin()const
1e59de90 659 const_iterator begin() const BOOST_NOEXCEPT;
7c673cae
FG
660
661 //! @copydoc ::boost::intrusive::hashtable::cbegin()const
1e59de90 662 const_iterator cbegin() const BOOST_NOEXCEPT;
7c673cae
FG
663
664 //! @copydoc ::boost::intrusive::hashtable::end()
1e59de90 665 iterator end() BOOST_NOEXCEPT;
7c673cae
FG
666
667 //! @copydoc ::boost::intrusive::hashtable::end()const
1e59de90 668 const_iterator end() const BOOST_NOEXCEPT;
7c673cae
FG
669
670 //! @copydoc ::boost::intrusive::hashtable::cend()const
1e59de90 671 const_iterator cend() const BOOST_NOEXCEPT;
7c673cae
FG
672
673 //! @copydoc ::boost::intrusive::hashtable::hash_function()const
674 hasher hash_function() const;
675
676 //! @copydoc ::boost::intrusive::hashtable::key_eq()const
677 key_equal key_eq() const;
678
679 //! @copydoc ::boost::intrusive::hashtable::empty()const
1e59de90 680 bool empty() const BOOST_NOEXCEPT;
7c673cae
FG
681
682 //! @copydoc ::boost::intrusive::hashtable::size()const
1e59de90 683 size_type size() const BOOST_NOEXCEPT;
7c673cae
FG
684
685 //! @copydoc ::boost::intrusive::hashtable::hashtable
686 void swap(unordered_multiset_impl& other);
687
688 //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
689 template <class Cloner, class Disposer>
690 void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer);
691
692 #else
693
694 using table_type::clone_from;
695
696 #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
697
698 //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
699 template <class Cloner, class Disposer>
b32b8144 700 BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset_impl) src, Cloner cloner, Disposer disposer)
7c673cae
FG
701 { table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
702
703 //! @copydoc ::boost::intrusive::hashtable::insert_equal(reference)
b32b8144 704 BOOST_INTRUSIVE_FORCEINLINE iterator insert(reference value)
7c673cae
FG
705 { return table_type::insert_equal(value); }
706
707 //! @copydoc ::boost::intrusive::hashtable::insert_equal(Iterator,Iterator)
708 template<class Iterator>
b32b8144 709 BOOST_INTRUSIVE_FORCEINLINE void insert(Iterator b, Iterator e)
7c673cae
FG
710 { table_type::insert_equal(b, e); }
711
712 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
713
714 //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
715 void erase(const_iterator i);
716
717 //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
1e59de90 718 void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
7c673cae
FG
719
720 //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
721 size_type erase(const key_type &key);
722
723 //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
724 template<class KeyType, class KeyHasher, class KeyEqual>
725 size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
726
727 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
728 template<class Disposer>
729 BOOST_INTRUSIVE_DOC1ST(void
730 , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
1e59de90 731 erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
7c673cae
FG
732
733 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
734 template<class Disposer>
1e59de90 735 void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
7c673cae
FG
736
737 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
738 template<class Disposer>
739 size_type erase_and_dispose(const key_type &key, Disposer disposer);
740
741 //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
742 template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
743 size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
744
745 //! @copydoc ::boost::intrusive::hashtable::clear
1e59de90 746 void clear() BOOST_NOEXCEPT;
7c673cae
FG
747
748 //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
749 template<class Disposer>
1e59de90 750 void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
7c673cae
FG
751
752 //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
753 size_type count(const key_type &key) const;
754
755 //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
756 template<class KeyType, class KeyHasher, class KeyEqual>
757 size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
758
759 //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
760 iterator find(const key_type &key);
761
762 //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
763 template<class KeyType, class KeyHasher, class KeyEqual>
764 iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
765
766 //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
767 const_iterator find(const key_type &key) const;
768
769 //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
770 template<class KeyType, class KeyHasher, class KeyEqual>
771 const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
772
773 //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
774 std::pair<iterator,iterator> equal_range(const key_type &key);
775
776 //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
777 template<class KeyType, class KeyHasher, class KeyEqual>
778 std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
779
780 //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
781 std::pair<const_iterator, const_iterator>
782 equal_range(const key_type &key) const;
783
784 //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
785 template<class KeyType, class KeyHasher, class KeyEqual>
786 std::pair<const_iterator, const_iterator>
787 equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
788
789 //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
1e59de90 790 iterator iterator_to(reference value) BOOST_NOEXCEPT;
7c673cae
FG
791
792 //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
1e59de90 793 const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
7c673cae
FG
794
795 //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
1e59de90 796 static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT;
7c673cae
FG
797
798 //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
1e59de90 799 static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT;
7c673cae
FG
800
801 //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
1e59de90 802 local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT;
7c673cae
FG
803
804 //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
1e59de90 805 const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT;
7c673cae
FG
806
807 //! @copydoc ::boost::intrusive::hashtable::bucket_count
1e59de90 808 size_type bucket_count() const BOOST_NOEXCEPT;
7c673cae
FG
809
810 //! @copydoc ::boost::intrusive::hashtable::bucket_size
1e59de90 811 size_type bucket_size(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
812
813 //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
814 size_type bucket(const key_type& k) const;
815
816 //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
817 template<class KeyType, class KeyHasher>
818 size_type bucket(const KeyType& k, KeyHasher hash_func) const;
819
820 //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
1e59de90 821 bucket_ptr bucket_pointer() const BOOST_NOEXCEPT;
7c673cae
FG
822
823 //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
1e59de90 824 local_iterator begin(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
825
826 //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
1e59de90 827 const_local_iterator begin(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
828
829 //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
1e59de90 830 const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
831
832 //! @copydoc ::boost::intrusive::hashtable::end(size_type)
1e59de90 833 local_iterator end(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
834
835 //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
1e59de90 836 const_local_iterator end(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
837
838 //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
1e59de90 839 const_local_iterator cend(size_type n) const BOOST_NOEXCEPT;
7c673cae
FG
840
841 //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
842 void rehash(const bucket_traits &new_bucket_traits);
843
844 //! @copydoc ::boost::intrusive::hashtable::full_rehash
845 void full_rehash();
846
847 //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
848 bool incremental_rehash(bool grow = true);
849
850 //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
851 bool incremental_rehash(const bucket_traits &new_bucket_traits);
852
853 //! @copydoc ::boost::intrusive::hashtable::split_count
1e59de90 854 size_type split_count() const BOOST_NOEXCEPT;
7c673cae
FG
855
856 //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
1e59de90 857 static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
858
859 //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
1e59de90 860 static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT;
7c673cae
FG
861
862 #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
863};
864
865//! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
866//! same options (either explicitly or implicitly) are used.
867#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
868template<class T, class ...Options>
869#else
870template<class T, class O1 = void, class O2 = void
871 , class O3 = void, class O4 = void
872 , class O5 = void, class O6 = void
873 , class O7 = void, class O8 = void
874 , class O9 = void, class O10= void
875 >
876#endif
877struct make_unordered_multiset
878{
879 /// @cond
880 typedef typename pack_options
881 < hashtable_defaults,
882 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
883 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
884 #else
885 Options...
886 #endif
887 >::type packed_options;
888
889 typedef typename detail::get_value_traits
890 <T, typename packed_options::proto_value_traits>::type value_traits;
891
892 typedef typename make_bucket_traits
893 <T, true, packed_options>::type bucket_traits;
894
895 typedef unordered_multiset_impl
896 < value_traits
897 , typename packed_options::key_of_value
898 , typename packed_options::hash
899 , typename packed_options::equal
900 , typename packed_options::size_type
901 , bucket_traits
902 , (std::size_t(false)*hash_bool_flags::unique_keys_pos)
903 | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
904 | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
905 | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
906 | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
907 | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
908 > implementation_defined;
909
910 /// @endcond
911 typedef implementation_defined type;
912};
913
914#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
915
916#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
917template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
918#else
919template<class T, class ...Options>
920#endif
921class unordered_multiset
922 : public make_unordered_multiset<T,
923 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
924 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
925 #else
926 Options...
927 #endif
928 >::type
929{
930 typedef typename make_unordered_multiset
931 <T,
932 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
933 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
934 #else
935 Options...
936 #endif
937 >::type Base;
938 //Assert if passed value traits are compatible with the type
939 BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
940 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset)
941
942 public:
943 typedef typename Base::value_traits value_traits;
944 typedef typename Base::bucket_traits bucket_traits;
945 typedef typename Base::iterator iterator;
946 typedef typename Base::const_iterator const_iterator;
947 typedef typename Base::bucket_ptr bucket_ptr;
948 typedef typename Base::size_type size_type;
949 typedef typename Base::hasher hasher;
950 typedef typename Base::key_equal key_equal;
951
92f5a8d4 952 BOOST_INTRUSIVE_FORCEINLINE
7c673cae
FG
953 explicit unordered_multiset( const bucket_traits &b_traits
954 , const hasher & hash_func = hasher()
955 , const key_equal &equal_func = key_equal()
956 , const value_traits &v_traits = value_traits())
957 : Base(b_traits, hash_func, equal_func, v_traits)
958 {}
959
92f5a8d4
TL
960 template<class Iterator>
961 BOOST_INTRUSIVE_FORCEINLINE
7c673cae
FG
962 unordered_multiset( Iterator b
963 , Iterator e
964 , const bucket_traits &b_traits
965 , const hasher & hash_func = hasher()
966 , const key_equal &equal_func = key_equal()
967 , const value_traits &v_traits = value_traits())
968 : Base(b, e, b_traits, hash_func, equal_func, v_traits)
969 {}
970
b32b8144 971 BOOST_INTRUSIVE_FORCEINLINE unordered_multiset(BOOST_RV_REF(unordered_multiset) x)
7c673cae
FG
972 : Base(BOOST_MOVE_BASE(Base, x))
973 {}
974
b32b8144 975 BOOST_INTRUSIVE_FORCEINLINE unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
7c673cae
FG
976 { return static_cast<unordered_multiset&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
977
978 template <class Cloner, class Disposer>
b32b8144 979 BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
7c673cae
FG
980 { Base::clone_from(src, cloner, disposer); }
981
982 template <class Cloner, class Disposer>
b32b8144 983 BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset) src, Cloner cloner, Disposer disposer)
7c673cae
FG
984 { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
985};
986
987#endif
988
989} //namespace intrusive
990} //namespace boost
991
992#include <boost/intrusive/detail/config_end.hpp>
993
994#endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP