comparison DEPENDENCIES/generic/include/boost/intrusive/unordered_set.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga 2006-2013
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/move.hpp>
20 #include <iterator>
21
22
23 namespace boost {
24 namespace intrusive {
25
26 //! The class template unordered_set is an intrusive container, that mimics most of
27 //! the interface of std::tr1::unordered_set as described in the C++ TR1.
28 //!
29 //! unordered_set is a semi-intrusive container: each object to be stored in the
30 //! container must contain a proper hook, but the container also needs
31 //! additional auxiliary memory to work: unordered_set needs a pointer to an array
32 //! of type `bucket_type` to be passed in the constructor. This bucket array must
33 //! have at least the same lifetime as the container. This makes the use of
34 //! unordered_set more complicated than purely intrusive containers.
35 //! `bucket_type` is default-constructible, copyable and assignable
36 //!
37 //! The template parameter \c T is the type to be managed by the container.
38 //! The user can specify additional options and if no options are provided
39 //! default options are used.
40 //!
41 //! The container supports the following options:
42 //! \c base_hook<>/member_hook<>/value_traits<>,
43 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
44 //! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
45 //!
46 //! unordered_set only provides forward iterators but it provides 4 iterator types:
47 //! iterator and const_iterator to navigate through the whole container and
48 //! local_iterator and const_local_iterator to navigate through the values
49 //! stored in a single bucket. Local iterators are faster and smaller.
50 //!
51 //! It's not recommended to use non constant-time size unordered_sets because several
52 //! key functions, like "empty()", become non-constant time functions. Non
53 //! constant-time size unordered_sets are mainly provided to support auto-unlink hooks.
54 //!
55 //! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor
56 //! offers functions related to a load factor. Rehashing can be explicitly requested
57 //! and the user must provide a new bucket array that will be used from that moment.
58 //!
59 //! Since no automatic rehashing is done, iterators are never invalidated when
60 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
61 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
62 template<class T, class ...Options>
63 #else
64 template<class ValueTraits, class Hash, class Equal, class SizeType, class BucketTraits, std::size_t BoolFlags>
65 #endif
66 class unordered_set_impl
67 : public hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags>
68 {
69 /// @cond
70 private:
71 typedef hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags> table_type;
72
73 //! This class is
74 //! movable
75 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set_impl)
76
77 typedef table_type implementation_defined;
78 /// @endcond
79
80 public:
81 typedef typename implementation_defined::value_type value_type;
82 typedef typename implementation_defined::value_traits value_traits;
83 typedef typename implementation_defined::bucket_traits bucket_traits;
84 typedef typename implementation_defined::pointer pointer;
85 typedef typename implementation_defined::const_pointer const_pointer;
86 typedef typename implementation_defined::reference reference;
87 typedef typename implementation_defined::const_reference const_reference;
88 typedef typename implementation_defined::difference_type difference_type;
89 typedef typename implementation_defined::size_type size_type;
90 typedef typename implementation_defined::key_type key_type;
91 typedef typename implementation_defined::key_equal key_equal;
92 typedef typename implementation_defined::hasher hasher;
93 typedef typename implementation_defined::bucket_type bucket_type;
94 typedef typename implementation_defined::bucket_ptr bucket_ptr;
95 typedef typename implementation_defined::iterator iterator;
96 typedef typename implementation_defined::const_iterator const_iterator;
97 typedef typename implementation_defined::insert_commit_data insert_commit_data;
98 typedef typename implementation_defined::local_iterator local_iterator;
99 typedef typename implementation_defined::const_local_iterator const_local_iterator;
100 typedef typename implementation_defined::node_traits node_traits;
101 typedef typename implementation_defined::node node;
102 typedef typename implementation_defined::node_ptr node_ptr;
103 typedef typename implementation_defined::const_node_ptr const_node_ptr;
104 typedef typename implementation_defined::node_algorithms node_algorithms;
105
106 public:
107
108 //! <b>Requires</b>: buckets must not be being used by any other resource.
109 //!
110 //! <b>Effects</b>: Constructs an empty unordered_set_impl, storing a reference
111 //! to the bucket array and copies of the hasher and equal functors.
112 //!
113 //! <b>Complexity</b>: Constant.
114 //!
115 //! <b>Throws</b>: If value_traits::node_traits::node
116 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
117 //! or the copy constructor or invocation of Hash or Equal throws.
118 //!
119 //! <b>Notes</b>: buckets array must be disposed only after
120 //! *this is disposed.
121 explicit unordered_set_impl( const bucket_traits &b_traits
122 , const hasher & hash_func = hasher()
123 , const key_equal &equal_func = key_equal()
124 , const value_traits &v_traits = value_traits())
125 : table_type(b_traits, hash_func, equal_func, v_traits)
126 {}
127
128 //! <b>Requires</b>: buckets must not be being used by any other resource
129 //! and Dereferencing iterator must yield an lvalue of type value_type.
130 //!
131 //! <b>Effects</b>: Constructs an empty unordered_set and inserts elements from
132 //! [b, e).
133 //!
134 //! <b>Complexity</b>: If N is std::distance(b, e): Average case is O(N)
135 //! (with a good hash function and with buckets_len >= N),worst case O(N2).
136 //!
137 //! <b>Throws</b>: If value_traits::node_traits::node
138 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
139 //! or the copy constructor or invocation of hasher or key_equal throws.
140 //!
141 //! <b>Notes</b>: buckets array must be disposed only after
142 //! *this is disposed.
143 template<class Iterator>
144 unordered_set_impl( Iterator b
145 , Iterator e
146 , const bucket_traits &b_traits
147 , const hasher & hash_func = hasher()
148 , const key_equal &equal_func = key_equal()
149 , const value_traits &v_traits = value_traits())
150 : table_type(b_traits, hash_func, equal_func, v_traits)
151 { table_type::insert_unique(b, e); }
152
153 //! <b>Effects</b>: to-do
154 //!
155 unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x)
156 : table_type(::boost::move(static_cast<table_type&>(x)))
157 {}
158
159 //! <b>Effects</b>: to-do
160 //!
161 unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x)
162 { return static_cast<unordered_set_impl&>(table_type::operator=(::boost::move(static_cast<table_type&>(x)))); }
163
164 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
165 //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set
166 //! are not deleted (i.e. no destructors are called).
167 //!
168 //! <b>Complexity</b>: Linear to the number of elements in the unordered_set, if
169 //! it's a safe-mode or auto-unlink value. Otherwise constant.
170 //!
171 //! <b>Throws</b>: Nothing.
172 ~unordered_set_impl()
173 {}
174
175 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
176 //!
177 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
178 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
179 //!
180 //! <b>Throws</b>: Nothing.
181 iterator begin()
182 { return table_type::begin(); }
183
184 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
185 //! of the unordered_set.
186 //!
187 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
188 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
189 //!
190 //! <b>Throws</b>: Nothing.
191 const_iterator begin() const
192 { return table_type::begin(); }
193
194 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
195 //! of the unordered_set.
196 //!
197 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
198 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
199 //!
200 //! <b>Throws</b>: Nothing.
201 const_iterator cbegin() const
202 { return table_type::cbegin(); }
203
204 //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
205 //!
206 //! <b>Complexity</b>: Constant.
207 //!
208 //! <b>Throws</b>: Nothing.
209 iterator end()
210 { return table_type::end(); }
211
212 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
213 //!
214 //! <b>Complexity</b>: Constant.
215 //!
216 //! <b>Throws</b>: Nothing.
217 const_iterator end() const
218 { return table_type::end(); }
219
220 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
221 //!
222 //! <b>Complexity</b>: Constant.
223 //!
224 //! <b>Throws</b>: Nothing.
225 const_iterator cend() const
226 { return table_type::cend(); }
227
228 //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
229 //!
230 //! <b>Complexity</b>: Constant.
231 //!
232 //! <b>Throws</b>: If hasher copy-constructor throws.
233 hasher hash_function() const
234 { return table_type::hash_function(); }
235
236 //! <b>Effects</b>: Returns the key_equal object used by the unordered_set.
237 //!
238 //! <b>Complexity</b>: Constant.
239 //!
240 //! <b>Throws</b>: If key_equal copy-constructor throws.
241 key_equal key_eq() const
242 { return table_type::key_eq(); }
243
244 //! <b>Effects</b>: Returns true if the container is empty.
245 //!
246 //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
247 //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
248 //! Otherwise constant.
249 //!
250 //! <b>Throws</b>: Nothing.
251 bool empty() const
252 { return table_type::empty(); }
253
254 //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
255 //!
256 //! <b>Complexity</b>: Linear to elements contained in *this if
257 //! constant-time size option is disabled. Constant-time otherwise.
258 //!
259 //! <b>Throws</b>: Nothing.
260 size_type size() const
261 { return table_type::size(); }
262
263 //! <b>Requires</b>: the hasher and the equality function unqualified swap
264 //! call should not throw.
265 //!
266 //! <b>Effects</b>: Swaps the contents of two unordered_sets.
267 //! Swaps also the contained bucket array and equality and hasher functors.
268 //!
269 //! <b>Complexity</b>: Constant.
270 //!
271 //! <b>Throws</b>: If the swap() call for the comparison or hash functors
272 //! found using ADL throw. Basic guarantee.
273 void swap(unordered_set_impl& other)
274 { table_type::swap(other.table_); }
275
276 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
277 //! Cloner should yield to nodes that compare equal and produce the same
278 //! hash than the original node.
279 //!
280 //! <b>Effects</b>: Erases all the elements from *this
281 //! calling Disposer::operator()(pointer), clones all the
282 //! elements from src calling Cloner::operator()(const_reference )
283 //! and inserts them on *this. The hash function and the equality
284 //! predicate are copied from the source.
285 //!
286 //! If store_hash option is true, this method does not use the hash function.
287 //!
288 //! If any operation throws, all cloned elements are unlinked and disposed
289 //! calling Disposer::operator()(pointer).
290 //!
291 //! <b>Complexity</b>: Linear to erased plus inserted elements.
292 //!
293 //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
294 //! throws. Basic guarantee.
295 template <class Cloner, class Disposer>
296 void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer)
297 { table_type::clone_from(src.table_, cloner, disposer); }
298
299 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
300
301 //! <b>Requires</b>: value must be an lvalue
302 //!
303 //! <b>Effects</b>: Tries to inserts value into the unordered_set.
304 //!
305 //! <b>Returns</b>: If the value
306 //! is not already present inserts it and returns a pair containing the
307 //! iterator to the new value and true. If there is an equivalent value
308 //! returns a pair containing an iterator to the already present value
309 //! and false.
310 //!
311 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
312 //!
313 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
314 //!
315 //! <b>Note</b>: Does not affect the validity of iterators and references.
316 //! No copy-constructors are called.
317 std::pair<iterator, bool> insert(reference value)
318 { return table_type::insert_unique(value); }
319
320 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
321 //! of type value_type.
322 //!
323 //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
324 //!
325 //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e).
326 //! Worst case O(N*this->size()).
327 //!
328 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
329 //!
330 //! <b>Note</b>: Does not affect the validity of iterators and references.
331 //! No copy-constructors are called.
332 template<class Iterator>
333 void insert(Iterator b, Iterator e)
334 { table_type::insert_unique(b, e); }
335
336 //! <b>Requires</b>: "hasher" must be a hash function that induces
337 //! the same hash values as the stored hasher. The difference is that
338 //! "hasher" hashes the given key instead of the value_type.
339 //!
340 //! "key_value_equal" must be a equality function that induces
341 //! the same equality as key_equal. The difference is that
342 //! "key_value_equal" compares an arbitrary key with the contained values.
343 //!
344 //! <b>Effects</b>: Checks if a value can be inserted in the unordered_set, using
345 //! a user provided key instead of the value itself.
346 //!
347 //! <b>Returns</b>: If there is an equivalent value
348 //! returns a pair containing an iterator to the already present value
349 //! and false. If the value can be inserted returns true in the returned
350 //! pair boolean and fills "commit_data" that is meant to be used with
351 //! the "insert_commit" function.
352 //!
353 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
354 //!
355 //! <b>Throws</b>: If hasher or key_value_equal throw. Strong guarantee.
356 //!
357 //! <b>Notes</b>: This function is used to improve performance when constructing
358 //! a value_type is expensive: if there is an equivalent value
359 //! the constructed object must be discarded. Many times, the part of the
360 //! node that is used to impose the hash or the equality is much cheaper to
361 //! construct than the value_type and this function offers the possibility to
362 //! use that the part to check if the insertion will be successful.
363 //!
364 //! If the check is successful, the user can construct the value_type and use
365 //! "insert_commit" to insert the object in constant-time.
366 //!
367 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
368 //! objects are inserted or erased from the unordered_set.
369 //!
370 //! After a successful rehashing insert_commit_data remains valid.
371 template<class KeyType, class KeyHasher, class KeyValueEqual>
372 std::pair<iterator, bool> insert_check
373 (const KeyType &key, KeyHasher hasher, KeyValueEqual key_value_equal, insert_commit_data &commit_data)
374 { return table_type::insert_unique_check(key, hasher, key_value_equal, commit_data); }
375
376 //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
377 //! must have been obtained from a previous call to "insert_check".
378 //! No objects should have been inserted or erased from the unordered_set between
379 //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
380 //!
381 //! <b>Effects</b>: Inserts the value in the unordered_set using the information obtained
382 //! from the "commit_data" that a previous "insert_check" filled.
383 //!
384 //! <b>Returns</b>: An iterator to the newly inserted object.
385 //!
386 //! <b>Complexity</b>: Constant time.
387 //!
388 //! <b>Throws</b>: Nothing.
389 //!
390 //! <b>Notes</b>: This function has only sense if a "insert_check" has been
391 //! previously executed to fill "commit_data". No value should be inserted or
392 //! erased between the "insert_check" and "insert_commit" calls.
393 //!
394 //! After a successful rehashing insert_commit_data remains valid.
395 iterator insert_commit(reference value, const insert_commit_data &commit_data)
396 { return table_type::insert_unique_commit(value, commit_data); }
397
398 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
399
400 //! <b>Effects</b>: Erases the element pointed to by i.
401 //!
402 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
403 //!
404 //! <b>Throws</b>: Nothing.
405 //!
406 //! <b>Note</b>: Invalidates the iterators (but not the references)
407 //! to the erased element. No destructors are called.
408 void erase(const_iterator i)
409 { table_type::erase(i); }
410
411 //! <b>Effects</b>: Erases the range pointed to by b end e.
412 //!
413 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
414 //! worst case O(this->size()).
415 //!
416 //! <b>Throws</b>: Nothing.
417 //!
418 //! <b>Note</b>: Invalidates the iterators (but not the references)
419 //! to the erased elements. No destructors are called.
420 void erase(const_iterator b, const_iterator e)
421 { table_type::erase(b, e); }
422
423 //! <b>Effects</b>: Erases all the elements with the given value.
424 //!
425 //! <b>Returns</b>: The number of erased elements.
426 //!
427 //! <b>Complexity</b>: Average case O(this->count(value)).
428 //! Worst case O(this->size()).
429 //!
430 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
431 //!
432 //! <b>Note</b>: Invalidates the iterators (but not the references)
433 //! to the erased elements. No destructors are called.
434 size_type erase(const_reference value)
435 { return table_type::erase(value); }
436
437 //! <b>Requires</b>: "hasher" must be a hash function that induces
438 //! the same hash values as the stored hasher. The difference is that
439 //! "hasher" hashes the given key instead of the value_type.
440 //!
441 //! "key_value_equal" must be a equality function that induces
442 //! the same equality as key_equal. The difference is that
443 //! "key_value_equal" compares an arbitrary key with the contained values.
444 //!
445 //! <b>Effects</b>: Erases all the elements that have the same hash and
446 //! compare equal with the given key.
447 //!
448 //! <b>Returns</b>: The number of erased elements.
449 //!
450 //! <b>Complexity</b>: Average case O(this->count(value)).
451 //! Worst case O(this->size()).
452 //!
453 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
454 //!
455 //! <b>Note</b>: Invalidates the iterators (but not the references)
456 //! to the erased elements. No destructors are called.
457 template<class KeyType, class KeyHasher, class KeyValueEqual>
458 size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
459 { return table_type::erase(key, hash_func, equal_func); }
460
461 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
462 //!
463 //! <b>Effects</b>: Erases the element pointed to by i.
464 //! Disposer::operator()(pointer) is called for the removed element.
465 //!
466 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
467 //!
468 //! <b>Throws</b>: Nothing.
469 //!
470 //! <b>Note</b>: Invalidates the iterators
471 //! to the erased elements.
472 template<class Disposer>
473 void erase_and_dispose(const_iterator i, Disposer disposer
474 /// @cond
475 , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
476 /// @endcond
477 )
478 { table_type::erase_and_dispose(i, disposer); }
479
480 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
481 //!
482 //! <b>Effects</b>: Erases the range pointed to by b end e.
483 //! Disposer::operator()(pointer) is called for the removed elements.
484 //!
485 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
486 //! worst case O(this->size()).
487 //!
488 //! <b>Throws</b>: Nothing.
489 //!
490 //! <b>Note</b>: Invalidates the iterators
491 //! to the erased elements.
492 template<class Disposer>
493 void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
494 { table_type::erase_and_dispose(b, e, disposer); }
495
496 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
497 //!
498 //! <b>Effects</b>: Erases all the elements with the given value.
499 //! Disposer::operator()(pointer) is called for the removed elements.
500 //!
501 //! <b>Returns</b>: The number of erased elements.
502 //!
503 //! <b>Complexity</b>: Average case O(this->count(value)).
504 //! Worst case O(this->size()).
505 //!
506 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
507 //!
508 //! <b>Note</b>: Invalidates the iterators (but not the references)
509 //! to the erased elements. No destructors are called.
510 template<class Disposer>
511 size_type erase_and_dispose(const_reference value, Disposer disposer)
512 { return table_type::erase_and_dispose(value, disposer); }
513
514 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
515 //!
516 //! <b>Effects</b>: Erases all the elements with the given key.
517 //! according to the comparison functor "equal_func".
518 //! Disposer::operator()(pointer) is called for the removed elements.
519 //!
520 //! <b>Returns</b>: The number of erased elements.
521 //!
522 //! <b>Complexity</b>: Average case O(this->count(value)).
523 //! Worst case O(this->size()).
524 //!
525 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
526 //!
527 //! <b>Note</b>: Invalidates the iterators
528 //! to the erased elements.
529 template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
530 size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
531 { return table_type::erase_and_dispose(key, hash_func, equal_func, disposer); }
532
533 //! <b>Effects</b>: Erases all of the elements.
534 //!
535 //! <b>Complexity</b>: Linear to the number of elements on the container.
536 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
537 //!
538 //! <b>Throws</b>: Nothing.
539 //!
540 //! <b>Note</b>: Invalidates the iterators (but not the references)
541 //! to the erased elements. No destructors are called.
542 void clear()
543 { return table_type::clear(); }
544
545 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
546 //!
547 //! <b>Effects</b>: Erases all of the elements.
548 //!
549 //! <b>Complexity</b>: Linear to the number of elements on the container.
550 //! Disposer::operator()(pointer) is called for the removed elements.
551 //!
552 //! <b>Throws</b>: Nothing.
553 //!
554 //! <b>Note</b>: Invalidates the iterators (but not the references)
555 //! to the erased elements. No destructors are called.
556 template<class Disposer>
557 void clear_and_dispose(Disposer disposer)
558 { return table_type::clear_and_dispose(disposer); }
559
560 //! <b>Effects</b>: Returns the number of contained elements with the given value
561 //!
562 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
563 //!
564 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
565 size_type count(const_reference value) const
566 { return table_type::find(value) != end(); }
567
568 //! <b>Requires</b>: "hash_func" must be a hash function that induces
569 //! the same hash values as the stored hasher. The difference is that
570 //! "hash_func" hashes the given key instead of the value_type.
571 //!
572 //! "equal_func" must be a equality function that induces
573 //! the same equality as key_equal. The difference is that
574 //! "equal_func" compares an arbitrary key with the contained values.
575 //!
576 //! <b>Effects</b>: Returns the number of contained elements with the given key
577 //!
578 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
579 //!
580 //! <b>Throws</b>: If hash_func or equal_func throw.
581 template<class KeyType, class KeyHasher, class KeyValueEqual>
582 size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
583 { return table_type::find(key, hash_func, equal_func) != end(); }
584
585 //! <b>Effects</b>: Finds an iterator to the first element is equal to
586 //! "value" or end() if that element does not exist.
587 //!
588 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
589 //!
590 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
591 iterator find(const_reference value)
592 { return table_type::find(value); }
593
594 //! <b>Requires</b>: "hash_func" must be a hash function that induces
595 //! the same hash values as the stored hasher. The difference is that
596 //! "hash_func" hashes the given key instead of the value_type.
597 //!
598 //! "equal_func" must be a equality function that induces
599 //! the same equality as key_equal. The difference is that
600 //! "equal_func" compares an arbitrary key with the contained values.
601 //!
602 //! <b>Effects</b>: Finds an iterator to the first element whose key is
603 //! "key" according to the given hasher and equality functor or end() if
604 //! that element does not exist.
605 //!
606 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
607 //!
608 //! <b>Throws</b>: If hash_func or equal_func throw.
609 //!
610 //! <b>Note</b>: This function is used when constructing a value_type
611 //! is expensive and the value_type can be compared with a cheaper
612 //! key type. Usually this key is part of the value_type.
613 template<class KeyType, class KeyHasher, class KeyValueEqual>
614 iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
615 { return table_type::find(key, hash_func, equal_func); }
616
617 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
618 //! "key" or end() if that element does not exist.
619 //!
620 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
621 //!
622 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
623 const_iterator find(const_reference value) const
624 { return table_type::find(value); }
625
626 //! <b>Requires</b>: "hash_func" must be a hash function that induces
627 //! the same hash values as the stored hasher. The difference is that
628 //! "hash_func" hashes the given key instead of the value_type.
629 //!
630 //! "equal_func" must be a equality function that induces
631 //! the same equality as key_equal. The difference is that
632 //! "equal_func" compares an arbitrary key with the contained values.
633 //!
634 //! <b>Effects</b>: Finds an iterator to the first element whose key is
635 //! "key" according to the given hasher and equality functor or end() if
636 //! that element does not exist.
637 //!
638 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
639 //!
640 //! <b>Throws</b>: If hash_func or equal_func throw.
641 //!
642 //! <b>Note</b>: This function is used when constructing a value_type
643 //! is expensive and the value_type can be compared with a cheaper
644 //! key type. Usually this key is part of the value_type.
645 template<class KeyType, class KeyHasher, class KeyValueEqual>
646 const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
647 { return table_type::find(key, hash_func, equal_func); }
648
649 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
650 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
651 //! elements exist.
652 //!
653 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
654 //!
655 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
656 std::pair<iterator,iterator> equal_range(const_reference value)
657 { return table_type::equal_range(value); }
658
659 //! <b>Requires</b>: "hash_func" must be a hash function that induces
660 //! the same hash values as the stored hasher. The difference is that
661 //! "hash_func" hashes the given key instead of the value_type.
662 //!
663 //! "equal_func" must be a equality function that induces
664 //! the same equality as key_equal. The difference is that
665 //! "equal_func" compares an arbitrary key with the contained values.
666 //!
667 //! <b>Effects</b>: Returns a range containing all elements with equivalent
668 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
669 //! elements exist.
670 //!
671 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, hash_func)).
672 //! Worst case O(this->size()).
673 //!
674 //! <b>Throws</b>: If hash_func or the equal_func throw.
675 //!
676 //! <b>Note</b>: This function is used when constructing a value_type
677 //! is expensive and the value_type can be compared with a cheaper
678 //! key type. Usually this key is part of the value_type.
679 template<class KeyType, class KeyHasher, class KeyValueEqual>
680 std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
681 { return table_type::equal_range(key, hash_func, equal_func); }
682
683 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
684 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
685 //! elements exist.
686 //!
687 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
688 //!
689 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
690 std::pair<const_iterator, const_iterator>
691 equal_range(const_reference value) const
692 { return table_type::equal_range(value); }
693
694 //! <b>Requires</b>: "hash_func" must be a hash function that induces
695 //! the same hash values as the stored hasher. The difference is that
696 //! "hash_func" hashes the given key instead of the value_type.
697 //!
698 //! "equal_func" must be a equality function that induces
699 //! the same equality as key_equal. The difference is that
700 //! "equal_func" compares an arbitrary key with the contained values.
701 //!
702 //! <b>Effects</b>: Returns a range containing all elements with equivalent
703 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
704 //! elements exist.
705 //!
706 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
707 //! Worst case O(this->size()).
708 //!
709 //! <b>Throws</b>: If the hash_func or equal_func throw.
710 //!
711 //! <b>Note</b>: This function is used when constructing a value_type
712 //! is expensive and the value_type can be compared with a cheaper
713 //! key type. Usually this key is part of the value_type.
714 template<class KeyType, class KeyHasher, class KeyValueEqual>
715 std::pair<const_iterator, const_iterator>
716 equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
717 { return table_type::equal_range(key, hash_func, equal_func); }
718
719 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
720 //! appropriate type. Otherwise the behavior is undefined.
721 //!
722 //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_set
723 //! that points to the value
724 //!
725 //! <b>Complexity</b>: Constant.
726 //!
727 //! <b>Throws</b>: If the internal hash function throws.
728 iterator iterator_to(reference value)
729 { return table_type::iterator_to(value); }
730
731 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
732 //! appropriate type. Otherwise the behavior is undefined.
733 //!
734 //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
735 //! unordered_set that points to the value
736 //!
737 //! <b>Complexity</b>: Constant.
738 //!
739 //! <b>Throws</b>: If the internal hash function throws.
740 const_iterator iterator_to(const_reference value) const
741 { return table_type::iterator_to(value); }
742
743 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
744 //! appropriate type. Otherwise the behavior is undefined.
745 //!
746 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
747 //! that points to the value
748 //!
749 //! <b>Complexity</b>: Constant.
750 //!
751 //! <b>Throws</b>: Nothing.
752 //!
753 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
754 //! is stateless.
755 static local_iterator s_local_iterator_to(reference value)
756 { return table_type::s_local_iterator_to(value); }
757
758 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
759 //! appropriate type. Otherwise the behavior is undefined.
760 //!
761 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
762 //! the unordered_set that points to the value
763 //!
764 //! <b>Complexity</b>: Constant.
765 //!
766 //! <b>Throws</b>: Nothing.
767 //!
768 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
769 //! is stateless.
770 static const_local_iterator s_local_iterator_to(const_reference value)
771 { return table_type::s_local_iterator_to(value); }
772
773 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
774 //! appropriate type. Otherwise the behavior is undefined.
775 //!
776 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
777 //! that points to the value
778 //!
779 //! <b>Complexity</b>: Constant.
780 //!
781 //! <b>Throws</b>: Nothing.
782 local_iterator local_iterator_to(reference value)
783 { return table_type::local_iterator_to(value); }
784
785 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
786 //! appropriate type. Otherwise the behavior is undefined.
787 //!
788 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
789 //! the unordered_set that points to the value
790 //!
791 //! <b>Complexity</b>: Constant.
792 //!
793 //! <b>Throws</b>: Nothing.
794 const_local_iterator local_iterator_to(const_reference value) const
795 { return table_type::local_iterator_to(value); }
796
797 //! <b>Effects</b>: Returns the number of buckets passed in the constructor
798 //! or the last rehash function.
799 //!
800 //! <b>Complexity</b>: Constant.
801 //!
802 //! <b>Throws</b>: Nothing.
803 size_type bucket_count() const
804 { return table_type::bucket_count(); }
805
806 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
807 //!
808 //! <b>Effects</b>: Returns the number of elements in the nth bucket.
809 //!
810 //! <b>Complexity</b>: Constant.
811 //!
812 //! <b>Throws</b>: Nothing.
813 size_type bucket_size(size_type n) const
814 { return table_type::bucket_size(n); }
815
816 //! <b>Effects</b>: Returns the index of the bucket in which elements
817 //! with keys equivalent to k would be found, if any such element existed.
818 //!
819 //! <b>Complexity</b>: Constant.
820 //!
821 //! <b>Throws</b>: If the hash functor throws.
822 //!
823 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
824 size_type bucket(const value_type& k) const
825 { return table_type::bucket(k); }
826
827 //! <b>Requires</b>: "hash_func" must be a hash function that induces
828 //! the same hash values as the stored hasher. The difference is that
829 //! "hash_func" hashes the given key instead of the value_type.
830 //!
831 //! <b>Effects</b>: Returns the index of the bucket in which elements
832 //! with keys equivalent to k would be found, if any such element existed.
833 //!
834 //! <b>Complexity</b>: Constant.
835 //!
836 //! <b>Throws</b>: If hash_func throws.
837 //!
838 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
839 template<class KeyType, class KeyHasher>
840 size_type bucket(const KeyType& k, KeyHasher hash_func) const
841 { return table_type::bucket(k, hash_func); }
842
843 //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
844 //! or the last rehash function.
845 //!
846 //! <b>Complexity</b>: Constant.
847 //!
848 //! <b>Throws</b>: Nothing.
849 bucket_ptr bucket_pointer() const
850 { return table_type::bucket_pointer(); }
851
852 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
853 //!
854 //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
855 //! of the sequence stored in the bucket n.
856 //!
857 //! <b>Complexity</b>: Constant.
858 //!
859 //! <b>Throws</b>: Nothing.
860 //!
861 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
862 //! containing all of the elements in the nth bucket.
863 local_iterator begin(size_type n)
864 { return table_type::begin(n); }
865
866 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
867 //!
868 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
869 //! of the sequence stored in the bucket n.
870 //!
871 //! <b>Complexity</b>: Constant.
872 //!
873 //! <b>Throws</b>: Nothing.
874 //!
875 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
876 //! containing all of the elements in the nth bucket.
877 const_local_iterator begin(size_type n) const
878 { return table_type::begin(n); }
879
880 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
881 //!
882 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
883 //! of the sequence stored in the bucket n.
884 //!
885 //! <b>Complexity</b>: Constant.
886 //!
887 //! <b>Throws</b>: Nothing.
888 //!
889 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
890 //! containing all of the elements in the nth bucket.
891 const_local_iterator cbegin(size_type n) const
892 { return table_type::cbegin(n); }
893
894 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
895 //!
896 //! <b>Effects</b>: Returns a local_iterator pointing to the end
897 //! of the sequence stored in the bucket n.
898 //!
899 //! <b>Complexity</b>: Constant.
900 //!
901 //! <b>Throws</b>: Nothing.
902 //!
903 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
904 //! containing all of the elements in the nth bucket.
905 local_iterator end(size_type n)
906 { return table_type::end(n); }
907
908 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
909 //!
910 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
911 //! of the sequence stored in the bucket n.
912 //!
913 //! <b>Complexity</b>: Constant.
914 //!
915 //! <b>Throws</b>: Nothing.
916 //!
917 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
918 //! containing all of the elements in the nth bucket.
919 const_local_iterator end(size_type n) const
920 { return table_type::end(n); }
921
922 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
923 //!
924 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
925 //! of the sequence stored in the bucket n.
926 //!
927 //! <b>Complexity</b>: Constant.
928 //!
929 //! <b>Throws</b>: Nothing.
930 //!
931 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
932 //! containing all of the elements in the nth bucket.
933 const_local_iterator cend(size_type n) const
934 { return table_type::cend(n); }
935
936 //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
937 //! or the same as the old bucket array. new_size is the length of the
938 //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
939 //! n can be bigger or smaller than this->bucket_count().
940 //!
941 //! <b>Effects</b>: Updates the internal reference with the new bucket erases
942 //! the values from the old bucket and inserts then in the new one.
943 //!
944 //! If store_hash option is true, this method does not use the hash function.
945 //!
946 //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
947 //!
948 //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
949 void rehash(const bucket_traits &new_bucket_traits)
950 { table_type::rehash(new_bucket_traits); }
951
952 //! <b>Requires</b>:
953 //!
954 //! <b>Effects</b>:
955 //!
956 //! <b>Complexity</b>:
957 //!
958 //! <b>Throws</b>:
959 //!
960 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
961 bool incremental_rehash(bool grow = true)
962 { return table_type::incremental_rehash(grow); }
963
964 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
965 bool incremental_rehash(const bucket_traits &new_bucket_traits)
966 { return table_type::incremental_rehash(new_bucket_traits); }
967
968 //! <b>Requires</b>:
969 //!
970 //! <b>Effects</b>:
971 //!
972 //! <b>Complexity</b>:
973 //!
974 //! <b>Throws</b>:
975 size_type split_count() const
976 { return table_type::split_count(); }
977
978 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
979 //! the container that is bigger than n. This suggestion can be used
980 //! to create bucket arrays with a size that will usually improve
981 //! container's performance. If such value does not exist, the
982 //! higher possible value is returned.
983 //!
984 //! <b>Complexity</b>: Amortized constant time.
985 //!
986 //! <b>Throws</b>: Nothing.
987 static size_type suggested_upper_bucket_count(size_type n)
988 { return table_type::suggested_upper_bucket_count(n); }
989
990 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
991 //! the container that is smaller than n. This suggestion can be used
992 //! to create bucket arrays with a size that will usually improve
993 //! container's performance. If such value does not exist, the
994 //! lower possible value is returned.
995 //!
996 //! <b>Complexity</b>: Amortized constant time.
997 //!
998 //! <b>Throws</b>: Nothing.
999 static size_type suggested_lower_bucket_count(size_type n)
1000 { return table_type::suggested_lower_bucket_count(n); }
1001
1002 #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1003 };
1004
1005 //! Helper metafunction to define an \c unordered_set that yields to the same type when the
1006 //! same options (either explicitly or implicitly) are used.
1007 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1008 template<class T, class ...Options>
1009 #else
1010 template<class T, class O1 = void, class O2 = void
1011 , class O3 = void, class O4 = void
1012 , class O5 = void, class O6 = void
1013 , class O7 = void, class O8 = void
1014 , class O9 = void, class O10= void
1015 >
1016 #endif
1017 struct make_unordered_set
1018 {
1019 /// @cond
1020 typedef typename pack_options
1021 < hashtable_defaults,
1022 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1023 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
1024 #else
1025 Options...
1026 #endif
1027 >::type packed_options;
1028
1029 typedef typename detail::get_value_traits
1030 <T, typename packed_options::proto_value_traits>::type value_traits;
1031
1032 typedef typename make_real_bucket_traits
1033 <T, true, packed_options>::type real_bucket_traits;
1034
1035 typedef unordered_set_impl
1036 < value_traits
1037 , typename packed_options::hash
1038 , typename packed_options::equal
1039 , typename packed_options::size_type
1040 , real_bucket_traits
1041 , (std::size_t(true)*hash_bool_flags::unique_keys_pos)
1042 | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
1043 | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
1044 | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
1045 | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
1046 | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
1047 > implementation_defined;
1048
1049 /// @endcond
1050 typedef implementation_defined type;
1051 };
1052
1053 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1054
1055 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1056 template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
1057 #else
1058 template<class T, class ...Options>
1059 #endif
1060 class unordered_set
1061 : public make_unordered_set<T,
1062 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1063 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
1064 #else
1065 Options...
1066 #endif
1067 >::type
1068 {
1069 typedef typename make_unordered_set
1070 <T,
1071 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1072 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
1073 #else
1074 Options...
1075 #endif
1076 >::type Base;
1077
1078 //Assert if passed value traits are compatible with the type
1079 BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
1080 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set)
1081
1082 public:
1083 typedef typename Base::value_traits value_traits;
1084 typedef typename Base::bucket_traits bucket_traits;
1085 typedef typename Base::iterator iterator;
1086 typedef typename Base::const_iterator const_iterator;
1087 typedef typename Base::bucket_ptr bucket_ptr;
1088 typedef typename Base::size_type size_type;
1089 typedef typename Base::hasher hasher;
1090 typedef typename Base::key_equal key_equal;
1091
1092 explicit unordered_set ( const bucket_traits &b_traits
1093 , const hasher & hash_func = hasher()
1094 , const key_equal &equal_func = key_equal()
1095 , const value_traits &v_traits = value_traits())
1096 : Base(b_traits, hash_func, equal_func, v_traits)
1097 {}
1098
1099 template<class Iterator>
1100 unordered_set ( Iterator b
1101 , Iterator e
1102 , const bucket_traits &b_traits
1103 , const hasher & hash_func = hasher()
1104 , const key_equal &equal_func = key_equal()
1105 , const value_traits &v_traits = value_traits())
1106 : Base(b, e, b_traits, hash_func, equal_func, v_traits)
1107 {}
1108
1109 unordered_set(BOOST_RV_REF(unordered_set) x)
1110 : Base(::boost::move(static_cast<Base&>(x)))
1111 {}
1112
1113 unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
1114 { return static_cast<unordered_set&>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
1115 };
1116
1117 #endif
1118
1119
1120 //! The class template unordered_multiset is an intrusive container, that mimics most of
1121 //! the interface of std::tr1::unordered_multiset as described in the C++ TR1.
1122 //!
1123 //! unordered_multiset is a semi-intrusive container: each object to be stored in the
1124 //! container must contain a proper hook, but the container also needs
1125 //! additional auxiliary memory to work: unordered_multiset needs a pointer to an array
1126 //! of type `bucket_type` to be passed in the constructor. This bucket array must
1127 //! have at least the same lifetime as the container. This makes the use of
1128 //! unordered_multiset more complicated than purely intrusive containers.
1129 //! `bucket_type` is default-constructible, copyable and assignable
1130 //!
1131 //! The template parameter \c T is the type to be managed by the container.
1132 //! The user can specify additional options and if no options are provided
1133 //! default options are used.
1134 //!
1135 //! The container supports the following options:
1136 //! \c base_hook<>/member_hook<>/value_traits<>,
1137 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
1138 //! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
1139 //!
1140 //! unordered_multiset only provides forward iterators but it provides 4 iterator types:
1141 //! iterator and const_iterator to navigate through the whole container and
1142 //! local_iterator and const_local_iterator to navigate through the values
1143 //! stored in a single bucket. Local iterators are faster and smaller.
1144 //!
1145 //! It's not recommended to use non constant-time size unordered_multisets because several
1146 //! key functions, like "empty()", become non-constant time functions. Non
1147 //! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks.
1148 //!
1149 //! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor
1150 //! offers functions related to a load factor. Rehashing can be explicitly requested
1151 //! and the user must provide a new bucket array that will be used from that moment.
1152 //!
1153 //! Since no automatic rehashing is done, iterators are never invalidated when
1154 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
1155 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1156 template<class T, class ...Options>
1157 #else
1158 template<class ValueTraits, class Hash, class Equal, class SizeType, class BucketTraits, std::size_t BoolFlags>
1159 #endif
1160 class unordered_multiset_impl
1161 : public hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags>
1162 {
1163 /// @cond
1164 private:
1165 typedef hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags> table_type;
1166 /// @endcond
1167
1168 //Movable
1169 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset_impl)
1170
1171 typedef table_type implementation_defined;
1172
1173 public:
1174 typedef typename implementation_defined::value_type value_type;
1175 typedef typename implementation_defined::value_traits value_traits;
1176 typedef typename implementation_defined::bucket_traits bucket_traits;
1177 typedef typename implementation_defined::pointer pointer;
1178 typedef typename implementation_defined::const_pointer const_pointer;
1179 typedef typename implementation_defined::reference reference;
1180 typedef typename implementation_defined::const_reference const_reference;
1181 typedef typename implementation_defined::difference_type difference_type;
1182 typedef typename implementation_defined::size_type size_type;
1183 typedef typename implementation_defined::key_type key_type;
1184 typedef typename implementation_defined::key_equal key_equal;
1185 typedef typename implementation_defined::hasher hasher;
1186 typedef typename implementation_defined::bucket_type bucket_type;
1187 typedef typename implementation_defined::bucket_ptr bucket_ptr;
1188 typedef typename implementation_defined::iterator iterator;
1189 typedef typename implementation_defined::const_iterator const_iterator;
1190 typedef typename implementation_defined::insert_commit_data insert_commit_data;
1191 typedef typename implementation_defined::local_iterator local_iterator;
1192 typedef typename implementation_defined::const_local_iterator const_local_iterator;
1193 typedef typename implementation_defined::node_traits node_traits;
1194 typedef typename implementation_defined::node node;
1195 typedef typename implementation_defined::node_ptr node_ptr;
1196 typedef typename implementation_defined::const_node_ptr const_node_ptr;
1197 typedef typename implementation_defined::node_algorithms node_algorithms;
1198
1199 public:
1200
1201 //! <b>Requires</b>: buckets must not be being used by any other resource.
1202 //!
1203 //! <b>Effects</b>: Constructs an empty unordered_multiset, storing a reference
1204 //! to the bucket array and copies of the hasher and equal functors.
1205 //!
1206 //! <b>Complexity</b>: Constant.
1207 //!
1208 //! <b>Throws</b>: If value_traits::node_traits::node
1209 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
1210 //! or the copy constructor or invocation of Hash or Equal throws.
1211 //!
1212 //! <b>Notes</b>: buckets array must be disposed only after
1213 //! *this is disposed.
1214 explicit unordered_multiset_impl ( const bucket_traits &b_traits
1215 , const hasher & hash_func = hasher()
1216 , const key_equal &equal_func = key_equal()
1217 , const value_traits &v_traits = value_traits())
1218 : table_type(b_traits, hash_func, equal_func, v_traits)
1219 {}
1220
1221 //! <b>Requires</b>: buckets must not be being used by any other resource
1222 //! and Dereferencing iterator must yield an lvalue of type value_type.
1223 //!
1224 //! <b>Effects</b>: Constructs an empty unordered_multiset and inserts elements from
1225 //! [b, e).
1226 //!
1227 //! <b>Complexity</b>: If N is std::distance(b, e): Average case is O(N)
1228 //! (with a good hash function and with buckets_len >= N),worst case O(N2).
1229 //!
1230 //! <b>Throws</b>: If value_traits::node_traits::node
1231 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
1232 //! or the copy constructor or invocation of hasher or key_equal throws.
1233 //!
1234 //! <b>Notes</b>: buckets array must be disposed only after
1235 //! *this is disposed.
1236 template<class Iterator>
1237 unordered_multiset_impl ( Iterator b
1238 , Iterator e
1239 , const bucket_traits &b_traits
1240 , const hasher & hash_func = hasher()
1241 , const key_equal &equal_func = key_equal()
1242 , const value_traits &v_traits = value_traits())
1243 : table_type(b_traits, hash_func, equal_func, v_traits)
1244 { table_type::insert_equal(b, e); }
1245
1246 //! <b>Effects</b>: to-do
1247 //!
1248 unordered_multiset_impl(BOOST_RV_REF(unordered_multiset_impl) x)
1249 : table_type(::boost::move(static_cast<table_type&>(x)))
1250 {}
1251
1252 //! <b>Effects</b>: to-do
1253 //!
1254 unordered_multiset_impl& operator=(BOOST_RV_REF(unordered_multiset_impl) x)
1255 { return static_cast<unordered_multiset_impl&>(table_type::operator=(::boost::move(static_cast<table_type&>(x)))); }
1256
1257 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1258
1259 //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_multiset
1260 //! are not deleted (i.e. no destructors are called).
1261 //!
1262 //! <b>Complexity</b>: Linear to the number of elements in the unordered_multiset, if
1263 //! it's a safe-mode or auto-unlink value. Otherwise constant.
1264 //!
1265 //! <b>Throws</b>: Nothing.
1266 ~unordered_multiset_impl()
1267 {}
1268
1269 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
1270 //!
1271 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
1272 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
1273 //!
1274 //! <b>Throws</b>: Nothing.
1275 iterator begin()
1276 { return table_type::begin(); }
1277
1278 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
1279 //! of the unordered_multiset.
1280 //!
1281 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
1282 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
1283 //!
1284 //! <b>Throws</b>: Nothing.
1285 const_iterator begin() const
1286 { return table_type::begin(); }
1287
1288 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
1289 //! of the unordered_multiset.
1290 //!
1291 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
1292 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
1293 //!
1294 //! <b>Throws</b>: Nothing.
1295 const_iterator cbegin() const
1296 { return table_type::cbegin(); }
1297
1298 //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_multiset.
1299 //!
1300 //! <b>Complexity</b>: Constant.
1301 //!
1302 //! <b>Throws</b>: Nothing.
1303 iterator end()
1304 { return table_type::end(); }
1305
1306 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
1307 //!
1308 //! <b>Complexity</b>: Constant.
1309 //!
1310 //! <b>Throws</b>: Nothing.
1311 const_iterator end() const
1312 { return table_type::end(); }
1313
1314 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
1315 //!
1316 //! <b>Complexity</b>: Constant.
1317 //!
1318 //! <b>Throws</b>: Nothing.
1319 const_iterator cend() const
1320 { return table_type::cend(); }
1321
1322 //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
1323 //!
1324 //! <b>Complexity</b>: Constant.
1325 //!
1326 //! <b>Throws</b>: If hasher copy-constructor throws.
1327 hasher hash_function() const
1328 { return table_type::hash_function(); }
1329
1330 //! <b>Effects</b>: Returns the key_equal object used by the unordered_multiset.
1331 //!
1332 //! <b>Complexity</b>: Constant.
1333 //!
1334 //! <b>Throws</b>: If key_equal copy-constructor throws.
1335 key_equal key_eq() const
1336 { return table_type::key_eq(); }
1337
1338 //! <b>Effects</b>: Returns true if the container is empty.
1339 //!
1340 //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
1341 //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
1342 //! Otherwise constant.
1343 //!
1344 //! <b>Throws</b>: Nothing.
1345 bool empty() const
1346 { return table_type::empty(); }
1347
1348 //! <b>Effects</b>: Returns the number of elements stored in the unordered_multiset.
1349 //!
1350 //! <b>Complexity</b>: Linear to elements contained in *this if
1351 //! constant-time size option is disabled. Constant-time otherwise.
1352 //!
1353 //! <b>Throws</b>: Nothing.
1354 size_type size() const
1355 { return table_type::size(); }
1356
1357 //! <b>Requires</b>: the hasher and the equality function unqualified swap
1358 //! call should not throw.
1359 //!
1360 //! <b>Effects</b>: Swaps the contents of two unordered_multisets.
1361 //! Swaps also the contained bucket array and equality and hasher functors.
1362 //!
1363 //!
1364 //! <b>Complexity</b>: Constant.
1365 //!
1366 //! <b>Throws</b>: If the swap() call for the comparison or hash functors
1367 //! found using ADL throw. Basic guarantee.
1368 void swap(unordered_multiset_impl& other)
1369 { table_type::swap(other.table_); }
1370
1371 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1372 //! Cloner should yield to nodes that compare equal and produce the same
1373 //! hash than the original node.
1374 //!
1375 //! <b>Effects</b>: Erases all the elements from *this
1376 //! calling Disposer::operator()(pointer), clones all the
1377 //! elements from src calling Cloner::operator()(const_reference )
1378 //! and inserts them on *this. The hash function and the equality
1379 //! predicate are copied from the source.
1380 //!
1381 //! If store_hash option is true, this method does not use the hash function.
1382 //!
1383 //! If any operation throws, all cloned elements are unlinked and disposed
1384 //! calling Disposer::operator()(pointer).
1385 //!
1386 //! <b>Complexity</b>: Linear to erased plus inserted elements.
1387 //!
1388 //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
1389 //! throws. Basic guarantee.
1390 template <class Cloner, class Disposer>
1391 void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer)
1392 { table_type::clone_from(src.table_, cloner, disposer); }
1393
1394 #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1395
1396 //! <b>Requires</b>: value must be an lvalue
1397 //!
1398 //! <b>Effects</b>: Inserts value into the unordered_multiset.
1399 //!
1400 //! <b>Returns</b>: An iterator to the new inserted value.
1401 //!
1402 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1403 //!
1404 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
1405 //!
1406 //! <b>Note</b>: Does not affect the validity of iterators and references.
1407 //! No copy-constructors are called.
1408 iterator insert(reference value)
1409 { return table_type::insert_equal(value); }
1410
1411 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
1412 //! of type value_type.
1413 //!
1414 //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
1415 //!
1416 //! <b>Complexity</b>: Average case is O(N), where N is the
1417 //! size of the range.
1418 //!
1419 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1420 //!
1421 //! <b>Note</b>: Does not affect the validity of iterators and references.
1422 //! No copy-constructors are called.
1423 template<class Iterator>
1424 void insert(Iterator b, Iterator e)
1425 { table_type::insert_equal(b, e); }
1426
1427 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1428
1429 //! <b>Effects</b>: Erases the element pointed to by i.
1430 //!
1431 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1432 //!
1433 //! <b>Throws</b>: Nothing.
1434 //!
1435 //! <b>Note</b>: Invalidates the iterators (but not the references)
1436 //! to the erased element. No destructors are called.
1437 void erase(const_iterator i)
1438 { table_type::erase(i); }
1439
1440 //! <b>Effects</b>: Erases the range pointed to by b end e.
1441 //!
1442 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
1443 //! worst case O(this->size()).
1444 //!
1445 //! <b>Throws</b>: Nothing.
1446 //!
1447 //! <b>Note</b>: Invalidates the iterators (but not the references)
1448 //! to the erased elements. No destructors are called.
1449 void erase(const_iterator b, const_iterator e)
1450 { table_type::erase(b, e); }
1451
1452 //! <b>Effects</b>: Erases all the elements with the given value.
1453 //!
1454 //! <b>Returns</b>: The number of erased elements.
1455 //!
1456 //! <b>Complexity</b>: Average case O(this->count(value)).
1457 //! Worst case O(this->size()).
1458 //!
1459 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1460 //!
1461 //! <b>Note</b>: Invalidates the iterators (but not the references)
1462 //! to the erased elements. No destructors are called.
1463 size_type erase(const_reference value)
1464 { return table_type::erase(value); }
1465
1466 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1467 //! the same hash values as the stored hasher. The difference is that
1468 //! "hash_func" hashes the given key instead of the value_type.
1469 //!
1470 //! "key_value_equal" must be a equality function that induces
1471 //! the same equality as key_equal. The difference is that
1472 //! "key_value_equal" compares an arbitrary key with the contained values.
1473 //!
1474 //! <b>Effects</b>: Erases all the elements that have the same hash and
1475 //! compare equal with the given key.
1476 //!
1477 //! <b>Returns</b>: The number of erased elements.
1478 //!
1479 //! <b>Complexity</b>: Average case O(this->count(value)).
1480 //! Worst case O(this->size()).
1481 //!
1482 //! <b>Throws</b>: If the hash_func or the equal_func functors throws.
1483 //! Basic guarantee.
1484 //!
1485 //! <b>Note</b>: Invalidates the iterators (but not the references)
1486 //! to the erased elements. No destructors are called.
1487 template<class KeyType, class KeyHasher, class KeyValueEqual>
1488 size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
1489 { return table_type::erase(key, hash_func, equal_func); }
1490
1491 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1492 //!
1493 //! <b>Effects</b>: Erases the element pointed to by i.
1494 //! Disposer::operator()(pointer) is called for the removed element.
1495 //!
1496 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1497 //!
1498 //! <b>Throws</b>: Nothing.
1499 //!
1500 //! <b>Note</b>: Invalidates the iterators
1501 //! to the erased elements.
1502 template<class Disposer>
1503 void erase_and_dispose(const_iterator i, Disposer disposer
1504 /// @cond
1505 , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
1506 /// @endcond
1507 )
1508 { table_type::erase_and_dispose(i, disposer); }
1509
1510 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1511 template<class Disposer>
1512 void erase_and_dispose(const_iterator i, Disposer disposer)
1513 { this->erase_and_dispose(const_iterator(i), disposer); }
1514 #endif
1515
1516 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1517 //!
1518 //! <b>Effects</b>: Erases the range pointed to by b end e.
1519 //! Disposer::operator()(pointer) is called for the removed elements.
1520 //!
1521 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
1522 //! worst case O(this->size()).
1523 //!
1524 //! <b>Throws</b>: Nothing.
1525 //!
1526 //! <b>Note</b>: Invalidates the iterators
1527 //! to the erased elements.
1528 template<class Disposer>
1529 void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
1530 { table_type::erase_and_dispose(b, e, disposer); }
1531
1532 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1533 //!
1534 //! <b>Effects</b>: Erases all the elements with the given value.
1535 //! Disposer::operator()(pointer) is called for the removed elements.
1536 //!
1537 //! <b>Returns</b>: The number of erased elements.
1538 //!
1539 //! <b>Complexity</b>: Average case O(this->count(value)).
1540 //! Worst case O(this->size()).
1541 //!
1542 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1543 //!
1544 //! <b>Note</b>: Invalidates the iterators (but not the references)
1545 //! to the erased elements. No destructors are called.
1546 template<class Disposer>
1547 size_type erase_and_dispose(const_reference value, Disposer disposer)
1548 { return table_type::erase_and_dispose(value, disposer); }
1549
1550 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1551 //!
1552 //! <b>Effects</b>: Erases all the elements with the given key.
1553 //! according to the comparison functor "equal_func".
1554 //! Disposer::operator()(pointer) is called for the removed elements.
1555 //!
1556 //! <b>Returns</b>: The number of erased elements.
1557 //!
1558 //! <b>Complexity</b>: Average case O(this->count(value)).
1559 //! Worst case O(this->size()).
1560 //!
1561 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
1562 //!
1563 //! <b>Note</b>: Invalidates the iterators
1564 //! to the erased elements.
1565 template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
1566 size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
1567 { return table_type::erase_and_dispose(key, hash_func, equal_func, disposer); }
1568
1569 //! <b>Effects</b>: Erases all the elements of the container.
1570 //!
1571 //! <b>Complexity</b>: Linear to the number of elements on the container.
1572 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
1573 //!
1574 //! <b>Throws</b>: Nothing.
1575 //!
1576 //! <b>Note</b>: Invalidates the iterators (but not the references)
1577 //! to the erased elements. No destructors are called.
1578 void clear()
1579 { return table_type::clear(); }
1580
1581 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1582 //!
1583 //! <b>Effects</b>: Erases all the elements of the container.
1584 //!
1585 //! <b>Complexity</b>: Linear to the number of elements on the container.
1586 //! Disposer::operator()(pointer) is called for the removed elements.
1587 //!
1588 //! <b>Throws</b>: Nothing.
1589 //!
1590 //! <b>Note</b>: Invalidates the iterators (but not the references)
1591 //! to the erased elements. No destructors are called.
1592 template<class Disposer>
1593 void clear_and_dispose(Disposer disposer)
1594 { return table_type::clear_and_dispose(disposer); }
1595
1596 //! <b>Effects</b>: Returns the number of contained elements with the given key
1597 //!
1598 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1599 //!
1600 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1601 size_type count(const_reference value) const
1602 { return table_type::count(value); }
1603
1604 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1605 //! the same hash values as the stored hasher. The difference is that
1606 //! "hash_func" hashes the given key instead of the value_type.
1607 //!
1608 //! "key_value_equal" must be a equality function that induces
1609 //! the same equality as key_equal. The difference is that
1610 //! "key_value_equal" compares an arbitrary key with the contained values.
1611 //!
1612 //! <b>Effects</b>: Returns the number of contained elements with the given key
1613 //!
1614 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1615 //!
1616 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1617 template<class KeyType, class KeyHasher, class KeyValueEqual>
1618 size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
1619 { return table_type::count(key, hash_func, equal_func); }
1620
1621 //! <b>Effects</b>: Finds an iterator to the first element whose value is
1622 //! "value" or end() if that element does not exist.
1623 //!
1624 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1625 //!
1626 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1627 iterator find(const_reference value)
1628 { return table_type::find(value); }
1629
1630 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1631 //! the same hash values as the stored hasher. The difference is that
1632 //! "hash_func" hashes the given key instead of the value_type.
1633 //!
1634 //! "key_value_equal" must be a equality function that induces
1635 //! the same equality as key_equal. The difference is that
1636 //! "key_value_equal" compares an arbitrary key with the contained values.
1637 //!
1638 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1639 //! "key" according to the given hasher and equality functor or end() if
1640 //! that element does not exist.
1641 //!
1642 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1643 //!
1644 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1645 //!
1646 //! <b>Note</b>: This function is used when constructing a value_type
1647 //! is expensive and the value_type can be compared with a cheaper
1648 //! key type. Usually this key is part of the value_type.
1649 template<class KeyType, class KeyHasher, class KeyValueEqual>
1650 iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
1651 { return table_type::find(key, hash_func, equal_func); }
1652
1653 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
1654 //! "key" or end() if that element does not exist.
1655 //!
1656 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1657 //!
1658 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1659 const_iterator find(const_reference value) const
1660 { return table_type::find(value); }
1661
1662 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1663 //! the same hash values as the stored hasher. The difference is that
1664 //! "hash_func" hashes the given key instead of the value_type.
1665 //!
1666 //! "key_value_equal" must be a equality function that induces
1667 //! the same equality as key_equal. The difference is that
1668 //! "key_value_equal" compares an arbitrary key with the contained values.
1669 //!
1670 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1671 //! "key" according to the given hasher and equality functor or end() if
1672 //! that element does not exist.
1673 //!
1674 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1675 //!
1676 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1677 //!
1678 //! <b>Note</b>: This function is used when constructing a value_type
1679 //! is expensive and the value_type can be compared with a cheaper
1680 //! key type. Usually this key is part of the value_type.
1681 template<class KeyType, class KeyHasher, class KeyValueEqual>
1682 const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
1683 { return table_type::find(key, hash_func, equal_func); }
1684
1685 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
1686 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
1687 //! elements exist.
1688 //!
1689 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
1690 //!
1691 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1692 std::pair<iterator,iterator> equal_range(const_reference value)
1693 { return table_type::equal_range(value); }
1694
1695 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1696 //! the same hash values as the stored hasher. The difference is that
1697 //! "hash_func" hashes the given key instead of the value_type.
1698 //!
1699 //! "key_value_equal" must be a equality function that induces
1700 //! the same equality as key_equal. The difference is that
1701 //! "key_value_equal" compares an arbitrary key with the contained values.
1702 //!
1703 //! <b>Effects</b>: Returns a range containing all elements with equivalent
1704 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
1705 //! elements exist.
1706 //!
1707 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
1708 //! Worst case O(this->size()).
1709 //!
1710 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1711 //!
1712 //! <b>Note</b>: This function is used when constructing a value_type
1713 //! is expensive and the value_type can be compared with a cheaper
1714 //! key type. Usually this key is part of the value_type.
1715 template<class KeyType, class KeyHasher, class KeyValueEqual>
1716 std::pair<iterator,iterator> equal_range
1717 (const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
1718 { return table_type::equal_range(key, hash_func, equal_func); }
1719
1720 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
1721 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
1722 //! elements exist.
1723 //!
1724 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
1725 //!
1726 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1727 std::pair<const_iterator, const_iterator>
1728 equal_range(const_reference value) const
1729 { return table_type::equal_range(value); }
1730
1731 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1732 //! the same hash values as the stored hasher. The difference is that
1733 //! "hash_func" hashes the given key instead of the value_type.
1734 //!
1735 //! "key_value_equal" must be a equality function that induces
1736 //! the same equality as key_equal. The difference is that
1737 //! "key_value_equal" compares an arbitrary key with the contained values.
1738 //!
1739 //! <b>Effects</b>: Returns a range containing all elements with equivalent
1740 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
1741 //! elements exist.
1742 //!
1743 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
1744 //! Worst case O(this->size()).
1745 //!
1746 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1747 //!
1748 //! <b>Note</b>: This function is used when constructing a value_type
1749 //! is expensive and the value_type can be compared with a cheaper
1750 //! key type. Usually this key is part of the value_type.
1751 template<class KeyType, class KeyHasher, class KeyValueEqual>
1752 std::pair<const_iterator, const_iterator>
1753 equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
1754 { return table_type::equal_range(key, hash_func, equal_func); }
1755
1756 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
1757 //! appropriate type. Otherwise the behavior is undefined.
1758 //!
1759 //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_multiset
1760 //! that points to the value
1761 //!
1762 //! <b>Complexity</b>: Constant.
1763 //!
1764 //! <b>Throws</b>: If the hash function throws.
1765 iterator iterator_to(reference value)
1766 { return table_type::iterator_to(value); }
1767
1768 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
1769 //! appropriate type. Otherwise the behavior is undefined.
1770 //!
1771 //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
1772 //! unordered_multiset that points to the value
1773 //!
1774 //! <b>Complexity</b>: Constant.
1775 //!
1776 //! <b>Throws</b>: If the hash function throws.
1777 const_iterator iterator_to(const_reference value) const
1778 { return table_type::iterator_to(value); }
1779
1780 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1781 //! appropriate type. Otherwise the behavior is undefined.
1782 //!
1783 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
1784 //! that points to the value
1785 //!
1786 //! <b>Complexity</b>: Constant.
1787 //!
1788 //! <b>Throws</b>: Nothing.
1789 //!
1790 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1791 //! is stateless.
1792 static local_iterator s_local_iterator_to(reference value)
1793 { return table_type::s_local_iterator_to(value); }
1794
1795 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1796 //! appropriate type. Otherwise the behavior is undefined.
1797 //!
1798 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
1799 //! the unordered_set that points to the value
1800 //!
1801 //! <b>Complexity</b>: Constant.
1802 //!
1803 //! <b>Throws</b>: Nothing.
1804 //!
1805 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1806 //! is stateless.
1807 static const_local_iterator s_local_iterator_to(const_reference value)
1808 { return table_type::s_local_iterator_to(value); }
1809
1810 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1811 //! appropriate type. Otherwise the behavior is undefined.
1812 //!
1813 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
1814 //! that points to the value
1815 //!
1816 //! <b>Complexity</b>: Constant.
1817 //!
1818 //! <b>Throws</b>: Nothing.
1819 local_iterator local_iterator_to(reference value)
1820 { return table_type::local_iterator_to(value); }
1821
1822 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1823 //! appropriate type. Otherwise the behavior is undefined.
1824 //!
1825 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
1826 //! the unordered_set that points to the value
1827 //!
1828 //! <b>Complexity</b>: Constant.
1829 //!
1830 //! <b>Throws</b>: Nothing.
1831 const_local_iterator local_iterator_to(const_reference value) const
1832 { return table_type::local_iterator_to(value); }
1833
1834 //! <b>Effects</b>: Returns the number of buckets passed in the constructor
1835 //! or the last rehash function.
1836 //!
1837 //! <b>Complexity</b>: Constant.
1838 //!
1839 //! <b>Throws</b>: Nothing.
1840 size_type bucket_count() const
1841 { return table_type::bucket_count(); }
1842
1843 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1844 //!
1845 //! <b>Effects</b>: Returns the number of elements in the nth bucket.
1846 //!
1847 //! <b>Complexity</b>: Constant.
1848 //!
1849 //! <b>Throws</b>: Nothing.
1850 size_type bucket_size(size_type n) const
1851 { return table_type::bucket_size(n); }
1852
1853 //! <b>Effects</b>: Returns the index of the bucket in which elements
1854 //! with keys equivalent to k would be found, if any such element existed.
1855 //!
1856 //! <b>Complexity</b>: Constant.
1857 //!
1858 //! <b>Throws</b>: If the hash functor throws.
1859 //!
1860 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
1861 size_type bucket(const value_type& k) const
1862 { return table_type::bucket(k); }
1863
1864 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1865 //! the same hash values as the stored hasher. The difference is that
1866 //! "hash_func" hashes the given key instead of the value_type.
1867 //!
1868 //! <b>Effects</b>: Returns the index of the bucket in which elements
1869 //! with keys equivalent to k would be found, if any such element existed.
1870 //!
1871 //! <b>Complexity</b>: Constant.
1872 //!
1873 //! <b>Throws</b>: If the hash functor throws.
1874 //!
1875 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
1876 template<class KeyType, class KeyHasher>
1877 size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
1878 { return table_type::bucket(k, hash_func); }
1879
1880 //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
1881 //! or the last rehash function.
1882 //!
1883 //! <b>Complexity</b>: Constant.
1884 //!
1885 //! <b>Throws</b>: Nothing.
1886 bucket_ptr bucket_pointer() const
1887 { return table_type::bucket_pointer(); }
1888
1889 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1890 //!
1891 //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
1892 //! of the sequence stored in the bucket n.
1893 //!
1894 //! <b>Complexity</b>: Constant.
1895 //!
1896 //! <b>Throws</b>: Nothing.
1897 //!
1898 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1899 //! containing all of the elements in the nth bucket.
1900 local_iterator begin(size_type n)
1901 { return table_type::begin(n); }
1902
1903 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1904 //!
1905 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
1906 //! of the sequence stored in the bucket n.
1907 //!
1908 //! <b>Complexity</b>: Constant.
1909 //!
1910 //! <b>Throws</b>: Nothing.
1911 //!
1912 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1913 //! containing all of the elements in the nth bucket.
1914 const_local_iterator begin(size_type n) const
1915 { return table_type::begin(n); }
1916
1917 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1918 //!
1919 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
1920 //! of the sequence stored in the bucket n.
1921 //!
1922 //! <b>Complexity</b>: Constant.
1923 //!
1924 //! <b>Throws</b>: Nothing.
1925 //!
1926 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1927 //! containing all of the elements in the nth bucket.
1928 const_local_iterator cbegin(size_type n) const
1929 { return table_type::cbegin(n); }
1930
1931 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1932 //!
1933 //! <b>Effects</b>: Returns a local_iterator pointing to the end
1934 //! of the sequence stored in the bucket n.
1935 //!
1936 //! <b>Complexity</b>: Constant.
1937 //!
1938 //! <b>Throws</b>: Nothing.
1939 //!
1940 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1941 //! containing all of the elements in the nth bucket.
1942 local_iterator end(size_type n)
1943 { return table_type::end(n); }
1944
1945 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1946 //!
1947 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
1948 //! of the sequence stored in the bucket n.
1949 //!
1950 //! <b>Complexity</b>: Constant.
1951 //!
1952 //! <b>Throws</b>: Nothing.
1953 //!
1954 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1955 //! containing all of the elements in the nth bucket.
1956 const_local_iterator end(size_type n) const
1957 { return table_type::end(n); }
1958
1959 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1960 //!
1961 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
1962 //! of the sequence stored in the bucket n.
1963 //!
1964 //! <b>Complexity</b>: Constant.
1965 //!
1966 //! <b>Throws</b>: Nothing.
1967 //!
1968 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1969 //! containing all of the elements in the nth bucket.
1970 const_local_iterator cend(size_type n) const
1971 { return table_type::cend(n); }
1972
1973 //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
1974 //! or the same as the old bucket array. new_size is the length of the
1975 //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
1976 //! n can be bigger or smaller than this->bucket_count().
1977 //!
1978 //! <b>Effects</b>: Updates the internal reference with the new bucket erases
1979 //! the values from the old bucket and inserts then in the new one.
1980 //!
1981 //! If store_hash option is true, this method does not use the hash function.
1982 //!
1983 //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
1984 //!
1985 //! <b>Throws</b>: If the hasher functor throws.
1986 void rehash(const bucket_traits &new_bucket_traits)
1987 { table_type::rehash(new_bucket_traits); }
1988
1989 //! <b>Requires</b>:
1990 //!
1991 //! <b>Effects</b>:
1992 //!
1993 //! <b>Complexity</b>:
1994 //!
1995 //! <b>Throws</b>:
1996 //!
1997 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
1998 bool incremental_rehash(bool grow = true)
1999 { return table_type::incremental_rehash(grow); }
2000
2001 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
2002 bool incremental_rehash(const bucket_traits &new_bucket_traits)
2003 { return table_type::incremental_rehash(new_bucket_traits); }
2004
2005 //! <b>Requires</b>:
2006 //!
2007 //! <b>Effects</b>:
2008 //!
2009 //! <b>Complexity</b>:
2010 //!
2011 //! <b>Throws</b>:
2012 size_type split_count() const
2013 { return table_type::split_count(); }
2014
2015 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
2016 //! the container that is bigger than n. This suggestion can be used
2017 //! to create bucket arrays with a size that will usually improve
2018 //! container's performance. If such value does not exist, the
2019 //! higher possible value is returned.
2020 //!
2021 //! <b>Complexity</b>: Amortized constant time.
2022 //!
2023 //! <b>Throws</b>: Nothing.
2024 static size_type suggested_upper_bucket_count(size_type n)
2025 { return table_type::suggested_upper_bucket_count(n); }
2026
2027 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
2028 //! the container that is smaller than n. This suggestion can be used
2029 //! to create bucket arrays with a size that will usually improve
2030 //! container's performance. If such value does not exist, the
2031 //! lower possible value is returned.
2032 //!
2033 //! <b>Complexity</b>: Amortized constant time.
2034 //!
2035 //! <b>Throws</b>: Nothing.
2036 static size_type suggested_lower_bucket_count(size_type n)
2037 { return table_type::suggested_lower_bucket_count(n); }
2038
2039 #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2040 };
2041
2042 //! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
2043 //! same options (either explicitly or implicitly) are used.
2044 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2045 template<class T, class ...Options>
2046 #else
2047 template<class T, class O1 = void, class O2 = void
2048 , class O3 = void, class O4 = void
2049 , class O5 = void, class O6 = void
2050 , class O7 = void, class O8 = void
2051 , class O9 = void, class O10= void
2052 >
2053 #endif
2054 struct make_unordered_multiset
2055 {
2056 /// @cond
2057 typedef typename pack_options
2058 < hashtable_defaults,
2059 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2060 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
2061 #else
2062 Options...
2063 #endif
2064 >::type packed_options;
2065
2066 typedef typename detail::get_value_traits
2067 <T, typename packed_options::proto_value_traits>::type value_traits;
2068
2069 typedef typename make_real_bucket_traits
2070 <T, true, packed_options>::type real_bucket_traits;
2071
2072 typedef unordered_multiset_impl
2073 < value_traits
2074 , typename packed_options::hash
2075 , typename packed_options::equal
2076 , typename packed_options::size_type
2077 , real_bucket_traits
2078 , (std::size_t(false)*hash_bool_flags::unique_keys_pos)
2079 | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
2080 | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
2081 | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
2082 | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
2083 | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
2084 > implementation_defined;
2085
2086 /// @endcond
2087 typedef implementation_defined type;
2088 };
2089
2090 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2091
2092 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2093 template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
2094 #else
2095 template<class T, class ...Options>
2096 #endif
2097 class unordered_multiset
2098 : public make_unordered_multiset<T,
2099 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2100 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
2101 #else
2102 Options...
2103 #endif
2104 >::type
2105 {
2106 typedef typename make_unordered_multiset
2107 <T,
2108 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2109 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
2110 #else
2111 Options...
2112 #endif
2113 >::type Base;
2114 //Assert if passed value traits are compatible with the type
2115 BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
2116 BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset)
2117
2118 public:
2119 typedef typename Base::value_traits value_traits;
2120 typedef typename Base::bucket_traits bucket_traits;
2121 typedef typename Base::iterator iterator;
2122 typedef typename Base::const_iterator const_iterator;
2123 typedef typename Base::bucket_ptr bucket_ptr;
2124 typedef typename Base::size_type size_type;
2125 typedef typename Base::hasher hasher;
2126 typedef typename Base::key_equal key_equal;
2127
2128 explicit unordered_multiset( const bucket_traits &b_traits
2129 , const hasher & hash_func = hasher()
2130 , const key_equal &equal_func = key_equal()
2131 , const value_traits &v_traits = value_traits())
2132 : Base(b_traits, hash_func, equal_func, v_traits)
2133 {}
2134
2135 template<class Iterator>
2136 unordered_multiset( Iterator b
2137 , Iterator e
2138 , const bucket_traits &b_traits
2139 , const hasher & hash_func = hasher()
2140 , const key_equal &equal_func = key_equal()
2141 , const value_traits &v_traits = value_traits())
2142 : Base(b, e, b_traits, hash_func, equal_func, v_traits)
2143 {}
2144
2145 unordered_multiset(BOOST_RV_REF(unordered_multiset) x)
2146 : Base(::boost::move(static_cast<Base&>(x)))
2147 {}
2148
2149 unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
2150 { return static_cast<unordered_multiset&>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
2151 };
2152
2153 #endif
2154
2155 } //namespace intrusive
2156 } //namespace boost
2157
2158 #include <boost/intrusive/detail/config_end.hpp>
2159
2160 #endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP