BDE 4.14.0 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/// // NOT IMPLEMENTED
110/// NodeFactory(const NodeFactory&);
111/// NodeFactory& operator=(const NodeFactory&);
112///
113/// public:
114/// // CREATORS
115/// NodeFactory(const ALLOCATOR& allocator);
116/// // Create a tree node-factory that will use the specified
117/// // 'allocator' to supply memory.
118///
119/// // MANIPULATORS
120/// TreeNode<VALUE> *createNode(const VALUE& value);
121/// // Create a new 'TreeNode' object holding the specified 'value'.
122///
123/// void deleteNode(bslalg::RbTreeNode *node);
124/// // Destroy and deallocate the specified 'node'. The behavior is
125/// // undefined unless 'node' is the address of a
126/// // 'TreeNode<VALUE>' object.
127/// };
128/// @endcode
129/// Now, we implement the `NodeFactory` type:
130/// @code
131/// template <class VALUE, class ALLOCATOR>
132/// inline
133/// NodeFactory<VALUE, ALLOCATOR>::NodeFactory(const ALLOCATOR& allocator)
134/// : d_allocator(allocator)
135/// {
136/// }
137/// @endcode
138/// We implement the `createNode` function by using the rebound
139/// `allocator_traits` for our allocator to in-place copy-construct the
140/// supplied `value` into the `value` data member of our `result` node
141/// object. Note that `TreeNode` is a POD-like type, without a constructor, so
142/// we do not need to call its constructor here:
143/// @code
144/// template <class VALUE, class ALLOCATOR>
145/// inline
146/// TreeNode<VALUE> *
147/// NodeFactory<VALUE, ALLOCATOR>::createNode(const VALUE& value)
148/// {
149/// TreeNode<VALUE> *result = AllocatorTraits::allocate(d_allocator, 1);
150/// AllocatorTraits::construct(d_allocator,
151/// bsls::Util::addressOf(result->value()),
152/// value);
153/// return result;
154/// }
155/// @endcode
156/// Finally, we implement the function `deleteNode`. Again, we use the
157/// rebound `allocator_traits` for our tree node type, this time to destroy the
158/// `value` date member of node, and then to deallocate its footprint. Note
159/// that `TreeNode` is a POD-like type, so we do not need to call its destructor
160/// here:
161/// @code
162/// template <class VALUE, class ALLOCATOR>
163/// inline
164/// void NodeFactory<VALUE, ALLOCATOR>::deleteNode(bslalg::RbTreeNode *node)
165/// {
166/// TreeNode<VALUE> *treeNode = static_cast<TreeNode<VALUE> *>(node);
167/// AllocatorTraits::destroy(d_allocator,
168/// bsls::Util::addressOf(treeNode->value()));
169/// AllocatorTraits::deallocate(d_allocator, treeNode, 1);
170/// }
171/// @endcode
172///
173/// ### Example 2: Creating a Simple Tree of TreeNode Objects. {#bslstl_treenode-example-2-creating-a-simple-tree-of-treenode-objects}
174///
175///
176/// In the following example we create a container-type `Set` for
177/// holding a set of values of a parameterized `VALUE`.
178///
179/// First, we define a comparator for `VALUE` of `TreeNode<VALUE>` objects.
180/// This type is designed to be supplied to functions in `bslalg::RbTreeUtil`.
181/// Note that, for simplicity, this type uses `operator<` to compare values,
182/// rather than a client defined comparator type.
183/// @code
184/// template <class VALUE>
185/// class Comparator {
186/// public:
187/// // CREATORS
188/// Comparator() {}
189/// // Create a node-value comparator.
190///
191/// // ACCESSORS
192/// bool operator()(const VALUE& lhs,
193/// const bslalg::RbTreeNode& rhs) const;
194/// bool operator()(const bslalg::RbTreeNode& lhs,
195/// const VALUE& rhs) const;
196/// // Return 'true' if the specified 'lhs' is less than (ordered
197/// // before) the specified 'rhs', and 'false' otherwise. The
198/// // behavior is undefined unless the supplied 'bslalg::RbTreeNode'
199/// // object is of the derived 'TreeNode<VALUE>' type.
200/// };
201/// @endcode
202/// Then, we implement the comparison methods of `Comparator`. Note that the
203/// supplied `RbTreeNode` objects must be @ref static_cast to
204/// `TreeNode<VALUE>` to access their value:
205/// @code
206/// template <class VALUE>
207/// inline
208/// bool Comparator<VALUE>::operator()(const VALUE& lhs,
209/// const bslalg::RbTreeNode& rhs) const
210/// {
211/// return lhs < static_cast<const TreeNode<VALUE>& >(rhs).value();
212/// }
213///
214/// template <class VALUE>
215/// inline
216/// bool Comparator<VALUE>::operator()(const bslalg::RbTreeNode& lhs,
217/// const VALUE& rhs) const
218/// {
219/// return static_cast<const TreeNode<VALUE>& >(lhs).value() < rhs;
220/// }
221/// @endcode
222/// Now, having defined the requisite helper types, we define the public
223/// interface for `Set`. Note that for the purposes of illustrating the use of
224/// `TreeNode` a number of simplifications have been made. For example, this
225/// implementation provides only `insert`, `remove`, `isMember`, and
226/// `numMembers` operations:
227/// @code
228/// template <class VALUE,
229/// class ALLOCATOR = bsl::allocator<VALUE> >
230/// class Set {
231/// // PRIVATE TYPES
232/// typedef Comparator<VALUE> ValueComparator;
233/// typedef NodeFactory<VALUE, ALLOCATOR> Factory;
234///
235/// // DATA
236/// bslalg::RbTreeAnchor d_tree; // tree of node objects
237/// Factory d_factory; // allocator for node objects
238///
239/// // NOT IMPLEMENTED
240/// Set(const Set&);
241/// Set& operator=(const Set&);
242///
243/// public:
244/// // CREATORS
245/// Set(const ALLOCATOR& allocator = ALLOCATOR());
246/// // Create an empty set. Optionally specify a 'allocator' used to
247/// // supply memory. If 'allocator' is not specified, a default
248/// // constructed 'ALLOCATOR' object is used.
249///
250/// ~Set();
251/// // Destroy this set.
252///
253/// // MANIPULATORS
254/// void insert(const VALUE& value);
255/// // Insert the specified value into this set.
256///
257/// bool remove(const VALUE& value);
258/// // If 'value' is a member of this set, then remove it and return
259/// // 'true', and return 'false' otherwise.
260///
261/// // ACCESSORS
262/// bool isElement(const VALUE& value) const;
263/// // Return 'true' if the specified 'value' is a member of this set,
264/// // and 'false' otherwise.
265///
266/// int numElements() const;
267/// // Return the number of elements in this set.
268/// };
269/// @endcode
270/// Now, we define the implementation of `Set`:
271/// @code
272/// // CREATORS
273/// template <class VALUE, class ALLOCATOR>
274/// inline
275/// Set<VALUE, ALLOCATOR>::Set(const ALLOCATOR& allocator)
276/// : d_tree()
277/// , d_factory(allocator)
278/// {
279/// }
280///
281/// template <class VALUE, class ALLOCATOR>
282/// inline
283/// Set<VALUE, ALLOCATOR>::~Set()
284/// {
285/// bslalg::RbTreeUtil::deleteTree(&d_tree, &d_factory);
286/// }
287///
288/// // MANIPULATORS
289/// template <class VALUE, class ALLOCATOR>
290/// void Set<VALUE, ALLOCATOR>::insert(const VALUE& value)
291/// {
292/// int comparisonResult;
293/// ValueComparator comparator;
294/// bslalg::RbTreeNode *parent =
295/// bslalg::RbTreeUtil::findUniqueInsertLocation(&comparisonResult,
296/// &d_tree,
297/// comparator,
298/// value);
299/// if (0 != comparisonResult) {
300/// bslalg::RbTreeNode *node = d_factory.createNode(value);
301/// bslalg::RbTreeUtil::insertAt(&d_tree,
302/// parent,
303/// comparisonResult < 0,
304/// node);
305/// }
306/// }
307///
308/// template <class VALUE, class ALLOCATOR>
309/// bool Set<VALUE, ALLOCATOR>::remove(const VALUE& value)
310/// {
311/// bslalg::RbTreeNode *node =
312/// bslalg::RbTreeUtil::find(d_tree, ValueComparator(), value);
313/// if (node) {
314/// bslalg::RbTreeUtil::remove(&d_tree, node);
315/// d_factory.deleteNode(node);
316/// }
317/// return node;
318/// }
319///
320/// // ACCESSORS
321/// template <class VALUE, class ALLOCATOR>
322/// inline
323/// bool Set<VALUE, ALLOCATOR>::isElement(const VALUE& value) const
324/// {
325/// ValueComparator comparator;
326/// return bslalg::RbTreeUtil::find(d_tree, comparator, value);
327/// }
328///
329/// template <class VALUE, class ALLOCATOR>
330/// inline
331/// int Set<VALUE, ALLOCATOR>::numElements() const
332/// {
333/// return d_tree.numNodes();
334/// }
335/// @endcode
336/// Notice that the definition and implementation of `Set` never directly
337/// uses the `TreeNode` type, but instead use it indirectly through
338/// `Comparator`, and `NodeFactory`, and uses it via its base-class
339/// `bslalg::RbTreeNode`.
340///
341/// Finally, we test our `Set`.
342/// @code
343/// Set<int> set;
344/// assert(0 == set.numElements());
345///
346/// set.insert(1);
347/// assert(set.isElement(1));
348/// assert(1 == set.numElements());
349///
350/// set.insert(1);
351/// assert(set.isElement(1));
352/// assert(1 == set.numElements());
353///
354/// set.insert(2);
355/// assert(set.isElement(1));
356/// assert(set.isElement(2));
357/// assert(2 == set.numElements());
358/// @endcode
359/// @}
360/** @} */
361/** @} */
362
363/** @addtogroup bsl
364 * @{
365 */
366/** @addtogroup bslstl
367 * @{
368 */
369/** @addtogroup bslstl_treenode
370 * @{
371 */
372
373#include <bslalg_rbtreenode.h>
374
375
376namespace bslstl {
377
378 // ==============
379 // class TreeNode
380 // ==============
381
382/// This POD-like `class` describes a node suitable for use in a red-black
383/// binary search tree of values of the parameterized `VALUE`. This class
384/// is a "POD-like" to facilitate efficient allocation and use in the
385/// context of a container implementation. In order to meet the essential
386/// requirements of a POD type, this `class` does not define a constructor
387/// or destructor. The manipulator, `value`, returns a modifiable reference
388/// to `d_value` so that it may be constructed in-place by the appropriate
389/// `bsl::allocator_traits` object.
390///
391/// See @ref bslstl_treenode
392template <class VALUE>
394
395 // DATA
396 VALUE d_value; // payload value
397
398 private:
399 // The following functions are not defined because a 'TreeNode' should
400 // never be constructed, destructed, or assigned. The 'd_value' member
401 // should be separately constructed and destroyed using an appropriate
402 // 'bsl::allocator_traits' object.
403
404 TreeNode(); // Declared but not defined
405 TreeNode(const TreeNode&); // Declared but not defined
406 TreeNode& operator=(const TreeNode&); // Declared but not defined
407 ~TreeNode(); // Declared but not defined
408
409 public:
410 // MANIPULATORS
411
412 /// Return a reference providing modifiable access to the `value` of
413 /// this object.
414 VALUE& value();
415
416 // ACCESSORS
417
418 /// Return a reference providing non-modifiable access to the `value` of
419 /// this object.
420 const VALUE& value() const;
421};
422
423// ============================================================================
424// TEMPLATE AND INLINE FUNCTION DEFINITIONS
425// ============================================================================
426
427template <class VALUE>
428inline
430{
431 return d_value;
432}
433
434template <class VALUE>
435inline
436const VALUE& TreeNode<VALUE>::value() const
437{
438 return d_value;
439}
440
441
442} // close package namespace
443
444
445#endif
446
447// ----------------------------------------------------------------------------
448// Copyright 2013 Bloomberg Finance L.P.
449//
450// Licensed under the Apache License, Version 2.0 (the "License");
451// you may not use this file except in compliance with the License.
452// You may obtain a copy of the License at
453//
454// http://www.apache.org/licenses/LICENSE-2.0
455//
456// Unless required by applicable law or agreed to in writing, software
457// distributed under the License is distributed on an "AS IS" BASIS,
458// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
459// See the License for the specific language governing permissions and
460// limitations under the License.
461// ----------------------------- END-OF-FILE ----------------------------------
462
463/** @} */
464/** @} */
465/** @} */
Definition bslalg_rbtreenode.h:376
Definition bslstl_treenode.h:393
VALUE & value()
Definition bslstl_treenode.h:429
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslstl_algorithm.h:82