1 /////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga 2006-2008
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)
10 // See http://www.boost.org/libs/intrusive for documentation.
12 /////////////////////////////////////////////////////////////////////////////
13 #ifndef BOOST_INTRUSIVE_UNORDERED_SET_HPP
14 #define BOOST_INTRUSIVE_UNORDERED_SET_HPP
16 #include <boost/intrusive/detail/config_begin.hpp>
17 #include <boost/intrusive/intrusive_fwd.hpp>
18 #include <boost/intrusive/hashtable.hpp>
24 //! The class template unordered_set is an intrusive container, that mimics most of
25 //! the interface of std::tr1::unordered_set as described in the C++ TR1.
27 //! unordered_set is a semi-intrusive container: each object to be stored in the
28 //! container must contain a proper hook, but the container also needs
29 //! additional auxiliary memory to work: unordered_set needs a pointer to an array
30 //! of type `bucket_type` to be passed in the constructor. This bucket array must
31 //! have at least the same lifetime as the container. This makes the use of
32 //! unordered_set more complicated than purely intrusive containers.
33 //! `bucket_type` is default-constructible, copyable and assignable
35 //! The template parameter \c T is the type to be managed by the container.
36 //! The user can specify additional options and if no options are provided
37 //! default options are used.
39 //! The container supports the following options:
40 //! \c base_hook<>/member_hook<>/value_traits<>,
41 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
42 //! \c bucket_traits<>, power_2_buckets<> and cache_begin<>.
44 //! unordered_set only provides forward iterators but it provides 4 iterator types:
45 //! iterator and const_iterator to navigate through the whole container and
46 //! local_iterator and const_local_iterator to navigate through the values
47 //! stored in a single bucket. Local iterators are faster and smaller.
49 //! It's not recommended to use non constant-time size unordered_sets because several
50 //! key functions, like "empty()", become non-constant time functions. Non
51 //! constant-time size unordered_sets are mainly provided to support auto-unlink hooks.
53 //! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor
54 //! offers functions related to a load factor. Rehashing can be explicitly requested
55 //! and the user must provide a new bucket array that will be used from that moment.
57 //! Since no automatic rehashing is done, iterators are never invalidated when
58 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
59 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
60 template<class T
, class ...Options
>
62 template<class Config
>
64 class unordered_set_impl
68 typedef hashtable_impl
<Config
> table_type
;
72 unordered_set_impl (const unordered_set_impl
&);
76 unordered_set_impl
&operator =(const unordered_set_impl
&);
78 typedef table_type implementation_defined
;
82 typedef typename
implementation_defined::value_type value_type
;
83 typedef typename
implementation_defined::value_traits value_traits
;
84 typedef typename
implementation_defined::bucket_traits bucket_traits
;
85 typedef typename
implementation_defined::pointer pointer
;
86 typedef typename
implementation_defined::const_pointer const_pointer
;
87 typedef typename
implementation_defined::reference reference
;
88 typedef typename
implementation_defined::const_reference const_reference
;
89 typedef typename
implementation_defined::difference_type difference_type
;
90 typedef typename
implementation_defined::size_type size_type
;
91 typedef typename
implementation_defined::key_type key_type
;
92 typedef typename
implementation_defined::key_equal key_equal
;
93 typedef typename
implementation_defined::hasher hasher
;
94 typedef typename
implementation_defined::bucket_type bucket_type
;
95 typedef typename
implementation_defined::bucket_ptr bucket_ptr
;
96 typedef typename
implementation_defined::iterator iterator
;
97 typedef typename
implementation_defined::const_iterator const_iterator
;
98 typedef typename
implementation_defined::insert_commit_data insert_commit_data
;
99 typedef typename
implementation_defined::local_iterator local_iterator
;
100 typedef typename
implementation_defined::const_local_iterator const_local_iterator
;
101 typedef typename
implementation_defined::node_traits node_traits
;
102 typedef typename
implementation_defined::node node
;
103 typedef typename
implementation_defined::node_ptr node_ptr
;
104 typedef typename
implementation_defined::const_node_ptr const_node_ptr
;
105 typedef typename
implementation_defined::node_algorithms node_algorithms
;
114 //! <b>Requires</b>: buckets must not be being used by any other resource.
116 //! <b>Effects</b>: Constructs an empty unordered_set_impl, storing a reference
117 //! to the bucket array and copies of the hasher and equal functors.
119 //! <b>Complexity</b>: Constant.
121 //! <b>Throws</b>: If value_traits::node_traits::node
122 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
123 //! or the copy constructor or invocation of Hash or Equal throws.
125 //! <b>Notes</b>: buckets array must be disposed only after
126 //! *this is disposed.
127 unordered_set_impl( const bucket_traits
&b_traits
128 , const hasher
& hash_func
= hasher()
129 , const key_equal
&equal_func
= key_equal()
130 , const value_traits
&v_traits
= value_traits())
131 : table_(b_traits
, hash_func
, equal_func
, v_traits
)
134 //! <b>Requires</b>: buckets must not be being used by any other resource
135 //! and Dereferencing iterator must yield an lvalue of type value_type.
137 //! <b>Effects</b>: Constructs an empty unordered_set and inserts elements from
140 //! <b>Complexity</b>: If N is std::distance(b, e): Average case is O(N)
141 //! (with a good hash function and with buckets_len >= N),worst case O(N2).
143 //! <b>Throws</b>: If value_traits::node_traits::node
144 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
145 //! or the copy constructor or invocation of hasher or key_equal throws.
147 //! <b>Notes</b>: buckets array must be disposed only after
148 //! *this is disposed.
149 template<class Iterator
>
150 unordered_set_impl( Iterator b
152 , const bucket_traits
&b_traits
153 , const hasher
& hash_func
= hasher()
154 , const key_equal
&equal_func
= key_equal()
155 , const value_traits
&v_traits
= value_traits())
156 : table_(b_traits
, hash_func
, equal_func
, v_traits
)
157 { table_
.insert_unique(b
, e
); }
159 //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set
160 //! are not deleted (i.e. no destructors are called).
162 //! <b>Complexity</b>: Linear to the number of elements in the unordered_set, if
163 //! it's a safe-mode or auto-unlink value. Otherwise constant.
165 //! <b>Throws</b>: Nothing.
166 ~unordered_set_impl()
169 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
171 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
172 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
174 //! <b>Throws</b>: Nothing.
176 { return table_
.begin(); }
178 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
179 //! of the unordered_set.
181 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
182 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
184 //! <b>Throws</b>: Nothing.
185 const_iterator
begin() const
186 { return table_
.begin(); }
188 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
189 //! of the unordered_set.
191 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
192 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
194 //! <b>Throws</b>: Nothing.
195 const_iterator
cbegin() const
196 { return table_
.cbegin(); }
198 //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
200 //! <b>Complexity</b>: Constant.
202 //! <b>Throws</b>: Nothing.
204 { return table_
.end(); }
206 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
208 //! <b>Complexity</b>: Constant.
210 //! <b>Throws</b>: Nothing.
211 const_iterator
end() const
212 { return table_
.end(); }
214 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
216 //! <b>Complexity</b>: Constant.
218 //! <b>Throws</b>: Nothing.
219 const_iterator
cend() const
220 { return table_
.cend(); }
222 //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
224 //! <b>Complexity</b>: Constant.
226 //! <b>Throws</b>: If hasher copy-constructor throws.
227 hasher
hash_function() const
228 { return table_
.hash_function(); }
230 //! <b>Effects</b>: Returns the key_equal object used by the unordered_set.
232 //! <b>Complexity</b>: Constant.
234 //! <b>Throws</b>: If key_equal copy-constructor throws.
235 key_equal
key_eq() const
236 { return table_
.key_eq(); }
238 //! <b>Effects</b>: Returns true if the container is empty.
240 //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
241 //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
242 //! Otherwise constant.
244 //! <b>Throws</b>: Nothing.
246 { return table_
.empty(); }
248 //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
250 //! <b>Complexity</b>: Linear to elements contained in *this if
251 //! constant-time size option is enabled. Constant-time otherwise.
253 //! <b>Throws</b>: Nothing.
254 size_type
size() const
255 { return table_
.size(); }
257 //! <b>Requires</b>: the hasher and the equality function unqualified swap
258 //! call should not throw.
260 //! <b>Effects</b>: Swaps the contents of two unordered_sets.
261 //! Swaps also the contained bucket array and equality and hasher functors.
263 //! <b>Complexity</b>: Constant.
265 //! <b>Throws</b>: If the swap() call for the comparison or hash functors
266 //! found using ADL throw. Basic guarantee.
267 void swap(unordered_set_impl
& other
)
268 { table_
.swap(other
.table_
); }
270 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
271 //! Cloner should yield to nodes that compare equal and produce the same
272 //! hash than the original node.
274 //! <b>Effects</b>: Erases all the elements from *this
275 //! calling Disposer::operator()(pointer), clones all the
276 //! elements from src calling Cloner::operator()(const_reference )
277 //! and inserts them on *this. The hash function and the equality
278 //! predicate are copied from the source.
280 //! If store_hash option is true, this method does not use the hash function.
282 //! If any operation throws, all cloned elements are unlinked and disposed
283 //! calling Disposer::operator()(pointer).
285 //! <b>Complexity</b>: Linear to erased plus inserted elements.
287 //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
288 //! throws. Basic guarantee.
289 template <class Cloner
, class Disposer
>
290 void clone_from(const unordered_set_impl
&src
, Cloner cloner
, Disposer disposer
)
291 { table_
.clone_from(src
.table_
, cloner
, disposer
); }
293 //! <b>Requires</b>: value must be an lvalue
295 //! <b>Effects</b>: Tries to inserts value into the unordered_set.
297 //! <b>Returns</b>: If the value
298 //! is not already present inserts it and returns a pair containing the
299 //! iterator to the new value and true. If there is an equivalent value
300 //! returns a pair containing an iterator to the already present value
303 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
305 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
307 //! <b>Note</b>: Does not affect the validity of iterators and references.
308 //! No copy-constructors are called.
309 std::pair
<iterator
, bool> insert(reference value
)
310 { return table_
.insert_unique(value
); }
312 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
313 //! of type value_type.
315 //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
317 //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e).
318 //! Worst case O(N*this->size()).
320 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
322 //! <b>Note</b>: Does not affect the validity of iterators and references.
323 //! No copy-constructors are called.
324 template<class Iterator
>
325 void insert(Iterator b
, Iterator e
)
326 { table_
.insert_unique(b
, e
); }
328 //! <b>Requires</b>: "hasher" must be a hash function that induces
329 //! the same hash values as the stored hasher. The difference is that
330 //! "hasher" hashes the given key instead of the value_type.
332 //! "key_value_equal" must be a equality function that induces
333 //! the same equality as key_equal. The difference is that
334 //! "key_value_equal" compares an arbitrary key with the contained values.
336 //! <b>Effects</b>: Checks if a value can be inserted in the unordered_set, using
337 //! a user provided key instead of the value itself.
339 //! <b>Returns</b>: If there is an equivalent value
340 //! returns a pair containing an iterator to the already present value
341 //! and false. If the value can be inserted returns true in the returned
342 //! pair boolean and fills "commit_data" that is meant to be used with
343 //! the "insert_commit" function.
345 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
347 //! <b>Throws</b>: If hasher or key_value_equal throw. Strong guarantee.
349 //! <b>Notes</b>: This function is used to improve performance when constructing
350 //! a value_type is expensive: if there is an equivalent value
351 //! the constructed object must be discarded. Many times, the part of the
352 //! node that is used to impose the hash or the equality is much cheaper to
353 //! construct than the value_type and this function offers the possibility to
354 //! use that the part to check if the insertion will be successful.
356 //! If the check is successful, the user can construct the value_type and use
357 //! "insert_commit" to insert the object in constant-time.
359 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
360 //! objects are inserted or erased from the unordered_set.
362 //! After a successful rehashing insert_commit_data remains valid.
363 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
364 std::pair
<iterator
, bool> insert_check
365 (const KeyType
&key
, KeyHasher hasher
, KeyValueEqual key_value_equal
, insert_commit_data
&commit_data
)
366 { return table_
.insert_unique_check(key
, hasher
, key_value_equal
, commit_data
); }
368 //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
369 //! must have been obtained from a previous call to "insert_check".
370 //! No objects should have been inserted or erased from the unordered_set between
371 //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
373 //! <b>Effects</b>: Inserts the value in the unordered_set using the information obtained
374 //! from the "commit_data" that a previous "insert_check" filled.
376 //! <b>Returns</b>: An iterator to the newly inserted object.
378 //! <b>Complexity</b>: Constant time.
380 //! <b>Throws</b>: Nothing.
382 //! <b>Notes</b>: This function has only sense if a "insert_check" has been
383 //! previously executed to fill "commit_data". No value should be inserted or
384 //! erased between the "insert_check" and "insert_commit" calls.
386 //! After a successful rehashing insert_commit_data remains valid.
387 iterator
insert_commit(reference value
, const insert_commit_data
&commit_data
)
388 { return table_
.insert_unique_commit(value
, commit_data
); }
390 //! <b>Effects</b>: Erases the element pointed to by i.
392 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
394 //! <b>Throws</b>: Nothing.
396 //! <b>Note</b>: Invalidates the iterators (but not the references)
397 //! to the erased element. No destructors are called.
398 void erase(const_iterator i
)
401 //! <b>Effects</b>: Erases the range pointed to by b end e.
403 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
404 //! worst case O(this->size()).
406 //! <b>Throws</b>: Nothing.
408 //! <b>Note</b>: Invalidates the iterators (but not the references)
409 //! to the erased elements. No destructors are called.
410 void erase(const_iterator b
, const_iterator e
)
411 { table_
.erase(b
, e
); }
413 //! <b>Effects</b>: Erases all the elements with the given value.
415 //! <b>Returns</b>: The number of erased elements.
417 //! <b>Complexity</b>: Average case O(this->count(value)).
418 //! Worst case O(this->size()).
420 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
422 //! <b>Note</b>: Invalidates the iterators (but not the references)
423 //! to the erased elements. No destructors are called.
424 size_type
erase(const_reference value
)
425 { return table_
.erase(value
); }
427 //! <b>Requires</b>: "hasher" must be a hash function that induces
428 //! the same hash values as the stored hasher. The difference is that
429 //! "hasher" hashes the given key instead of the value_type.
431 //! "key_value_equal" must be a equality function that induces
432 //! the same equality as key_equal. The difference is that
433 //! "key_value_equal" compares an arbitrary key with the contained values.
435 //! <b>Effects</b>: Erases all the elements that have the same hash and
436 //! compare equal with the given key.
438 //! <b>Returns</b>: The number of erased elements.
440 //! <b>Complexity</b>: Average case O(this->count(value)).
441 //! Worst case O(this->size()).
443 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
445 //! <b>Note</b>: Invalidates the iterators (but not the references)
446 //! to the erased elements. No destructors are called.
447 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
448 size_type
erase(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
)
449 { return table_
.erase(key
, hash_func
, equal_func
); }
451 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
453 //! <b>Effects</b>: Erases the element pointed to by i.
454 //! Disposer::operator()(pointer) is called for the removed element.
456 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
458 //! <b>Throws</b>: Nothing.
460 //! <b>Note</b>: Invalidates the iterators
461 //! to the erased elements.
462 template<class Disposer
>
463 iterator
erase_and_dispose(const_iterator i
, Disposer disposer
)
464 { return table_
.erase_and_dispose(i
, disposer
); }
466 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
467 template<class Disposer
>
468 iterator
erase_and_dispose(iterator i
, Disposer disposer
)
469 { return this->erase_and_dispose(const_iterator(i
), disposer
); }
472 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
474 //! <b>Effects</b>: Erases the range pointed to by b end e.
475 //! Disposer::operator()(pointer) is called for the removed elements.
477 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
478 //! worst case O(this->size()).
480 //! <b>Throws</b>: Nothing.
482 //! <b>Note</b>: Invalidates the iterators
483 //! to the erased elements.
484 template<class Disposer
>
485 iterator
erase_and_dispose(const_iterator b
, const_iterator e
, Disposer disposer
)
486 { return table_
.erase_and_dispose(b
, e
, disposer
); }
488 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
490 //! <b>Effects</b>: Erases all the elements with the given value.
491 //! Disposer::operator()(pointer) is called for the removed elements.
493 //! <b>Returns</b>: The number of erased elements.
495 //! <b>Complexity</b>: Average case O(this->count(value)).
496 //! Worst case O(this->size()).
498 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
500 //! <b>Note</b>: Invalidates the iterators (but not the references)
501 //! to the erased elements. No destructors are called.
502 template<class Disposer
>
503 size_type
erase_and_dispose(const_reference value
, Disposer disposer
)
504 { return table_
.erase_and_dispose(value
, disposer
); }
506 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
508 //! <b>Effects</b>: Erases all the elements with the given key.
509 //! according to the comparison functor "equal_func".
510 //! Disposer::operator()(pointer) is called for the removed elements.
512 //! <b>Returns</b>: The number of erased elements.
514 //! <b>Complexity</b>: Average case O(this->count(value)).
515 //! Worst case O(this->size()).
517 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
519 //! <b>Note</b>: Invalidates the iterators
520 //! to the erased elements.
521 template<class KeyType
, class KeyHasher
, class KeyValueEqual
, class Disposer
>
522 size_type
erase_and_dispose(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
, Disposer disposer
)
523 { return table_
.erase_and_dispose(key
, hash_func
, equal_func
, disposer
); }
525 //! <b>Effects</b>: Erases all of the elements.
527 //! <b>Complexity</b>: Linear to the number of elements on the container.
528 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
530 //! <b>Throws</b>: Nothing.
532 //! <b>Note</b>: Invalidates the iterators (but not the references)
533 //! to the erased elements. No destructors are called.
535 { return table_
.clear(); }
537 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
539 //! <b>Effects</b>: Erases all of the elements.
541 //! <b>Complexity</b>: Linear to the number of elements on the container.
542 //! Disposer::operator()(pointer) is called for the removed elements.
544 //! <b>Throws</b>: Nothing.
546 //! <b>Note</b>: Invalidates the iterators (but not the references)
547 //! to the erased elements. No destructors are called.
548 template<class Disposer
>
549 void clear_and_dispose(Disposer disposer
)
550 { return table_
.clear_and_dispose(disposer
); }
552 //! <b>Effects</b>: Returns the number of contained elements with the given value
554 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
556 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
557 size_type
count(const_reference value
) const
558 { return table_
.find(value
) != end(); }
560 //! <b>Requires</b>: "hash_func" must be a hash function that induces
561 //! the same hash values as the stored hasher. The difference is that
562 //! "hash_func" hashes the given key instead of the value_type.
564 //! "equal_func" must be a equality function that induces
565 //! the same equality as key_equal. The difference is that
566 //! "equal_func" compares an arbitrary key with the contained values.
568 //! <b>Effects</b>: Returns the number of contained elements with the given key
570 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
572 //! <b>Throws</b>: If hash_func or equal_func throw.
573 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
574 size_type
count(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
) const
575 { return table_
.find(key
, hash_func
, equal_func
) != end(); }
577 //! <b>Effects</b>: Finds an iterator to the first element is equal to
578 //! "value" or end() if that element does not exist.
580 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
582 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
583 iterator
find(const_reference value
)
584 { return table_
.find(value
); }
586 //! <b>Requires</b>: "hash_func" must be a hash function that induces
587 //! the same hash values as the stored hasher. The difference is that
588 //! "hash_func" hashes the given key instead of the value_type.
590 //! "equal_func" must be a equality function that induces
591 //! the same equality as key_equal. The difference is that
592 //! "equal_func" compares an arbitrary key with the contained values.
594 //! <b>Effects</b>: Finds an iterator to the first element whose key is
595 //! "key" according to the given hasher and equality functor or end() if
596 //! that element does not exist.
598 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
600 //! <b>Throws</b>: If hash_func or equal_func throw.
602 //! <b>Note</b>: This function is used when constructing a value_type
603 //! is expensive and the value_type can be compared with a cheaper
604 //! key type. Usually this key is part of the value_type.
605 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
606 iterator
find(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
)
607 { return table_
.find(key
, hash_func
, equal_func
); }
609 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
610 //! "key" or end() if that element does not exist.
612 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
614 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
615 const_iterator
find(const_reference value
) const
616 { return table_
.find(value
); }
618 //! <b>Requires</b>: "hash_func" must be a hash function that induces
619 //! the same hash values as the stored hasher. The difference is that
620 //! "hash_func" hashes the given key instead of the value_type.
622 //! "equal_func" must be a equality function that induces
623 //! the same equality as key_equal. The difference is that
624 //! "equal_func" compares an arbitrary key with the contained values.
626 //! <b>Effects</b>: Finds an iterator to the first element whose key is
627 //! "key" according to the given hasher and equality functor or end() if
628 //! that element does not exist.
630 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
632 //! <b>Throws</b>: If hash_func or equal_func throw.
634 //! <b>Note</b>: This function is used when constructing a value_type
635 //! is expensive and the value_type can be compared with a cheaper
636 //! key type. Usually this key is part of the value_type.
637 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
638 const_iterator
find(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
) const
639 { return table_
.find(key
, hash_func
, equal_func
); }
641 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
642 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
645 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
647 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
648 std::pair
<iterator
,iterator
> equal_range(const_reference value
)
649 { return table_
.equal_range(value
); }
651 //! <b>Requires</b>: "hash_func" must be a hash function that induces
652 //! the same hash values as the stored hasher. The difference is that
653 //! "hash_func" hashes the given key instead of the value_type.
655 //! "equal_func" must be a equality function that induces
656 //! the same equality as key_equal. The difference is that
657 //! "equal_func" compares an arbitrary key with the contained values.
659 //! <b>Effects</b>: Returns a range containing all elements with equivalent
660 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
663 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, hash_func)).
664 //! Worst case O(this->size()).
666 //! <b>Throws</b>: If hash_func or the equal_func throw.
668 //! <b>Note</b>: This function is used when constructing a value_type
669 //! is expensive and the value_type can be compared with a cheaper
670 //! key type. Usually this key is part of the value_type.
671 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
672 std::pair
<iterator
,iterator
> equal_range(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
)
673 { return table_
.equal_range(key
, hash_func
, equal_func
); }
675 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
676 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
679 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
681 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
682 std::pair
<const_iterator
, const_iterator
>
683 equal_range(const_reference value
) const
684 { return table_
.equal_range(value
); }
686 //! <b>Requires</b>: "hash_func" must be a hash function that induces
687 //! the same hash values as the stored hasher. The difference is that
688 //! "hash_func" hashes the given key instead of the value_type.
690 //! "equal_func" must be a equality function that induces
691 //! the same equality as key_equal. The difference is that
692 //! "equal_func" compares an arbitrary key with the contained values.
694 //! <b>Effects</b>: Returns a range containing all elements with equivalent
695 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
698 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
699 //! Worst case O(this->size()).
701 //! <b>Throws</b>: If the hash_func or equal_func throw.
703 //! <b>Note</b>: This function is used when constructing a value_type
704 //! is expensive and the value_type can be compared with a cheaper
705 //! key type. Usually this key is part of the value_type.
706 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
707 std::pair
<const_iterator
, const_iterator
>
708 equal_range(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
) const
709 { return table_
.equal_range(key
, hash_func
, equal_func
); }
711 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
712 //! appropriate type. Otherwise the behavior is undefined.
714 //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_set
715 //! that points to the value
717 //! <b>Complexity</b>: Constant.
719 //! <b>Throws</b>: If the internal hash function throws.
720 iterator
iterator_to(reference value
)
721 { return table_
.iterator_to(value
); }
723 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
724 //! appropriate type. Otherwise the behavior is undefined.
726 //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
727 //! unordered_set that points to the value
729 //! <b>Complexity</b>: Constant.
731 //! <b>Throws</b>: If the internal hash function throws.
732 const_iterator
iterator_to(const_reference value
) const
733 { return table_
.iterator_to(value
); }
735 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
736 //! appropriate type. Otherwise the behavior is undefined.
738 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
739 //! that points to the value
741 //! <b>Complexity</b>: Constant.
743 //! <b>Throws</b>: Nothing.
745 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
747 static local_iterator
s_local_iterator_to(reference value
)
748 { return table_type::s_local_iterator_to(value
); }
750 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
751 //! appropriate type. Otherwise the behavior is undefined.
753 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
754 //! the unordered_set that points to the value
756 //! <b>Complexity</b>: Constant.
758 //! <b>Throws</b>: Nothing.
760 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
762 static const_local_iterator
s_local_iterator_to(const_reference value
)
763 { return table_type::s_local_iterator_to(value
); }
765 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
766 //! appropriate type. Otherwise the behavior is undefined.
768 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
769 //! that points to the value
771 //! <b>Complexity</b>: Constant.
773 //! <b>Throws</b>: Nothing.
774 local_iterator
local_iterator_to(reference value
)
775 { return table_
.local_iterator_to(value
); }
777 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
778 //! appropriate type. Otherwise the behavior is undefined.
780 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
781 //! the unordered_set that points to the value
783 //! <b>Complexity</b>: Constant.
785 //! <b>Throws</b>: Nothing.
786 const_local_iterator
local_iterator_to(const_reference value
) const
787 { return table_
.local_iterator_to(value
); }
789 //! <b>Effects</b>: Returns the number of buckets passed in the constructor
790 //! or the last rehash function.
792 //! <b>Complexity</b>: Constant.
794 //! <b>Throws</b>: Nothing.
795 size_type
bucket_count() const
796 { return table_
.bucket_count(); }
798 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
800 //! <b>Effects</b>: Returns the number of elements in the nth bucket.
802 //! <b>Complexity</b>: Constant.
804 //! <b>Throws</b>: Nothing.
805 size_type
bucket_size(size_type n
) const
806 { return table_
.bucket_size(n
); }
808 //! <b>Effects</b>: Returns the index of the bucket in which elements
809 //! with keys equivalent to k would be found, if any such element existed.
811 //! <b>Complexity</b>: Constant.
813 //! <b>Throws</b>: If the hash functor throws.
815 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
816 size_type
bucket(const value_type
& k
) const
817 { return table_
.bucket(k
); }
819 //! <b>Requires</b>: "hash_func" must be a hash function that induces
820 //! the same hash values as the stored hasher. The difference is that
821 //! "hash_func" hashes the given key instead of the value_type.
823 //! <b>Effects</b>: Returns the index of the bucket in which elements
824 //! with keys equivalent to k would be found, if any such element existed.
826 //! <b>Complexity</b>: Constant.
828 //! <b>Throws</b>: If hash_func throws.
830 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
831 template<class KeyType
, class KeyHasher
>
832 size_type
bucket(const KeyType
& k
, KeyHasher hash_func
) const
833 { return table_
.bucket(k
, hash_func
); }
835 //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
836 //! or the last rehash function.
838 //! <b>Complexity</b>: Constant.
840 //! <b>Throws</b>: Nothing.
841 bucket_ptr
bucket_pointer() const
842 { return table_
.bucket_pointer(); }
844 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
846 //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
847 //! of the sequence stored in the bucket n.
849 //! <b>Complexity</b>: Constant.
851 //! <b>Throws</b>: Nothing.
853 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
854 //! containing all of the elements in the nth bucket.
855 local_iterator
begin(size_type n
)
856 { return table_
.begin(n
); }
858 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
860 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
861 //! of the sequence stored in the bucket n.
863 //! <b>Complexity</b>: Constant.
865 //! <b>Throws</b>: Nothing.
867 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
868 //! containing all of the elements in the nth bucket.
869 const_local_iterator
begin(size_type n
) const
870 { return table_
.begin(n
); }
872 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
874 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
875 //! of the sequence stored in the bucket n.
877 //! <b>Complexity</b>: Constant.
879 //! <b>Throws</b>: Nothing.
881 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
882 //! containing all of the elements in the nth bucket.
883 const_local_iterator
cbegin(size_type n
) const
884 { return table_
.cbegin(n
); }
886 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
888 //! <b>Effects</b>: Returns a local_iterator pointing to the end
889 //! of the sequence stored in the bucket n.
891 //! <b>Complexity</b>: Constant.
893 //! <b>Throws</b>: Nothing.
895 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
896 //! containing all of the elements in the nth bucket.
897 local_iterator
end(size_type n
)
898 { return table_
.end(n
); }
900 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
902 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
903 //! of the sequence stored in the bucket n.
905 //! <b>Complexity</b>: Constant.
907 //! <b>Throws</b>: Nothing.
909 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
910 //! containing all of the elements in the nth bucket.
911 const_local_iterator
end(size_type n
) const
912 { return table_
.end(n
); }
914 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
916 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
917 //! of the sequence stored in the bucket n.
919 //! <b>Complexity</b>: Constant.
921 //! <b>Throws</b>: Nothing.
923 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
924 //! containing all of the elements in the nth bucket.
925 const_local_iterator
cend(size_type n
) const
926 { return table_
.cend(n
); }
928 //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
929 //! or the same as the old bucket array. new_size is the length of the
930 //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
931 //! n can be bigger or smaller than this->bucket_count().
933 //! <b>Effects</b>: Updates the internal reference with the new bucket erases
934 //! the values from the old bucket and inserts then in the new one.
936 //! If store_hash option is true, this method does not use the hash function.
938 //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
940 //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
941 void rehash(const bucket_traits
&new_bucket_traits
)
942 { table_
.rehash(new_bucket_traits
); }
948 //! <b>Complexity</b>:
952 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
953 bool incremental_rehash(bool grow
= true)
954 { return table_
.incremental_rehash(grow
); }
956 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
957 bool incremental_rehash(const bucket_traits
&new_bucket_traits
)
958 { return table_
.incremental_rehash(new_bucket_traits
); }
964 //! <b>Complexity</b>:
967 size_type
split_count() const
968 { return table_
.split_count(); }
970 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
971 //! the container that is bigger than n. This suggestion can be used
972 //! to create bucket arrays with a size that will usually improve
973 //! container's performance. If such value does not exist, the
974 //! higher possible value is returned.
976 //! <b>Complexity</b>: Amortized constant time.
978 //! <b>Throws</b>: Nothing.
979 static size_type
suggested_upper_bucket_count(size_type n
)
980 { return table_type::suggested_upper_bucket_count(n
); }
982 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
983 //! the container that is smaller than n. This suggestion can be used
984 //! to create bucket arrays with a size that will usually improve
985 //! container's performance. If such value does not exist, the
986 //! lower possible value is returned.
988 //! <b>Complexity</b>: Amortized constant time.
990 //! <b>Throws</b>: Nothing.
991 static size_type
suggested_lower_bucket_count(size_type n
)
992 { return table_type::suggested_lower_bucket_count(n
); }
995 //! Helper metafunction to define an \c unordered_set that yields to the same type when the
996 //! same options (either explicitly or implicitly) are used.
997 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
998 template<class T
, class ...Options
>
1000 template<class T
, class O1
= none
, class O2
= none
1001 , class O3
= none
, class O4
= none
1002 , class O5
= none
, class O6
= none
1003 , class O7
= none
, class O8
= none
1004 , class O9
= none
, class O10
= none
1007 struct make_unordered_set
1010 typedef unordered_set_impl
1011 < typename make_hashtable_opt
1013 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1014 O1
, O2
, O3
, O4
, O5
, O6
, O7
, O8
, O9
, O10
1019 > implementation_defined
;
1021 typedef implementation_defined type
;
1024 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1026 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1027 template<class T
, class O1
, class O2
, class O3
, class O4
, class O5
, class O6
, class O7
, class O8
, class O9
, class O10
>
1029 template<class T
, class ...Options
>
1032 : public make_unordered_set
<T
,
1033 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1034 O1
, O2
, O3
, O4
, O5
, O6
, O7
, O8
, O9
, O10
1040 typedef typename make_unordered_set
1042 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1043 O1
, O2
, O3
, O4
, O5
, O6
, O7
, O8
, O9
, O10
1049 //Assert if passed value traits are compatible with the type
1050 BOOST_STATIC_ASSERT((detail::is_same
<typename
Base::value_traits::value_type
, T
>::value
));
1053 typedef typename
Base::value_traits value_traits
;
1054 typedef typename
Base::bucket_traits bucket_traits
;
1055 typedef typename
Base::iterator iterator
;
1056 typedef typename
Base::const_iterator const_iterator
;
1057 typedef typename
Base::bucket_ptr bucket_ptr
;
1058 typedef typename
Base::size_type size_type
;
1059 typedef typename
Base::hasher hasher
;
1060 typedef typename
Base::key_equal key_equal
;
1062 unordered_set ( const bucket_traits
&b_traits
1063 , const hasher
& hash_func
= hasher()
1064 , const key_equal
&equal_func
= key_equal()
1065 , const value_traits
&v_traits
= value_traits())
1066 : Base(b_traits
, hash_func
, equal_func
, v_traits
)
1069 template<class Iterator
>
1070 unordered_set ( Iterator b
1072 , const bucket_traits
&b_traits
1073 , const hasher
& hash_func
= hasher()
1074 , const key_equal
&equal_func
= key_equal()
1075 , const value_traits
&v_traits
= value_traits())
1076 : Base(b
, e
, b_traits
, hash_func
, equal_func
, v_traits
)
1083 //! The class template unordered_multiset is an intrusive container, that mimics most of
1084 //! the interface of std::tr1::unordered_multiset as described in the C++ TR1.
1086 //! unordered_multiset is a semi-intrusive container: each object to be stored in the
1087 //! container must contain a proper hook, but the container also needs
1088 //! additional auxiliary memory to work: unordered_multiset needs a pointer to an array
1089 //! of type `bucket_type` to be passed in the constructor. This bucket array must
1090 //! have at least the same lifetime as the container. This makes the use of
1091 //! unordered_multiset more complicated than purely intrusive containers.
1092 //! `bucket_type` is default-constructible, copyable and assignable
1094 //! The template parameter \c T is the type to be managed by the container.
1095 //! The user can specify additional options and if no options are provided
1096 //! default options are used.
1098 //! The container supports the following options:
1099 //! \c base_hook<>/member_hook<>/value_traits<>,
1100 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
1101 //! \c bucket_traits<>, power_2_buckets<> and cache_begin<>.
1103 //! unordered_multiset only provides forward iterators but it provides 4 iterator types:
1104 //! iterator and const_iterator to navigate through the whole container and
1105 //! local_iterator and const_local_iterator to navigate through the values
1106 //! stored in a single bucket. Local iterators are faster and smaller.
1108 //! It's not recommended to use non constant-time size unordered_multisets because several
1109 //! key functions, like "empty()", become non-constant time functions. Non
1110 //! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks.
1112 //! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor
1113 //! offers functions related to a load factor. Rehashing can be explicitly requested
1114 //! and the user must provide a new bucket array that will be used from that moment.
1116 //! Since no automatic rehashing is done, iterators are never invalidated when
1117 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
1118 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1119 template<class T
, class ...Options
>
1121 template<class Config
>
1123 class unordered_multiset_impl
1127 typedef hashtable_impl
<Config
> table_type
;
1132 unordered_multiset_impl (const unordered_multiset_impl
&);
1136 unordered_multiset_impl
&operator =(const unordered_multiset_impl
&);
1138 typedef table_type implementation_defined
;
1141 typedef typename
implementation_defined::value_type value_type
;
1142 typedef typename
implementation_defined::value_traits value_traits
;
1143 typedef typename
implementation_defined::bucket_traits bucket_traits
;
1144 typedef typename
implementation_defined::pointer pointer
;
1145 typedef typename
implementation_defined::const_pointer const_pointer
;
1146 typedef typename
implementation_defined::reference reference
;
1147 typedef typename
implementation_defined::const_reference const_reference
;
1148 typedef typename
implementation_defined::difference_type difference_type
;
1149 typedef typename
implementation_defined::size_type size_type
;
1150 typedef typename
implementation_defined::key_type key_type
;
1151 typedef typename
implementation_defined::key_equal key_equal
;
1152 typedef typename
implementation_defined::hasher hasher
;
1153 typedef typename
implementation_defined::bucket_type bucket_type
;
1154 typedef typename
implementation_defined::bucket_ptr bucket_ptr
;
1155 typedef typename
implementation_defined::iterator iterator
;
1156 typedef typename
implementation_defined::const_iterator const_iterator
;
1157 typedef typename
implementation_defined::insert_commit_data insert_commit_data
;
1158 typedef typename
implementation_defined::local_iterator local_iterator
;
1159 typedef typename
implementation_defined::const_local_iterator const_local_iterator
;
1160 typedef typename
implementation_defined::node_traits node_traits
;
1161 typedef typename
implementation_defined::node node
;
1162 typedef typename
implementation_defined::node_ptr node_ptr
;
1163 typedef typename
implementation_defined::const_node_ptr const_node_ptr
;
1164 typedef typename
implementation_defined::node_algorithms node_algorithms
;
1173 //! <b>Requires</b>: buckets must not be being used by any other resource.
1175 //! <b>Effects</b>: Constructs an empty unordered_multiset, storing a reference
1176 //! to the bucket array and copies of the hasher and equal functors.
1178 //! <b>Complexity</b>: Constant.
1180 //! <b>Throws</b>: If value_traits::node_traits::node
1181 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
1182 //! or the copy constructor or invocation of Hash or Equal throws.
1184 //! <b>Notes</b>: buckets array must be disposed only after
1185 //! *this is disposed.
1186 unordered_multiset_impl ( const bucket_traits
&b_traits
1187 , const hasher
& hash_func
= hasher()
1188 , const key_equal
&equal_func
= key_equal()
1189 , const value_traits
&v_traits
= value_traits())
1190 : table_(b_traits
, hash_func
, equal_func
, v_traits
)
1193 //! <b>Requires</b>: buckets must not be being used by any other resource
1194 //! and Dereferencing iterator must yield an lvalue of type value_type.
1196 //! <b>Effects</b>: Constructs an empty unordered_multiset and inserts elements from
1199 //! <b>Complexity</b>: If N is std::distance(b, e): Average case is O(N)
1200 //! (with a good hash function and with buckets_len >= N),worst case O(N2).
1202 //! <b>Throws</b>: If value_traits::node_traits::node
1203 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
1204 //! or the copy constructor or invocation of hasher or key_equal throws.
1206 //! <b>Notes</b>: buckets array must be disposed only after
1207 //! *this is disposed.
1208 template<class Iterator
>
1209 unordered_multiset_impl ( Iterator b
1211 , const bucket_traits
&b_traits
1212 , const hasher
& hash_func
= hasher()
1213 , const key_equal
&equal_func
= key_equal()
1214 , const value_traits
&v_traits
= value_traits())
1215 : table_(b_traits
, hash_func
, equal_func
, v_traits
)
1216 { table_
.insert_equal(b
, e
); }
1218 //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_multiset
1219 //! are not deleted (i.e. no destructors are called).
1221 //! <b>Complexity</b>: Linear to the number of elements in the unordered_multiset, if
1222 //! it's a safe-mode or auto-unlink value. Otherwise constant.
1224 //! <b>Throws</b>: Nothing.
1225 ~unordered_multiset_impl()
1228 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
1230 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
1231 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
1233 //! <b>Throws</b>: Nothing.
1235 { return table_
.begin(); }
1237 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
1238 //! of the unordered_multiset.
1240 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
1241 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
1243 //! <b>Throws</b>: Nothing.
1244 const_iterator
begin() const
1245 { return table_
.begin(); }
1247 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
1248 //! of the unordered_multiset.
1250 //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
1251 //! constant time with worst case (empty unordered_set) O(this->bucket_count())
1253 //! <b>Throws</b>: Nothing.
1254 const_iterator
cbegin() const
1255 { return table_
.cbegin(); }
1257 //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_multiset.
1259 //! <b>Complexity</b>: Constant.
1261 //! <b>Throws</b>: Nothing.
1263 { return table_
.end(); }
1265 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
1267 //! <b>Complexity</b>: Constant.
1269 //! <b>Throws</b>: Nothing.
1270 const_iterator
end() const
1271 { return table_
.end(); }
1273 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
1275 //! <b>Complexity</b>: Constant.
1277 //! <b>Throws</b>: Nothing.
1278 const_iterator
cend() const
1279 { return table_
.cend(); }
1281 //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
1283 //! <b>Complexity</b>: Constant.
1285 //! <b>Throws</b>: If hasher copy-constructor throws.
1286 hasher
hash_function() const
1287 { return table_
.hash_function(); }
1289 //! <b>Effects</b>: Returns the key_equal object used by the unordered_multiset.
1291 //! <b>Complexity</b>: Constant.
1293 //! <b>Throws</b>: If key_equal copy-constructor throws.
1294 key_equal
key_eq() const
1295 { return table_
.key_eq(); }
1297 //! <b>Effects</b>: Returns true if the container is empty.
1299 //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
1300 //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
1301 //! Otherwise constant.
1303 //! <b>Throws</b>: Nothing.
1305 { return table_
.empty(); }
1307 //! <b>Effects</b>: Returns the number of elements stored in the unordered_multiset.
1309 //! <b>Complexity</b>: Linear to elements contained in *this if
1310 //! constant-time size option is enabled. Constant-time otherwise.
1312 //! <b>Throws</b>: Nothing.
1313 size_type
size() const
1314 { return table_
.size(); }
1316 //! <b>Requires</b>: the hasher and the equality function unqualified swap
1317 //! call should not throw.
1319 //! <b>Effects</b>: Swaps the contents of two unordered_multisets.
1320 //! Swaps also the contained bucket array and equality and hasher functors.
1323 //! <b>Complexity</b>: Constant.
1325 //! <b>Throws</b>: If the swap() call for the comparison or hash functors
1326 //! found using ADL throw. Basic guarantee.
1327 void swap(unordered_multiset_impl
& other
)
1328 { table_
.swap(other
.table_
); }
1330 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1331 //! Cloner should yield to nodes that compare equal and produce the same
1332 //! hash than the original node.
1334 //! <b>Effects</b>: Erases all the elements from *this
1335 //! calling Disposer::operator()(pointer), clones all the
1336 //! elements from src calling Cloner::operator()(const_reference )
1337 //! and inserts them on *this. The hash function and the equality
1338 //! predicate are copied from the source.
1340 //! If store_hash option is true, this method does not use the hash function.
1342 //! If any operation throws, all cloned elements are unlinked and disposed
1343 //! calling Disposer::operator()(pointer).
1345 //! <b>Complexity</b>: Linear to erased plus inserted elements.
1347 //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
1348 //! throws. Basic guarantee.
1349 template <class Cloner
, class Disposer
>
1350 void clone_from(const unordered_multiset_impl
&src
, Cloner cloner
, Disposer disposer
)
1351 { table_
.clone_from(src
.table_
, cloner
, disposer
); }
1353 //! <b>Requires</b>: value must be an lvalue
1355 //! <b>Effects</b>: Inserts value into the unordered_multiset.
1357 //! <b>Returns</b>: An iterator to the new inserted value.
1359 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1361 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
1363 //! <b>Note</b>: Does not affect the validity of iterators and references.
1364 //! No copy-constructors are called.
1365 iterator
insert(reference value
)
1366 { return table_
.insert_equal(value
); }
1368 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
1369 //! of type value_type.
1371 //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
1373 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
1374 //! size of the range. However, it is linear in N if the range is already sorted
1375 //! by value_comp().
1377 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1379 //! <b>Note</b>: Does not affect the validity of iterators and references.
1380 //! No copy-constructors are called.
1381 template<class Iterator
>
1382 void insert(Iterator b
, Iterator e
)
1383 { table_
.insert_equal(b
, e
); }
1385 //! <b>Effects</b>: Erases the element pointed to by i.
1387 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1389 //! <b>Throws</b>: Nothing.
1391 //! <b>Note</b>: Invalidates the iterators (but not the references)
1392 //! to the erased element. No destructors are called.
1393 void erase(const_iterator i
)
1394 { table_
.erase(i
); }
1396 //! <b>Effects</b>: Erases the range pointed to by b end e.
1398 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
1399 //! worst case O(this->size()).
1401 //! <b>Throws</b>: Nothing.
1403 //! <b>Note</b>: Invalidates the iterators (but not the references)
1404 //! to the erased elements. No destructors are called.
1405 void erase(const_iterator b
, const_iterator e
)
1406 { table_
.erase(b
, e
); }
1408 //! <b>Effects</b>: Erases all the elements with the given value.
1410 //! <b>Returns</b>: The number of erased elements.
1412 //! <b>Complexity</b>: Average case O(this->count(value)).
1413 //! Worst case O(this->size()).
1415 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1417 //! <b>Note</b>: Invalidates the iterators (but not the references)
1418 //! to the erased elements. No destructors are called.
1419 size_type
erase(const_reference value
)
1420 { return table_
.erase(value
); }
1422 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1423 //! the same hash values as the stored hasher. The difference is that
1424 //! "hash_func" hashes the given key instead of the value_type.
1426 //! "key_value_equal" must be a equality function that induces
1427 //! the same equality as key_equal. The difference is that
1428 //! "key_value_equal" compares an arbitrary key with the contained values.
1430 //! <b>Effects</b>: Erases all the elements that have the same hash and
1431 //! compare equal with the given key.
1433 //! <b>Returns</b>: The number of erased elements.
1435 //! <b>Complexity</b>: Average case O(this->count(value)).
1436 //! Worst case O(this->size()).
1438 //! <b>Throws</b>: If the hash_func or the equal_func functors throws.
1439 //! Basic guarantee.
1441 //! <b>Note</b>: Invalidates the iterators (but not the references)
1442 //! to the erased elements. No destructors are called.
1443 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
1444 size_type
erase(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
)
1445 { return table_
.erase(key
, hash_func
, equal_func
); }
1447 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1449 //! <b>Effects</b>: Erases the element pointed to by i.
1450 //! Disposer::operator()(pointer) is called for the removed element.
1452 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1454 //! <b>Throws</b>: Nothing.
1456 //! <b>Note</b>: Invalidates the iterators
1457 //! to the erased elements.
1458 template<class Disposer
>
1459 void erase_and_dispose(const_iterator i
, Disposer disposer
)
1460 { table_
.erase_and_dispose(i
, disposer
); }
1462 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1463 template<class Disposer
>
1464 iterator
erase_and_dispose(iterator i
, Disposer disposer
)
1465 { return this->erase_and_dispose(const_iterator(i
), disposer
); }
1468 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1470 //! <b>Effects</b>: Erases the range pointed to by b end e.
1471 //! Disposer::operator()(pointer) is called for the removed elements.
1473 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
1474 //! worst case O(this->size()).
1476 //! <b>Throws</b>: Nothing.
1478 //! <b>Note</b>: Invalidates the iterators
1479 //! to the erased elements.
1480 template<class Disposer
>
1481 void erase_and_dispose(const_iterator b
, const_iterator e
, Disposer disposer
)
1482 { table_
.erase_and_dispose(b
, e
, disposer
); }
1484 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1486 //! <b>Effects</b>: Erases all the elements with the given value.
1487 //! Disposer::operator()(pointer) is called for the removed elements.
1489 //! <b>Returns</b>: The number of erased elements.
1491 //! <b>Complexity</b>: Average case O(this->count(value)).
1492 //! Worst case O(this->size()).
1494 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1496 //! <b>Note</b>: Invalidates the iterators (but not the references)
1497 //! to the erased elements. No destructors are called.
1498 template<class Disposer
>
1499 size_type
erase_and_dispose(const_reference value
, Disposer disposer
)
1500 { return table_
.erase_and_dispose(value
, disposer
); }
1502 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1504 //! <b>Effects</b>: Erases all the elements with the given key.
1505 //! according to the comparison functor "equal_func".
1506 //! Disposer::operator()(pointer) is called for the removed elements.
1508 //! <b>Returns</b>: The number of erased elements.
1510 //! <b>Complexity</b>: Average case O(this->count(value)).
1511 //! Worst case O(this->size()).
1513 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
1515 //! <b>Note</b>: Invalidates the iterators
1516 //! to the erased elements.
1517 template<class KeyType
, class KeyHasher
, class KeyValueEqual
, class Disposer
>
1518 size_type
erase_and_dispose(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
, Disposer disposer
)
1519 { return table_
.erase_and_dispose(key
, hash_func
, equal_func
, disposer
); }
1521 //! <b>Effects</b>: Erases all the elements of the container.
1523 //! <b>Complexity</b>: Linear to the number of elements on the container.
1524 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
1526 //! <b>Throws</b>: Nothing.
1528 //! <b>Note</b>: Invalidates the iterators (but not the references)
1529 //! to the erased elements. No destructors are called.
1531 { return table_
.clear(); }
1533 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1535 //! <b>Effects</b>: Erases all the elements of the container.
1537 //! <b>Complexity</b>: Linear to the number of elements on the container.
1538 //! Disposer::operator()(pointer) is called for the removed elements.
1540 //! <b>Throws</b>: Nothing.
1542 //! <b>Note</b>: Invalidates the iterators (but not the references)
1543 //! to the erased elements. No destructors are called.
1544 template<class Disposer
>
1545 void clear_and_dispose(Disposer disposer
)
1546 { return table_
.clear_and_dispose(disposer
); }
1548 //! <b>Effects</b>: Returns the number of contained elements with the given key
1550 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1552 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1553 size_type
count(const_reference value
) const
1554 { return table_
.count(value
); }
1556 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1557 //! the same hash values as the stored hasher. The difference is that
1558 //! "hash_func" hashes the given key instead of the value_type.
1560 //! "key_value_equal" must be a equality function that induces
1561 //! the same equality as key_equal. The difference is that
1562 //! "key_value_equal" compares an arbitrary key with the contained values.
1564 //! <b>Effects</b>: Returns the number of contained elements with the given key
1566 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1568 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1569 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
1570 size_type
count(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
) const
1571 { return table_
.count(key
, hash_func
, equal_func
); }
1573 //! <b>Effects</b>: Finds an iterator to the first element whose value is
1574 //! "value" or end() if that element does not exist.
1576 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1578 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1579 iterator
find(const_reference value
)
1580 { return table_
.find(value
); }
1582 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1583 //! the same hash values as the stored hasher. The difference is that
1584 //! "hash_func" hashes the given key instead of the value_type.
1586 //! "key_value_equal" must be a equality function that induces
1587 //! the same equality as key_equal. The difference is that
1588 //! "key_value_equal" compares an arbitrary key with the contained values.
1590 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1591 //! "key" according to the given hasher and equality functor or end() if
1592 //! that element does not exist.
1594 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1596 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1598 //! <b>Note</b>: This function is used when constructing a value_type
1599 //! is expensive and the value_type can be compared with a cheaper
1600 //! key type. Usually this key is part of the value_type.
1601 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
1602 iterator
find(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
)
1603 { return table_
.find(key
, hash_func
, equal_func
); }
1605 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
1606 //! "key" or end() if that element does not exist.
1608 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1610 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1611 const_iterator
find(const_reference value
) const
1612 { return table_
.find(value
); }
1614 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1615 //! the same hash values as the stored hasher. The difference is that
1616 //! "hash_func" hashes the given key instead of the value_type.
1618 //! "key_value_equal" must be a equality function that induces
1619 //! the same equality as key_equal. The difference is that
1620 //! "key_value_equal" compares an arbitrary key with the contained values.
1622 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1623 //! "key" according to the given hasher and equality functor or end() if
1624 //! that element does not exist.
1626 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1628 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1630 //! <b>Note</b>: This function is used when constructing a value_type
1631 //! is expensive and the value_type can be compared with a cheaper
1632 //! key type. Usually this key is part of the value_type.
1633 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
1634 const_iterator
find(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
) const
1635 { return table_
.find(key
, hash_func
, equal_func
); }
1637 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
1638 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
1641 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
1643 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1644 std::pair
<iterator
,iterator
> equal_range(const_reference value
)
1645 { return table_
.equal_range(value
); }
1647 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1648 //! the same hash values as the stored hasher. The difference is that
1649 //! "hash_func" hashes the given key instead of the value_type.
1651 //! "key_value_equal" must be a equality function that induces
1652 //! the same equality as key_equal. The difference is that
1653 //! "key_value_equal" compares an arbitrary key with the contained values.
1655 //! <b>Effects</b>: Returns a range containing all elements with equivalent
1656 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
1659 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
1660 //! Worst case O(this->size()).
1662 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1664 //! <b>Note</b>: This function is used when constructing a value_type
1665 //! is expensive and the value_type can be compared with a cheaper
1666 //! key type. Usually this key is part of the value_type.
1667 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
1668 std::pair
<iterator
,iterator
> equal_range
1669 (const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
)
1670 { return table_
.equal_range(key
, hash_func
, equal_func
); }
1672 //! <b>Effects</b>: Returns a range containing all elements with values equivalent
1673 //! to value. Returns std::make_pair(this->end(), this->end()) if no such
1676 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
1678 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1679 std::pair
<const_iterator
, const_iterator
>
1680 equal_range(const_reference value
) const
1681 { return table_
.equal_range(value
); }
1683 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1684 //! the same hash values as the stored hasher. The difference is that
1685 //! "hash_func" hashes the given key instead of the value_type.
1687 //! "key_value_equal" must be a equality function that induces
1688 //! the same equality as key_equal. The difference is that
1689 //! "key_value_equal" compares an arbitrary key with the contained values.
1691 //! <b>Effects</b>: Returns a range containing all elements with equivalent
1692 //! keys. Returns std::make_pair(this->end(), this->end()) if no such
1695 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
1696 //! Worst case O(this->size()).
1698 //! <b>Throws</b>: If the internal hasher or the equality functor throws.
1700 //! <b>Note</b>: This function is used when constructing a value_type
1701 //! is expensive and the value_type can be compared with a cheaper
1702 //! key type. Usually this key is part of the value_type.
1703 template<class KeyType
, class KeyHasher
, class KeyValueEqual
>
1704 std::pair
<const_iterator
, const_iterator
>
1705 equal_range(const KeyType
& key
, KeyHasher hash_func
, KeyValueEqual equal_func
) const
1706 { return table_
.equal_range(key
, hash_func
, equal_func
); }
1708 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
1709 //! appropriate type. Otherwise the behavior is undefined.
1711 //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_multiset
1712 //! that points to the value
1714 //! <b>Complexity</b>: Constant.
1716 //! <b>Throws</b>: If the hash function throws.
1717 iterator
iterator_to(reference value
)
1718 { return table_
.iterator_to(value
); }
1720 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
1721 //! appropriate type. Otherwise the behavior is undefined.
1723 //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
1724 //! unordered_multiset that points to the value
1726 //! <b>Complexity</b>: Constant.
1728 //! <b>Throws</b>: If the hash function throws.
1729 const_iterator
iterator_to(const_reference value
) const
1730 { return table_
.iterator_to(value
); }
1732 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1733 //! appropriate type. Otherwise the behavior is undefined.
1735 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
1736 //! that points to the value
1738 //! <b>Complexity</b>: Constant.
1740 //! <b>Throws</b>: Nothing.
1742 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1744 static local_iterator
s_local_iterator_to(reference value
)
1745 { return table_type::s_local_iterator_to(value
); }
1747 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1748 //! appropriate type. Otherwise the behavior is undefined.
1750 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
1751 //! the unordered_set that points to the value
1753 //! <b>Complexity</b>: Constant.
1755 //! <b>Throws</b>: Nothing.
1757 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1759 static const_local_iterator
s_local_iterator_to(const_reference value
)
1760 { return table_type::s_local_iterator_to(value
); }
1762 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1763 //! appropriate type. Otherwise the behavior is undefined.
1765 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
1766 //! that points to the value
1768 //! <b>Complexity</b>: Constant.
1770 //! <b>Throws</b>: Nothing.
1771 local_iterator
local_iterator_to(reference value
)
1772 { return table_
.local_iterator_to(value
); }
1774 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
1775 //! appropriate type. Otherwise the behavior is undefined.
1777 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
1778 //! the unordered_set that points to the value
1780 //! <b>Complexity</b>: Constant.
1782 //! <b>Throws</b>: Nothing.
1783 const_local_iterator
local_iterator_to(const_reference value
) const
1784 { return table_
.local_iterator_to(value
); }
1786 //! <b>Effects</b>: Returns the number of buckets passed in the constructor
1787 //! or the last rehash function.
1789 //! <b>Complexity</b>: Constant.
1791 //! <b>Throws</b>: Nothing.
1792 size_type
bucket_count() const
1793 { return table_
.bucket_count(); }
1795 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1797 //! <b>Effects</b>: Returns the number of elements in the nth bucket.
1799 //! <b>Complexity</b>: Constant.
1801 //! <b>Throws</b>: Nothing.
1802 size_type
bucket_size(size_type n
) const
1803 { return table_
.bucket_size(n
); }
1805 //! <b>Effects</b>: Returns the index of the bucket in which elements
1806 //! with keys equivalent to k would be found, if any such element existed.
1808 //! <b>Complexity</b>: Constant.
1810 //! <b>Throws</b>: If the hash functor throws.
1812 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
1813 size_type
bucket(const value_type
& k
) const
1814 { return table_
.bucket(k
); }
1816 //! <b>Requires</b>: "hash_func" must be a hash function that induces
1817 //! the same hash values as the stored hasher. The difference is that
1818 //! "hash_func" hashes the given key instead of the value_type.
1820 //! <b>Effects</b>: Returns the index of the bucket in which elements
1821 //! with keys equivalent to k would be found, if any such element existed.
1823 //! <b>Complexity</b>: Constant.
1825 //! <b>Throws</b>: If the hash functor throws.
1827 //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
1828 template<class KeyType
, class KeyHasher
>
1829 size_type
bucket(const KeyType
& k
, const KeyHasher
&hash_func
) const
1830 { return table_
.bucket(k
, hash_func
); }
1832 //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
1833 //! or the last rehash function.
1835 //! <b>Complexity</b>: Constant.
1837 //! <b>Throws</b>: Nothing.
1838 bucket_ptr
bucket_pointer() const
1839 { return table_
.bucket_pointer(); }
1841 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1843 //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
1844 //! of the sequence stored in the bucket n.
1846 //! <b>Complexity</b>: Constant.
1848 //! <b>Throws</b>: Nothing.
1850 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1851 //! containing all of the elements in the nth bucket.
1852 local_iterator
begin(size_type n
)
1853 { return table_
.begin(n
); }
1855 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1857 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
1858 //! of the sequence stored in the bucket n.
1860 //! <b>Complexity</b>: Constant.
1862 //! <b>Throws</b>: Nothing.
1864 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1865 //! containing all of the elements in the nth bucket.
1866 const_local_iterator
begin(size_type n
) const
1867 { return table_
.begin(n
); }
1869 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1871 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
1872 //! of the sequence stored in the bucket n.
1874 //! <b>Complexity</b>: Constant.
1876 //! <b>Throws</b>: Nothing.
1878 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1879 //! containing all of the elements in the nth bucket.
1880 const_local_iterator
cbegin(size_type n
) const
1881 { return table_
.cbegin(n
); }
1883 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1885 //! <b>Effects</b>: Returns a local_iterator pointing to the end
1886 //! of the sequence stored in the bucket n.
1888 //! <b>Complexity</b>: Constant.
1890 //! <b>Throws</b>: Nothing.
1892 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1893 //! containing all of the elements in the nth bucket.
1894 local_iterator
end(size_type n
)
1895 { return table_
.end(n
); }
1897 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1899 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
1900 //! of the sequence stored in the bucket n.
1902 //! <b>Complexity</b>: Constant.
1904 //! <b>Throws</b>: Nothing.
1906 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1907 //! containing all of the elements in the nth bucket.
1908 const_local_iterator
end(size_type n
) const
1909 { return table_
.end(n
); }
1911 //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
1913 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
1914 //! of the sequence stored in the bucket n.
1916 //! <b>Complexity</b>: Constant.
1918 //! <b>Throws</b>: Nothing.
1920 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
1921 //! containing all of the elements in the nth bucket.
1922 const_local_iterator
cend(size_type n
) const
1923 { return table_
.cend(n
); }
1925 //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
1926 //! or the same as the old bucket array. new_size is the length of the
1927 //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
1928 //! n can be bigger or smaller than this->bucket_count().
1930 //! <b>Effects</b>: Updates the internal reference with the new bucket erases
1931 //! the values from the old bucket and inserts then in the new one.
1933 //! If store_hash option is true, this method does not use the hash function.
1935 //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
1937 //! <b>Throws</b>: If the hasher functor throws.
1938 void rehash(const bucket_traits
&new_bucket_traits
)
1939 { table_
.rehash(new_bucket_traits
); }
1941 //! <b>Requires</b>:
1945 //! <b>Complexity</b>:
1949 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
1950 bool incremental_rehash(bool grow
= true)
1951 { return table_
.incremental_rehash(grow
); }
1953 //! <b>Note</b>: this method is only available if incremental<true> option is activated.
1954 bool incremental_rehash(const bucket_traits
&new_bucket_traits
)
1955 { return table_
.incremental_rehash(new_bucket_traits
); }
1957 //! <b>Requires</b>:
1961 //! <b>Complexity</b>:
1964 size_type
split_count() const
1965 { return table_
.split_count(); }
1967 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
1968 //! the container that is bigger than n. This suggestion can be used
1969 //! to create bucket arrays with a size that will usually improve
1970 //! container's performance. If such value does not exist, the
1971 //! higher possible value is returned.
1973 //! <b>Complexity</b>: Amortized constant time.
1975 //! <b>Throws</b>: Nothing.
1976 static size_type
suggested_upper_bucket_count(size_type n
)
1977 { return table_type::suggested_upper_bucket_count(n
); }
1979 //! <b>Effects</b>: Returns the nearest new bucket count optimized for
1980 //! the container that is smaller than n. This suggestion can be used
1981 //! to create bucket arrays with a size that will usually improve
1982 //! container's performance. If such value does not exist, the
1983 //! lower possible value is returned.
1985 //! <b>Complexity</b>: Amortized constant time.
1987 //! <b>Throws</b>: Nothing.
1988 static size_type
suggested_lower_bucket_count(size_type n
)
1989 { return table_type::suggested_lower_bucket_count(n
); }
1992 //! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
1993 //! same options (either explicitly or implicitly) are used.
1994 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1995 template<class T
, class ...Options
>
1997 template<class T
, class O1
= none
, class O2
= none
1998 , class O3
= none
, class O4
= none
1999 , class O5
= none
, class O6
= none
2000 , class O7
= none
, class O8
= none
2001 , class O9
= none
, class O10
= none
2004 struct make_unordered_multiset
2007 typedef unordered_multiset_impl
2008 < typename make_hashtable_opt
2010 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2011 O1
, O2
, O3
, O4
, O5
, O6
, O7
, O8
, O9
, O10
2016 > implementation_defined
;
2018 typedef implementation_defined type
;
2021 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2023 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2024 template<class T
, class O1
, class O2
, class O3
, class O4
, class O5
, class O6
, class O7
, class O8
, class O9
, class O10
>
2026 template<class T
, class ...Options
>
2028 class unordered_multiset
2029 : public make_unordered_multiset
<T
,
2030 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2031 O1
, O2
, O3
, O4
, O5
, O6
, O7
, O8
, O9
, O10
2037 typedef typename make_unordered_multiset
2039 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2040 O1
, O2
, O3
, O4
, O5
, O6
, O7
, O8
, O9
, O10
2045 //Assert if passed value traits are compatible with the type
2046 BOOST_STATIC_ASSERT((detail::is_same
<typename
Base::value_traits::value_type
, T
>::value
));
2049 typedef typename
Base::value_traits value_traits
;
2050 typedef typename
Base::bucket_traits bucket_traits
;
2051 typedef typename
Base::iterator iterator
;
2052 typedef typename
Base::const_iterator const_iterator
;
2053 typedef typename
Base::bucket_ptr bucket_ptr
;
2054 typedef typename
Base::size_type size_type
;
2055 typedef typename
Base::hasher hasher
;
2056 typedef typename
Base::key_equal key_equal
;
2058 unordered_multiset( const bucket_traits
&b_traits
2059 , const hasher
& hash_func
= hasher()
2060 , const key_equal
&equal_func
= key_equal()
2061 , const value_traits
&v_traits
= value_traits())
2062 : Base(b_traits
, hash_func
, equal_func
, v_traits
)
2065 template<class Iterator
>
2066 unordered_multiset( Iterator b
2068 , const bucket_traits
&b_traits
2069 , const hasher
& hash_func
= hasher()
2070 , const key_equal
&equal_func
= key_equal()
2071 , const value_traits
&v_traits
= value_traits())
2072 : Base(b
, e
, b_traits
, hash_func
, equal_func
, v_traits
)
2078 } //namespace intrusive
2081 #include <boost/intrusive/detail/config_end.hpp>
2083 #endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP