BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_hashtablebucketiterator.h
Go to the documentation of this file.
1/// @file bslstl_hashtablebucketiterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_hashtablebucketiterator.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_HASHTABLEBUCKETITERATOR
9#define INCLUDED_BSLSTL_HASHTABLEBUCKETITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_hashtablebucketiterator bslstl_hashtablebucketiterator
15/// @brief Provide an STL compliant iterator over hash table buckets.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_hashtablebucketiterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_hashtablebucketiterator-purpose"> Purpose</a>
25/// * <a href="#bslstl_hashtablebucketiterator-classes"> Classes </a>
26/// * <a href="#bslstl_hashtablebucketiterator-description"> Description </a>
27/// * <a href="#bslstl_hashtablebucketiterator-usage"> Usage </a>
28/// * <a href="#bslstl_hashtablebucketiterator-example-1-iterating-a-hash-table-bucket-using-hashtableiterator"> Example 1: Iterating a Hash Table Bucket Using HashTableIterator </a>
29///
30/// # Purpose {#bslstl_hashtablebucketiterator-purpose}
31/// Provide an STL compliant iterator over hash table buckets.
32///
33/// # Classes {#bslstl_hashtablebucketiterator-classes}
34///
35/// - bslstl::HashBucketIterator: iterator to walk a hash-table bucket
36///
37/// @see bslstl_unorderedmultimap, bslstl_unorderedmultiset
38///
39/// # Description {#bslstl_hashtablebucketiterator-description}
40/// This component provides a standard-conforming forward iterator,
41/// `bslstl::HashTableBucketIterator`, over a list of elements (of
42/// `bslalg::BidirectionalLinkList` type) in a single bucket (of
43/// `bslalg::HashTableBucket` type) of a hashtable. The requirements of a
44/// forward iterator are outlined in the C++11 standard in section [24.2.5]
45/// under the tag [forward.iterators]. The `bslstl::HashTableBucketIterator`
46/// class template has two template parameters: `VALUE_TYPE`, and
47/// `DIFFERENCE_TYPE`. `VALUE_TYPE` indicates the type of the value to which
48/// this iterator provides references, and may be const-qualified for constant
49/// iterators. `DIFFERENCE_TYPE` determines the (standard mandated)
50/// @ref difference_type for the iterator, and will typically be supplied by the
51/// allocator used by the hash-table being iterated over.
52///
53/// ## Usage {#bslstl_hashtablebucketiterator-usage}
54///
55///
56/// This section illustrates intended use of this component.
57///
58/// ### Example 1: Iterating a Hash Table Bucket Using HashTableIterator {#bslstl_hashtablebucketiterator-example-1-iterating-a-hash-table-bucket-using-hashtableiterator}
59///
60///
61/// In the following example we create a simple hashtable and then use a
62/// `HashTableBucketIterator` to iterate through the elements in one of its
63/// buckets.
64///
65/// First, we define a typedef, `Node`, prepresenting a bidirectional node
66/// holding an integer value:
67/// @code
68/// typedef bslalg::BidirectionalNode<int> Node;
69/// @endcode
70/// Then, we construct a test allocator, and we use it to allocate an array of
71/// `Node` objects, each holding a unique integer value:
72/// @code
73/// bslma::TestAllocator scratch("scratch", veryVeryVeryVerbose);
74///
75/// const int NUM_NODES = 5;
76/// const int NUM_BUCKETS = 3;
77///
78/// Node *nodes[NUM_NODES];
79/// for (int i = 0; i < NUM_NODES; ++i) {
80/// nodes[i] = static_cast<Node *>(scratch.allocate(sizeof(Node)));
81/// nodes[i]->value() = i;
82/// }
83/// @endcode
84/// Next, we create an array of `HashTableBuckets` objects, and we use the array
85/// to construct an empty hash table characterized by a `HashTableAnchor`
86/// object:
87/// @code
88/// bslalg::HashTableBucket buckets[NUM_BUCKETS];
89/// for (int i = 0; i < NUM_BUCKETS; ++i) {
90/// buckets[i].reset();
91/// }
92/// bslalg::HashTableAnchor hashTable(buckets, NUM_BUCKETS, 0);
93/// @endcode
94/// Then, we insert each node in the array of nodes into the hash table using
95/// `bslalg::HashTableImpUtil`, supplying the integer value held by each node as
96/// its hash value:
97/// @code
98/// for (int i = 0; i < NUM_NODES; ++i) {
99/// bslalg::HashTableImpUtil::insertAtFrontOfBucket(&hashTable,
100/// nodes[i],
101/// nodes[i]->value());
102/// }
103/// @endcode
104/// Next, we define a `typedef` that is an alias an instance of
105/// `HashTableBucketIterator` that can traverse buckets in a hash table holding
106/// integer values.
107/// @code
108/// typedef bslstl::HashTableBucketIterator<int, ptrdiff_t> Iter;
109/// @endcode
110/// Now, we create two iterators: one pointing to the start the second bucket in
111/// the hash table, and the other representing the end sentinel. We use the
112/// iterators to navigate and print the elements in the hash table bucket:
113/// @code
114/// Iter iter(&hashTable.bucketArrayAddress()[1]);
115/// Iter end(0, &hashTable.bucketArrayAddress()[1]);
116/// for (;iter != end; ++iter) {
117/// printf("%d\n", *iter);
118/// }
119/// @endcode
120/// Then, we observe the following output:
121/// @code
122/// 1
123/// 3
124/// @endcode
125/// Finally, we deallocate the memory used by the hash table:
126/// @code
127/// for (int i = 0; i < NUM_NODES; ++i) {
128/// scratch.deallocate(nodes[i]);
129/// }
130/// @endcode
131/// @}
132/** @} */
133/** @} */
134
135/** @addtogroup bsl
136 * @{
137 */
138/** @addtogroup bslstl
139 * @{
140 */
141/** @addtogroup bslstl_hashtablebucketiterator
142 * @{
143 */
144
145#include <bslscm_version.h>
146
147#include <bslstl_iterator.h>
148
152
153#include <bslmf_removecv.h>
154
155#include <bsls_assert.h>
156#include <bsls_libraryfeatures.h>
157#include <bsls_util.h>
158
159#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
160#include <bslmf_removecvq.h>
161#include <bsls_nativestd.h>
162#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
163
164
165namespace bslstl {
166
167 // =============================
168 // class HashTableBucketIterator
169 // =============================
170
171/// This class template implements an in-core value-semantic type that is an
172/// standard-conforming forward iterator (see section 24.2.5
173/// [forward.iterators] of the C++11 standard) over a list of
174/// `bslalg::BidirectionalLink` objects referred to by a single
175/// `bslalg::HashTableBucket` object. A `HashTableBucketIterator` object
176/// provides access to values of the (template parameter) `VALUE_TYPE`,
177/// stored in a bucket of a hash table. The (template parameter)
178/// `DIFFERENCE_TYPE` determines the standard mandated @ref difference_type of
179/// the iterator, without requiring access to the allocator-traits for the
180/// node.
181#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
182/// On Solaris just to keep studio12-v4 happy, since algorithms takes only
183/// iterators inheriting from `std::iterator`.
184///
185/// See @ref bslstl_hashtablebucketiterator
186template <class VALUE_TYPE, class DIFFERENCE_TYPE>
187class HashTableBucketIterator
188: public std::iterator<std::forward_iterator_tag, VALUE_TYPE> {
189#else
190template <class VALUE_TYPE, class DIFFERENCE_TYPE>
192#endif
193
194 // PRIVATE TYPES
195 typedef typename bsl::remove_cv<VALUE_TYPE>::type NonConstType;
198
199 public:
200 // PUBLIC TYPES
201 typedef NonConstType value_type;
202 typedef DIFFERENCE_TYPE difference_type;
203 typedef VALUE_TYPE *pointer;
204 typedef VALUE_TYPE& reference;
205
206 /// Standard iterator defined types [24.4.2].
207 typedef std::forward_iterator_tag iterator_category;
208
209 private:
210 // DATA
212 const bslalg::HashTableBucket *d_bucket_p;
213
214 private:
215 // PRIVATE MANIPULATORS
216
217 /// Advance to the next element.
218 void advance();
219
220 public:
221 // CREATORS
222
223 /// Create a default-constructed iterator referring to an empty list of
224 /// nodes. All default-constructed iterators are non-dereferenceable
225 /// and refer to the same empty list.
227
228 /// Create an iterator referring to the specified `bucket`, initially
229 /// pointing to the first node in that `bucket`, or a past-the-end value
230 /// if the `bucket` is empty. Note that this constructor is an
231 /// implementation detail and is not part of the C++ standard.
233
234 /// Create an iterator referring to the specified `bucket`, initially
235 /// pointing to the specified `node` in that bucket. The behavior is
236 /// undefined unless `node` is part of `bucket`, or `node` is 0. Note
237 /// that this constructor is an implementation detail and is not part of
238 /// the C++ standard.
241
242 /// Create an iterator at the same position as the specified `original`
243 /// iterator. Note that this constructor enables converting from
244 /// modifiable to `const` iterator types.
245 HashTableBucketIterator(const NonConstIter& original); // IMPLICIT
246
247 /// Create an iterator having the same value as the specified
248 /// `original`. Note that this operation is either defined by the
249 /// constructor taking `NonConstIter` (if `NonConstType` is the same as
250 /// `VALUE_TYPE`), or generated automatically by the compiler. Also
251 /// note that this constructor cannot be defined explicitly (without
252 /// using `bsls::enableif`) to avoid a duplicate declaration when
253 /// `NonConstType` is the same as `VALUE_TYPE`.
255 = default;
256
258
259 // MANIPULATORS
260
262 // = default;
263
264 /// Copy the value of the specified `rhs` of another (compatible)
265 /// `HashTableBucketIterator` type, (e.g., a mutable iterator of the
266 /// same type) to this iterator. Return a reference to this modifiable
267 /// object. Note that this method may be the copy-assignment operator
268 /// (inhibiting the implicit declaration of a copy-assignment operator
269 /// above), or may be an additional overload.
271
272 /// Move this iterator to the next element in the hash table bucket and
273 /// return a reference providing modifiable access to this iterator.
274 /// The behavior is undefined unless the iterator refers to a valid (not
275 /// yet erased) element in a bucket. Note that this iterator is
276 /// invalidated when the underlying hash table is rehashed.
278
279 // ACCESSORS
280
281 /// Return a reference providing modifiable access to the element (of
282 /// the template parameter `VALUE_TYPE`) at which this iterator is
283 /// positioned. The behavior is undefined unless the iterator refers to
284 /// a valid (not yet erased) element in a hash table bucket. Note that
285 /// this iterator is invalidated when the underlying hash table is
286 /// rehashed.
287 reference operator*() const;
288
289 /// Return the address of the element (of the template parameter
290 /// `VALUE_TYPE`) at which this iterator is positioned. The behavior is
291 /// undefined unless the iterator refers to a valid (not yet erased)
292 /// element a hash table bucket. Note that this iterator is invalidated
293 /// when the underlying hash table is rehashed.
294 pointer operator->() const;
295
296 /// Return the address of the node holding the element at which this
297 /// iterator is positioned, or 0 if this iterator is positioned after
298 /// the end of a bucket. Note that this method is an implementation
299 /// detail and is not part of the C++ standard.
301
302 /// Return the address of the hash table bucket referred to by this
303 /// iterator. Note that this method is an implementation detail
304 /// intended for debugging purposes only, and is not part of the C++
305 /// standard.
306 const bslalg::HashTableBucket *bucket() const;
307};
308
309// FREE FUNCTIONS AND OPERATORS
310
311/// Return `true` if the specified `lhs` and the specified `rhs` iterators
312/// have the same value and `false` otherwise. Two iterators have the same
313/// value if they refer to the same element in the same hash table, or if
314/// both iterators are positioned after the end of a hash table bucket.
315template <class VALUE_TYPE, class DIFFERENCE_TYPE>
316bool operator==(
319template <class VALUE_TYPE, class DIFFERENCE_TYPE>
320bool operator==(
323template <class VALUE_TYPE, class DIFFERENCE_TYPE>
324bool operator==(
327template <class VALUE_TYPE, class DIFFERENCE_TYPE>
328bool operator==(
331
332/// Return `true` if the specified `lhs` and the specified `rhs` iterators
333/// do not have the same value and `false` otherwise. Two iterators do not
334/// have the same value if they refer to the different elements in the same
335/// hash table, or if either (but not both) of the iterators are positioned
336/// after the end of a hash table bucket.
337template <class VALUE_TYPE, class DIFFERENCE_TYPE>
338bool operator!=(
341template <class VALUE_TYPE, class DIFFERENCE_TYPE>
342bool operator!=(
345template <class VALUE_TYPE, class DIFFERENCE_TYPE>
346bool operator!=(
349template <class VALUE_TYPE, class DIFFERENCE_TYPE>
350bool operator!=(
353
354/// Move the specified `iter` to the next element in the hash table bucket
355/// and return the value of `iter` prior to this call. The behavior is
356/// undefined unless `iter` refers to a valid (not yet erased) element in a
357/// bucket. Note that `iter` is invalidated when the underlying hash table
358/// is rehashed.
359template <class VALUE_TYPE, class DIFFERENCE_TYPE>
362 int);
363
364// ============================================================================
365// INLINE FUNCTION DEFINITIONS
366// ============================================================================
367
368 //------------------------------
369 // class HashTableBucketIterator
370 //------------------------------
371
372//CREATORS
373template <class VALUE_TYPE, class DIFFERENCE_TYPE>
374inline
381
382template <class VALUE_TYPE, class DIFFERENCE_TYPE>
383inline
386: d_node_p(bucket ? bucket->first() : 0)
387, d_bucket_p(bucket)
388{
389}
390
391template <class VALUE_TYPE, class DIFFERENCE_TYPE>
392inline
395 const bslalg::HashTableBucket *bucket)
396: d_node_p(node)
397, d_bucket_p(bucket)
398{
399}
400
401template <class VALUE_TYPE, class DIFFERENCE_TYPE>
402inline
405: d_node_p(original.node())
406, d_bucket_p(original.bucket())
407{
408}
409
410// MANIPULATORS
411template <class VALUE_TYPE, class DIFFERENCE_TYPE>
412inline
415 const NonConstIter& rhs)
416{
417 d_node_p = rhs.node();
418 d_bucket_p = rhs.bucket();
419 return *this;
420}
421
422template <class VALUE_TYPE, class DIFFERENCE_TYPE>
423inline
424void
426advance()
427{
428 BSLS_ASSERT_SAFE(this->d_node_p);
429 BSLS_ASSERT_SAFE(this->d_bucket_p);
430
431 if (this->d_bucket_p->last() == this->d_node_p) {
432 this->d_node_p = 0;
433 }
434 else {
435 this->d_node_p = this->d_node_p->nextLink();
436 }
437}
438
439template <class VALUE_TYPE, class DIFFERENCE_TYPE>
440inline
441HashTableBucketIterator<VALUE_TYPE, DIFFERENCE_TYPE>&
444{
445 BSLS_ASSERT_SAFE(this->d_node_p);
446 BSLS_ASSERT_SAFE(this->d_bucket_p);
447
448 this->advance();
449 return *this;
450}
451
452// ACCESSORS
453template <class VALUE_TYPE, class DIFFERENCE_TYPE>
454inline
455typename
458operator*() const
459{
460 BSLS_ASSERT_SAFE(this->d_node_p);
461
462 return static_cast<bslalg::BidirectionalNode<VALUE_TYPE> *>(
463 d_node_p)->value();
464}
465
466template <class VALUE_TYPE, class DIFFERENCE_TYPE>
467inline
468typename
471operator->() const
472{
473 BSLS_ASSERT_SAFE(this->d_node_p);
474
477 d_node_p)->value());
478}
479
480template <class VALUE_TYPE, class DIFFERENCE_TYPE>
481inline
484{
485 return this->d_node_p;
486}
487
488template <class VALUE_TYPE, class DIFFERENCE_TYPE>
489inline
492{
493 return this->d_bucket_p;
494}
495
496template <class VALUE_TYPE, class DIFFERENCE_TYPE>
497inline
498bool operator==(
501{
502 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
503
504 return lhs.node() == rhs.node();
505}
506
507template <class VALUE_TYPE, class DIFFERENCE_TYPE>
508inline
509bool operator==(
512{
513 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
514
515 return lhs.node() == rhs.node();
516}
517
518template <class VALUE_TYPE, class DIFFERENCE_TYPE>
519inline
520bool operator==(
523{
524 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
525
526 return lhs.node() == rhs.node();
527}
528
529template <class VALUE_TYPE, class DIFFERENCE_TYPE>
530inline
531bool operator==(
534{
535 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
536
537 return lhs.node() == rhs.node();
538}
539
540template <class VALUE_TYPE, class DIFFERENCE_TYPE>
541inline
542bool operator!=(
545{
546 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
547
548 return lhs.node() != rhs.node();
549}
550
551template <class VALUE_TYPE, class DIFFERENCE_TYPE>
552inline
553bool operator!=(
556{
557 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
558
559 return lhs.node() != rhs.node();
560}
561
562template <class VALUE_TYPE, class DIFFERENCE_TYPE>
563inline
564bool operator!=(
567{
568 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
569
570 return lhs.node() != rhs.node();
571}
572
573template <class VALUE_TYPE, class DIFFERENCE_TYPE>
574inline
575bool operator!=(
578{
579 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
580
581 return lhs.node() != rhs.node();
582}
583
584template <class VALUE_TYPE, class DIFFERENCE_TYPE>
585inline
586HashTableBucketIterator<VALUE_TYPE, DIFFERENCE_TYPE>
588{
589 BSLS_ASSERT_SAFE(iter.node());
590 BSLS_ASSERT_SAFE(iter.bucket());
591
593 ++iter;
594 return temp;
595}
596
597} // close package namespace
598
599
600#endif
601
602// ----------------------------------------------------------------------------
603// Copyright 2019 Bloomberg Finance L.P.
604//
605// Licensed under the Apache License, Version 2.0 (the "License");
606// you may not use this file except in compliance with the License.
607// You may obtain a copy of the License at
608//
609// http://www.apache.org/licenses/LICENSE-2.0
610//
611// Unless required by applicable law or agreed to in writing, software
612// distributed under the License is distributed on an "AS IS" BASIS,
613// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
614// See the License for the specific language governing permissions and
615// limitations under the License.
616// ----------------------------- END-OF-FILE ----------------------------------
617
618/** @} */
619/** @} */
620/** @} */
Definition bslalg_bidirectionalnode.h:357
Definition bslstl_hashtablebucketiterator.h:191
bslalg::BidirectionalLink * node() const
Definition bslstl_hashtablebucketiterator.h:483
NonConstType value_type
Definition bslstl_hashtablebucketiterator.h:201
reference operator*() const
Definition bslstl_hashtablebucketiterator.h:458
HashTableBucketIterator()
Definition bslstl_hashtablebucketiterator.h:376
VALUE_TYPE * pointer
Definition bslstl_hashtablebucketiterator.h:203
const bslalg::HashTableBucket * bucket() const
Definition bslstl_hashtablebucketiterator.h:491
pointer operator->() const
Definition bslstl_hashtablebucketiterator.h:471
HashTableBucketIterator(const HashTableBucketIterator &original)=default
std::forward_iterator_tag iterator_category
Standard iterator defined types [24.4.2].
Definition bslstl_hashtablebucketiterator.h:207
DIFFERENCE_TYPE difference_type
Definition bslstl_hashtablebucketiterator.h:202
HashTableBucketIterator & operator=(const HashTableBucketIterator &) HashTableBucketIterator &operator
Definition bslstl_hashtablebucketiterator.h:414
HashTableBucketIterator & operator++()
Definition bslstl_hashtablebucketiterator.h:443
VALUE_TYPE & reference
Definition bslstl_hashtablebucketiterator.h:204
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslstl_algorithm.h:82
BidirectionalIterator< T, ITER_IMP, TAG_TYPE > operator++(BidirectionalIterator< T, ITER_IMP, TAG_TYPE > &iter, int)
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:126
Definition bslalg_hashtablebucket.h:297
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305