BDE 4.39.x 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 if the `bucket` is empty.
230 ///
231 /// \note Note that this constructor is an
232 /// implementation detail and is not part of the C++ standard.
234
235 /// Create an iterator referring to the specified `bucket`, initially
236 /// pointing to the specified `node` in that bucket.
237 ///
238 /// \pre The behavior is undefined unless `node` is part of `bucket`, or `node` is 0.
239 ///
240 /// \note Note that this constructor is an implementation detail and is not part of
241 /// the C++ standard.
244
245 /// Create an iterator at the same position as the specified `original` iterator.
246 ///
247 /// \note Note that this constructor enables converting from
248 /// modifiable to `const` iterator types.
249 HashTableBucketIterator(const NonConstIter& original); // IMPLICIT
250
251 /// Create an iterator having the same value as the specified `original`.
252 ///
253 /// \note Note that this operation is either defined by the
254 /// constructor taking `NonConstIter` (if `NonConstType` is the same as
255 /// `VALUE_TYPE`), or generated automatically by the compiler. Also
256 /// note that this constructor cannot be defined explicitly (without
257 /// using `bsls::enableif`) to avoid a duplicate declaration when
258 /// `NonConstType` is the same as `VALUE_TYPE`.
260 = default;
261
263
264 // MANIPULATORS
265
267 // = default;
268
269 /// Copy the value of the specified `rhs` of another (compatible)
270 /// `HashTableBucketIterator` type, (e.g., a mutable iterator of the
271 /// same type) to this iterator. Return a reference to this modifiable object.
272 ///
273 /// \note Note that this method may be the copy-assignment operator
274 /// (inhibiting the implicit declaration of a copy-assignment operator
275 /// above), or may be an additional overload.
277
278 /// Move this iterator to the next element in the hash table bucket and
279 /// return a reference providing modifiable access to this iterator.
280 ///
281 /// \pre The behavior is undefined unless the iterator refers to a valid (not yet erased) element in a bucket.
282 ///
283 /// \note Note that this iterator is
284 /// invalidated when the underlying hash table is rehashed.
286
287 // ACCESSORS
288
289 /// Return a reference providing modifiable access to the element (of
290 /// the template parameter `VALUE_TYPE`) at which this iterator is positioned.
291 ///
292 /// \pre The behavior is undefined unless the iterator refers to
293 /// a valid (not yet erased) element in a hash table bucket.
294 ///
295 /// \note Note that this iterator is invalidated when the underlying hash table is
296 /// rehashed.
297 reference operator*() const;
298
299 /// Return the address of the element (of the template parameter
300 /// `VALUE_TYPE`) at which this iterator is positioned.
301 ///
302 /// \pre The behavior is undefined unless the iterator refers to a valid (not yet erased) element a hash table bucket.
303 ///
304 /// \note Note that this iterator is invalidated
305 /// when the underlying hash table is rehashed.
306 pointer operator->() const;
307
308 /// Return the address of the node holding the element at which this
309 /// iterator is positioned, or 0 if this iterator is positioned after the end of a bucket.
310 ///
311 /// \note Note that this method is an implementation
312 /// detail and is not part of the C++ standard.
314
315 /// Return the address of the hash table bucket referred to by this iterator.
316 ///
317 /// \note Note that this method is an implementation detail
318 /// intended for debugging purposes only, and is not part of the C++
319 /// standard.
320 const bslalg::HashTableBucket *bucket() const;
321};
322
323// FREE FUNCTIONS AND OPERATORS
324
325/// Return `true` if the specified `lhs` and the specified `rhs` iterators
326/// have the same value and `false` otherwise. Two iterators have the same
327/// value if they refer to the same element in the same hash table, or if
328/// both iterators are positioned after the end of a hash table bucket.
329template <class VALUE_TYPE, class DIFFERENCE_TYPE>
330bool operator==(
333template <class VALUE_TYPE, class DIFFERENCE_TYPE>
334bool operator==(
337template <class VALUE_TYPE, class DIFFERENCE_TYPE>
338bool operator==(
341template <class VALUE_TYPE, class DIFFERENCE_TYPE>
342bool operator==(
345
346/// Return `true` if the specified `lhs` and the specified `rhs` iterators
347/// do not have the same value and `false` otherwise. Two iterators do not
348/// have the same value if they refer to the different elements in the same
349/// hash table, or if either (but not both) of the iterators are positioned
350/// after the end of a hash table bucket.
351template <class VALUE_TYPE, class DIFFERENCE_TYPE>
352bool operator!=(
355template <class VALUE_TYPE, class DIFFERENCE_TYPE>
356bool operator!=(
359template <class VALUE_TYPE, class DIFFERENCE_TYPE>
360bool operator!=(
363template <class VALUE_TYPE, class DIFFERENCE_TYPE>
364bool operator!=(
367
368/// Move the specified `iter` to the next element in the hash table bucket
369/// and return the value of `iter` prior to this call.
370///
371/// \pre The behavior is undefined unless `iter` refers to a valid (not yet erased) element in a bucket.
372///
373/// \note Note that `iter` is invalidated when the underlying hash table
374/// is rehashed.
375template <class VALUE_TYPE, class DIFFERENCE_TYPE>
378 int);
379
380// ============================================================================
381// INLINE FUNCTION DEFINITIONS
382// ============================================================================
383
384 //------------------------------
385 // class HashTableBucketIterator
386 //------------------------------
387
388//CREATORS
389template <class VALUE_TYPE, class DIFFERENCE_TYPE>
390inline
397
398template <class VALUE_TYPE, class DIFFERENCE_TYPE>
399inline
402: d_node_p(bucket ? bucket->first() : 0)
403, d_bucket_p(bucket)
404{
405}
406
407template <class VALUE_TYPE, class DIFFERENCE_TYPE>
408inline
411 const bslalg::HashTableBucket *bucket)
412: d_node_p(node)
413, d_bucket_p(bucket)
414{
415}
416
417template <class VALUE_TYPE, class DIFFERENCE_TYPE>
418inline
421: d_node_p(original.node())
422, d_bucket_p(original.bucket())
423{
424}
425
426// MANIPULATORS
427template <class VALUE_TYPE, class DIFFERENCE_TYPE>
428inline
431 const NonConstIter& rhs)
432{
433 d_node_p = rhs.node();
434 d_bucket_p = rhs.bucket();
435 return *this;
436}
437
438template <class VALUE_TYPE, class DIFFERENCE_TYPE>
439inline
440void
442advance()
443{
444 BSLS_ASSERT_SAFE(this->d_node_p);
445 BSLS_ASSERT_SAFE(this->d_bucket_p);
446
447 if (this->d_bucket_p->last() == this->d_node_p) {
448 this->d_node_p = 0;
449 }
450 else {
451 this->d_node_p = this->d_node_p->nextLink();
452 }
453}
454
455template <class VALUE_TYPE, class DIFFERENCE_TYPE>
456inline
457HashTableBucketIterator<VALUE_TYPE, DIFFERENCE_TYPE>&
460{
461 BSLS_ASSERT_SAFE(this->d_node_p);
462 BSLS_ASSERT_SAFE(this->d_bucket_p);
463
464 this->advance();
465 return *this;
466}
467
468// ACCESSORS
469template <class VALUE_TYPE, class DIFFERENCE_TYPE>
470inline
471typename
474operator*() const
475{
476 BSLS_ASSERT_SAFE(this->d_node_p);
477
478 return static_cast<bslalg::BidirectionalNode<VALUE_TYPE> *>(
479 d_node_p)->value();
480}
481
482template <class VALUE_TYPE, class DIFFERENCE_TYPE>
483inline
484typename
487operator->() const
488{
489 BSLS_ASSERT_SAFE(this->d_node_p);
490
493 d_node_p)->value());
494}
495
496template <class VALUE_TYPE, class DIFFERENCE_TYPE>
497inline
500{
501 return this->d_node_p;
502}
503
504template <class VALUE_TYPE, class DIFFERENCE_TYPE>
505inline
508{
509 return this->d_bucket_p;
510}
511
512template <class VALUE_TYPE, class DIFFERENCE_TYPE>
513inline
514bool operator==(
517{
518 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
519
520 return lhs.node() == rhs.node();
521}
522
523template <class VALUE_TYPE, class DIFFERENCE_TYPE>
524inline
525bool operator==(
528{
529 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
530
531 return lhs.node() == rhs.node();
532}
533
534template <class VALUE_TYPE, class DIFFERENCE_TYPE>
535inline
536bool operator==(
539{
540 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
541
542 return lhs.node() == rhs.node();
543}
544
545template <class VALUE_TYPE, class DIFFERENCE_TYPE>
546inline
547bool operator==(
550{
551 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
552
553 return lhs.node() == rhs.node();
554}
555
556template <class VALUE_TYPE, class DIFFERENCE_TYPE>
557inline
558bool operator!=(
561{
562 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
563
564 return lhs.node() != rhs.node();
565}
566
567template <class VALUE_TYPE, class DIFFERENCE_TYPE>
568inline
569bool operator!=(
572{
573 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
574
575 return lhs.node() != rhs.node();
576}
577
578template <class VALUE_TYPE, class DIFFERENCE_TYPE>
579inline
580bool operator!=(
583{
584 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
585
586 return lhs.node() != rhs.node();
587}
588
589template <class VALUE_TYPE, class DIFFERENCE_TYPE>
590inline
591bool operator!=(
594{
595 BSLS_ASSERT_SAFE(lhs.bucket() == rhs.bucket() );
596
597 return lhs.node() != rhs.node();
598}
599
600template <class VALUE_TYPE, class DIFFERENCE_TYPE>
601inline
602HashTableBucketIterator<VALUE_TYPE, DIFFERENCE_TYPE>
604{
605 BSLS_ASSERT_SAFE(iter.node());
606 BSLS_ASSERT_SAFE(iter.bucket());
607
609 ++iter;
610 return temp;
611}
612
613} // close package namespace
614
615
616#endif
617
618// ----------------------------------------------------------------------------
619// Copyright 2019 Bloomberg Finance L.P.
620//
621// Licensed under the Apache License, Version 2.0 (the "License");
622// you may not use this file except in compliance with the License.
623// You may obtain a copy of the License at
624//
625// http://www.apache.org/licenses/LICENSE-2.0
626//
627// Unless required by applicable law or agreed to in writing, software
628// distributed under the License is distributed on an "AS IS" BASIS,
629// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
630// See the License for the specific language governing permissions and
631// limitations under the License.
632// ----------------------------- END-OF-FILE ----------------------------------
633
634/** @} */
635/** @} */
636/** @} */
Definition bslalg_bidirectionalnode.h:357
Definition bslstl_hashtablebucketiterator.h:191
bslalg::BidirectionalLink * node() const
Definition bslstl_hashtablebucketiterator.h:499
NonConstType value_type
Definition bslstl_hashtablebucketiterator.h:201
reference operator*() const
Definition bslstl_hashtablebucketiterator.h:474
HashTableBucketIterator()
Definition bslstl_hashtablebucketiterator.h:392
VALUE_TYPE * pointer
Definition bslstl_hashtablebucketiterator.h:203
const bslalg::HashTableBucket * bucket() const
Definition bslstl_hashtablebucketiterator.h:507
pointer operator->() const
Definition bslstl_hashtablebucketiterator.h:487
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:430
HashTableBucketIterator & operator++()
Definition bslstl_hashtablebucketiterator.h:459
VALUE_TYPE & reference
Definition bslstl_hashtablebucketiterator.h:204
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslstl_algorithm.h:84
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:128
Definition bslalg_hashtablebucket.h:297
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:312