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