BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslalg_hashtablebucket.h
Go to the documentation of this file.
1/// @file bslalg_hashtablebucket.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslalg_hashtablebucket.h -*-C++-*-
8#ifndef INCLUDED_BSLALG_HASHTABLEBUCKET
9#define INCLUDED_BSLALG_HASHTABLEBUCKET
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslalg_hashtablebucket bslalg_hashtablebucket
15/// @brief Provide a bucket representation for hash table data structures.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslalg
19/// @{
20/// @addtogroup bslalg_hashtablebucket
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslalg_hashtablebucket-purpose"> Purpose</a>
25/// * <a href="#bslalg_hashtablebucket-classes"> Classes </a>
26/// * <a href="#bslalg_hashtablebucket-description"> Description </a>
27/// * <a href="#bslalg_hashtablebucket-usage"> Usage </a>
28/// * <a href="#bslalg_hashtablebucket-example-1-creating-and-using-a-list-template-class"> Example 1: Creating and Using a List Template Class </a>
29///
30/// # Purpose {#bslalg_hashtablebucket-purpose}
31/// Provide a bucket representation for hash table data structures.
32///
33/// # Classes {#bslalg_hashtablebucket-classes}
34///
35/// - bslalg::HashTableBucket : hash-table, manages externally allocated nodes
36///
37/// @see bslalg_hashtableimputil, bslalg_bidirectionallink,
38/// bslalg_bidirectionalnode
39///
40/// # Description {#bslalg_hashtablebucket-description}
41/// This component provides an ability to keep track of a segment
42/// of a linked list of `bslalg::BidirectionalLink` objects. It contains
43/// pointers to the first and last elements of the list segment in question, or
44/// two null pointers for an empty list.
45///
46/// ## Usage {#bslalg_hashtablebucket-usage}
47///
48///
49/// This section illustrates intended usage of this component.
50///
51/// ### Example 1: Creating and Using a List Template Class {#bslalg_hashtablebucket-example-1-creating-and-using-a-list-template-class}
52///
53///
54/// Suppose we want to create a linked list template class, it will be called
55/// `MyList`.
56///
57/// First, we create the iterator helper class, which will eventually be
58/// defined as a nested type within the `MyList` class.
59/// @code
60/// // ===============
61/// // MyList_Iterator
62/// // ===============
63///
64/// /// `Iterator` type for class `MyList`. This class will be typedef'ed
65/// /// to be a nested class within `MyList`.
66/// template <class PAYLOAD>
67/// class MyList_Iterator {
68///
69/// // PRIVATE TYPES
70/// typedef bslalg::BidirectionalNode<PAYLOAD> Node;
71///
72/// // DATA
73/// Node *d_node;
74///
75/// // FRIENDS
76/// template <class PL>
77/// friend bool operator==(MyList_Iterator<PL>,
78/// MyList_Iterator<PL>);
79///
80/// public:
81/// // CREATORS
82/// MyList_Iterator() : d_node(0) {}
83/// explicit
84/// MyList_Iterator(Node *node) : d_node(node) {}
85/// //! MyList_Iterator(const MyList_Iterator& original) = default;
86/// //! ~MyList_Iterator() = default;
87///
88/// // MANIPULATORS
89/// //! MyList_Iterator& operator=(const MyList_Iterator& other) = default;
90///
91/// MyList_Iterator operator++();
92///
93/// // ACCESSORS
94/// PAYLOAD& operator*() const { return d_node->value(); }
95/// };
96/// @endcode
97/// Then, we define our `MyList` class, which will inherit from
98/// `bslalg::HashTableBucket`. `MyList::Iterator` will be a public typedef of
99/// `MyList_Iterator`. For brevity, we will omit a lot of functionality that a
100/// full, general-purpose list class would have, implementing only what we will
101/// need for this example.
102/// @code
103/// // ======
104/// // MyList
105/// // ======
106///
107/// /// This class stores a doubly-linked list containing objects of type
108/// /// `PAYLOAD`.
109/// template <class PAYLOAD>
110/// class MyList : public bslalg::HashTableBucket {
111///
112/// // PRIVATE TYPES
113/// typedef bslalg::BidirectionalNode<PAYLOAD> Node;
114///
115/// public:
116/// // PUBLIC TYPES
117/// typedef PAYLOAD ValueType;
118/// typedef MyList_Iterator<ValueType> Iterator;
119///
120/// // DATA
121/// bslma::Allocator *d_allocator_p;
122///
123/// public:
124/// // CREATORS
125/// explicit
126/// MyList(bslma::Allocator *basicAllocator = 0)
127/// : d_allocator_p(bslma::Default::allocator(basicAllocator))
128/// {
129/// reset();
130/// }
131/// ~MyList();
132///
133/// // MANIPULATORS
134/// Iterator begin() { return Iterator((Node *) first()); }
135/// Iterator end() { return Iterator(0); }
136/// void pushBack(const ValueType& value);
137/// void popBack();
138/// };
139/// @endcode
140/// Next, we implement the functions for the iterator type.
141/// @code
142/// // ---------------
143/// // MyList_Iterator
144/// // ---------------
145///
146/// // MANIPULATORS
147/// template <class PAYLOAD>
148/// MyList_Iterator<PAYLOAD> MyList_Iterator<PAYLOAD>::operator++()
149/// {
150/// d_node = (Node *) d_node->nextLink();
151/// return *this;
152/// }
153///
154/// template <class PAYLOAD>
155/// inline
156/// bool operator==(MyList_Iterator<PAYLOAD> lhs,
157/// MyList_Iterator<PAYLOAD> rhs)
158/// {
159/// return lhs.d_node == rhs.d_node;
160/// }
161///
162/// template <class PAYLOAD>
163/// inline
164/// bool operator!=(MyList_Iterator<PAYLOAD> lhs,
165/// MyList_Iterator<PAYLOAD> rhs)
166/// {
167/// return !(lhs == rhs);
168/// }
169/// @endcode
170/// Then, we implement the functions for the `MyList` class:
171/// @code
172/// // ------
173/// // MyList
174/// // ------
175///
176/// // CREATORS
177/// template <class PAYLOAD>
178/// MyList<PAYLOAD>::~MyList()
179/// {
180/// typedef bslalg::BidirectionalLink BDL;
181///
182/// for (Node *p = (Node *) first(); p; ) {
183/// Node *toDelete = p;
184/// p = (Node *) p->nextLink();
185///
186/// toDelete->value().~ValueType();
187/// d_allocator_p->deleteObjectRaw(static_cast<BDL *>(toDelete));
188/// }
189///
190/// reset();
191/// }
192///
193/// // MANIPULATORS
194/// template <class PAYLOAD>
195/// void MyList<PAYLOAD>::pushBack(const PAYLOAD& value)
196/// {
197/// Node *node = (Node *) d_allocator_p->allocate(sizeof(Node));
198/// node->setNextLink(0);
199/// node->setPreviousLink(last());
200/// bslalg::ScalarPrimitives::copyConstruct(&node->value(),
201/// value,
202/// d_allocator_p);
203///
204/// if (0 == last()) {
205/// BSLS_ASSERT_SAFE(0 == first());
206///
207/// setFirstAndLast(node, node);
208/// }
209/// else {
210/// last()->setNextLink(node);
211/// setLast(node);
212/// }
213/// }
214///
215/// template <class PAYLOAD>
216/// void MyList<PAYLOAD>::popBack()
217/// {
218/// BSLS_ASSERT_SAFE(first() && last());
219///
220/// Node *toDelete = (Node *) last();
221///
222/// if (first() != toDelete) {
223/// BSLS_ASSERT_SAFE(0 != last());
224/// setLast(last()->previousLink());
225/// last()->setNextLink(0);
226/// }
227/// else {
228/// reset();
229/// }
230///
231/// d_allocator_p->deleteObject(toDelete);
232/// }
233/// @endcode
234/// Next, in `main`, we use our `MyList` class to store a list of ints:
235/// @code
236/// MyList<int> intList;
237/// @endcode
238/// Then, we declare an array of ints to populate it with:
239/// @code
240/// int intArray[] = { 8, 2, 3, 5, 7, 2 };
241/// enum { NUM_INTS = sizeof intArray / sizeof *intArray };
242/// @endcode
243/// Now, we iterate, pushing ints to the list:
244/// @code
245/// for (const int *pInt = intArray; pInt < intArray + NUM_INTS; ++pInt) {
246/// intList.pushBack(*pInt);
247/// }
248/// @endcode
249/// Finally, we use our `Iterator` type to traverse the list and observe its
250/// values:
251/// @code
252/// MyList<int>::Iterator it = intList.begin();
253/// assert(8 == *it);
254/// assert(2 == *++it);
255/// assert(3 == *++it);
256/// assert(5 == *++it);
257/// assert(7 == *++it);
258/// assert(2 == *++it);
259/// assert(intList.end() == ++it);
260/// @endcode
261/// @}
262/** @} */
263/** @} */
264
265/** @addtogroup bsl
266 * @{
267 */
268/** @addtogroup bslalg
269 * @{
270 */
271/** @addtogroup bslalg_hashtablebucket
272 * @{
273 */
274
275#include <bslscm_version.h>
276
278
281
282#include <bsls_assert.h>
283
284#include <cstddef>
285
286#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
287#include <bsls_nativestd.h>
288#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
289
290
291namespace bslalg {
292
293 // =====================
294 // class HashTableBucket
295 // =====================
296
298 public:
299 // DATA
302
303 // TRAITS
306
307 public:
308 // No creators -- must be a POD so that aggregate initialization can be
309 // done.
310
311 // MANIPULATORS
312
313 /// Set the `first` element of this bucket to the specified `node`. The
314 /// behavior is undefined unless `node` is an element from the same
315 /// bidirectional list as the `last` element in this bucket, and `node`
316 /// either precedes `last` in that list, or is the same node, or this
317 /// bucket is empty and `node` has a null pointer value.
318 void setFirst(BidirectionalLink *node);
319
320 /// Set the `last` element of this bucket to the specified `node`. The
321 /// behavior is undefined unless `node` is an element from the same
322 /// bidirectional list as the `first` element in this bucket, and `node`
323 /// either follows `first` in that list, or is the same node, or this
324 /// bucket is empty and `node` has a null pointer value.
325 void setLast(BidirectionalLink *node);
326
327 /// Set `first` and `last` to the specified values. Behavior is
328 /// undefined unless unless `first == last`, or unless `first` and
329 /// `last` are links from the same list, where `first` precedes `last`
330 /// in the list. Note that `first` and `last` may both have a null
331 /// pointer value, indicating an empty bucket.
333
334 /// Set `first` and `last` to a null pointer value.
335 void reset();
336
337 // ACCESSORS
338
339 /// Return the next node after the end of this bucket, or 0 if
340 /// `0 == last()`, so the range to traverse to traverse all nodes in the
341 /// bucket is always `[ first(), end() )` regardless of whether the
342 /// bucket is empty.
343 BidirectionalLink *end() const;
344
345 /// Return the address of the first element in this hash bucket, or a
346 /// null pointer value if the bucket is empty.
347 BidirectionalLink *first() const;
348
349 /// Return the address of the last element in this hash bucket, or a
350 /// null pointer value if the bucket is empty.
351 BidirectionalLink *last() const;
352
353 /// Return the number of nodes in this hash bucket.
354 std::size_t countElements() const;
355};
356
357// ============================================================================
358// FREE OPERATORS
359// ============================================================================
360
361/// Return `true` if the specified hash table buckets `lhs` and `rhs` are
362/// equivalent and `false` otherwise.
363bool operator==(const HashTableBucket& lhs, const HashTableBucket& rhs);
364
365/// Return `true` if the specified hash table buckets `lhs` and `rhs` are
366/// not equivalent and `false` otherwise.
367bool operator!=(const HashTableBucket& lhs, const HashTableBucket& rhs);
368
369// ============================================================================
370// TEMPLATE AND INLINE FUNCTION DEFINITIONS
371// ============================================================================
372
373 //----------------------
374 // class HashTableBucket
375 //----------------------
376
377// MANIPULATORS
378inline
380{
381 BSLS_ASSERT_SAFE(!d_first_p == !node);
382
383 d_first_p = node;
384}
385
386inline
388{
389 BSLS_ASSERT_SAFE(!d_last_p == !node);
390
391 d_last_p = node;
392}
393
394inline
403
404inline
406{
407 d_first_p = d_last_p = 0;
408}
409
410// ACCESSORS
411inline
413{
414 return d_last_p ? d_last_p->nextLink() : 0;
415}
416
417inline
422
423inline
425{
426 return d_last_p;
427}
428
429} // close package namespace
430
431// FREE OPERATORS
432inline
434 const bslalg::HashTableBucket& rhs)
435{
436 return lhs.first() == rhs.first() && lhs.last() == rhs.last();
437}
438
439inline
441 const bslalg::HashTableBucket& rhs)
442{
443 return lhs.first() != rhs.first() || lhs.last() != rhs.last();
444}
445
446
447
448
449#endif
450
451// ----------------------------------------------------------------------------
452// Copyright 2013 Bloomberg Finance L.P.
453//
454// Licensed under the Apache License, Version 2.0 (the "License");
455// you may not use this file except in compliance with the License.
456// You may obtain a copy of the License at
457//
458// http://www.apache.org/licenses/LICENSE-2.0
459//
460// Unless required by applicable law or agreed to in writing, software
461// distributed under the License is distributed on an "AS IS" BASIS,
462// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
463// See the License for the specific language governing permissions and
464// limitations under the License.
465// ----------------------------- END-OF-FILE ----------------------------------
466
467/** @} */
468/** @} */
469/** @} */
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlc_flathashmap.h:1805
bool operator==(const HashTableAnchor &lhs, const HashTableAnchor &rhs)
bool operator!=(const HashTableAnchor &lhs, const HashTableAnchor &rhs)
Definition bslalg_hashtablebucket.h:297
BidirectionalLink * d_first_p
Definition bslalg_hashtablebucket.h:300
BidirectionalLink * first() const
Definition bslalg_hashtablebucket.h:418
BidirectionalLink * d_last_p
Definition bslalg_hashtablebucket.h:301
void setFirst(BidirectionalLink *node)
Definition bslalg_hashtablebucket.h:379
void setLast(BidirectionalLink *node)
Definition bslalg_hashtablebucket.h:387
BidirectionalLink * end() const
Definition bslalg_hashtablebucket.h:412
BidirectionalLink * last() const
Definition bslalg_hashtablebucket.h:424
BSLMF_NESTED_TRAIT_DECLARATION(HashTableBucket, bslmf::IsBitwiseCopyable)
void setFirstAndLast(BidirectionalLink *first, BidirectionalLink *last)
Definition bslalg_hashtablebucket.h:395
void reset()
Set first and last to a null pointer value.
Definition bslalg_hashtablebucket.h:405
std::size_t countElements() const
Return the number of nodes in this hash bucket.
Definition bslmf_isbitwisecopyable.h:298