BDE 4.39.x 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-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_hashtableiterator-description"> Description </a>
28/// * <a href="#bslstl_hashtableiterator-usage"> Usage </a>
29/// * <a href="#bslstl_hashtableiterator-example-1-iterating-a-hash-table-using-hashtableiterator"> Example 1: Iterating a Hash Table Using HashTableIterator </a>
30///
31/// # Purpose {#bslstl_hashtableiterator-purpose}
32/// Provide an STL compliant iterator for hash tables.
33///
34/// # Classes {#bslstl_hashtableiterator-classes}
35///
36/// - bslstl::HashTableIterator: an STL compliant forward iterator
37///
38/// # Canonical Header {#bslstl_hashtableiterator-canonical-header}
39/// bsl_unordered_map.h, bsl_unordered_set.h
40///
41/// @see bslalg_bidirectionallink, bslstl_unorderedmap, bslstl_unorderedset
42///
43/// # Description {#bslstl_hashtableiterator-description}
44/// This component provides a standard-conforming forward iterator,
45/// `bslstl::HashTableIterator`, over a list of elements (of type
46/// `bslalg::BidirectionalLink`) in a hashtable. The requirements of a forward
47/// iterator are outlined in the C++11 standard in section [24.2.5] under the
48/// tag [forward.iterators]. The `bslstl::HashTableIterator` class template has
49/// two template parameters: `VALUE_TYPE`, and `DIFFERENCE_TYPE`. `VALUE_TYPE`
50/// indicates the type of the value to which this iterator provides references,
51/// and may be const-qualified for constant iterators. `DIFFERENCE_TYPE`
52/// determines the (standard mandated) @ref difference_type for the iterator, and
53/// will typically be supplied by the allocator used by the hash-table being
54/// iterated over.
55///
56/// ## Usage {#bslstl_hashtableiterator-usage}
57///
58///
59/// This section illustrates intended use of this component.
60///
61/// ### Example 1: Iterating a Hash Table Using HashTableIterator {#bslstl_hashtableiterator-example-1-iterating-a-hash-table-using-hashtableiterator}
62///
63///
64/// In the following example we create a simple hashtable and then use a
65/// `HashTableIterator` to iterate through its elements.
66///
67/// First, we define a typedef, `Node`, prepresenting a bidirectional node
68/// holding an integer value:
69/// @code
70/// typedef bslalg::BidirectionalNode<int> Node;
71/// @endcode
72/// Then, we construct a test allocator, and we use it to allocate an array of
73/// `Node` objects, each holding a unique integer value:
74/// @code
75/// bslma::TestAllocator scratch;
76///
77/// const int NUM_NODES = 5;
78/// const int NUM_BUCKETS = 3;
79///
80/// Node *nodes[NUM_NODES];
81/// for (int i = 0; i < NUM_NODES; ++i) {
82/// nodes[i] = static_cast<Node *>(scratch.allocate(sizeof(Node)));
83/// nodes[i]->value() = i;
84/// }
85/// @endcode
86/// Next, we create an array of `HashTableBuckets` objects, and we use the array
87/// to construct an empty hash table characterized by a `HashTableAnchor`
88/// object:
89/// @code
90/// bslalg::HashTableBucket buckets[NUM_BUCKETS];
91/// for (int i = 0; i < NUM_BUCKETS; ++i) {
92/// buckets[i].reset();
93/// }
94/// bslalg::HashTableAnchor hashTable(buckets, NUM_BUCKETS, 0);
95/// @endcode
96/// Then, we insert each node in the array of nodes into the hash table using
97/// `bslalg::HashTableImpUtil`, supplying the integer value held by each node as
98/// its hash value:
99/// @code
100/// for (int i = 0; i < NUM_NODES; ++i) {
101/// bslalg::HashTableImpUtil::insertAtFrontOfBucket(&hashTable,
102/// nodes[i],
103/// nodes[i]->value());
104/// }
105/// @endcode
106/// Next, we define a `typedef` that is an alias an instance of
107/// `HashTableIterator` that can traverse hash tables holding integer values.
108/// @code
109/// typedef bslstl::HashTableIterator<int, ptrdiff_t> Iter;
110/// @endcode
111/// Now, we create two iterators: one pointing to the start of the bidirectional
112/// linked list held by the hash table, and the other representing the end
113/// sentinel. We use them to navigate and print the elements of the hash table:
114/// @code
115/// Iter iter(hashTable.listRootAddress());
116/// Iter end;
117/// for (;iter != end; ++iter) {
118/// printf("%d\n", *iter);
119/// }
120/// @endcode
121/// Then, we observe the following output:
122/// @code
123/// 2
124/// 4
125/// 1
126/// 3
127/// 0
128/// @endcode
129/// Finally, we deallocate the memory used by the hash table:
130/// @code
131/// for (int i = 0; i < NUM_NODES; ++i) {
132/// scratch.deallocate(nodes[i]);
133/// }
134/// @endcode
135/// @}
136/** @} */
137/** @} */
138
139/** @addtogroup bsl
140 * @{
141 */
142/** @addtogroup bslstl
143 * @{
144 */
145/** @addtogroup bslstl_hashtableiterator
146 * @{
147 */
148
149#include <bslscm_version.h>
150
151#include <bslstl_iterator.h>
152
155
156#include <bslmf_removecv.h>
157
158#include <bsls_assert.h>
160#include <bsls_libraryfeatures.h>
161#include <bsls_util.h>
162
163#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
164#include <bslmf_removecvq.h>
165#include <bsls_nativestd.h>
166#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
167
168
169namespace bslstl {
170
171 // =======================
172 // class HashTableIterator
173 // =======================
174
175/// This class template implements an in-core value-semantic type that is an
176/// standard-conforming forward iterator (see section 24.2.5
177/// [forward.iterators] of the C++11 standard) over a list of
178/// `bslalg::BidirectionalLink` objects. A `HashTableIterator` object
179/// provides access to values of the (template parameter) `VALUE_TYPE`,
180/// stored in a hash table composed of `bslalg::BidirectionalLink` nodes.
181/// The (template parameter) `DIFFERENCE_TYPE` determines the standard
182/// mandated @ref difference_type of the iterator, without requiring access to
183/// the allocator-traits for the node.
184#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
185/// On Solaris just to keep studio12-v4 happy, since algorithms take only
186/// iterators inheriting from `std::iterator`.
187///
188/// See @ref bslstl_hashtableiterator
189template <class VALUE_TYPE, class DIFFERENCE_TYPE>
190class HashTableIterator
191: public std::iterator<std::forward_iterator_tag, VALUE_TYPE> {
192#else
193template <class VALUE_TYPE, class DIFFERENCE_TYPE>
195#endif
196
197 // PRIVATE TYPES
198 typedef typename bsl::remove_cv<VALUE_TYPE>::type NcType;
200
201 public:
202 // PUBLIC TYPES
203 typedef NcType value_type;
204 typedef DIFFERENCE_TYPE difference_type;
205 typedef VALUE_TYPE *pointer;
206 typedef VALUE_TYPE& reference;
207
208 /// Standard iterator defined types [24.4.2].
209 typedef bsl::forward_iterator_tag iterator_category;
210
211 private:
212 // DATA
213 bslalg::BidirectionalLink *d_node_p; // pointer to the node referred to by
214 // this iterator
215
216 private:
217 // PRIVATE MANIPULATORS
218
219 /// Move this iterator to refer to the next node in the list.
220 void advance();
221
222 public:
223 // CREATORS
224
225 /// Create a default-constructed iterator referring to an empty list of
226 /// nodes. All default-constructed iterators are non-dereferenceable
227 /// and refer to the same empty list.
229
230 /// Create an iterator referring to the specified `node`.
231 ///
232 /// \pre The behavior is undefined unless `node` is of the type
233 /// `bslalg::BidirectionalNode<VALUE_TYPE>`, which is derived from `bslalg::BidirectionalLink`.
234 ///
235 /// \note Note that this constructor is an
236 /// implementation detail and is not part of the C++ standard.
238
239 /// Create an iterator at the same position as the specified `original` iterator.
240 ///
241 /// \note Note that this constructor enables converting from
242 /// modifiable to `const` iterator types.
243 HashTableIterator(const NcIter& original); // IMPLICIT
244
245 /// Create an iterator having the same value as the specified `original`.
246 ///
247 /// \note Note that this operation is either defined by the
248 /// constructor taking `NcIter` (if `NcType` is the same as
249 /// `VALUE_TYPE`), or generated automatically by the compiler. Also
250 /// note that this constructor cannot be defined explicitly (without
251 /// using `bsls::enableif`) to avoid a duplicate declaration when
252 /// `NcType` is the same as `VALUE_TYPE`.
253 HashTableIterator(const HashTableIterator& original) = default;
254
255#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS)
256 /// Destroy this object.
257 ~HashTableIterator() = default;
258
259 // MANIPULATORS
260
261 /// Assign to this object the value of the specified `rhs` object, and
262 /// a return a reference providing modifiable access to this object.
263 HashTableIterator& operator=(const HashTableIterator& rhs) = default;
264#endif
265
266 /// Move this iterator to the next node in the list and return a
267 /// reference providing modifiable access to this iterator.
268 ///
269 /// \pre The behavior is undefined unless the iterator refers to a valid (not yet
270 /// erased) node in the list.
272
273 // ACCESSORS
274
275 /// Return a reference providing modifiable access to the value (of the
276 /// template parameter `VALUE_TYPE`) of the node at which this iterator is positioned.
277 ///
278 /// \pre The behavior is undefined unless the iterator refers
279 /// to a valid (not yet erased) node the list.
280 reference operator*() const;
281
282 /// Return the address of the value (of the template parameter
283 /// `VALUE_TYPE`) of the element at which this iterator is positioned.
284 ///
285 /// \pre The behavior is undefined unless the iterator refers to a valid (not
286 /// yet erased) node the list.
287 pointer operator->() const;
288
289 /// Return the address of the node at which this iterator is positioned
290 /// in the list, or 0 if this iterator is positioned after the end of a list.
291 ///
292 /// \note Note that this method is an implementation detail and is not
293 /// part of the C++ standard.
295};
296
297// FREE OPERATORS
298
299/// Return `true` if the specified `lhs` and the specified `rhs` iterators
300/// have the same value and `false` otherwise. Two iterators have the same
301/// value if they refer to the same node in the same list, or if both
302/// iterators are at the past-the-end position of the tree.
303template <class VALUE_TYPE, class DIFFERENCE_TYPE>
304bool operator==(const HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>& lhs,
306template <class VALUE_TYPE, class DIFFERENCE_TYPE>
307bool operator==(
310template <class VALUE_TYPE, class DIFFERENCE_TYPE>
311bool operator==(
314template <class VALUE_TYPE, class DIFFERENCE_TYPE>
315bool operator==(
318
319/// Return `true` if the specified `lhs` and the specified `rhs` iterators
320/// do not have the same value and `false` otherwise. Two iterators do not
321/// have the same value if they refer to the different nodes in the same
322/// list, or if either (but not both) of the iterators are at the
323/// past-the-end position of the tree.
324template <class VALUE_TYPE, class DIFFERENCE_TYPE>
325bool operator!=(const HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>& lhs,
327template <class VALUE_TYPE, class DIFFERENCE_TYPE>
328bool operator!=(
331template <class VALUE_TYPE, class DIFFERENCE_TYPE>
332bool operator!=(
335template <class VALUE_TYPE, class DIFFERENCE_TYPE>
336bool operator!=(
339
340
341/// Move the specified `iter` to the next node in the list and return
342/// value of `iter` prior to this call.
343///
344/// \pre The behavior is undefined unless `iter` refers to a valid (not yet erased) node a the list.
345template <class VALUE_TYPE, class DIFFERENCE_TYPE>
348
349
350// ============================================================================
351// TEMPLATE AND INLINE FUNCTION DEFINITIONS
352// ============================================================================
353
354 // -----------------------
355 // class HashTableIterator
356 // -----------------------
357
358// CREATORS
359template <class VALUE_TYPE, class DIFFERENCE_TYPE>
360inline
366
367template <class VALUE_TYPE, class DIFFERENCE_TYPE>
368inline
374
375template <class VALUE_TYPE, class DIFFERENCE_TYPE>
376inline
378HashTableIterator(const NcIter& original)
379: d_node_p(original.node())
380{
381}
382
383template <class VALUE_TYPE, class DIFFERENCE_TYPE>
384inline
386{
387 BSLS_ASSERT_SAFE(d_node_p);
388
389 this->d_node_p = this->d_node_p->nextLink();
390}
391
392template <class VALUE_TYPE, class DIFFERENCE_TYPE>
393inline
394HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>&
396{
397 BSLS_ASSERT_SAFE(this->d_node_p);
398
399 this->advance();
400 return *this;
401}
402
403// ACCESSORS
404template <class VALUE_TYPE, class DIFFERENCE_TYPE>
405inline
408{
409 BSLS_ASSERT_SAFE(this->d_node_p);
410
411 return static_cast<bslalg::BidirectionalNode<VALUE_TYPE> *>(
412 d_node_p)->value();
413}
414
415template <class VALUE_TYPE, class DIFFERENCE_TYPE>
416inline
419{
420 BSLS_ASSERT_SAFE(this->d_node_p);
421
424 d_node_p)->value());
425}
426
427template <class VALUE_TYPE, class DIFFERENCE_TYPE>
428inline
431{
432 return d_node_p;
433}
434
435// FREE OPERATORS
436template <class VALUE_TYPE, class DIFFERENCE_TYPE>
437inline
440{
441 return lhs.node() == rhs.node();
442}
443
444template <class VALUE_TYPE, class DIFFERENCE_TYPE>
445inline
446bool operator==(
449{
450 return lhs.node() == rhs.node();
451}
452
453template <class VALUE_TYPE, class DIFFERENCE_TYPE>
454inline
455bool operator==(
458{
459 return lhs.node() == rhs.node();
460}
461
462template <class VALUE_TYPE, class DIFFERENCE_TYPE>
463inline
464bool operator==(
467{
468 return lhs.node() == rhs.node();
469}
470
471template <class VALUE_TYPE, class DIFFERENCE_TYPE>
472inline
475{
476 return lhs.node() != rhs.node();
477}
478
479template <class VALUE_TYPE, class DIFFERENCE_TYPE>
480inline
481bool operator!=(
484{
485 return lhs.node() != rhs.node();
486}
487
488template <class VALUE_TYPE, class DIFFERENCE_TYPE>
489inline
490bool operator!=(
493{
494 return lhs.node() != rhs.node();
495}
496
497template <class VALUE_TYPE, class DIFFERENCE_TYPE>
498inline
499bool operator!=(
502{
503 return lhs.node() != rhs.node();
504}
505
506template <class VALUE_TYPE, class DIFFERENCE_TYPE>
507inline
508HashTableIterator<VALUE_TYPE, DIFFERENCE_TYPE>
510{
511 BSLS_ASSERT_SAFE(iter.node());
512
514 ++iter;
515 return temp;
516}
517
518} // close package namespace
519
520
521#endif
522
523// ----------------------------------------------------------------------------
524// Copyright 2019 Bloomberg Finance L.P.
525//
526// Licensed under the Apache License, Version 2.0 (the "License");
527// you may not use this file except in compliance with the License.
528// You may obtain a copy of the License at
529//
530// http://www.apache.org/licenses/LICENSE-2.0
531//
532// Unless required by applicable law or agreed to in writing, software
533// distributed under the License is distributed on an "AS IS" BASIS,
534// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
535// See the License for the specific language governing permissions and
536// limitations under the License.
537// ----------------------------- END-OF-FILE ----------------------------------
538
539/** @} */
540/** @} */
541/** @} */
Definition bslalg_bidirectionalnode.h:357
Definition bslstl_hashtableiterator.h:194
bsl::forward_iterator_tag iterator_category
Standard iterator defined types [24.4.2].
Definition bslstl_hashtableiterator.h:209
reference operator*() const
Definition bslstl_hashtableiterator.h:407
VALUE_TYPE * pointer
Definition bslstl_hashtableiterator.h:205
NcType value_type
Definition bslstl_hashtableiterator.h:203
VALUE_TYPE & reference
Definition bslstl_hashtableiterator.h:206
HashTableIterator()
Definition bslstl_hashtableiterator.h:362
HashTableIterator & operator++()
Definition bslstl_hashtableiterator.h:395
bslalg::BidirectionalLink * node() const
Definition bslstl_hashtableiterator.h:430
DIFFERENCE_TYPE difference_type
Definition bslstl_hashtableiterator.h:204
HashTableIterator(const HashTableIterator &original)=default
pointer operator->() const
Definition bslstl_hashtableiterator.h:418
#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
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:312