BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_hashtableiterator.h
Go to the documentation of this file.
1/// @file bslstl_hashtableiterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_hashtableiterator.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_HASHTABLEITERATOR
9#define INCLUDED_BSLSTL_HASHTABLEITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_hashtableiterator bslstl_hashtableiterator
15/// @brief Provide an STL compliant iterator for hash tables.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_hashtableiterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_hashtableiterator-purpose"> Purpose</a>
25/// * <a href="#bslstl_hashtableiterator-classes"> Classes </a>
26/// * <a href="#bslstl_hashtableiterator-description"> Description </a>
27/// * <a href="#bslstl_hashtableiterator-usage"> Usage </a>
28/// * <a href="#bslstl_hashtableiterator-example-1-iterating-a-hash-table-using-hashtableiterator"> Example 1: Iterating a Hash Table Using HashTableIterator </a>
29///
30/// # Purpose {#bslstl_hashtableiterator-purpose}
31/// Provide an STL compliant iterator for hash tables.
32///
33/// # Classes {#bslstl_hashtableiterator-classes}
34///
35/// - bslstl::HashTableIterator: an STL compliant forward iterator
36///
37/// **Canonical header:** bsl_unordered_map.h, bsl_unordered_set.h
38///
39/// @see bslalg_bidirectionallink, bslstl_unorderedmap, bslstl_unorderedset
40///
41/// # Description {#bslstl_hashtableiterator-description}
42/// This component provides a standard-conforming forward iterator,
43/// `bslstl::HashTableIterator`, over a list of elements (of type
44/// `bslalg::BidirectionalLink`) in a hashtable. The requirements of a forward
45/// iterator are outlined in the C++11 standard in section [24.2.5] under the
46/// tag [forward.iterators]. The `bslstl::HashTableIterator` class template has
47/// two template parameters: `VALUE_TYPE`, and `DIFFERENCE_TYPE`. `VALUE_TYPE`
48/// indicates the type of the value to which this iterator provides references,
49/// and may be const-qualified for constant iterators. `DIFFERENCE_TYPE`
50/// determines the (standard mandated) @ref difference_type for the iterator, and
51/// will typically be supplied by the allocator used by the hash-table being
52/// iterated over.
53///
54/// ## Usage {#bslstl_hashtableiterator-usage}
55///
56///
57/// This section illustrates intended use of this component.
58///
59/// ### Example 1: Iterating a Hash Table Using HashTableIterator {#bslstl_hashtableiterator-example-1-iterating-a-hash-table-using-hashtableiterator}
60///
61///
62/// In the following example we create a simple hashtable and then use a
63/// `HashTableIterator` to iterate through its elements.
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;
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/// `HashTableIterator` that can traverse hash tables holding integer values.
106/// @code
107/// typedef bslstl::HashTableIterator<int, ptrdiff_t> Iter;
108/// @endcode
109/// Now, we create two iterators: one pointing to the start of the bidirectional
110/// linked list held by the hash table, and the other representing the end
111/// sentinel. We use them to navigate and print the elements of the hash table:
112/// @code
113/// Iter iter(hashTable.listRootAddress());
114/// Iter end;
115/// for (;iter != end; ++iter) {
116/// printf("%d\n", *iter);
117/// }
118/// @endcode
119/// Then, we observe the following output:
120/// @code
121/// 2
122/// 4
123/// 1
124/// 3
125/// 0
126/// @endcode
127/// Finally, we deallocate the memory used by the hash table:
128/// @code
129/// for (int i = 0; i < NUM_NODES; ++i) {
130/// scratch.deallocate(nodes[i]);
131/// }
132/// @endcode
133/// @}
134/** @} */
135/** @} */
136
137/** @addtogroup bsl
138 * @{
139 */
140/** @addtogroup bslstl
141 * @{
142 */
143/** @addtogroup bslstl_hashtableiterator
144 * @{
145 */
146
147#include <bslscm_version.h>
148
149#include <bslstl_iterator.h>
150
153
154#include <bslmf_removecv.h>
155
156#include <bsls_assert.h>
158#include <bsls_libraryfeatures.h>
159#include <bsls_util.h>
160
161#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
162#include <bslmf_removecvq.h>
163#include <bsls_nativestd.h>
164#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
165
166
167namespace bslstl {
168
169 // =======================
170 // class HashTableIterator
171 // =======================
172
173/// This class template implements an in-core value-semantic type that is an
174/// standard-conforming forward iterator (see section 24.2.5
175/// [forward.iterators] of the C++11 standard) over a list of
176/// `bslalg::BidirectionalLink` objects. A `HashTableIterator` object
177/// provides access to values of the (template parameter) `VALUE_TYPE`,
178/// stored in a hash table composed of `bslalg::BidirectionalLink` nodes.
179/// The (template parameter) `DIFFERENCE_TYPE` determines the standard
180/// mandated @ref difference_type of the iterator, without requiring access to
181/// the allocator-traits for the node.
182#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
183/// On Solaris just to keep studio12-v4 happy, since algorithms take only
184/// iterators inheriting from `std::iterator`.
185///
186/// See @ref bslstl_hashtableiterator
187template <class VALUE_TYPE, class DIFFERENCE_TYPE>
188class HashTableIterator
189: public std::iterator<std::forward_iterator_tag, VALUE_TYPE> {
190#else
191template <class VALUE_TYPE, class DIFFERENCE_TYPE>
193#endif
194
195 // PRIVATE TYPES
196 typedef typename bsl::remove_cv<VALUE_TYPE>::type NcType;
198
199 public:
200 // PUBLIC TYPES
201 typedef NcType 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 bsl::forward_iterator_tag iterator_category;
208
209 private:
210 // DATA
211 bslalg::BidirectionalLink *d_node_p; // pointer to the node referred to by
212 // this iterator
213
214 private:
215 // PRIVATE MANIPULATORS
216
217 /// Move this iterator to refer to the next node in the list.
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 `node`. The behavior
229 /// is undefined unless `node` is of the type
230 /// `bslalg::BidirectionalNode<VALUE_TYPE>`, which is derived from
231 /// `bslalg::BidirectionalLink`. Note that this constructor is an
232 /// implementation detail and is not part of the C++ standard.
234
235 /// Create an iterator at the same position as the specified `original`
236 /// iterator. Note that this constructor enables converting from
237 /// modifiable to `const` iterator types.
238 HashTableIterator(const NcIter& original); // IMPLICIT
239
240 /// Create an iterator having the same value as the specified
241 /// `original`. Note that this operation is either defined by the
242 /// constructor taking `NcIter` (if `NcType` is the same as
243 /// `VALUE_TYPE`), or generated automatically by the compiler. Also
244 /// note that this constructor cannot be defined explicitly (without
245 /// using `bsls::enableif`) to avoid a duplicate declaration when
246 /// `NcType` is the same as `VALUE_TYPE`.
247 HashTableIterator(const HashTableIterator& original) = default;
248
249#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS)
250 /// Destroy this object.
251 ~HashTableIterator() = default;
252
253 // MANIPULATORS
254
255 /// Assign to this object the value of the specified `rhs` object, and
256 /// a return a reference providing modifiable access to this object.
257 HashTableIterator& operator=(const HashTableIterator& rhs) = default;
258#endif
259
260 /// Move this iterator to the next node in the list and return a
261 /// reference providing modifiable access to this iterator. The
262 /// behavior is undefined unless the iterator refers to a valid (not yet
263 /// erased) node in the list.
265
266 // ACCESSORS
267
268 /// Return a reference providing modifiable access to the value (of the
269 /// template parameter `VALUE_TYPE`) of the node at which this iterator
270 /// is positioned. The behavior is undefined unless the iterator refers
271 /// to a valid (not yet erased) node the list.
272 reference operator*() const;
273
274 /// Return the address of the value (of the template parameter
275 /// `VALUE_TYPE`) of the element at which this iterator is positioned.
276 /// The behavior is undefined unless the iterator refers to a valid (not
277 /// yet erased) node the list.
278 pointer operator->() const;
279
280 /// Return the address of the node at which this iterator is positioned
281 /// in the list, or 0 if this iterator is positioned after the end of a
282 /// list. Note that this method is an implementation detail and is not
283 /// part of the C++ standard.
285};
286
287// FREE OPERATORS
288
289/// Return `true` if the specified `lhs` and the specified `rhs` iterators
290/// have the same value and `false` otherwise. Two iterators have the same
291/// value if they refer to the same node in the same list, or if both
292/// iterators are at the past-the-end position of the tree.
293template <class VALUE_TYPE, class DIFFERENCE_TYPE>
294bool operator==(const HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>& lhs,
296template <class VALUE_TYPE, class DIFFERENCE_TYPE>
297bool operator==(
300template <class VALUE_TYPE, class DIFFERENCE_TYPE>
301bool operator==(
304template <class VALUE_TYPE, class DIFFERENCE_TYPE>
305bool operator==(
308
309/// Return `true` if the specified `lhs` and the specified `rhs` iterators
310/// do not have the same value and `false` otherwise. Two iterators do not
311/// have the same value if they refer to the different nodes in the same
312/// list, or if either (but not both) of the iterators are at the
313/// past-the-end position of the tree.
314template <class VALUE_TYPE, class DIFFERENCE_TYPE>
315bool operator!=(const HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>& lhs,
317template <class VALUE_TYPE, class DIFFERENCE_TYPE>
318bool operator!=(
321template <class VALUE_TYPE, class DIFFERENCE_TYPE>
322bool operator!=(
325template <class VALUE_TYPE, class DIFFERENCE_TYPE>
326bool operator!=(
329
330
331/// Move the specified `iter` to the next node in the list and return
332/// value of `iter` prior to this call. The behavior is undefined
333/// unless `iter` refers to a valid (not yet erased) node a the list.
334template <class VALUE_TYPE, class DIFFERENCE_TYPE>
337
338
339// ============================================================================
340// TEMPLATE AND INLINE FUNCTION DEFINITIONS
341// ============================================================================
342
343 // -----------------------
344 // class HashTableIterator
345 // -----------------------
346
347// CREATORS
348template <class VALUE_TYPE, class DIFFERENCE_TYPE>
349inline
355
356template <class VALUE_TYPE, class DIFFERENCE_TYPE>
357inline
363
364template <class VALUE_TYPE, class DIFFERENCE_TYPE>
365inline
367HashTableIterator(const NcIter& original)
368: d_node_p(original.node())
369{
370}
371
372template <class VALUE_TYPE, class DIFFERENCE_TYPE>
373inline
375{
376 BSLS_ASSERT_SAFE(d_node_p);
377
378 this->d_node_p = this->d_node_p->nextLink();
379}
380
381template <class VALUE_TYPE, class DIFFERENCE_TYPE>
382inline
383HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>&
385{
386 BSLS_ASSERT_SAFE(this->d_node_p);
387
388 this->advance();
389 return *this;
390}
391
392// ACCESSORS
393template <class VALUE_TYPE, class DIFFERENCE_TYPE>
394inline
397{
398 BSLS_ASSERT_SAFE(this->d_node_p);
399
400 return static_cast<bslalg::BidirectionalNode<VALUE_TYPE> *>(
401 d_node_p)->value();
402}
403
404template <class VALUE_TYPE, class DIFFERENCE_TYPE>
405inline
408{
409 BSLS_ASSERT_SAFE(this->d_node_p);
410
413 d_node_p)->value());
414}
415
416template <class VALUE_TYPE, class DIFFERENCE_TYPE>
417inline
420{
421 return d_node_p;
422}
423
424// FREE OPERATORS
425template <class VALUE_TYPE, class DIFFERENCE_TYPE>
426inline
429{
430 return lhs.node() == rhs.node();
431}
432
433template <class VALUE_TYPE, class DIFFERENCE_TYPE>
434inline
435bool operator==(
438{
439 return lhs.node() == rhs.node();
440}
441
442template <class VALUE_TYPE, class DIFFERENCE_TYPE>
443inline
444bool operator==(
447{
448 return lhs.node() == rhs.node();
449}
450
451template <class VALUE_TYPE, class DIFFERENCE_TYPE>
452inline
453bool operator==(
456{
457 return lhs.node() == rhs.node();
458}
459
460template <class VALUE_TYPE, class DIFFERENCE_TYPE>
461inline
464{
465 return lhs.node() != rhs.node();
466}
467
468template <class VALUE_TYPE, class DIFFERENCE_TYPE>
469inline
470bool operator!=(
473{
474 return lhs.node() != rhs.node();
475}
476
477template <class VALUE_TYPE, class DIFFERENCE_TYPE>
478inline
479bool operator!=(
482{
483 return lhs.node() != rhs.node();
484}
485
486template <class VALUE_TYPE, class DIFFERENCE_TYPE>
487inline
488bool operator!=(
491{
492 return lhs.node() != rhs.node();
493}
494
495template <class VALUE_TYPE, class DIFFERENCE_TYPE>
496inline
497HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>
499{
500 BSLS_ASSERT_SAFE(iter.node());
501
503 ++iter;
504 return temp;
505}
506
507} // close package namespace
508
509
510#endif
511
512// ----------------------------------------------------------------------------
513// Copyright 2019 Bloomberg Finance L.P.
514//
515// Licensed under the Apache License, Version 2.0 (the "License");
516// you may not use this file except in compliance with the License.
517// You may obtain a copy of the License at
518//
519// http://www.apache.org/licenses/LICENSE-2.0
520//
521// Unless required by applicable law or agreed to in writing, software
522// distributed under the License is distributed on an "AS IS" BASIS,
523// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
524// See the License for the specific language governing permissions and
525// limitations under the License.
526// ----------------------------- END-OF-FILE ----------------------------------
527
528/** @} */
529/** @} */
530/** @} */
Definition bslalg_bidirectionalnode.h:357
Definition bslstl_hashtableiterator.h:192
bsl::forward_iterator_tag iterator_category
Standard iterator defined types [24.4.2].
Definition bslstl_hashtableiterator.h:207
reference operator*() const
Definition bslstl_hashtableiterator.h:396
VALUE_TYPE * pointer
Definition bslstl_hashtableiterator.h:203
NcType value_type
Definition bslstl_hashtableiterator.h:201
VALUE_TYPE & reference
Definition bslstl_hashtableiterator.h:204
HashTableIterator()
Definition bslstl_hashtableiterator.h:351
HashTableIterator & operator++()
Definition bslstl_hashtableiterator.h:384
bslalg::BidirectionalLink * node() const
Definition bslstl_hashtableiterator.h:419
DIFFERENCE_TYPE difference_type
Definition bslstl_hashtableiterator.h:202
HashTableIterator(const HashTableIterator &original)=default
pointer operator->() const
Definition bslstl_hashtableiterator.h:407
#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
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305