BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_treenode.h
Go to the documentation of this file.
1/// @file bslstl_treenode.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_treenode.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_TREENODE
9#define INCLUDED_BSLSTL_TREENODE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_treenode bslstl_treenode
15/// @brief Provide a POD-like tree node type holding a parameterized value.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_treenode
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_treenode-purpose"> Purpose</a>
25/// * <a href="#bslstl_treenode-classes"> Classes </a>
26/// * <a href="#bslstl_treenode-description"> Description </a>
27/// * <a href="#bslstl_treenode-usage"> Usage </a>
28/// * <a href="#bslstl_treenode-example-1-allocating-and-deallocating-treenode-objects"> Example 1: Allocating and Deallocating TreeNode Objects. </a>
29/// * <a href="#bslstl_treenode-example-2-creating-a-simple-tree-of-treenode-objects"> Example 2: Creating a Simple Tree of TreeNode Objects. </a>
30///
31/// # Purpose {#bslstl_treenode-purpose}
32/// Provide a POD-like tree node type holding a parameterized value.
33///
34/// # Classes {#bslstl_treenode-classes}
35///
36/// - bslstl::TreeNode: a tree node holding a parameterized value
37///
38/// @see bslstl_treenodefactory, bslstl_set, bslstl_map
39///
40/// # Description {#bslstl_treenode-description}
41/// This component provides a single POD-like class, `TreeNode`,
42/// used to represent a node in a red-black binary search tree holding a value
43/// of a parameterized type. A `TreeNode` inherits from `bslalg::RbTreeNode`,
44/// so it may be used with `bslalg::RbTreeUtil` functions, and adds an attribute
45/// `value` of the parameterized `VALUE`. The following inheritance hierarchy
46/// diagram shows the classes involved and their methods:
47/// @code
48/// ,----------------.
49/// ( bslstl::TreeNode )
50/// `----------------'
51/// | value
52/// V
53/// ,------------------.
54/// ( bslalg::RbTreeNode )
55/// `------------------'
56/// ctor
57/// dtor
58/// makeBlack
59/// makeRed
60/// setParent
61/// setLeftChild
62/// setRightChild
63/// setColor
64/// toggleColor
65/// parent
66/// leftChild
67/// rightChild
68/// isBlack
69/// isRed
70/// color
71/// @endcode
72/// This class is "POD-like" to facilitate efficient allocation and use in the
73/// context of a container implementation. In order to meet the essential
74/// requirements of a POD type, both this `class` and `bslalg::RbTreeNode` do
75/// not define a constructor or destructor. The manipulator, `value`, returns a
76/// modifiable reference to the object that may be constructed in-place by the
77/// appropriate `bsl::allocator_traits` object.
78///
79/// ## Usage {#bslstl_treenode-usage}
80///
81///
82/// In this section we show intended usage of this component.
83///
84/// ### Example 1: Allocating and Deallocating TreeNode Objects. {#bslstl_treenode-example-1-allocating-and-deallocating-treenode-objects}
85///
86///
87/// In the following example we define a factory class for allocating and
88/// destroying `TreeNode` objects.
89///
90/// First, we define the interface for the class `NodeFactory`:
91/// @code
92/// template <class VALUE, class ALLOCATOR>
93/// class NodeFactory {
94/// @endcode
95/// The parameterized `ALLOCATOR` is intended to allocate objects of the
96/// parameterized `VALUE`, so to use it to allocate objects of `TreeNode<VALUE>`
97/// we must rebind it to the tree node type. Note that in general, we use
98/// `allocator_traits` to perform actions using an allocator (including the
99/// rebind below):
100/// @code
101/// // PRIVATE TYPES
102/// typedef typename bsl::allocator_traits<ALLOCATOR>::template
103/// rebind_traits<TreeNode<VALUE> > AllocatorTraits;
104/// typedef typename AllocatorTraits::allocator_type NodeAllocator;
105///
106/// // DATA
107/// NodeAllocator d_allocator; // rebound tree-node allocator
108///
109/// private:
110/// // NOT IMPLEMENTED
111/// NodeFactory(const NodeFactory&);
112/// NodeFactory& operator=(const NodeFactory&);
113///
114/// public:
115/// // CREATORS
116/// NodeFactory(const ALLOCATOR& allocator);
117/// // Create a tree node-factory that will use the specified
118/// // 'allocator' to supply memory.
119///
120/// // MANIPULATORS
121/// TreeNode<VALUE> *createNode(const VALUE& value);
122/// // Create a new 'TreeNode' object holding the specified 'value'.
123///
124/// void deleteNode(bslalg::RbTreeNode *node);
125/// // Destroy and deallocate the specified 'node'. The behavior is
126/// // undefined unless 'node' is the address of a
127/// // 'TreeNode<VALUE>' object.
128/// };
129/// @endcode
130/// Now, we implement the `NodeFactory` type:
131/// @code
132/// template <class VALUE, class ALLOCATOR>
133/// inline
134/// NodeFactory<VALUE, ALLOCATOR>::NodeFactory(const ALLOCATOR& allocator)
135/// : d_allocator(allocator)
136/// {
137/// }
138/// @endcode
139/// We implement the `createNode` function by using the rebound
140/// `allocator_traits` for our allocator to in-place copy-construct the
141/// supplied `value` into the `value` data member of our `result` node
142/// object. Note that `TreeNode` is a POD-like type, without a constructor, so
143/// we do not need to call its constructor here:
144/// @code
145/// template <class VALUE, class ALLOCATOR>
146/// inline
147/// TreeNode<VALUE> *
148/// NodeFactory<VALUE, ALLOCATOR>::createNode(const VALUE& value)
149/// {
150/// TreeNode<VALUE> *result = AllocatorTraits::allocate(d_allocator, 1);
151/// AllocatorTraits::construct(d_allocator,
152/// bsls::Util::addressOf(result->value()),
153/// value);
154/// return result;
155/// }
156/// @endcode
157/// Finally, we implement the function `deleteNode`. Again, we use the
158/// rebound `allocator_traits` for our tree node type, this time to destroy the
159/// `value` date member of node, and then to deallocate its footprint. Note
160/// that `TreeNode` is a POD-like type, so we do not need to call its destructor
161/// here:
162/// @code
163/// template <class VALUE, class ALLOCATOR>
164/// inline
165/// void NodeFactory<VALUE, ALLOCATOR>::deleteNode(bslalg::RbTreeNode *node)
166/// {
167/// TreeNode<VALUE> *treeNode = static_cast<TreeNode<VALUE> *>(node);
168/// AllocatorTraits::destroy(d_allocator,
169/// bsls::Util::addressOf(treeNode->value()));
170/// AllocatorTraits::deallocate(d_allocator, treeNode, 1);
171/// }
172/// @endcode
173///
174/// ### Example 2: Creating a Simple Tree of TreeNode Objects. {#bslstl_treenode-example-2-creating-a-simple-tree-of-treenode-objects}
175///
176///
177/// In the following example we create a container-type `Set` for
178/// holding a set of values of a parameterized `VALUE`.
179///
180/// First, we define a comparator for `VALUE` of `TreeNode<VALUE>` objects.
181/// This type is designed to be supplied to functions in `bslalg::RbTreeUtil`.
182/// Note that, for simplicity, this type uses `operator<` to compare values,
183/// rather than a client defined comparator type.
184/// @code
185/// template <class VALUE>
186/// class Comparator {
187/// public:
188/// // CREATORS
189/// Comparator() {}
190/// // Create a node-value comparator.
191///
192/// // ACCESSORS
193/// bool operator()(const VALUE& lhs,
194/// const bslalg::RbTreeNode& rhs) const;
195/// bool operator()(const bslalg::RbTreeNode& lhs,
196/// const VALUE& rhs) const;
197/// // Return 'true' if the specified 'lhs' is less than (ordered
198/// // before) the specified 'rhs', and 'false' otherwise. The
199/// // behavior is undefined unless the supplied 'bslalg::RbTreeNode'
200/// // object is of the derived 'TreeNode<VALUE>' type.
201/// };
202/// @endcode
203/// Then, we implement the comparison methods of `Comparator`. Note that the
204/// supplied `RbTreeNode` objects must be @ref static_cast to
205/// `TreeNode<VALUE>` to access their value:
206/// @code
207/// template <class VALUE>
208/// inline
209/// bool Comparator<VALUE>::operator()(const VALUE& lhs,
210/// const bslalg::RbTreeNode& rhs) const
211/// {
212/// return lhs < static_cast<const TreeNode<VALUE>& >(rhs).value();
213/// }
214///
215/// template <class VALUE>
216/// inline
217/// bool Comparator<VALUE>::operator()(const bslalg::RbTreeNode& lhs,
218/// const VALUE& rhs) const
219/// {
220/// return static_cast<const TreeNode<VALUE>& >(lhs).value() < rhs;
221/// }
222/// @endcode
223/// Now, having defined the requisite helper types, we define the public
224/// interface for `Set`. Note that for the purposes of illustrating the use of
225/// `TreeNode` a number of simplifications have been made. For example, this
226/// implementation provides only `insert`, `remove`, `isMember`, and
227/// `numMembers` operations:
228/// @code
229/// template <class VALUE,
230/// class ALLOCATOR = bsl::allocator<VALUE> >
231/// class Set {
232/// // PRIVATE TYPES
233/// typedef Comparator<VALUE> ValueComparator;
234/// typedef NodeFactory<VALUE, ALLOCATOR> Factory;
235///
236/// // DATA
237/// bslalg::RbTreeAnchor d_tree; // tree of node objects
238/// Factory d_factory; // allocator for node objects
239///
240/// private:
241/// // NOT IMPLEMENTED
242/// Set(const Set&);
243/// Set& operator=(const Set&);
244///
245/// public:
246/// // CREATORS
247/// Set(const ALLOCATOR& allocator = ALLOCATOR());
248/// // Create an empty set. Optionally specify a 'allocator' used to
249/// // supply memory. If 'allocator' is not specified, a default
250/// // constructed 'ALLOCATOR' object is used.
251///
252/// ~Set();
253/// // Destroy this set.
254///
255/// // MANIPULATORS
256/// void insert(const VALUE& value);
257/// // Insert the specified value into this set.
258///
259/// bool remove(const VALUE& value);
260/// // If 'value' is a member of this set, then remove it and return
261/// // 'true', and return 'false' otherwise.
262///
263/// // ACCESSORS
264/// bool isElement(const VALUE& value) const;
265/// // Return 'true' if the specified 'value' is a member of this set,
266/// // and 'false' otherwise.
267///
268/// int numElements() const;
269/// // Return the number of elements in this set.
270/// };
271/// @endcode
272/// Now, we define the implementation of `Set`:
273/// @code
274/// // CREATORS
275/// template <class VALUE, class ALLOCATOR>
276/// inline
277/// Set<VALUE, ALLOCATOR>::Set(const ALLOCATOR& allocator)
278/// : d_tree()
279/// , d_factory(allocator)
280/// {
281/// }
282///
283/// template <class VALUE, class ALLOCATOR>
284/// inline
285/// Set<VALUE, ALLOCATOR>::~Set()
286/// {
287/// bslalg::RbTreeUtil::deleteTree(&d_tree, &d_factory);
288/// }
289///
290/// // MANIPULATORS
291/// template <class VALUE, class ALLOCATOR>
292/// void Set<VALUE, ALLOCATOR>::insert(const VALUE& value)
293/// {
294/// int comparisonResult;
295/// ValueComparator comparator;
296/// bslalg::RbTreeNode *parent =
297/// bslalg::RbTreeUtil::findUniqueInsertLocation(&comparisonResult,
298/// &d_tree,
299/// comparator,
300/// value);
301/// if (0 != comparisonResult) {
302/// bslalg::RbTreeNode *node = d_factory.createNode(value);
303/// bslalg::RbTreeUtil::insertAt(&d_tree,
304/// parent,
305/// comparisonResult < 0,
306/// node);
307/// }
308/// }
309///
310/// template <class VALUE, class ALLOCATOR>
311/// bool Set<VALUE, ALLOCATOR>::remove(const VALUE& value)
312/// {
313/// bslalg::RbTreeNode *node =
314/// bslalg::RbTreeUtil::find(d_tree, ValueComparator(), value);
315/// if (node) {
316/// bslalg::RbTreeUtil::remove(&d_tree, node);
317/// d_factory.deleteNode(node);
318/// }
319/// return node;
320/// }
321///
322/// // ACCESSORS
323/// template <class VALUE, class ALLOCATOR>
324/// inline
325/// bool Set<VALUE, ALLOCATOR>::isElement(const VALUE& value) const
326/// {
327/// ValueComparator comparator;
328/// return bslalg::RbTreeUtil::find(d_tree, comparator, value);
329/// }
330///
331/// template <class VALUE, class ALLOCATOR>
332/// inline
333/// int Set<VALUE, ALLOCATOR>::numElements() const
334/// {
335/// return d_tree.numNodes();
336/// }
337/// @endcode
338/// Notice that the definition and implementation of `Set` never directly
339/// uses the `TreeNode` type, but instead use it indirectly through
340/// `Comparator`, and `NodeFactory`, and uses it via its base-class
341/// `bslalg::RbTreeNode`.
342///
343/// Finally, we test our `Set`.
344/// @code
345/// Set<int> set;
346/// assert(0 == set.numElements());
347///
348/// set.insert(1);
349/// assert(set.isElement(1));
350/// assert(1 == set.numElements());
351///
352/// set.insert(1);
353/// assert(set.isElement(1));
354/// assert(1 == set.numElements());
355///
356/// set.insert(2);
357/// assert(set.isElement(1));
358/// assert(set.isElement(2));
359/// assert(2 == set.numElements());
360/// @endcode
361/// @}
362/** @} */
363/** @} */
364
365/** @addtogroup bsl
366 * @{
367 */
368/** @addtogroup bslstl
369 * @{
370 */
371/** @addtogroup bslstl_treenode
372 * @{
373 */
374
375#include <bslalg_rbtreenode.h>
376
377
378namespace bslstl {
379
380 // ==============
381 // class TreeNode
382 // ==============
383
384/// This POD-like `class` describes a node suitable for use in a red-black
385/// binary search tree of values of the parameterized `VALUE`. This class
386/// is a "POD-like" to facilitate efficient allocation and use in the
387/// context of a container implementation. In order to meet the essential
388/// requirements of a POD type, this `class` does not define a constructor
389/// or destructor. The manipulator, `value`, returns a modifiable reference
390/// to `d_value` so that it may be constructed in-place by the appropriate
391/// `bsl::allocator_traits` object.
392///
393/// See @ref bslstl_treenode
394template <class VALUE>
396
397 // DATA
398 VALUE d_value; // payload value
399
400 private:
401 // The following functions are not defined because a 'TreeNode' should
402 // never be constructed, destructed, or assigned. The 'd_value' member
403 // should be separately constructed and destroyed using an appropriate
404 // 'bsl::allocator_traits' object.
405
406 TreeNode(); // Declared but not defined
407 TreeNode(const TreeNode&); // Declared but not defined
408 TreeNode& operator=(const TreeNode&); // Declared but not defined
409 ~TreeNode(); // Declared but not defined
410
411 public:
412 // MANIPULATORS
413
414 /// Return a reference providing modifiable access to the `value` of
415 /// this object.
416 VALUE& value();
417
418 // ACCESSORS
419
420 /// Return a reference providing non-modifiable access to the `value` of
421 /// this object.
422 const VALUE& value() const;
423};
424
425// ============================================================================
426// TEMPLATE AND INLINE FUNCTION DEFINITIONS
427// ============================================================================
428
429template <class VALUE>
430inline
432{
433 return d_value;
434}
435
436template <class VALUE>
437inline
438const VALUE& TreeNode<VALUE>::value() const
439{
440 return d_value;
441}
442
443
444} // close package namespace
445
446
447#endif
448
449// ----------------------------------------------------------------------------
450// Copyright 2013 Bloomberg Finance L.P.
451//
452// Licensed under the Apache License, Version 2.0 (the "License");
453// you may not use this file except in compliance with the License.
454// You may obtain a copy of the License at
455//
456// http://www.apache.org/licenses/LICENSE-2.0
457//
458// Unless required by applicable law or agreed to in writing, software
459// distributed under the License is distributed on an "AS IS" BASIS,
460// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
461// See the License for the specific language governing permissions and
462// limitations under the License.
463// ----------------------------- END-OF-FILE ----------------------------------
464
465/** @} */
466/** @} */
467/** @} */
Definition bslalg_rbtreenode.h:377
Definition bslstl_treenode.h:395
VALUE & value()
Definition bslstl_treenode.h:431
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslstl_algorithm.h:84