fix doc example typo
[boost.git] / boost / intrusive / unordered_set.hpp
blobcdca8603116b4dfd7d323c374974f8aaf651d9cd
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga 2006-2008
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.
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>
19 #include <iterator>
21 namespace boost {
22 namespace intrusive {
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.
26 //!
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
34 //!
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.
38 //!
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<>.
43 //!
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.
48 //!
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.
52 //!
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.
56 //!
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>
61 #else
62 template<class Config>
63 #endif
64 class unordered_set_impl
66 /// @cond
67 private:
68 typedef hashtable_impl<Config> table_type;
70 //! This class is
71 //! non-copyable
72 unordered_set_impl (const unordered_set_impl&);
74 //! This class is
75 //! non-assignable
76 unordered_set_impl &operator =(const unordered_set_impl&);
78 typedef table_type implementation_defined;
79 /// @endcond
81 public:
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;
107 /// @cond
108 private:
109 table_type table_;
110 /// @endcond
112 public:
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.
118 //!
119 //! <b>Complexity</b>: Constant.
120 //!
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.
136 //!
137 //! <b>Effects</b>: Constructs an empty unordered_set and inserts elements from
138 //! [b, e).
139 //!
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).
142 //!
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
151 , Iterator e
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).
161 //!
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.
164 //!
165 //! <b>Throws</b>: Nothing.
166 ~unordered_set_impl()
169 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
170 //!
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())
173 //!
174 //! <b>Throws</b>: Nothing.
175 iterator begin()
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())
183 //!
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())
193 //!
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.
199 //!
200 //! <b>Complexity</b>: Constant.
201 //!
202 //! <b>Throws</b>: Nothing.
203 iterator end()
204 { return table_.end(); }
206 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
207 //!
208 //! <b>Complexity</b>: Constant.
209 //!
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.
215 //!
216 //! <b>Complexity</b>: Constant.
217 //!
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.
223 //!
224 //! <b>Complexity</b>: Constant.
225 //!
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.
231 //!
232 //! <b>Complexity</b>: Constant.
233 //!
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.
239 //!
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.
243 //!
244 //! <b>Throws</b>: Nothing.
245 bool empty() const
246 { return table_.empty(); }
248 //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
249 //!
250 //! <b>Complexity</b>: Linear to elements contained in *this if
251 //! constant-time size option is enabled. Constant-time otherwise.
252 //!
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.
259 //!
260 //! <b>Effects</b>: Swaps the contents of two unordered_sets.
261 //! Swaps also the contained bucket array and equality and hasher functors.
262 //!
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).
284 //!
285 //! <b>Complexity</b>: Linear to erased plus inserted elements.
286 //!
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
294 //!
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
301 //! and false.
302 //!
303 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
304 //!
305 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
306 //!
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.
314 //!
315 //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
316 //!
317 //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e).
318 //! Worst case O(N*this->size()).
319 //!
320 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
321 //!
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.
335 //!
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.
344 //!
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.
348 //!
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".
372 //!
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.
377 //!
378 //! <b>Complexity</b>: Constant time.
380 //! <b>Throws</b>: Nothing.
381 //!
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.
391 //!
392 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
393 //!
394 //! <b>Throws</b>: Nothing.
395 //!
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)
399 { table_.erase(i); }
401 //! <b>Effects</b>: Erases the range pointed to by b end e.
402 //!
403 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
404 //! worst case O(this->size()).
405 //!
406 //! <b>Throws</b>: Nothing.
407 //!
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.
414 //!
415 //! <b>Returns</b>: The number of erased elements.
416 //!
417 //! <b>Complexity</b>: Average case O(this->count(value)).
418 //! Worst case O(this->size()).
419 //!
420 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
421 //!
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.
437 //!
438 //! <b>Returns</b>: The number of erased elements.
439 //!
440 //! <b>Complexity</b>: Average case O(this->count(value)).
441 //! Worst case O(this->size()).
442 //!
443 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
444 //!
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.
455 //!
456 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
457 //!
458 //! <b>Throws</b>: Nothing.
459 //!
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); }
470 #endif
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.
476 //!
477 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
478 //! worst case O(this->size()).
479 //!
480 //! <b>Throws</b>: Nothing.
481 //!
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.
492 //!
493 //! <b>Returns</b>: The number of erased elements.
494 //!
495 //! <b>Complexity</b>: Average case O(this->count(value)).
496 //! Worst case O(this->size()).
497 //!
498 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
499 //!
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.
513 //!
514 //! <b>Complexity</b>: Average case O(this->count(value)).
515 //! Worst case O(this->size()).
516 //!
517 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
518 //!
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.
526 //!
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.
529 //!
530 //! <b>Throws</b>: Nothing.
531 //!
532 //! <b>Note</b>: Invalidates the iterators (but not the references)
533 //! to the erased elements. No destructors are called.
534 void clear()
535 { return table_.clear(); }
537 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
538 //!
539 //! <b>Effects</b>: Erases all of the elements.
540 //!
541 //! <b>Complexity</b>: Linear to the number of elements on the container.
542 //! Disposer::operator()(pointer) is called for the removed elements.
543 //!
544 //! <b>Throws</b>: Nothing.
545 //!
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
553 //!
554 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
555 //!
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()).
571 //!
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()).
581 //!
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()).
599 //!
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.
611 //!
612 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
613 //!
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.
629 //!
630 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
631 //!
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
643 //! elements exist.
644 //!
645 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
646 //!
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
661 //! elements exist.
662 //!
663 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, hash_func)).
664 //! Worst case O(this->size()).
665 //!
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
677 //! elements exist.
678 //!
679 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
680 //!
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
696 //! elements exist.
697 //!
698 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
699 //! Worst case O(this->size()).
700 //!
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.
713 //!
714 //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_set
715 //! that points to the value
716 //!
717 //! <b>Complexity</b>: Constant.
718 //!
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.
725 //!
726 //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
727 //! unordered_set that points to the value
728 //!
729 //! <b>Complexity</b>: Constant.
730 //!
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.
737 //!
738 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
739 //! that points to the value
740 //!
741 //! <b>Complexity</b>: Constant.
742 //!
743 //! <b>Throws</b>: Nothing.
744 //!
745 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
746 //! is stateless.
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.
752 //!
753 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
754 //! the unordered_set that points to the value
755 //!
756 //! <b>Complexity</b>: Constant.
757 //!
758 //! <b>Throws</b>: Nothing.
759 //!
760 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
761 //! is stateless.
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.
767 //!
768 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
769 //! that points to the value
770 //!
771 //! <b>Complexity</b>: Constant.
772 //!
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.
779 //!
780 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
781 //! the unordered_set that points to the value
782 //!
783 //! <b>Complexity</b>: Constant.
784 //!
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.
791 //!
792 //! <b>Complexity</b>: Constant.
793 //!
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.
801 //!
802 //! <b>Complexity</b>: Constant.
803 //!
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.
810 //!
811 //! <b>Complexity</b>: Constant.
812 //!
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.
825 //!
826 //! <b>Complexity</b>: Constant.
827 //!
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.
837 //!
838 //! <b>Complexity</b>: Constant.
839 //!
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.
848 //!
849 //! <b>Complexity</b>: Constant.
850 //!
851 //! <b>Throws</b>: Nothing.
852 //!
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.
862 //!
863 //! <b>Complexity</b>: Constant.
864 //!
865 //! <b>Throws</b>: Nothing.
866 //!
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.
876 //!
877 //! <b>Complexity</b>: Constant.
878 //!
879 //! <b>Throws</b>: Nothing.
880 //!
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.
890 //!
891 //! <b>Complexity</b>: Constant.
892 //!
893 //! <b>Throws</b>: Nothing.
894 //!
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.
904 //!
905 //! <b>Complexity</b>: Constant.
906 //!
907 //! <b>Throws</b>: Nothing.
908 //!
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.
918 //!
919 //! <b>Complexity</b>: Constant.
920 //!
921 //! <b>Throws</b>: Nothing.
922 //!
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.
937 //!
938 //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
939 //!
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); }
944 //! <b>Requires</b>:
946 //! <b>Effects</b>:
947 //!
948 //! <b>Complexity</b>:
949 //!
950 //! <b>Throws</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); }
960 //! <b>Requires</b>:
962 //! <b>Effects</b>:
963 //!
964 //! <b>Complexity</b>:
965 //!
966 //! <b>Throws</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.
975 //!
976 //! <b>Complexity</b>: Amortized constant time.
977 //!
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.
987 //!
988 //! <b>Complexity</b>: Amortized constant time.
989 //!
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>
999 #else
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
1006 #endif
1007 struct make_unordered_set
1009 /// @cond
1010 typedef unordered_set_impl
1011 < typename make_hashtable_opt
1012 <T, true,
1013 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1014 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
1015 #else
1016 Options...
1017 #endif
1018 >::type
1019 > implementation_defined;
1020 /// @endcond
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>
1028 #else
1029 template<class T, class ...Options>
1030 #endif
1031 class unordered_set
1032 : public make_unordered_set<T,
1033 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1034 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
1035 #else
1036 Options...
1037 #endif
1038 >::type
1040 typedef typename make_unordered_set
1041 <T,
1042 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1043 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
1044 #else
1045 Options...
1046 #endif
1047 >::type Base;
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));
1052 public:
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
1071 , Iterator e
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)
1080 #endif
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>
1120 #else
1121 template<class Config>
1122 #endif
1123 class unordered_multiset_impl
1125 /// @cond
1126 private:
1127 typedef hashtable_impl<Config> table_type;
1128 /// @endcond
1130 //! This class is
1131 //! non-copyable
1132 unordered_multiset_impl (const unordered_multiset_impl&);
1134 //! This class is
1135 //! non-assignable
1136 unordered_multiset_impl &operator =(const unordered_multiset_impl&);
1138 typedef table_type implementation_defined;
1140 public:
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;
1166 /// @cond
1167 private:
1168 table_type table_;
1169 /// @endcond
1171 public:
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.
1177 //!
1178 //! <b>Complexity</b>: Constant.
1179 //!
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.
1195 //!
1196 //! <b>Effects</b>: Constructs an empty unordered_multiset and inserts elements from
1197 //! [b, e).
1198 //!
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).
1201 //!
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
1210 , Iterator e
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).
1220 //!
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.
1223 //!
1224 //! <b>Throws</b>: Nothing.
1225 ~unordered_multiset_impl()
1228 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
1229 //!
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())
1232 //!
1233 //! <b>Throws</b>: Nothing.
1234 iterator begin()
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())
1242 //!
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())
1252 //!
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.
1258 //!
1259 //! <b>Complexity</b>: Constant.
1260 //!
1261 //! <b>Throws</b>: Nothing.
1262 iterator end()
1263 { return table_.end(); }
1265 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
1266 //!
1267 //! <b>Complexity</b>: Constant.
1268 //!
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.
1274 //!
1275 //! <b>Complexity</b>: Constant.
1276 //!
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.
1282 //!
1283 //! <b>Complexity</b>: Constant.
1284 //!
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.
1290 //!
1291 //! <b>Complexity</b>: Constant.
1292 //!
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.
1298 //!
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.
1302 //!
1303 //! <b>Throws</b>: Nothing.
1304 bool empty() const
1305 { return table_.empty(); }
1307 //! <b>Effects</b>: Returns the number of elements stored in the unordered_multiset.
1308 //!
1309 //! <b>Complexity</b>: Linear to elements contained in *this if
1310 //! constant-time size option is enabled. Constant-time otherwise.
1311 //!
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.
1318 //!
1319 //! <b>Effects</b>: Swaps the contents of two unordered_multisets.
1320 //! Swaps also the contained bucket array and equality and hasher functors.
1322 //!
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).
1344 //!
1345 //! <b>Complexity</b>: Linear to erased plus inserted elements.
1346 //!
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
1354 //!
1355 //! <b>Effects</b>: Inserts value into the unordered_multiset.
1357 //! <b>Returns</b>: An iterator to the new inserted value.
1358 //!
1359 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1360 //!
1361 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
1362 //!
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.
1370 //!
1371 //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
1372 //!
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().
1376 //!
1377 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1378 //!
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.
1386 //!
1387 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1388 //!
1389 //! <b>Throws</b>: Nothing.
1390 //!
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.
1397 //!
1398 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
1399 //! worst case O(this->size()).
1400 //!
1401 //! <b>Throws</b>: Nothing.
1402 //!
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.
1409 //!
1410 //! <b>Returns</b>: The number of erased elements.
1411 //!
1412 //! <b>Complexity</b>: Average case O(this->count(value)).
1413 //! Worst case O(this->size()).
1414 //!
1415 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1416 //!
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.
1432 //!
1433 //! <b>Returns</b>: The number of erased elements.
1434 //!
1435 //! <b>Complexity</b>: Average case O(this->count(value)).
1436 //! Worst case O(this->size()).
1437 //!
1438 //! <b>Throws</b>: If the hash_func or the equal_func functors throws.
1439 //! Basic guarantee.
1440 //!
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.
1451 //!
1452 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1453 //!
1454 //! <b>Throws</b>: Nothing.
1455 //!
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); }
1466 #endif
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.
1472 //!
1473 //! <b>Complexity</b>: Average case O(std::distance(b, e)),
1474 //! worst case O(this->size()).
1475 //!
1476 //! <b>Throws</b>: Nothing.
1477 //!
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.
1488 //!
1489 //! <b>Returns</b>: The number of erased elements.
1490 //!
1491 //! <b>Complexity</b>: Average case O(this->count(value)).
1492 //! Worst case O(this->size()).
1493 //!
1494 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
1495 //!
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.
1509 //!
1510 //! <b>Complexity</b>: Average case O(this->count(value)).
1511 //! Worst case O(this->size()).
1512 //!
1513 //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
1514 //!
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.
1522 //!
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.
1525 //!
1526 //! <b>Throws</b>: Nothing.
1527 //!
1528 //! <b>Note</b>: Invalidates the iterators (but not the references)
1529 //! to the erased elements. No destructors are called.
1530 void clear()
1531 { return table_.clear(); }
1533 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1534 //!
1535 //! <b>Effects</b>: Erases all the elements of the container.
1536 //!
1537 //! <b>Complexity</b>: Linear to the number of elements on the container.
1538 //! Disposer::operator()(pointer) is called for the removed elements.
1539 //!
1540 //! <b>Throws</b>: Nothing.
1541 //!
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
1549 //!
1550 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1551 //!
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()).
1567 //!
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()).
1577 //!
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()).
1595 //!
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.
1607 //!
1608 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1609 //!
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.
1625 //!
1626 //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
1627 //!
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
1639 //! elements exist.
1640 //!
1641 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
1642 //!
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
1657 //! elements exist.
1658 //!
1659 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
1660 //! Worst case O(this->size()).
1661 //!
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
1674 //! elements exist.
1675 //!
1676 //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
1677 //!
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
1693 //! elements exist.
1694 //!
1695 //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
1696 //! Worst case O(this->size()).
1697 //!
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.
1710 //!
1711 //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_multiset
1712 //! that points to the value
1713 //!
1714 //! <b>Complexity</b>: Constant.
1715 //!
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.
1722 //!
1723 //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
1724 //! unordered_multiset that points to the value
1725 //!
1726 //! <b>Complexity</b>: Constant.
1727 //!
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.
1734 //!
1735 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
1736 //! that points to the value
1737 //!
1738 //! <b>Complexity</b>: Constant.
1739 //!
1740 //! <b>Throws</b>: Nothing.
1741 //!
1742 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1743 //! is stateless.
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.
1749 //!
1750 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
1751 //! the unordered_set that points to the value
1752 //!
1753 //! <b>Complexity</b>: Constant.
1754 //!
1755 //! <b>Throws</b>: Nothing.
1756 //!
1757 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1758 //! is stateless.
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.
1764 //!
1765 //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
1766 //! that points to the value
1767 //!
1768 //! <b>Complexity</b>: Constant.
1769 //!
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.
1776 //!
1777 //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
1778 //! the unordered_set that points to the value
1779 //!
1780 //! <b>Complexity</b>: Constant.
1781 //!
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.
1788 //!
1789 //! <b>Complexity</b>: Constant.
1790 //!
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.
1798 //!
1799 //! <b>Complexity</b>: Constant.
1800 //!
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.
1807 //!
1808 //! <b>Complexity</b>: Constant.
1809 //!
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.
1822 //!
1823 //! <b>Complexity</b>: Constant.
1824 //!
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.
1834 //!
1835 //! <b>Complexity</b>: Constant.
1836 //!
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.
1845 //!
1846 //! <b>Complexity</b>: Constant.
1847 //!
1848 //! <b>Throws</b>: Nothing.
1849 //!
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.
1859 //!
1860 //! <b>Complexity</b>: Constant.
1861 //!
1862 //! <b>Throws</b>: Nothing.
1863 //!
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.
1873 //!
1874 //! <b>Complexity</b>: Constant.
1875 //!
1876 //! <b>Throws</b>: Nothing.
1877 //!
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.
1887 //!
1888 //! <b>Complexity</b>: Constant.
1889 //!
1890 //! <b>Throws</b>: Nothing.
1891 //!
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.
1901 //!
1902 //! <b>Complexity</b>: Constant.
1903 //!
1904 //! <b>Throws</b>: Nothing.
1905 //!
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.
1915 //!
1916 //! <b>Complexity</b>: Constant.
1917 //!
1918 //! <b>Throws</b>: Nothing.
1919 //!
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.
1934 //!
1935 //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
1936 //!
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>:
1943 //! <b>Effects</b>:
1944 //!
1945 //! <b>Complexity</b>:
1946 //!
1947 //! <b>Throws</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>:
1959 //! <b>Effects</b>:
1960 //!
1961 //! <b>Complexity</b>:
1962 //!
1963 //! <b>Throws</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.
1972 //!
1973 //! <b>Complexity</b>: Amortized constant time.
1974 //!
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.
1984 //!
1985 //! <b>Complexity</b>: Amortized constant time.
1986 //!
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>
1996 #else
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
2003 #endif
2004 struct make_unordered_multiset
2006 /// @cond
2007 typedef unordered_multiset_impl
2008 < typename make_hashtable_opt
2009 <T, false,
2010 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2011 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
2012 #else
2013 Options...
2014 #endif
2015 >::type
2016 > implementation_defined;
2017 /// @endcond
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>
2025 #else
2026 template<class T, class ...Options>
2027 #endif
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
2032 #else
2033 Options...
2034 #endif
2035 >::type
2037 typedef typename make_unordered_multiset
2038 <T,
2039 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2040 O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
2041 #else
2042 Options...
2043 #endif
2044 >::type Base;
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));
2048 public:
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
2067 , Iterator e
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)
2076 #endif
2078 } //namespace intrusive
2079 } //namespace boost
2081 #include <boost/intrusive/detail/config_end.hpp>
2083 #endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP