BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslalg_rbtreeutil.h
Go to the documentation of this file.
1/// @file bslalg_rbtreeutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslalg_rbtreeutil.h -*-C++-*-
8#ifndef INCLUDED_BSLALG_RBTREEUTIL
9#define INCLUDED_BSLALG_RBTREEUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$ $CSID$")
13
14/// @defgroup bslalg_rbtreeutil bslalg_rbtreeutil
15/// @brief Provide a suite of primitive algorithms on red-black trees.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslalg
19/// @{
20/// @addtogroup bslalg_rbtreeutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslalg_rbtreeutil-purpose"> Purpose</a>
25/// * <a href="#bslalg_rbtreeutil-classes"> Classes </a>
26/// * <a href="#bslalg_rbtreeutil-description"> Description </a>
27/// * <a href="#bslalg_rbtreeutil-summary"> Summary </a>
28/// * <a href="#bslalg_rbtreeutil-navigation"> Navigation </a>
29/// * <a href="#bslalg_rbtreeutil-modification"> Modification </a>
30/// * <a href="#bslalg_rbtreeutil-utility"> Utility </a>
31/// * <a href="#bslalg_rbtreeutil-testing"> Testing </a>
32/// * <a href="#bslalg_rbtreeutil-well-formed-rbtreeanchor-objects"> Well-Formed RbTreeAnchor Objects </a>
33/// * <a href="#bslalg_rbtreeutil-the-sentinel-node"> The Sentinel Node </a>
34/// * <a href="#bslalg_rbtreeutil-usage"> Usage </a>
35/// * <a href="#bslalg_rbtreeutil-example-1-creating-and-using-a-tree-with-rbtreeutil"> Example 1: Creating and Using a Tree with RbTreeUtil </a>
36/// * <a href="#bslalg_rbtreeutil-example-2-implementing-a-set-of-integers"> Example 2: Implementing a Set of Integers </a>
37///
38/// # Purpose {#bslalg_rbtreeutil-purpose}
39/// Provide a suite of primitive algorithms on red-black trees.
40///
41/// # Classes {#bslalg_rbtreeutil-classes}
42///
43/// - bslalg::RbTreeUtil: namespace for red-black tree functions
44/// - bslalg::RbTreeUtilTreeProctor: proctor to manage all nodes in a tree
45///
46/// @see bslalg_rbtreenode
47///
48/// # Description {#bslalg_rbtreeutil-description}
49/// This component provides a variety of algorithms that operate
50/// on nodes forming a red-black binary search tree.
51///
52/// This implementation is adapted from Cormen, Leiserson, Rivest,
53/// "Introduction to Algorithms" [MIT Press, 1997].
54///
55/// ## Summary {#bslalg_rbtreeutil-summary}
56///
57///
58/// The following section provides a short synopsis describing observable
59/// behavior of functions supplied in this component. See the full
60/// function-level contract for detailed description.
61///
62/// ### Navigation {#bslalg_rbtreeutil-navigation}
63///
64///
65/// The following algorithms search a tree for a value, or iterate over the
66/// nodes in a tree:
67/// @code
68/// leftmost Return the leftmost node.
69///
70/// rightmost Return the rightmost node.
71///
72/// next Return the next node in an in-order traversal.
73///
74/// previous Return the previous node in an in-order traversal.
75///
76/// find Find the node with the supplied value.
77///
78/// lowerBound Find the first node not less-than the supplied value.
79///
80/// upperBound Find the first node greater than the supplied value.
81/// @endcode
82///
83/// ### Modification {#bslalg_rbtreeutil-modification}
84///
85///
86/// The following algorithms are used in the process of manipulating the
87/// structure of a tree:
88/// @code
89/// copyTree Return a deep-copy of the supplied tree.
90///
91/// deleteTree Delete all the nodes of the supplied tree.
92///
93/// findInsertLocation Find the location where a value may be inserted.
94///
95/// findUniqueInsertLocation
96/// Find the location where a unique value may be inserted.
97///
98/// insert Insert the supplied node into the tree.
99///
100/// insertAt Insert the supplied node at the indicated position.
101///
102/// remove Remove the supplied node from the tree.
103///
104/// swap Swap the contents of two trees.
105/// @endcode
106///
107/// ### Utility {#bslalg_rbtreeutil-utility}
108///
109///
110/// The following algorithms are typically used when implementing higher-level
111/// algorithms (and are not generally used by clients):
112/// @code
113/// isLeftChild Return 'true' if the supplied node is a left child.
114///
115/// isRightChild Return 'true' if the supplied node is a right child.
116///
117/// rotateLeft Perform a counter-clockwise rotation on a node.
118///
119/// rotateRight Perform a clockwise rotation on a node.
120/// @endcode
121///
122/// ### Testing {#bslalg_rbtreeutil-testing}
123///
124///
125/// The following algorithms are used for testing and debugging, and
126/// generally should not be used in production code:
127/// @code
128/// printTreeStructure Print, to a file, the structure of the supplied tree.
129///
130/// validateRbTree Indicate if a tree is a valid red-black tree.
131///
132/// isWellFormed Indicate if the 'RbTreeAnchor' object is well-formed.
133/// @endcode
134///
135/// ## Well-Formed RbTreeAnchor Objects {#bslalg_rbtreeutil-well-formed-rbtreeanchor-objects}
136///
137///
138/// Many of the algorithms defined in this component operate over a complete
139/// tree of nodes, rather than a (possible) subtree referred to through a
140/// pointer to a node. These operations refer to a complete tree through a
141/// `RbTreeAnchor` object, which maintains references to the first, root, and
142/// sentinel nodes for the tree, as well as a count of the number of nodes in
143/// the tree. `RbTreeAnchor` objects supplied to `RbTreeUtil` are frequently
144/// required to meet a series of constraints that are not enforced by the
145/// `RbTreeAnchor` type itself. An `RbTreeAnchor` object meeting these
146/// constraints is said to be "well-formed", and `RbTreeUtil::isWellFormed`
147/// will return `true` for such an object. A `RbTreeAnchor` object is
148/// considered well-formed if all of the following are true:
149///
150/// 1. The root node refers to a valid red-black tree (see `validateRbTree`).
151/// 2. The first node refers to the leftmost node in the tree, or the sentinel
152/// node if the tree is empty.
153/// 3. The node count is the number of nodes in the tree (not counting the
154/// sentinel node).
155/// 4. The sentinel node refers to the root node as its left child, and the
156/// root node refers to the sentinel as its parent.
157/// 5. The root node is either 0 or is colored black.
158///
159/// The manipulation functions of `RbTreeUtil` guarantee that these properties
160/// are maintained for any supplied tree. Note that `RbTreeUtil::isWellFormed`
161/// has linear complexity with respect to the number of nodes in the tree, and
162/// is typically used for debugging and testing purposes only. Note also that
163/// the final condition, that the root node be either 0 or colored black, is
164/// not a canonical requirement of a red-black tree but an additional invariant
165/// enforced by the methods of `RbTreeUtil` to simplify the implementations.
166///
167/// ### The Sentinel Node {#bslalg_rbtreeutil-the-sentinel-node}
168///
169///
170/// The sentinel node is `RbTreeNode` object (unique to an `RbTreeAnchor`
171/// instance) which does not have a value, and provides a fixed end-point for
172/// navigation over the tree (which is distinct from the `rightmost` node of
173/// that tree). The sentinel node will be returned by `next` if the supplied
174/// node is the rightmost node in the tree, as well as by search operations
175/// when no nodes meet the supplied search-criteria. In addition, the sentinel
176/// node may be supplied as a `hint` to `findInsertLocation` and
177/// `findUniqueInsertLocation`, as well as supplied to `previous` to obtain the
178/// rightmost node of a (non-empty) tree.
179///
180/// ## Usage {#bslalg_rbtreeutil-usage}
181///
182///
183/// This section illustrates intended use of this component.
184///
185/// ### Example 1: Creating and Using a Tree with RbTreeUtil {#bslalg_rbtreeutil-example-1-creating-and-using-a-tree-with-rbtreeutil}
186///
187///
188/// This example demonstrates how to create a tree of integers using
189/// `RbTreeUtil`.
190///
191/// First, we define a type `SimpleIntNode` that will represent a nodes in our
192/// tree of integer values. `SimpleIntNode` contains an `int` payload, and
193/// inherits from `RbTreeNode`, allowing it to be operated on by
194/// `RbTreeUtil`.
195/// @code
196/// struct SimpleIntNode : public RbTreeNode {
197/// int d_value;
198/// };
199/// @endcode
200/// Then, we define a comparison function for `SimpleIntNode` objects (note
201/// that we static-cast `RBTreeNode` objects to the actual node type,
202/// `SimpleIntNode`, for comparison purposes):
203/// @code
204/// struct SimpleIntNodeValueComparator {
205/// // This class defines a comparator providing comparison operations
206/// // between 'SimpleIntNode' objects, and 'int' values.
207///
208/// bool operator()(const RbTreeNode& lhs, int rhs) const
209/// {
210/// return static_cast<const SimpleIntNode&>(lhs).d_value < rhs;
211/// }
212///
213/// bool operator()(int lhs, const RbTreeNode& rhs) const
214/// {
215/// return lhs < static_cast<const SimpleIntNode&>(rhs).d_value;
216/// }
217/// };
218///
219/// @endcode
220/// Next, we begin to define the example function that will build a tree of
221/// nodes holding integer values:
222/// @code
223/// void createTestTreeExample()
224/// {
225/// @endcode
226/// Then, within this function, we define a `RbTreeAnchor` object that will
227/// hold the root, first, last, and sentinel nodes of tree, as well a count of
228/// the number of nodes in the tree:
229/// @code
230/// RbTreeAnchor tree;
231/// @endcode
232/// Next, we define an array of 5 `SimpleIntNode` objects that we will insert
233/// into the tree; in practice, nodes are more often allocated on the heap (see
234/// example 2):
235/// @code
236/// const int NUM_NODES = 5;
237/// SimpleIntNode nodes[NUM_NODES];
238/// @endcode
239/// Then, we assign unique values to each of the `nodes`:
240/// @code
241/// for (int i = 0; i < NUM_NODES; ++i) {
242/// nodes[i].d_value = i;
243/// }
244/// @endcode
245/// Now, for each node in the tree, we use `RbTreeUtil` to first find the
246/// location at which the node should be inserted, and then insert that node
247/// into the tree:
248/// @code
249/// for (int i = 0; i < NUM_NODES; ++i) {
250/// int comparisonResult;
251/// SimpleIntNodeValueComparator comparator;
252/// RbTreeNode *insertLocation = RbTreeUtil::findUniqueInsertLocation(
253/// &comparisonResult,
254/// &tree,
255/// comparator,
256/// nodes[i].d_value);
257/// BSLS_ASSERT(comparisonResult);
258/// RbTreeUtil::insertAt(&tree,
259/// insertLocation,
260/// comparisonResult < 0,
261/// &nodes[i]);
262/// }
263/// @endcode
264/// And verify the resulting `tree` holds 5 nodes, and the first node has
265/// the value 0:
266/// @code
267/// assert(5 == tree.numNodes());
268/// assert(0 == static_cast<SimpleIntNode *>(tree.firstNode())->d_value);
269/// @endcode
270/// Finally, we use `RbTreeUtil` to iterate through the nodes of `tree`, and
271/// write the value of each node to the console:
272/// @code
273/// const RbTreeNode *nodeIterator = tree.firstNode();
274/// while (tree.sentinel() != nodeIterator) {
275/// printf("Node value: %d\n",
276/// static_cast<const SimpleIntNode *>(nodeIterator)->d_value);
277/// nodeIterator = RbTreeUtil::next(nodeIterator);
278/// }
279/// }
280/// @endcode
281/// Notice that each of the `RbTreeNode` objects must be @ref static_cast to the
282/// derived type, `SimpleIntNode`, in order to access their values.
283///
284/// The resulting output is displayed on the console:
285/// @code
286/// Node value: 0
287/// Node value: 1
288/// Node value: 2
289/// Node value: 3
290/// Node value: 4
291/// @endcode
292///
293/// ### Example 2: Implementing a Set of Integers {#bslalg_rbtreeutil-example-2-implementing-a-set-of-integers}
294///
295///
296/// This example demonstrates how to use `RbTreeUtil` to implement a simple
297/// container holding a set of (unique) integer values as a red-black binary
298/// search tree.
299///
300/// Before defining the `IntSet` class, we need to define a series of
301/// associated helper types:
302/// 1. The node-type, for the nodes in the tree.
303/// 2. An iterator, for iterating over nodes in the tree.
304/// 3. A comparison functor for comparing nodes and values.
305/// 4. A factory for creating and destroying nodes.
306///
307/// First, we define a type, `IntSet_Node`, that will represent the nodes in our
308/// tree of integer values; it contains an `int` payload, and inherits from
309/// `RbTreeNode`, allowing it to be operated on by `RbTreeUtil` (note that the
310/// underscore "_" indicates that this type is a private implementation type of
311/// `IntSet`, and not for use by clients of `IntSet`):
312/// @code
313/// class IntSet_Node : public RbTreeNode {
314/// // A red-black tree node containing an integer data-value.
315///
316/// // DATA
317/// int d_value; // actual value represented by the node
318///
319/// public:
320/// // MANIPULATORS
321/// int& value() { return d_value; }
322/// // Return a reference providing modifiable access to the 'value' of
323/// // this object.
324///
325/// // ACCESSORS
326/// const int& value() const { return d_value; }
327/// // Return a reference providing non-modifiable access to the
328/// // 'value' of this object.
329/// };
330/// @endcode
331/// Then, we define a iterator over `IntSet_Node` objects. We use the `next`
332/// function of `RbTreeUtil` to increment the iterator (note that, for
333/// simplicity, this iterator is *not* a fully STL compliant iterator
334/// implementation):
335/// @code
336/// class IntSetConstIterator {
337/// // This class defines an STL-style iterator over a non-modifiable tree
338/// // of 'IntSet_Node' objects.
339///
340/// // DATA
341/// const RbTreeNode *d_node_p; // current location of this iterator
342///
343/// public:
344/// IntSetConstIterator() : d_node_p(0) {}
345/// // Create an iterator that does not refer to a node.
346///
347/// IntSetConstIterator(const RbTreeNode *node) : d_node_p(node) {}
348/// // Create an iterator referring to the specified 'node'.
349///
350/// // IntSetConstIterator(const IntSetConstIterator&) = default;
351///
352/// // MANIPULATOR
353/// // IntSetConstIterator& operator=(const IntSetConstIterator&) = default;
354///
355/// @endcode
356/// Here, we implement the prefix-increment operator using the `next` function
357/// of 'RbTreeUtil:
358/// @code
359/// IntSetConstIterator& operator++()
360/// // Advance this iterator to the subsequent value it the 'IntSet',
361/// // and return a reference providing modifiable access to this
362/// // iterator. The behavior is undefined unless this iterator
363/// // refers to a element in an 'IntSet'.
364/// {
365/// d_node_p = RbTreeUtil::next(d_node_p);
366/// return *this;
367/// }
368///
369/// // ACCESSORS
370/// const int& operator*() const
371/// // Return a reference providing non-modifiable access to the value
372/// // referred to by this iterator.
373/// {
374/// return static_cast<const IntSet_Node *>(d_node_p)->value();
375/// }
376///
377/// const int *operator->() const
378/// // Return an address providing non-modifiable access to the value
379/// // referred to by this iterator.
380/// {
381/// return &(static_cast<const IntSet_Node *>(d_node_p)->value());
382/// }
383///
384/// const IntSet_Node *nodePtr() const
385/// // Return the address of the non-modifiable int-set node referred
386/// // to by this iterator
387/// {
388/// return static_cast<const IntSet_Node *>(d_node_p);
389/// }
390/// };
391///
392/// // FREE OPERATORS
393/// bool operator==(const IntSetConstIterator &lhs,
394/// const IntSetConstIterator &rhs)
395/// // Return 'true' if the 'lhs' and 'rhs' objects have the same value,
396/// // and 'false' otherwise. Two 'IntSetConstIterator' objects have the
397/// // same value if they refer to the same node.
398/// {
399/// return lhs.nodePtr() == rhs.nodePtr();
400/// }
401///
402/// bool operator!=(const IntSetConstIterator &lhs,
403/// const IntSetConstIterator &rhs)
404/// // Return 'true' if the specified 'lhs' and 'rhs' objects do not have
405/// // the same value, and 'false' otherwise. Two 'IntSetConstIterator'
406/// // objects do not have the same value if they refer to different nodes.
407/// {
408/// return lhs.nodePtr() != rhs.nodePtr();
409/// }
410/// @endcode
411/// Next, we define a comparison functor for `IntSet_Node` objects, which will
412/// be supplied to `RbTreeUtil` functions that must compare nodes with values
413/// -- i.e., those with a `NODE_VALUE_COMPARATOR` template parameter (e.g.,
414/// `find` and `findInsertLocation`):
415/// @code
416/// struct IntSet_NodeValueComparator {
417/// // This class defines a comparator providing comparison operations
418/// // between 'IntSet_Node' objects, and 'int' values.
419///
420/// bool operator()(const RbTreeNode& lhs, int rhs) const
421/// {
422/// return static_cast<const IntSet_Node&>(lhs).value() < rhs;
423/// }
424///
425/// bool operator()(int lhs, const RbTreeNode& rhs) const
426/// {
427/// return lhs < static_cast<const IntSet_Node&>(rhs).value();
428/// }
429/// };
430/// @endcode
431/// Notice that we static-cast `RbTreeNode` objects to the actual node type,
432/// `IntSet_Node` for comparison.
433///
434/// Next, we define a factory for creating and destroying `IntSet_Node`
435/// objects. This factory provides the operations `createNode` and
436/// `deleteNode`. These operations will be used directly by our container
437/// implementation, and they are also required by `RbTreeUtil` functions taking
438/// a `FACTORY` template parameter (e.g., `copyTree` and `deleteTree`):
439/// @code
440/// class IntSet_NodeFactory {
441/// // This class defines a creator object, that when invoked, creates a
442/// // new 'IntSet_Node' (either from a int value, or an existing
443/// // 'IntSet_Node' object) using the allocator supplied at construction.
444///
445/// bslma::Allocator *d_allocator_p; // allocator, (held, not owned)
446///
447/// public:
448///
449/// IntSet_NodeFactory(bslma::Allocator *allocator)
450/// : d_allocator_p(allocator)
451/// {
452/// BSLS_ASSERT_SAFE(allocator);
453/// }
454///
455/// RbTreeNode *createNode(int value) const
456/// {
457/// IntSet_Node *newNode = new (*d_allocator_p) IntSet_Node;
458/// newNode->value() = value;
459/// return newNode;
460/// }
461///
462/// RbTreeNode *createNode(const RbTreeNode& node) const
463/// {
464/// IntSet_Node *newNode = new (*d_allocator_p) IntSet_Node;
465/// newNode->value() = static_cast<const IntSet_Node&>(node).value();
466/// return newNode;
467/// }
468/// void deleteNode(RbTreeNode *node) const
469/// {
470/// d_allocator_p->deleteObject(static_cast<IntSet_Node *>(node));
471/// }
472///
473/// bslma::Allocator *allocator() const
474/// {
475/// return d_allocator_p;
476/// }
477/// };
478/// @endcode
479/// Then, having defined the requisite helper types, we define the public
480/// interface for our `IntSet` type. Note that for the purposes of
481/// illustrating the use of `RbTreeUtil` a number of simplifications have been
482/// made. For example, this implementation provides only a minimal set of
483/// critical operations, and it does not use the empty base-class optimization
484/// for the comparator, etc. We define the interface of `IntSet` as follows:
485/// @code
486/// class IntSet {
487/// // This class implements a set of (unique) 'int' values.
488///
489/// // DATA
490/// RbTreeAnchor d_tree; // root, first, and last tree
491/// // nodes
492///
493/// IntSet_NodeValueComparator
494/// d_comparator; // comparison functor for ints
495///
496/// IntSet_NodeFactory d_nodeFactory; // factory for creating and
497/// // destroying nodes
498///
499/// // FRIENDS
500/// friend bool operator==(const IntSet& lhs, const IntSet& rhs);
501///
502/// public:
503/// // PUBLIC TYPES
504/// typedef IntSetConstIterator const_iterator;
505///
506/// // CREATORS
507/// IntSet(bslma::Allocator *basicAllocator = 0);
508/// // Create a empty 'IntSet'. Optionally specify a 'basicAllocator'
509/// // used to supply memory. If 'basicAllocator' is 0, the currently
510/// // installed default allocator is used.
511///
512/// IntSet(const IntSet& original, bslma::Allocator *basicAllocator = 0);
513/// // Create a 'IntSet' object having the same value as the specified
514/// // 'original' object. If 'basicAllocator' is 0, the currently
515/// // installed default allocator is used.
516///
517/// ~IntSet();
518/// // Destroy this object.
519///
520/// // MANIPULATORS
521/// IntSet& operator=(const IntSet& rhs);
522/// // Assign to this object the value of the specified 'rhs' object,
523/// // and return a reference providing modifiable access to this
524/// // object.
525///
526/// const_iterator insert(int value);
527/// // If the specified 'value' is not already a member of this set,
528/// // insert it into this set, returning an iterator referring to the
529/// // newly added value, and return an iterator referring to the
530/// // existing instance of 'value' in this set, with no other effect,
531/// // otherwise.
532///
533/// const_iterator erase(const_iterator iterator);
534/// // Remove the value referred to by the specified 'iterator' from
535/// // this set, and return an iterator referring to the value
536/// // subsequent to 'iterator' (prior to its removal). The behavior
537/// // is undefined unless 'iterator' refers to a valid value in this
538/// // set.
539///
540/// void clear();
541/// // Remove all the elements from this set.
542///
543/// void swap(IntSet& other);
544/// // Efficiently exchange the value of this object with the value of
545/// // the specified 'other' object.
546///
547/// // ACCESSORS
548/// const_iterator begin() const;
549/// // Return an iterator referring leftmost node value in this set, or
550/// // 'end()' if this set is empty.
551///
552/// const_iterator end() const;
553/// // Return an iterator referring to the value one past the
554/// // rightmost value in this set.
555///
556/// const_iterator find(int value) const;
557/// // Return a iterator referring to the specified 'value' in this
558/// // set, or 'end()' if 'value' is not a member of this set.
559///
560/// int size() const;
561/// // Return the number of elements in this set.
562/// };
563///
564/// // FREE OPERATORS
565/// bool operator==(const IntSet& lhs, const IntSet& rhs);
566/// // Return 'true' if the 'lhs' and 'rhs' objects have the same value,
567/// // and 'false' otherwise. Two 'IntSet' objects have the same value if
568/// // they contain the same number of elements, and if for each element
569/// // in 'lhs' there is a corresponding element in 'rhs' with the same
570/// // value.
571///
572/// bool operator!=(const IntSet& lhs, const IntSet& rhs);
573/// // Return 'true' if the specified 'lhs' and 'rhs' objects do not have
574/// // the same value, and 'false' otherwise. Two 'IntSet' objects do not
575/// // have the same value if they differ in the number of elements they
576/// // contain, or if for any element in 'lhs' there is not a
577/// // corresponding element in 'rhs' with the same value.
578/// @endcode
579/// Now, we implement the methods of `IntSet` using `RbTreeUtil` and the
580/// helper types we defined earlier:
581/// @code
582/// // CREATORS
583/// IntSet::IntSet(bslma::Allocator *basicAllocator)
584/// : d_tree()
585/// , d_comparator()
586/// , d_nodeFactory(bslma::Default::allocator(basicAllocator))
587/// {
588/// }
589///
590/// IntSet::IntSet(const IntSet& original, bslma::Allocator *basicAllocator)
591/// : d_tree()
592/// , d_comparator()
593/// , d_nodeFactory(bslma::Default::allocator(basicAllocator))
594/// {
595/// if (original.d_tree.rootNode()) {
596/// RbTreeUtil::copyTree(&d_tree, original.d_tree, &d_nodeFactory);
597/// }
598/// }
599///
600/// IntSet::~IntSet()
601/// {
602/// clear();
603/// }
604///
605/// // MANIPULATORS
606/// IntSet& IntSet::operator=(const IntSet& rhs)
607/// {
608/// IntSet temp(rhs, d_nodeFactory.allocator());
609/// swap(temp);
610/// return *this;
611/// }
612///
613/// @endcode
614/// Here, we implement `insert` by using the `RbTreeUtil` algorithms
615/// `findUniqueInsertLocation` and `insertAt`:
616/// @code
617/// IntSet::const_iterator IntSet::insert(int value)
618/// {
619/// // To insert a value into the tree, we first find the location where
620/// // the node would be added, and whether 'value' is unique. If 'value'
621/// // is not unique we do not want to incur the expense of allocating
622/// // memory for a node.
623///
624/// int comparisonResult;
625/// RbTreeNode *insertLocation =
626/// RbTreeUtil::findUniqueInsertLocation(&comparisonResult,
627/// &d_tree,
628/// d_comparator,
629/// value);
630/// if (0 == comparisonResult) {
631/// // 'value' already exists in 'd_tree'.
632///
633/// return const_iterator(insertLocation); // RETURN
634/// }
635///
636/// // If 'value' is unique, we create a new node and supply it to
637/// // 'insertAt', along with the tree location returned by
638/// // 'findUniqueInsertLocation'.
639///
640/// RbTreeNode *newNode = d_nodeFactory.createNode(value);
641/// RbTreeUtil::insertAt(&d_tree,
642/// insertLocation,
643/// comparisonResult < 0,
644/// newNode);
645/// return const_iterator(newNode);
646/// }
647///
648/// IntSet::const_iterator IntSet::erase(const_iterator iterator)
649/// {
650/// BSLS_ASSERT(iterator.nodePtr());
651/// IntSet_Node *node = const_cast<IntSet_Node *>(iterator.nodePtr());
652///
653/// // Before removing the node, we first find the subsequent node to which
654/// // we will return an iterator.
655///
656/// RbTreeNode *next = RbTreeUtil::next(node);
657/// RbTreeUtil::remove(&d_tree, node);
658/// d_nodeFactory.deleteNode(node);
659/// return const_iterator(next);
660/// }
661///
662/// void IntSet::clear()
663/// {
664/// if (d_tree.rootNode()) {
665/// RbTreeUtil::deleteTree(&d_tree, &d_nodeFactory);
666/// }
667/// }
668///
669/// void IntSet::swap(IntSet& other) {
670/// BSLS_ASSERT(d_nodeFactory.allocator() ==
671/// other.d_nodeFactory.allocator());
672/// RbTreeUtil::swap(&d_tree, &other.d_tree);
673/// }
674///
675/// // ACCESSORS
676/// IntSet::const_iterator IntSet::begin() const
677/// {
678/// return const_iterator(d_tree.firstNode());
679/// }
680///
681/// IntSet::const_iterator IntSet::end() const
682/// {
683/// return const_iterator(d_tree.sentinel());
684/// }
685///
686/// IntSet::const_iterator IntSet::find(int value) const
687/// {
688/// return const_iterator(RbTreeUtil::find(d_tree, d_comparator, value));
689/// }
690///
691/// int IntSet::size() const
692/// {
693/// return d_tree.numNodes();
694/// }
695/// @endcode
696/// Finally, we implement the free operators on `IntSet`:
697/// @code
698/// // FREE OPERATORS
699/// bool operator==(const IntSet& lhs, const IntSet& rhs)
700/// {
701/// return bslalg::RangeCompare::equal(lhs.begin(),
702/// lhs.end(),
703/// lhs.size(),
704/// rhs.begin(),
705/// rhs.end(),
706/// rhs.size());
707/// }
708///
709/// bool operator!=(const IntSet& lhs, const IntSet& rhs)
710/// {
711/// return !(lhs == rhs);
712/// }
713/// @endcode
714/// @}
715/** @} */
716/** @} */
717
718/** @addtogroup bsl
719 * @{
720 */
721/** @addtogroup bslalg
722 * @{
723 */
724/** @addtogroup bslalg_rbtreeutil
725 * @{
726 */
727
728#include <bslscm_version.h>
729
730#include <bslalg_rbtreeanchor.h>
731#include <bslalg_rbtreenode.h>
732
734
735#include <bslmf_movableref.h>
736
737#include <bsls_assert.h>
738
739#include <stdio.h>
740
741
742namespace bslalg {
743
744 // ================
745 // class RbTreeUtil
746 // ================
747
748/// This `struct` provides a namespace for a suite of utility functions that
749/// operate on elements of type `RbTreeNode`.
750///
751/// Each method of this class, other than `copyTree`, provides the
752/// *no-throw* exception guarantee if the client-supplied comparator
753/// provides the no-throw guarantee, and provides the *strong* guarantee
754/// otherwise (see @ref bsldoc_glossary ). `copyTree` provides the *strong*
755/// guarantee.
756///
757/// See @ref bslalg_rbtreeutil
759
760 // CLASS METHODS
761 // Navigation
762
763 /// Return the address of the leftmost node in the specified `subtree`,
764 /// and `subtree` if `subtree` has no left child.
765 ///
766 /// \pre The behavior is undefined unless `0 != subtree`, and `subtree` refers to a valid binary tree.
767 ///
768 /// \note Note that the value held by the returned node will not
769 /// compare greater than that of any other node in `subtree` (as
770 /// determined by the comparator used to organize the red-black subtree
771 /// data).
772 static const RbTreeNode *leftmost(const RbTreeNode *subtree);
773 static RbTreeNode *leftmost( RbTreeNode *subtree);
774
775 /// Return the address of the rightmost node in the specified
776 /// `subtree`, and `subtree` if `subtree` has no right child.
777 ///
778 /// \pre The behavior is undefined unless `0 != subtree` and `subtree` refers to a valid binary tree.
779 ///
780 /// \note Note that the value held by the returned node
781 /// will not compare less than that of any other node in `subtree` (as
782 /// determined by the comparator used to organize the red-black subtree
783 /// data).
784 static const RbTreeNode *rightmost(const RbTreeNode *subtree);
785 static RbTreeNode *rightmost( RbTreeNode *subtree);
786
787 /// Return the address of the node that follows the specified `node` in
788 /// an in-order traversal of the binary tree to which `node` belongs, or
789 /// the tree's sentinel node if `node` is the rightmost node in the tree.
790 ///
791 /// \pre The behavior is undefined unless `node` is a member of a valid binary tree, and is not a sentinel node.
792 ///
793 /// \note Note that if the
794 /// tree does not contain duplicate values, then the returned node will
795 /// have the smallest value greater than that of `node`.
796 static const RbTreeNode *next(const RbTreeNode *node);
797 static RbTreeNode *next( RbTreeNode *node);
798
799 /// Return the address of the node that precedes the specified `node` in
800 /// an in-order traversal of the binary tree to which `node` belongs, or
801 /// the tree's rightmost node if `node` is the sentinel node of the tree.
802 ///
803 /// \pre The behavior is undefined unless or `node` is a non-leftmost member of a valid binary tree or is a sentinel `node`.
804 ///
805 /// \note Note that if
806 /// the tree does not contain duplicate values, then the returned node
807 /// will have the largest value less than that of `node`.
808 static const RbTreeNode *previous(const RbTreeNode *node);
809 static RbTreeNode *previous( RbTreeNode *node);
810
811 // Search
812
813 /// Return the address of the leftmost node holding the specified
814 /// `value` in the specified `tree` (organized according to the
815 /// specified `comparator) if found, and return `tree.sentinel()'
816 /// otherwise. `COMPARATOR` shall be a functor providing two methods
817 /// that can be called as if they had the following signatures:
818 /// @code
819 /// bool operator()(const RbTreeNode&, const VALUE&) const;
820 /// bool operator()(const VALUE&, const RbTreeNode&) const;
821 /// @endcode
822 ///
823 /// \pre The behavior is undefined unless `comparator` provides a strict
824 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed
825 /// (see `isWellFormed`).
826 template <class NODE_VALUE_COMPARATOR, class VALUE>
827 static const RbTreeNode *find(const RbTreeAnchor& tree,
828 NODE_VALUE_COMPARATOR& comparator,
829 const VALUE& value);
830 template <class NODE_VALUE_COMPARATOR, class VALUE>
831 static RbTreeNode *find(RbTreeAnchor& tree,
832 NODE_VALUE_COMPARATOR& comparator,
833 const VALUE& value);
834
835 /// Return the address of the leftmost node holding the smallest
836 /// value greater-than or equal-to `value` in the specified `tree`
837 /// (organized according to the specified 'comparator) if found, and
838 /// return `tree.sentinel()` if `value` is greater-than the rightmost
839 /// node in `tree`. `COMPARATOR` shall be a functor providing two
840 /// methods that can be called as if they had the following signatures:
841 /// @code
842 /// bool operator()(const RbTreeNode&, const VALUE&) const;
843 /// bool operator()(const VALUE&, const RbTreeNode&) const;
844 /// @endcode
845 ///
846 /// \pre The behavior is undefined unless `comparator` provides a strict
847 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed (`isWellFormed`).
848 ///
849 /// \note Note that this function returns the *first*
850 /// position before which `value` could be inserted into `tree` while
851 /// preserving its ordering.
852 template <class NODE_VALUE_COMPARATOR, class VALUE>
853 static const RbTreeNode *lowerBound(const RbTreeAnchor& tree,
854 NODE_VALUE_COMPARATOR& comparator,
855 const VALUE& value);
856 template <class NODE_VALUE_COMPARATOR, class VALUE>
857 static RbTreeNode *lowerBound(RbTreeAnchor& tree,
858 NODE_VALUE_COMPARATOR& comparator,
859 const VALUE& value);
860
861 /// Return the address of the leftmost node holding the smallest
862 /// value greater-than `value` in the specified `tree` (organized
863 /// according to the specified 'comparator) if found, and return
864 /// `tree.sentinel()` if `value` is greater-than or equal-to the
865 /// rightmost node in `tree`. `COMPARATOR` shall be a functor
866 /// providing two methods that can be called as if they had the
867 /// following signatures:
868 /// @code
869 /// bool operator()(const RbTreeNode&, const VALUE&) const;
870 /// bool operator()(const VALUE&, const RbTreeNode&) const;
871 /// @endcode
872 ///
873 /// \pre The behavior is undefined unless `comparator` provides a strict
874 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed (`isWellFormed`).
875 ///
876 /// \note Note that this function returns the *last*
877 /// position before which `value` could be inserted into `tree` while
878 /// preserving its ordering.
879 template <class NODE_VALUE_COMPARATOR, class VALUE>
880 static const RbTreeNode *upperBound(const RbTreeAnchor& tree,
881 NODE_VALUE_COMPARATOR& comparator,
882 const VALUE& value);
883 template <class NODE_VALUE_COMPARATOR, class VALUE>
884 static RbTreeNode *upperBound(RbTreeAnchor& tree,
885 NODE_VALUE_COMPARATOR& comparator,
886 const VALUE& value);
887
888 // Modification
889
890 /// Load, into the specified `result`, a collection of newly created
891 /// nodes having the same red-black tree structure as that of the
892 /// specified `original` tree, where each node in the returned tree is
893 /// created by invoking `nodeFactory->createNode` on the corresponding
894 /// `original` node; if an exception occurs, use
895 /// `nodeFactory->deleteNode` to destroy any newly created nodes, and
896 /// propagate the exception to the caller (i.e., this operation provides
897 /// the *strong* exception guarantee). `FACTORY` shall be a class
898 /// providing two methods that can be called as if they had the
899 /// following signatures:
900 /// @code
901 /// RbTreeNode *createNode(const RbTreeNode&);
902 /// void deleteNode(RbTreeNode *);
903 /// @endcode
904 ///
905 /// \pre The behavior is undefined unless `result` is an empty tree,
906 /// `original` is a well-formed (see `isWellFormed`), and
907 /// `nodeFactory->deleteNode` does not throw.
908 template <class FACTORY>
909 static void copyTree(RbTreeAnchor *result,
910 const RbTreeAnchor& original,
911 FACTORY *nodeFactory);
912
913 /// Load into the specified `result`, using the specified `nodeFactory`
914 /// to create and delete nodes, a collection of newly created nodes with
915 /// the same (red-black) tree structure as that of the specified
916 /// `original` tree, which uses the specified `originalNodeFactory` to
917 /// create and delete nodes, where the `value` attribute of each node in
918 /// `result` is constructed from explicitly moving the `value` attribute
919 /// of the corresponding node in `original`. `original` is left in a
920 /// valid but unspecified state. If an exception occurs, both `result`
921 /// and `original` are left in a valid but unspecified state.
922 ///
923 /// \pre The behavior is undefined unless `result` is an empty tree, `original`
924 /// is well-formed (see `isWellFormed`), and `nodeFactory->deleteNode`
925 /// and `originalNodeFactory->deleteNode` do not throw.
926 template <class FACTORY>
927 static void moveTree(RbTreeAnchor *result,
928 RbTreeAnchor *original,
929 FACTORY *nodeFactory,
930 FACTORY *originalNodeFactory);
931
932 /// Call `nodeFactory->deleteNode` on each node in `tree` and reset
933 /// `tree` to an empty state. `FACTORY` shall be a class providing a
934 /// method that can be called as if it has the following signature:
935 /// @code
936 /// void deleteNode(RbTreeNode *);
937 /// @endcode
938 ///
939 /// \pre The behavior is undefined unless `tree` is a valid binary tree, and
940 /// `nodeFactory->deleteNode` does not throw.
941 template <class FACTORY>
942 static void deleteTree(RbTreeAnchor *tree, FACTORY *nodeFactory);
943
944 /// Return the address of the node that would be the parent a node
945 /// holding the specified `value`, if it were to be inserted into the
946 /// specified `tree` (organized according to the specified
947 /// `comparator`), and load, into the specified `insertAsLeftChildFlag`,
948 /// `true` if `value` would be held as the returned node's left child,
949 /// and `false` if `value` would be held in its right child, unless
950 /// `tree` is empty, in which case return `tree->sentinel()` and load
951 /// `true` into `insertAsLeftChildFlag`. Optionally specify a `hint`,
952 /// suggesting a node in `tree` that might be the immediate successor of
953 /// a node holding `value` if it were to be inserted into `tree`. If
954 /// the supplied `hint` is the successor, this operation will take
955 /// amortized constant time; otherwise, it will take O(log(N))
956 /// operations, where N is the number of nodes in the tree. If a node
957 /// holding `value` is inserted as suggested by this method, the
958 /// resulting tree will be an ordered binary tree, but may require
959 /// rebalancing (and re-coloring) to again be a valid red-black tree.
960 /// `COMPARATOR` shall be a functor providing two methods that can be
961 /// called as if they have the following signatures:
962 /// @code
963 /// bool operator()(const RbTreeNode&, const VALUE&) const;
964 /// bool operator()(const VALUE&, const RbTreeNode&) const;
965 /// @endcode
966 ///
967 /// \pre The behavior is undefined unless `comparator` provides a strict
968 /// weak ordering on objects of type `VALUE`, `tree` is well-formed
969 /// (see `isWellFormed`), and `hint`, if supplied, is a node in `tree`.
970 ///
971 /// \note Note that this operation is intended to be used in conjunction with
972 /// the `insertAt` method.
973 template <class NODE_VALUE_COMPARATOR, class VALUE>
975 bool *insertAsLeftChildFlag,
976 RbTreeAnchor *tree,
977 NODE_VALUE_COMPARATOR& comparator,
978 const VALUE& value);
979 template <class NODE_VALUE_COMPARATOR, class VALUE>
981 bool *insertAsLeftChildFlag,
982 RbTreeAnchor *tree,
983 NODE_VALUE_COMPARATOR& comparator,
984 const VALUE& value,
985 RbTreeNode *hint);
986
987 /// Return the address of the node holding the specified `value` in the
988 /// specified `tree` (organized according to the specified `comparator`)
989 /// if found, and the address of the node that would be the parent for
990 /// `value` otherwise; load, into the specified `comparisonResult`, 0 if
991 /// `value` is found, a negative number if `value` would be held in its
992 /// left child, and a positive number if `value` would be held in its
993 /// right child, unless `tree` is empty, in which case load a negative
994 /// number into `comparisonResult` and return `tree->sentinel()`.
995 /// Optionally specify a `hint`, suggesting a node in `tree` that might
996 /// be the immediate successor of a node holding `value` if it were to
997 /// be inserted into `tree`. If the supplied `hint` is the successor,
998 /// this operation will take amortized constant time; otherwise, it will
999 /// take O(log(N)) operations, where N is the number of nodes in the
1000 /// tree. If a node holding `value` is inserted as suggested by this
1001 /// method, the resulting tree will be an ordered binary tree, but may
1002 /// require rebalancing (and re-coloring) to again be a valid red-black
1003 /// tree. `COMPARATOR` shall be a functor providing two methods that
1004 /// can be called as if they have the following signatures:
1005 /// @code
1006 /// bool operator()(const RbTreeNode&, const VALUE&) const;
1007 /// bool operator()(const VALUE&, const RbTreeNode&) const;
1008 /// @endcode
1009 ///
1010 /// \pre The behavior is undefined unless `comparator` provides a strict
1011 /// weak ordering on objects of type `VALUE`, `tree` is well-formed
1012 /// (see `isWellFormed`), and `hint`, if supplied, is a node in `tree`.
1013 ///
1014 /// \note Note that this operation is intended to be used in conjunction with
1015 /// the `insertAt` method.
1016 template <class NODE_VALUE_COMPARATOR, class VALUE>
1018 int *comparisonResult,
1019 RbTreeAnchor *tree,
1020 NODE_VALUE_COMPARATOR& comparator,
1021 const VALUE& value);
1022 template <class NODE_VALUE_COMPARATOR, class VALUE>
1024 int *comparisonResult,
1025 RbTreeAnchor *tree,
1026 NODE_VALUE_COMPARATOR& comparator,
1027 const VALUE& value,
1028 RbTreeNode *hint);
1029
1030 /// Insert the specified `newNode` into the specified `tree`, organized
1031 /// according to the specified `comparator`. The resulting tree will
1032 /// be well-formed (see `isWellFormed`). `NODE_COMPARATOR` shall be a
1033 /// functor providing a method that can be called as if it had the
1034 /// following signatures:
1035 /// @code
1036 /// bool operator()(const RbTreeNode&, const RbTreeNode&) const;
1037 /// @endcode
1038 ///
1039 /// \pre The behavior is undefined unless `comparator` provides a strict
1040 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed
1041 /// (see `isWellFormed`).
1042 template <class NODE_COMPARATOR>
1043 static void insert(RbTreeAnchor *tree,
1044 const NODE_COMPARATOR& comparator,
1045 RbTreeNode *newNode);
1046
1047 /// Insert the specified `newNode` into the specified `tree` as either
1048 /// the left or right child of the specified `parentNode`, as indicated
1049 /// by the specified `leftChildFlag`, and then rebalance the tree so
1050 /// that it is a valid red-black tree (see `validateRbTree`).
1051 ///
1052 /// \pre The behavior is undefined unless `tree` is well-formed (see
1053 /// `isWellFormed`), and, if `tree` is empty, `parentNode` is
1054 /// `tree->sentinel()` and `leftChildFlag` is `true`, or, if `tree` is
1055 /// not empty, `parentNode` is a node in `tree` whose left or right
1056 /// child (as indicated by `leftChildFlag`) is 0 where if `newNode` were
1057 /// attached as that child (without rebalancing) `tree` would still
1058 /// form an ordered binary tree (though not necessarily a valid red-black tree).
1059 ///
1060 /// \note Note that this operation is intended to be used in
1061 /// conjunction with the `findInsertLocation` or
1062 /// `findUniqueInsertLocation` methods.
1063 static void insertAt(RbTreeAnchor *tree,
1064 RbTreeNode *parentNode,
1065 bool leftChildFlag,
1066 RbTreeNode *newNode);
1067
1068 /// Remove the specified `node` from the specified `tree`, and then
1069 /// rebalance `tree` so that it again forms a valid red-black tree (see `validateRbTree`).
1070 ///
1071 /// \pre The behavior is undefined unless `tree` is
1072 /// well-formed (see `isWellFormed`).
1073 static void remove(RbTreeAnchor *tree, RbTreeNode *node);
1074
1075 /// Efficiently exchange the nodes in the specified `a` tree with the
1076 /// nodes in the specified `b` tree. This method provides the no-throw exception-safety guarantee.
1077 ///
1078 /// \pre The behavior is undefined unless `a`
1079 /// and `b` are well-formed (see `isWellFormed`).
1080 static void swap(RbTreeAnchor *a, RbTreeAnchor *b);
1081
1082 // Utility
1083
1084 /// Return `true` if the specified `node` is the left child of its parent, and `false` otherwise.
1085 ///
1086 /// \pre The behavior is undefined unless
1087 /// `0 != node->parent()`.
1088 static bool isLeftChild(const RbTreeNode *node);
1089
1090 /// Return `true` if the specified `node` is the left child of its parent, and `false` otherwise.
1091 ///
1092 /// \pre The behavior is undefined unless
1093 /// `0 != node->parent()`.
1094 static bool isRightChild(const RbTreeNode *node);
1095
1096 /// Perform counter-clockwise rotation on the specified `node`: Rotate
1097 /// the node's right child (the pivot) to be the node's parent, and
1098 /// attach the pivot's left child as the node's right child.
1099 /// @code
1100 /// (node) (pivot)
1101 /// / \ / \.
1102 /// a (pivot) ---> (node) c
1103 /// / \ / \.
1104 /// b c a b
1105 /// @endcode
1106 ///
1107 /// \pre The behavior is undefined unless `node->rightChild()` is not 0,
1108 /// `node->parent()` is not 0, and node's parent refers to `node` as one of its children.
1109 ///
1110 /// \note Note that this operation maintains the ordering
1111 /// of the subtree rooted at `node`. Also note this operation will
1112 /// successfully rotate the root node of an unbalanced, but otherwise
1113 /// well-formed, tree referred to by a `RbTreeAnchor` object (see
1114 /// `isWellFormed`) because the parent of the root node is the tree's
1115 /// sentinel node (i.e., not 0), which refers to the root node as its
1116 /// left child, and an `RbTreeAnchor` object returns the left child of
1117 /// the sentinel node as the root of the tree.
1118 static void rotateLeft(RbTreeNode *node);
1119
1120 /// Perform clockwise rotation on the specified `node`: Rotate the
1121 /// node's left child (the pivot) to be the node's parent, and attach
1122 /// the pivot's right child as the node's left child.
1123 /// @code
1124 /// (node) (pivot)
1125 /// / \ / \.
1126 /// (pivot) c ---> a (node)
1127 /// / \ / \.
1128 /// a b b c
1129 /// @endcode
1130 ///
1131 /// \pre The behavior is undefined unless `node->leftChild()` is not 0,
1132 /// `node->parent()` is not 0, and node's parent refers to `node` as one of its children.
1133 ///
1134 /// \note Note that this operation maintains the ordering
1135 /// of the subtree rooted at `node`. Also note this operation will
1136 /// successfully rotate the root node of an unbalanced, but otherwise
1137 /// well-formed, tree referred to by a `RbTreeAnchor` object (see
1138 /// `isWellFormed`) because the parent of the root node is the tree's
1139 /// sentinel node (i.e., not 0), which refers to the root node as its
1140 /// left child, and an `RbTreeAnchor` object returns the left child of
1141 /// the sentinel node as the root of the tree.
1142 static void rotateRight(RbTreeNode *node);
1143
1144 // Testing
1145
1146 /// Write a description of the structure of the specified `subtree` to
1147 /// the specified output `file` in a human-readable format, using the
1148 /// specified `printValueCallback` to render the value of each node.
1149 /// Optionally specify an initial indentation `level`, whose absolute
1150 /// value is incremented recursively for nested objects. If `level` is
1151 /// specified, optionally specify `spacesPerLevel`, whose absolute value
1152 /// indicates the number of spaces per indentation level for this and
1153 /// all of its nested objects. If `level` is negative, suppress
1154 /// indentation of the first line. If `spacesPerLevel` is negative,
1155 /// format the entire output on one line, suppressing all but the
1156 /// initial indentation (as governed by `level`).
1157 ///
1158 /// \pre The behavior is undefined unless `node` is 0, or the root of a valid binary tree.
1159 ///
1160 /// \note Note that the implementation of this function is recursive
1161 /// and expensive to perform, it is intended for debugging purposes
1162 /// only. Also note that the format is not fully specified, and can
1163 /// change without notice.
1165 FILE *file,
1166 const RbTreeNode *subtree,
1167 void (*printNodeValueCallback)(FILE *, const RbTreeNode *),
1168 int level = 0,
1169 int spacesPerLevel = 4);
1170
1171 /// Return the (common) number of black nodes on each path from the
1172 /// specified `rootNode` to a leaf in the tree, 0 if `rootNode` is 0,
1173 /// and a negative number if `rootNode` does not refer to a valid
1174 /// red-black binary search tree, ordered according to the specified
1175 /// `comparator`. Optionally specify `errorNode` and `errorDescription`
1176 /// in which to load the address of a node violating a red-black tree
1177 /// constraint and a description of that violation, respectively.
1178 ///
1179 /// \pre The behavior is undefined unless `rootNode` is 0, or refers to a valid
1180 /// binary tree.
1181 ///
1182 /// Each node of a red-black tree is colored either red or black; null
1183 /// nodes are considered black. Four requirements must be satisfied
1184 /// for `rootNode` to refer to a valid red-black binary search tree:
1185 ///
1186 /// 1. For each node in the tree, no descendents to the left of that
1187 /// node would order after that node (according to the `comparator`),
1188 /// and no descendents to the right of that node would order before
1189 /// it.
1190 /// 2. For each node in the tree, each non-null child of that node
1191 /// refers to that node as its parent.
1192 /// 3. If a node in the tree is colored red, all its children are
1193 /// colored black or are null (which is considered black).
1194 /// 4. For each node in the tree, every path from that node to a leaf
1195 /// contains the same number of black nodes, where null children are
1196 /// considered black leaf nodes.
1197 ///
1198 ///
1199 /// \pre The behavior is undefined unless `rootNode` is 0, or refers to a valid binary tree.
1200 ///
1201 /// \note Note that the implementation of this function
1202 /// is recursive and has linear complexity with respect to the number of
1203 /// nodes in `tree`, it is intended for debugging purposes only.
1204 template <class NODE_COMPARATOR>
1205 static int validateRbTree(const RbTreeNode *rootNode,
1206 const NODE_COMPARATOR& comparator);
1207 template <class NODE_COMPARATOR>
1208 static int validateRbTree(const RbTreeNode **errorNode,
1209 const char **errorDescription,
1210 const RbTreeNode *rootNode,
1211 const NODE_COMPARATOR& comparator);
1212
1213 /// Return `true` if the specified `tree` is well-formed and refers to
1214 /// a valid red-black tree, and `false` otherwise. For a
1215 /// `RbTreeAnchor` to be considered well-formed *all* of the following
1216 /// must be true:
1217 ///
1218 /// 1. `tree.rootNode()` must refer to a valid red-black tree, whose
1219 /// nodes are organized according to `comparator` (see
1220 /// `validateRbTree`).
1221 /// 2. `tree.firstNode()` must refer to `tree.sentinel()` if
1222 /// `tree.rootNode()` is 0, and leftmost(tree.rootNode())' otherwise.
1223 /// 3. `tree.nodeCount()` must be the count of nodes in `tree` (not
1224 /// including the sentinel node).
1225 /// 4. `tree.sentinel()->leftchild()` is `tree.rootNode()`, and (if
1226 /// `tree.rootNode()` is not 0) `tree.rootNode()->parent()` is
1227 /// `tree.sentinel()`.
1228 /// 5. `tree.rootNode()` is 0 or `tree.rootNode().isBlack()` is `true`
1229 ///
1230 ///
1231 /// \pre The behavior is undefined unless `tree.rootNode()` is 0 or refers to a valid binary tree.
1232 ///
1233 /// \note Note that the implementation of this
1234 /// function is recursive and has linear complexity with respect to the
1235 /// number of nodes in `tree`, it is intended for debugging purposes
1236 /// only. Note also that the final condition, that the root node be
1237 /// either 0 or colored black, is not a canonical requirement of a
1238 /// red-black tree but an additional invariant enforced by the methods
1239 /// of `RbTreeUtil` to simplify the implementations.
1240 template <class NODE_COMPARATOR>
1241 static bool isWellFormed(const RbTreeAnchor& tree,
1242 const NODE_COMPARATOR& comparator);
1243};
1244
1245 // ==========================
1246 // class RbTreeUtil_Validator
1247 // ==========================
1248
1249/// This `struct` provides a namespace for auxiliary functions used to
1250/// validate a red-black binary search tree.
1251///
1252/// See @ref bslalg_rbtreeutil
1254
1255 // CLASS METHODS
1256
1257 /// Return the (common) number of black nodes on each path from the
1258 /// specified `rootNode` to a leaf in the tree, 0 if `rootNode` is 0,
1259 /// and a negative number if `rootNode` does not refer to a valid
1260 /// red-black binary search tree (ordered according to the specified
1261 /// `comparator`) that contains no nodes whose value is less than the
1262 /// specified `minNodeValue` (if not 0) or greater-than the specified
1263 /// `maxNodeValue` (if not 0). If `rootNode` does not refer to a valid
1264 /// red-black tree containing nodes whose values are between the
1265 /// specified `minNodeValue` and `maxNodeValue` (inclusively) then load
1266 /// `errorNode` and `errorDescription` with the address of a node
1267 /// violating a red-black tree constraint and a description of that violation, respectively.
1268 ///
1269 /// \pre The behavior is undefined unless
1270 /// `rootNode` is 0, or refers to a valid binary tree.
1271 template <class NODE_COMPARATOR>
1272 static int validateRbTree(const RbTreeNode **errorNode,
1273 const char **errorDescription,
1274 const RbTreeNode *rootNode,
1275 const RbTreeNode *minNodeValue,
1276 const RbTreeNode *maxNodeValue,
1277 const NODE_COMPARATOR& comparator);
1278
1279 /// Return `true` if the specified `tree` is well-formed, without
1280 /// confirming that it refers to a valid-red-black tree, and
1281 /// `false` otherwise. This method will return `true` if *all* of the
1282 /// following are true:
1283 ///
1284 /// 1. `tree.firstNode()` must refer to `tree.sentinel()` if
1285 /// `tree.rootNode()` is 0, and leftmost(tree.rootNode())' otherwise.
1286 /// 2. `tree.nodeCount()` must be the count of nodes in `tree` (not
1287 /// including the sentinel node).
1288 /// 3. `tree.sentinel()->leftchild()` is `tree.rootNode()`, and (if
1289 /// `tree.rootNode()` is not 0), `tree.rootNode()->parent()` is
1290 /// 'tree.sentinel().
1291 /// 4. `tree.rootNode()` is 0 or `tree.rootNode().isBlack()` is `true`
1292 ///
1293 ///
1294 /// \pre The behavior is undefined unless `tree.rootNode()` is 0, or refers to a valid binary tree.
1295 ///
1296 /// \note Note that this function provides a
1297 /// non-templatized implementation for several criteria of a
1298 /// well-formed tree (but not the complete set verified by
1299 /// `RbTreeUtil::isWellFormed`).
1300 static bool isWellFormedAnchor(const RbTreeAnchor& tree);
1301};
1302
1303 // ============================
1304 // struct RbTreeUtilTreeProctor
1305 // ============================
1306
1307/// This class implements a proctor that, unless `release` is called,
1308/// invokes the parameterized `DELETER` on each node in the tree supplied at
1309/// construction.
1310///
1311/// See @ref bslalg_rbtreeutil
1312template <class DELETER>
1314
1315 // DATA
1316 RbTreeAnchor *d_tree_p; // address of root node (held, not owned)
1317
1318 DELETER *d_deleter_p; // address of deleter used to destroy each
1319 // node (held, not owned)
1320
1321 public:
1322 // CREATORS
1323
1324 /// Create a proctor object that, unless `release` is called, will,
1325 /// on destruction, invoke the specified `deleter` on each node in
1326 /// `tree`.
1327 RbTreeUtilTreeProctor(RbTreeAnchor *tree, DELETER *deleter);
1328
1329 /// Unless `release` has been called, invoke the deleter supplied at
1330 /// construction on each node in the tree supplied at construction.
1332
1333 // MANIPULATORS
1334
1335 /// Release from management the tree supplied at construction.
1336 void release();
1337};
1338
1339// ============================================================================
1340// INLINE FUNCTION DEFINITIONS
1341// ============================================================================
1342
1343 // ----------------
1344 // class RbTreeUtil
1345 // ----------------
1346
1347// CLASS METHODS
1348inline
1350{
1351 return const_cast<RbTreeNode *>(
1352 leftmost(const_cast<const RbTreeNode *>(subtree)));
1353}
1354
1355inline
1357{
1358 return const_cast<RbTreeNode *>(
1359 rightmost(const_cast<const RbTreeNode *>(subtree)));
1360}
1361
1362inline
1364{
1365 return const_cast<RbTreeNode *>(
1366 next(const_cast<const RbTreeNode *>(node)));
1367}
1368
1369inline
1371{
1372 return const_cast<RbTreeNode *>(
1373 previous(const_cast<const RbTreeNode *>(node)));
1374}
1375
1376template <class NODE_VALUE_COMPARATOR, class VALUE>
1377inline
1379 NODE_VALUE_COMPARATOR& comparator,
1380 const VALUE& value)
1381{
1382 return const_cast<RbTreeNode *>(
1383 find(const_cast<const RbTreeAnchor&>(tree), comparator, value));
1384}
1385
1386template <class NODE_VALUE_COMPARATOR, class VALUE>
1387inline
1389 NODE_VALUE_COMPARATOR& comparator,
1390 const VALUE& value)
1391{
1392 const RbTreeNode *lowBound = lowerBound(tree, comparator, value);
1393
1394 // Note that a Solaris compiler bug prevents using a ternary ('?:')
1395 // operator here in certain contexts.
1396
1397 if (lowBound != tree.sentinel() && !comparator(value, *lowBound)) {
1398 return lowBound; // RETURN
1399 }
1400 return tree.sentinel();
1401}
1402
1403template <class NODE_VALUE_COMPARATOR, class VALUE>
1405 NODE_VALUE_COMPARATOR& comparator,
1406 const VALUE& value)
1407{
1408 return const_cast<RbTreeNode *>(
1409 lowerBound(const_cast<const RbTreeAnchor&>(tree), comparator, value));
1410}
1411
1412template <class NODE_VALUE_COMPARATOR, class VALUE>
1413inline
1415 NODE_VALUE_COMPARATOR& comparator,
1416 const VALUE& value)
1417{
1418 const RbTreeNode *nextLargestNode = tree.sentinel();
1419 const RbTreeNode *node = tree.rootNode();
1420 while (node) {
1421 if (comparator(*node, value)) {
1422 node = node->rightChild();
1423 }
1424 else {
1425 nextLargestNode = node;
1426 node = node->leftChild();
1427 }
1428 }
1429 return nextLargestNode;
1430}
1431
1432template <class NODE_VALUE_COMPARATOR, class VALUE>
1433inline
1435 NODE_VALUE_COMPARATOR& comparator,
1436 const VALUE& value)
1437{
1438 return const_cast<RbTreeNode *>(
1439 upperBound(const_cast<const RbTreeAnchor&>(tree), comparator, value));
1440}
1441
1442template <class NODE_VALUE_COMPARATOR, class VALUE>
1443inline
1445 NODE_VALUE_COMPARATOR& comparator,
1446 const VALUE& value)
1447{
1448 const RbTreeNode *nextLargestNode = tree.sentinel();
1449 const RbTreeNode *node = tree.rootNode();
1450 while (node) {
1451 if (comparator(value, *node)) {
1452 nextLargestNode = node;
1453 node = node->leftChild();
1454 }
1455 else {
1456 node = node->rightChild();
1457 }
1458 }
1459 return nextLargestNode;
1460}
1461
1462template <class FACTORY>
1464 const RbTreeAnchor& original,
1465 FACTORY *nodeFactory)
1466{
1467 BSLS_ASSERT_SAFE(result);
1468 BSLS_ASSERT_SAFE(0 == result->rootNode());
1469 BSLS_ASSERT_SAFE(nodeFactory);
1470
1471 if (!original.rootNode()) {
1472 result->reset(0, result->sentinel(), 0);
1473 return; // RETURN
1474 }
1475
1476 // Perform an pre-order traversal of the nodes of the tree, invoking
1477 // 'nodeFactory->createNode()' on each node.
1478
1479 const RbTreeNode *originalNode = original.rootNode();
1480
1481 RbTreeNode *copiedRoot = nodeFactory->cloneNode(*originalNode);
1482 RbTreeAnchor tree(copiedRoot, 0, 1);
1483
1484 RbTreeUtilTreeProctor<FACTORY> proctor(&tree, nodeFactory);
1485
1486 RbTreeNode *copiedNode = copiedRoot;
1487
1488 copiedNode->setColor(originalNode->color());
1489 copiedNode->setParent(result->sentinel());
1490 copiedNode->setLeftChild(0);
1491 copiedNode->setRightChild(0);
1492 do {
1493 if (0 != originalNode->leftChild() && 0 == copiedNode->leftChild()) {
1494 originalNode = originalNode->leftChild();
1495 RbTreeNode *newNode = nodeFactory->cloneNode(*originalNode);
1496 copiedNode->setLeftChild(newNode);
1497 newNode->setColor(originalNode->color());
1498 newNode->setParent(copiedNode);
1499 newNode->setLeftChild(0);
1500 newNode->setRightChild(0);
1501
1502 copiedNode = newNode;
1503 }
1504 else if (0 != originalNode->rightChild() &&
1505 0 == copiedNode->rightChild()) {
1506 originalNode = originalNode->rightChild();
1507 RbTreeNode *newNode = nodeFactory->cloneNode(*originalNode);
1508 copiedNode->setRightChild(newNode);
1509 newNode->setColor(originalNode->color());
1510 newNode->setParent(copiedNode);
1511 newNode->setLeftChild(0);
1512 newNode->setRightChild(0);
1513
1514 copiedNode = newNode;
1515 }
1516 else {
1517 originalNode = originalNode->parent();
1518 copiedNode = copiedNode->parent();
1519 }
1520 } while (original.sentinel() != originalNode);
1521
1522 proctor.release();
1523
1524 result->reset(copiedRoot,
1525 leftmost(copiedRoot),
1526 original.numNodes());
1527}
1528
1529template <class FACTORY>
1531 RbTreeAnchor *original,
1532 FACTORY *nodeFactory,
1533 FACTORY *originalNodeFactory)
1534{
1535 BSLS_ASSERT_SAFE(result);
1536 BSLS_ASSERT_SAFE(0 == result->rootNode());
1537 BSLS_ASSERT_SAFE(nodeFactory);
1538 BSLS_ASSERT_SAFE(originalNodeFactory);
1539
1540 if (!original->rootNode()) {
1541 result->reset(0, result->sentinel(), 0);
1542 return; // RETURN
1543 }
1544
1545 // Perform an pre-order traversal of the nodes of the tree, invoking
1546 // 'nodeFactory->createNode()' on each node.
1547
1548 RbTreeNode *originalNode = original->rootNode();
1549
1550 RbTreeNode *copiedRoot = nodeFactory->moveIntoNewNode(originalNode);
1551
1552 RbTreeAnchor tree(copiedRoot, 0, 1);
1553
1554 RbTreeUtilTreeProctor<FACTORY> proctor(&tree, nodeFactory);
1555 RbTreeUtilTreeProctor<FACTORY> oproctor(original, originalNodeFactory);
1556
1557 RbTreeNode *copiedNode = copiedRoot;
1558
1559 copiedNode->setColor(originalNode->color());
1560 copiedNode->setParent(result->sentinel());
1561 copiedNode->setLeftChild(0);
1562 copiedNode->setRightChild(0);
1563 do {
1564 if (0 != originalNode->leftChild() && 0 == copiedNode->leftChild()) {
1565 originalNode = originalNode->leftChild();
1566 RbTreeNode *newNode = nodeFactory->moveIntoNewNode(originalNode);
1567 copiedNode->setLeftChild(newNode);
1568 newNode->setColor(originalNode->color());
1569 newNode->setParent(copiedNode);
1570 newNode->setLeftChild(0);
1571 newNode->setRightChild(0);
1572
1573 copiedNode = newNode;
1574 }
1575 else if (0 != originalNode->rightChild() &&
1576 0 == copiedNode->rightChild()) {
1577 originalNode = originalNode->rightChild();
1578 RbTreeNode *newNode = nodeFactory->moveIntoNewNode(originalNode);
1579 copiedNode->setRightChild(newNode);
1580 newNode->setColor(originalNode->color());
1581 newNode->setParent(copiedNode);
1582 newNode->setLeftChild(0);
1583 newNode->setRightChild(0);
1584
1585 copiedNode = newNode;
1586 }
1587 else {
1588 originalNode = originalNode->parent();
1589 copiedNode = copiedNode->parent();
1590 }
1591 } while (original->sentinel() != originalNode);
1592
1593 proctor.release();
1594
1595 result->reset(copiedRoot,
1596 leftmost(copiedRoot),
1597 original->numNodes());
1598
1599 // 'oproctor' takes care of clearing 'original', even when an exception is
1600 // not thrown, since the tree is no longer valid if the elements have been
1601 // moved from.
1602}
1603
1604template <class FACTORY>
1605void RbTreeUtil::deleteTree(RbTreeAnchor *tree, FACTORY *nodeFactory)
1606{
1607 BSLS_ASSERT_SAFE(tree);
1608 BSLS_ASSERT_SAFE(nodeFactory);
1609
1610 if (0 == tree->rootNode()) {
1611 BSLS_ASSERT_SAFE(tree->sentinel() == tree->firstNode());
1612 return; // RETURN
1613 }
1614
1615 // Perform a post-order traversal of the nodes of the tree, invoking
1616 // 'nodeFactory->deleteNode()' on each node.
1617
1618 RbTreeNode *node = tree->firstNode();
1619 do {
1620 // At each iteration through this loop, we are at a leftmost (i.e.,
1621 // minimum) node of some sub-tree. Note that 'node->leftChild()' may
1622 // not be 0 if we've simply deleted the left sub-tree of this node.
1623
1624 if (node->rightChild()) {
1625 // If this node has a right child, then navigate to the first node
1626 // in the subtree to remove, and set 'node->rightChild()' to 0 so
1627 // we know this sub-tree has been removed when we iterate back up
1628 // parent pointers of the tree to this node.
1629
1630 RbTreeNode *rightChild = node->rightChild();
1631 node->setRightChild(0);
1632 node = leftmost(rightChild);
1633 }
1634 else {
1635 RbTreeNode *parent = node->parent();
1636 nodeFactory->deleteNode(node);
1637 node = parent;
1638 }
1639 } while (tree->sentinel() != node);
1640 tree->reset(0, tree->sentinel(), 0);
1641}
1642
1643template <class NODE_VALUE_COMPARATOR, class VALUE>
1645 bool *insertAsLeftChildFlag,
1646 RbTreeAnchor *tree,
1647 NODE_VALUE_COMPARATOR& comparator,
1648 const VALUE& value)
1649{
1650 BSLS_ASSERT_SAFE(insertAsLeftChildFlag);
1651 BSLS_ASSERT_SAFE(tree);
1652
1653 RbTreeNode *parent = tree->sentinel();
1654 RbTreeNode *node = tree->rootNode();
1655 *insertAsLeftChildFlag = true;
1656 while (node) {
1657 // Find the leaf node that would be the parent of 'newNode'.
1658
1659 parent = node;
1660 *insertAsLeftChildFlag = comparator(value, *node);
1661 if (*insertAsLeftChildFlag) {
1662 node = node->leftChild();
1663 }
1664 else {
1665 node = node->rightChild();
1666 }
1667 }
1668 return parent;
1669}
1670
1671template <class NODE_VALUE_COMPARATOR, class VALUE>
1673 bool *insertAsLeftChildFlag,
1674 RbTreeAnchor *tree,
1675 NODE_VALUE_COMPARATOR& comparator,
1676 const VALUE& value,
1677 RbTreeNode *hint)
1678{
1679 BSLS_ASSERT_SAFE(insertAsLeftChildFlag);
1680 BSLS_ASSERT_SAFE(tree);
1681 BSLS_ASSERT_SAFE(hint);
1682
1683 // 'hint' is valid if it is equal to, or the smallest value greater than,
1684 // 'value'.
1685
1686 if (tree->sentinel() == hint || !comparator(*hint, value)) {
1687 // 'hint' is greater-than or equal-to 'value', if the previous node,
1688 // 'prev' is less-than or equal-to 'value', then we have a valid hint.
1689
1690 RbTreeNode *prev = (tree->firstNode() == hint) ? hint : previous(hint);
1691 if (tree->firstNode() == hint || !comparator(value, *prev)) {
1692 // There will be an empty position for a child node between every
1693 // two consecutive nodes (in an in-order traversal) of a binary
1694 // tree. Determine whether that empty position is the left child
1695 // of 'hint' or the right child of 'prev'.
1696
1697 if (0 == hint->leftChild()) {
1698 *insertAsLeftChildFlag = true;
1699 return hint; // RETURN
1700 }
1701 BSLS_ASSERT_SAFE(prev);
1702 *insertAsLeftChildFlag = false;
1703 return prev; // RETURN
1704 }
1705 // 'prev' is greater than 'value', so this is not a valid hint.
1706
1707 }
1708 // If 'hint' was less than 'value', it is not a valid hint.
1709
1710 // The 'hint' is not valid, fall-back and search the entire tree.
1711
1712 return findInsertLocation(insertAsLeftChildFlag, tree, comparator, value);
1713}
1714
1715template <class NODE_VALUE_COMPARATOR, class VALUE>
1717 int *comparisonResult,
1718 RbTreeAnchor *tree,
1719 NODE_VALUE_COMPARATOR& comparator,
1720 const VALUE& value)
1721{
1722 BSLS_ASSERT_SAFE(comparisonResult);
1723 BSLS_ASSERT_SAFE(tree);
1724
1725 // Note that 'nextSmallestNode' is used, rather than 'nextLargestNode' (as
1726 // seen in 'upperBound' and 'lowerBound') to avoid an unnecessary
1727 // negation.
1728
1729 RbTreeNode *parent = tree->sentinel();
1730 RbTreeNode *nextSmallestNode = 0;
1731 RbTreeNode *node = tree->rootNode();
1732
1733 bool leftChild = true;
1734 while (node) {
1735 // Find the leaf node that would be the parent of 'newNode'.
1736
1737 parent = node;
1738 leftChild = comparator(value, *node);
1739 if (leftChild) {
1740 node = node->leftChild();
1741 }
1742 else {
1743 nextSmallestNode = node;
1744 node = node->rightChild();
1745 }
1746 }
1747
1748 if (nextSmallestNode && !comparator(*nextSmallestNode, value)) {
1749 *comparisonResult = 0;
1750 return nextSmallestNode; // RETURN
1751 }
1752 *comparisonResult = leftChild ? -1 : 1;
1753 return parent;
1754}
1755
1756template <class NODE_VALUE_COMPARATOR, class VALUE>
1758 int *comparisonResult,
1759 RbTreeAnchor *tree,
1760 NODE_VALUE_COMPARATOR& comparator,
1761 const VALUE& value,
1762 RbTreeNode *hint)
1763{
1764 BSLS_ASSERT_SAFE(comparisonResult);
1765 BSLS_ASSERT_SAFE(tree);
1766 BSLS_ASSERT_SAFE(hint);
1767
1768 enum { LEFT_CHILD = -1, NODE_FOUND = 0, RIGHT_CHILD = 1 };
1769
1770 // 'hint' is valid if it is first value greater than 'value' in the tree.
1771
1772 if (tree->sentinel() == hint || comparator(value, *hint)) {
1773 // 'hint' is greater than 'value'. If the previous node, 'prev' is
1774 // less than the value, then we have a valid hint.
1775
1776 RbTreeNode *prev = (tree->firstNode() == hint) ? hint : previous(hint);
1777 if (tree->firstNode() == hint || comparator(*prev, value)) {
1778 // There will be an empty position for a child node between every
1779 // two consecutive nodes (in an in-order traversal) of a binary
1780 // tree. Determine whether that empty position is the left child
1781 // of 'hint' or the right child of 'prev'.
1782
1783 if (0 == hint->leftChild()) {
1784 *comparisonResult = LEFT_CHILD;
1785 return hint; // RETURN
1786 }
1787
1788 BSLS_ASSERT_SAFE(prev);
1789 *comparisonResult = RIGHT_CHILD;
1790 return prev; // RETURN
1791 }
1792 // 'value' is ordered before 'hint', but 'prev' is not ordered before
1793 // 'value', so either: (1) 'value' is equal to 'prev' or (2) 'hint' is
1794 // not a valid hint. Optimize for (1), by handling it as a special
1795 // case, as this may reasonably occur using 'upperBound' on 'value' to
1796 // determine a hint.
1797
1798 if (!comparator(value, *prev)) {
1799 *comparisonResult = NODE_FOUND;
1800 return prev; // RETURN
1801 }
1802
1803 // 'prev' is greater than 'value', so this is not a valid hint.
1804 }
1805 // If 'value' is not ordered before 'hint', either: (1) 'value' is equal
1806 // to 'hint', or (2) 'hint' is not a valid hint. Optimize for (1).
1807
1808 else if (tree->sentinel() != hint && !comparator(*hint, value)) {
1809 *comparisonResult = NODE_FOUND;
1810 return hint; // RETURN
1811 }
1812 // The 'hint' is not valid, fall-back and search the entire tree.
1813
1814 return findUniqueInsertLocation(comparisonResult,
1815 tree,
1816 comparator,
1817 value);
1818}
1819
1820template <class NODE_COMPARATOR>
1822 const NODE_COMPARATOR& comparator,
1823 RbTreeNode *newNode)
1824{
1825 BSLS_ASSERT_SAFE(tree);
1826 BSLS_ASSERT_SAFE(newNode);
1827
1828 // Note that the following logic is the same as 'findInsertLocation'
1829 // except that the comparator required for this operation compares two
1830 // nodes, rather than comparing a value to a node.
1831
1832 RbTreeNode *parent = tree->sentinel();
1833 RbTreeNode *node = tree->rootNode();
1834 bool leftChildFlag = true;
1835 while (node) {
1836 // Find the leaf node that would be the parent of 'newNode'.
1837
1838 parent = node;
1839 leftChildFlag = comparator(*newNode, *node);
1840 if (leftChildFlag) {
1841 node = node->leftChild();
1842 }
1843 else {
1844 node = node->rightChild();
1845 }
1846 }
1847 return insertAt(tree, parent, leftChildFlag, newNode);
1848}
1849
1850inline
1852{
1853 BSLS_ASSERT_SAFE(node);
1854 BSLS_ASSERT_SAFE(node->parent());
1855
1856 return node->parent()->leftChild() == node;
1857}
1858
1859inline
1861{
1862 BSLS_ASSERT_SAFE(node);
1863 BSLS_ASSERT_SAFE(node->parent());
1864
1865 return node->parent()->rightChild() == node;
1866}
1867
1868template <class NODE_COMPARATOR>
1869inline
1871 const NODE_COMPARATOR& comparator)
1872{
1873 const RbTreeNode *errorNode;
1874 const char *errorDescription;
1875 return validateRbTree(&errorNode, &errorDescription, rootNode, comparator);
1876}
1877
1878template <class NODE_COMPARATOR>
1880 const char **errorDescription,
1881 const RbTreeNode *rootNode,
1882 const NODE_COMPARATOR& comparator)
1883{
1884 BSLS_ASSERT(errorNode);
1885 BSLS_ASSERT(errorDescription);
1886
1887 return RbTreeUtil_Validator::validateRbTree(errorNode,
1888 errorDescription,
1889 rootNode,
1890 0,
1891 0,
1892 comparator);
1893}
1894
1895template <class NODE_COMPARATOR>
1896inline
1898 const NODE_COMPARATOR& comparator)
1899{
1901 return false; // RETURN
1902 }
1903 return 0 <= validateRbTree(tree.rootNode(), comparator);
1904}
1905
1906 // --------------------------
1907 // class RbTreeUtil_Validator
1908 // --------------------------
1909
1910// CLASS METHODS
1911template <class NODE_COMPARATOR>
1913 const RbTreeNode **errorNode,
1914 const char **errorDescription,
1915 const RbTreeNode *rootNode,
1916 const RbTreeNode *minNodeValue,
1917 const RbTreeNode *maxNodeValue,
1918 const NODE_COMPARATOR& comparator)
1919{
1920 BSLS_ASSERT_SAFE(errorNode);
1921 BSLS_ASSERT_SAFE(errorDescription);
1922
1923 //: 1 All the descendents to the left of each node are ordered that at or
1924 //: before that node, and all descendents to the right of each node are
1925 //: ordered at or after that node, as determined by 'comparator'.
1926 //:
1927 //: 2 Both children of every node refer to 'node' as a parent.
1928 //:
1929 //: 3 If a node in the tree has no children, it is black.
1930 //:
1931 //: 4 If a node in the tree is red, its children are either black or 0.
1932 //:
1933 //: 5 For each node in the tree, every path from that node to a leaf
1934 //: contains the same number of black nodes.
1935
1936 enum { INVALID_RBTREE = -1};
1937
1938 // 'NIL' nodes are considered black
1939
1940 if (!rootNode) {
1941 return 0; // RETURN
1942 }
1943
1944 // Rule 1.
1945
1946 if ((minNodeValue && comparator(*rootNode, *minNodeValue)) ||
1947 (maxNodeValue && comparator(*maxNodeValue, *rootNode))) {
1948 *errorNode = rootNode;
1949 *errorDescription = "Invalid binary search tree.";
1950 return INVALID_RBTREE; // RETURN
1951 }
1952
1953 const RbTreeNode *left = rootNode->leftChild();
1954 const RbTreeNode *right = rootNode->rightChild();
1955 if ((left != 0 || right != 0) && left == right) {
1956 *errorNode = rootNode;
1957 *errorDescription = "Invalid children";
1958 return INVALID_RBTREE; // RETURN
1959 }
1960
1961 // Rule 2.
1962
1963 if ((left && left->parent() != rootNode) ||
1964 (right && right->parent() != rootNode)) {
1965 *errorNode = rootNode;
1966 *errorDescription = "Invalid parent pointers for children";
1967 return INVALID_RBTREE; // RETURN
1968 }
1969
1970 // Rule 4.
1971
1972 if (RbTreeNode::BSLALG_RED == rootNode->color()) {
1973 if ((left && left->color() != RbTreeNode::BSLALG_BLACK) ||
1974 (right && right->color() != RbTreeNode::BSLALG_BLACK)) {
1975 *errorNode = rootNode;
1976 *errorDescription = "Red node with a red child.";
1977 return INVALID_RBTREE; // RETURN
1978 }
1979 }
1980
1981 int leftDepth = validateRbTree(errorNode,
1982 errorDescription,
1983 rootNode->leftChild(),
1984 minNodeValue,
1985 rootNode,
1986 comparator);
1987 int rightDepth = validateRbTree(errorNode,
1988 errorDescription,
1989 rootNode->rightChild(),
1990 rootNode,
1991 maxNodeValue,
1992 comparator);
1993
1994 if (leftDepth < 0 || rightDepth < 0) {
1995 return INVALID_RBTREE; // RETURN
1996 }
1997
1998 // Rule 5.
1999
2000 if (leftDepth != rightDepth) {
2001 *errorNode = rootNode;
2002 *errorDescription =
2003 "Black violation (unequal black depth from node to leaves).";
2004 return INVALID_RBTREE; // RETURN
2005 }
2006
2007 return (rootNode->color() == RbTreeNode::BSLALG_BLACK)
2008 ? leftDepth + 1
2009 : leftDepth;
2010}
2011
2012 // ----------------------------
2013 // struct RbTreeUtilTreeProctor
2014 // ----------------------------
2015
2016template <class DELETER>
2017inline
2019 DELETER *deleter)
2020: d_tree_p(tree)
2021, d_deleter_p(deleter)
2022{
2023 BSLS_ASSERT_SAFE(deleter);
2024}
2025
2026template <class DELETER>
2027inline
2029{
2030 if (d_tree_p && d_tree_p->rootNode()) {
2031 d_tree_p->rootNode()->setParent(d_tree_p->sentinel());
2032
2033 d_tree_p->setFirstNode(RbTreeUtil::leftmost(d_tree_p->rootNode()));
2034 RbTreeUtil::deleteTree(d_tree_p, d_deleter_p);
2035 }
2036}
2037
2038template <class DELETER>
2039inline
2041{
2042 d_tree_p = 0;
2043}
2044
2045} // close package namespace
2046
2047
2048#endif
2049
2050// ----------------------------------------------------------------------------
2051// Copyright 2013 Bloomberg Finance L.P.
2052//
2053// Licensed under the Apache License, Version 2.0 (the "License");
2054// you may not use this file except in compliance with the License.
2055// You may obtain a copy of the License at
2056//
2057// http://www.apache.org/licenses/LICENSE-2.0
2058//
2059// Unless required by applicable law or agreed to in writing, software
2060// distributed under the License is distributed on an "AS IS" BASIS,
2061// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2062// See the License for the specific language governing permissions and
2063// limitations under the License.
2064// ----------------------------- END-OF-FILE ----------------------------------
2065
2066/** @} */
2067/** @} */
2068/** @} */
Definition bslalg_rbtreeanchor.h:353
RbTreeNode * sentinel()
Definition bslalg_rbtreeanchor.h:537
RbTreeNode * firstNode()
Definition bslalg_rbtreeanchor.h:525
int numNodes() const
Return the numNodes attribute of this object.
Definition bslalg_rbtreeanchor.h:556
RbTreeNode * rootNode()
Definition bslalg_rbtreeanchor.h:531
void reset(RbTreeNode *rootNode, RbTreeNode *firstNode, int numNodes)
Definition bslalg_rbtreeanchor.h:483
Definition bslalg_rbtreenode.h:377
RbTreeNode * rightChild()
Definition bslalg_rbtreenode.h:603
RbTreeNode * leftChild()
Definition bslalg_rbtreenode.h:597
void setRightChild(RbTreeNode *address)
Definition bslalg_rbtreenode.h:557
void setParent(RbTreeNode *address)
Definition bslalg_rbtreenode.h:542
Color color() const
Return the color of this node.
Definition bslalg_rbtreenode.h:640
void setLeftChild(RbTreeNode *address)
Definition bslalg_rbtreenode.h:551
void setColor(Color value)
Set the color of this node to the specified value.
Definition bslalg_rbtreenode.h:563
RbTreeNode * parent()
Definition bslalg_rbtreenode.h:591
@ BSLALG_BLACK
Definition bslalg_rbtreenode.h:383
@ BSLALG_RED
Definition bslalg_rbtreenode.h:382
Definition bslalg_rbtreeutil.h:1313
void release()
Release from management the tree supplied at construction.
Definition bslalg_rbtreeutil.h:2040
~RbTreeUtilTreeProctor()
Definition bslalg_rbtreeutil.h:2028
RbTreeUtilTreeProctor(RbTreeAnchor *tree, DELETER *deleter)
Definition bslalg_rbtreeutil.h:2018
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlc_flathashmap.h:2218
Definition bslalg_rbtreeutil.h:1253
static int validateRbTree(const RbTreeNode **errorNode, const char **errorDescription, const RbTreeNode *rootNode, const RbTreeNode *minNodeValue, const RbTreeNode *maxNodeValue, const NODE_COMPARATOR &comparator)
Definition bslalg_rbtreeutil.h:1912
static bool isWellFormedAnchor(const RbTreeAnchor &tree)
Definition bslalg_rbtreeutil.h:758
static const RbTreeNode * rightmost(const RbTreeNode *subtree)
static bool isLeftChild(const RbTreeNode *node)
Definition bslalg_rbtreeutil.h:1851
static const RbTreeNode * previous(const RbTreeNode *node)
static void remove(RbTreeAnchor *tree, RbTreeNode *node)
static void rotateLeft(RbTreeNode *node)
static const RbTreeNode * upperBound(const RbTreeAnchor &tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1444
static void swap(RbTreeAnchor *a, RbTreeAnchor *b)
static void deleteTree(RbTreeAnchor *tree, FACTORY *nodeFactory)
Definition bslalg_rbtreeutil.h:1605
static void insertAt(RbTreeAnchor *tree, RbTreeNode *parentNode, bool leftChildFlag, RbTreeNode *newNode)
static const RbTreeNode * leftmost(const RbTreeNode *subtree)
static RbTreeNode * findInsertLocation(bool *insertAsLeftChildFlag, RbTreeAnchor *tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1644
static RbTreeNode * findUniqueInsertLocation(int *comparisonResult, RbTreeAnchor *tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1716
static void printTreeStructure(FILE *file, const RbTreeNode *subtree, void(*printNodeValueCallback)(FILE *, const RbTreeNode *), int level=0, int spacesPerLevel=4)
static int validateRbTree(const RbTreeNode *rootNode, const NODE_COMPARATOR &comparator)
Definition bslalg_rbtreeutil.h:1870
static void copyTree(RbTreeAnchor *result, const RbTreeAnchor &original, FACTORY *nodeFactory)
Definition bslalg_rbtreeutil.h:1463
static void moveTree(RbTreeAnchor *result, RbTreeAnchor *original, FACTORY *nodeFactory, FACTORY *originalNodeFactory)
Definition bslalg_rbtreeutil.h:1530
static const RbTreeNode * next(const RbTreeNode *node)
static const RbTreeNode * find(const RbTreeAnchor &tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1388
static bool isWellFormed(const RbTreeAnchor &tree, const NODE_COMPARATOR &comparator)
Definition bslalg_rbtreeutil.h:1897
static bool isRightChild(const RbTreeNode *node)
Definition bslalg_rbtreeutil.h:1860
static const RbTreeNode * lowerBound(const RbTreeAnchor &tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1414
static void insert(RbTreeAnchor *tree, const NODE_COMPARATOR &comparator, RbTreeNode *newNode)
Definition bslalg_rbtreeutil.h:1821
static void rotateRight(RbTreeNode *node)