BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslalg_bidirectionallink.h
Go to the documentation of this file.
1/// @file bslalg_bidirectionallink.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslalg_bidirectionallink.h -*-C++-*-
8#ifndef INCLUDED_BSLALG_BIDIRECTIONALLINK
9#define INCLUDED_BSLALG_BIDIRECTIONALLINK
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslalg_bidirectionallink bslalg_bidirectionallink
15/// @brief Provide a basic link type for building doubly-linked lists.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslalg
19/// @{
20/// @addtogroup bslalg_bidirectionallink
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslalg_bidirectionallink-purpose"> Purpose</a>
25/// * <a href="#bslalg_bidirectionallink-classes"> Classes </a>
26/// * <a href="#bslalg_bidirectionallink-description"> Description </a>
27/// * <a href="#bslalg_bidirectionallink-usage"> Usage </a>
28/// * <a href="#bslalg_bidirectionallink-example-1-creating-and-using-a-list-template-class"> Example 1: Creating and Using a List Template Class </a>
29///
30/// # Purpose {#bslalg_bidirectionallink-purpose}
31/// Provide a basic link type for building doubly-linked lists.
32///
33/// # Classes {#bslalg_bidirectionallink-classes}
34///
35/// - bslalg::BidirectionalLink : A node in a doubly-linked list
36///
37/// @see bslalg_bidirectionallinklistutil, bslalg_hashtableimputil
38///
39/// # Description {#bslalg_bidirectionallink-description}
40/// This component provides a single POD-like class,
41/// `BidirectionalLink`, used to represent a node in a doubly-linked list. A
42/// `BidirectionalLink` provides the address to its preceding node, and the
43/// address of its successor node. A null-pointer value for either address
44/// signifies the end of the list. `BidirectionalLink` does not, however,
45/// contain "payload" data (e.g., a value), as it is intended to work with
46/// generalized list operations (see @ref bslalg_bidirectionallinklistutil ).
47/// Clients creating a doubly-linked list must define their own node type that
48/// incorporates `BidirectionalLink` (generally via inheritance), and that
49/// maintains the "value" stored in that node.
50///
51///-----------------------------------------------------------------------------
52///
53/// ## Usage {#bslalg_bidirectionallink-usage}
54///
55///
56/// This section illustrates intended usage of this component.
57///
58/// ### Example 1: Creating and Using a List Template Class {#bslalg_bidirectionallink-example-1-creating-and-using-a-list-template-class}
59///
60///
61/// Suppose we want to create a linked list template class, it will be called
62/// `MyList`.
63///
64/// First, we create the `MyNode` class, which derives from the
65/// BidirectionalLink class to carry a `PAYLOAD` object.
66/// @code
67/// template <class PAYLOAD>
68/// class MyNode : public bslalg::BidirectionalLink {
69/// public:
70/// // PUBLIC TYPES
71/// typedef PAYLOAD ValueType;
72///
73/// private:
74/// // DATA
75/// ValueType d_value;
76///
77/// private:
78/// // NOT IMPLEMENTED
79/// MyNode();
80/// MyNode(const MyNode&);
81/// MyNode& operator=(const MyNode&);
82///
83/// public:
84/// // CREATOR
85/// ~MyNode() {}
86/// // Destroy this object.
87///
88/// // MANIPULATOR
89/// ValueType& value() { return d_value; }
90/// // Return a reference to the modifiable value stored in this node.
91///
92/// // ACCESSOR
93/// const ValueType& value() const { return d_value; }
94/// // Return a reference to the non-modifiable value stored in this
95/// // node.
96/// };
97/// @endcode
98/// Next, we create the iterator helper class, which will eventually be
99/// defined as a nested type within the `MyList` class.
100/// @code
101/// // ===============
102/// // MyList_Iterator
103/// // ===============
104///
105/// template <class PAYLOAD>
106/// class MyList_Iterator {
107/// // PRIVATE TYPES
108/// typedef MyNode<PAYLOAD> Node;
109///
110/// // DATA
111/// Node *d_node;
112///
113/// // FRIENDS
114/// template <class PL>
115/// friend bool operator==(MyList_Iterator<PL>,
116/// MyList_Iterator<PL>);
117///
118/// public:
119/// // CREATORS
120/// MyList_Iterator() : d_node(0) {}
121/// explicit
122/// MyList_Iterator(Node *node) : d_node(node) {}
123/// //! MyList_Iterator(const MyList_Iterator& original) = default;
124/// //! MyList_Iterator& operator=(const MyList_Iterator& other) = default;
125/// //! ~MyList_Iterator() = default;
126///
127/// // MANIPULATORS
128/// MyList_Iterator operator++();
129///
130/// // ACCESSORS
131/// PAYLOAD& operator*() const { return d_node->value(); }
132/// };
133/// @endcode
134/// Then, we define our `MyList` class, with `MyList::Iterator` being a public
135/// typedef of `MyList_Iterator`. For brevity, we will omit a lot of
136/// functionality that a full, general-purpose list class would have,
137/// implementing only what we will need for this example.
138/// @code
139/// // ======
140/// // MyList
141/// // ======
142///
143/// template <class PAYLOAD>
144/// class MyList {
145/// // PRIVATE TYPES
146/// typedef MyNode<PAYLOAD> Node;
147///
148/// public:
149/// // PUBLIC TYPES
150/// typedef PAYLOAD ValueType;
151/// typedef MyList_Iterator<ValueType> Iterator;
152///
153/// private:
154/// // DATA
155/// Node *d_begin;
156/// Node *d_end;
157/// bslma::Allocator *d_allocator_p;
158///
159/// public:
160/// // CREATORS
161/// explicit
162/// MyList(bslma::Allocator *basicAllocator = 0)
163/// : d_begin(0)
164/// , d_end(0)
165/// , d_allocator_p(bslma::Default::allocator(basicAllocator))
166/// {}
167///
168/// ~MyList();
169///
170/// // MANIPULATORS
171/// Iterator begin();
172/// Iterator end();
173/// void pushBack(const ValueType& value);
174/// void popBack();
175/// };
176/// @endcode
177/// Next, we implement the functions for the iterator type.
178/// @code
179/// // ---------------
180/// // MyList_Iterator
181/// // ---------------
182///
183/// // MANIPULATORS
184/// template <class PAYLOAD>
185/// MyList_Iterator<PAYLOAD> MyList_Iterator<PAYLOAD>::operator++()
186/// {
187/// d_node = (Node *) d_node->nextLink();
188/// return *this;
189/// }
190///
191/// template <class PAYLOAD>
192/// inline
193/// bool operator==(MyList_Iterator<PAYLOAD> lhs,
194/// MyList_Iterator<PAYLOAD> rhs)
195/// {
196/// return lhs.d_node == rhs.d_node;
197/// }
198///
199/// template <class PAYLOAD>
200/// inline
201/// bool operator!=(MyList_Iterator<PAYLOAD> lhs,
202/// MyList_Iterator<PAYLOAD> rhs)
203/// {
204/// return !(lhs == rhs);
205/// }
206/// @endcode
207/// Then, we implement the functions for the `MyList` class:
208/// @code
209/// // ------
210/// // MyList
211/// // ------
212///
213/// // CREATORS
214/// template <class PAYLOAD>
215/// MyList<PAYLOAD>::~MyList()
216/// {
217/// for (Node *p = d_begin; p; ) {
218/// Node *toDelete = p;
219/// p = (Node *) p->nextLink();
220///
221/// d_allocator_p->deleteObjectRaw(toDelete);
222/// }
223/// }
224///
225/// // MANIPULATORS
226/// template <class PAYLOAD>
227/// typename MyList<PAYLOAD>::Iterator MyList<PAYLOAD>::begin()
228/// {
229/// return Iterator(d_begin);
230/// }
231///
232/// template <class PAYLOAD>
233/// typename MyList<PAYLOAD>::Iterator MyList<PAYLOAD>::end()
234/// {
235/// return Iterator(0);
236/// }
237///
238/// template <class PAYLOAD>
239/// void MyList<PAYLOAD>::pushBack(const PAYLOAD& value)
240/// {
241/// Node *node = (Node *) d_allocator_p->allocate(sizeof(Node));
242/// node->setNextLink(0);
243/// node->setPreviousLink(d_end);
244/// bslalg::ScalarPrimitives::copyConstruct(&node->value(),
245/// value,
246/// d_allocator_p);
247///
248/// if (d_end) {
249/// BSLS_ASSERT_SAFE(d_begin);
250///
251/// d_end->setNextLink(node);
252/// d_end = node;
253/// }
254/// else {
255/// BSLS_ASSERT_SAFE(0 == d_begin);
256///
257/// d_begin = d_end = node;
258/// }
259/// }
260///
261/// template <class PAYLOAD>
262/// void MyList<PAYLOAD>::popBack()
263/// {
264/// BSLS_ASSERT_SAFE(d_begin && d_end);
265///
266/// Node *toDelete = d_end;
267/// d_end = (Node *) d_end->previousLink();
268///
269/// if (d_begin != toDelete) {
270/// BSLS_ASSERT_SAFE(0 != d_end);
271/// d_end->setNextLink(0);
272/// }
273/// else {
274/// BSLS_ASSERT_SAFE(0 == d_end);
275/// d_begin = 0;
276/// }
277///
278/// d_allocator_p->deleteObject(toDelete);
279/// }
280/// @endcode
281/// Next, in `main`, we use our `MyList` class to store a list of ints:
282/// @code
283/// MyList<int> intList;
284/// @endcode
285/// Then, we declare an array of ints to populate it with:
286/// @code
287/// int intArray[] = { 8, 2, 3, 5, 7, 2 };
288/// enum { NUM_INTS = sizeof intArray / sizeof *intArray };
289/// @endcode
290/// Now, we iterate, pushing ints to the list:
291/// @code
292/// for (const int *pInt = intArray; pInt < intArray + NUM_INTS; ++pInt) {
293/// intList.pushBack(*pInt);
294/// }
295/// @endcode
296/// Finally, we use our `Iterator` type to traverse the list and observe its
297/// values:
298/// @code
299/// MyList<int>::Iterator it = intList.begin();
300/// assert(8 == *it);
301/// assert(2 == *++it);
302/// assert(3 == *++it);
303/// assert(5 == *++it);
304/// assert(7 == *++it);
305/// assert(2 == *++it);
306/// assert(intList.end() == ++it);
307/// @endcode
308/// @}
309/** @} */
310/** @} */
311
312/** @addtogroup bsl
313 * @{
314 */
315/** @addtogroup bslalg
316 * @{
317 */
318/** @addtogroup bslalg_bidirectionallink
319 * @{
320 */
321
322#include <bslscm_version.h>
323
324
325namespace bslalg {
326
327 // =======================
328 // class BidirectionalLink
329 // =======================
330
331/// This POD-like `class` describes a node suitable for use in a doubly-
332/// linked (bidirectional) list, holding the addresses of the preceding and
333/// succeeding nodes, either or both of which may be 0. This class is
334/// "POD-like" to facilitate efficient allocation and use in the context of
335/// a container implementations. In order to meet the essential
336/// requirements of a POD type, this `class` does not declare a constructor
337/// or destructor. However its data members are private. It satisfies the
338/// requirements of a *trivial* type and a *standard* *layout* type defined
339/// by the C++11 standard. Note that this type does not contain any
340/// "payload" member data: Clients creating a doubly-linked list of data
341/// must define an appropriate node type that incorporates
342/// `BidirectionalLink` (generally via inheritance), and that holds the
343/// "value" of any data stored in that node.
344///
345/// See @ref bslalg_bidirectionallink
347
348 private:
349 // DATA
350 BidirectionalLink *d_next_p; // The next node in a list traversal
351 BidirectionalLink *d_prev_p; // The preceding node in a list traversal
352
353 public:
354 // CREATORS
355 BidirectionalLink() = default;
356 // Create a 'BidirectionalLink' object having uninitialized values,
357 // or zero-initialized values if value-initialized.
358
359 BidirectionalLink(const BidirectionalLink& original) = default;
360 // Create a 'BidirectionalLink' object having the same data member
361 // values as the specified 'original' object.
362
364 // Destroy this object.
365
366 // MANIPULATORS
368 // Assign to the data members of this object the values of the data
369 // members of the specified 'rhs' object, and return a reference
370 // providing modifiable access to this object.
371
372 /// Set the successor of this node to be the specified `next` link.
373 void setNextLink(BidirectionalLink *next);
374
375 /// Set the predecessor of this node to be the specified `prev` link.
376 void setPreviousLink(BidirectionalLink *previous);
377
378 /// Set the `nextLink` and `previousLink` attributes of this value to 0.
379 void reset();
380
381 // ACCESSORS
382
383 /// Return the address of the next node linked from this node.
385
386 /// Return the address of the preceding node linked from this node.
388
389};
390
391// ============================================================================
392// TEMPLATE AND INLINE FUNCTION DEFINITIONS
393// ============================================================================
394
395 //------------------------
396 // class BidirectionalLink
397 //------------------------
398
399// MANIPULATORS
400inline
402{
403 d_next_p = next;
404}
405
406inline
408{
409 d_prev_p = previous;
410}
411
412inline
414{
415 d_prev_p = 0;
416 d_next_p = 0;
417}
418
419// ACCESSORS
420inline
422{
423 return d_next_p;
424}
425
426inline
428{
429 return d_prev_p;
430}
431
432} // close package namespace
433
434
435#endif
436
437// ----------------------------------------------------------------------------
438// Copyright 2013 Bloomberg Finance L.P.
439//
440// Licensed under the Apache License, Version 2.0 (the "License");
441// you may not use this file except in compliance with the License.
442// You may obtain a copy of the License at
443//
444// http://www.apache.org/licenses/LICENSE-2.0
445//
446// Unless required by applicable law or agreed to in writing, software
447// distributed under the License is distributed on an "AS IS" BASIS,
448// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
449// See the License for the specific language governing permissions and
450// limitations under the License.
451// ----------------------------- END-OF-FILE ----------------------------------
452
453/** @} */
454/** @} */
455/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlc_flathashmap.h:1805