BDE 4.14.0 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.
757
758 // CLASS METHODS
759 // Navigation
760
761 /// Return the address of the leftmost node in the specified `subtree`,
762 /// and `subtree` if `subtree` has no left child. The behavior is
763 /// undefined unless `0 != subtree`, and `subtree` refers to a valid
764 /// binary tree. Note that the value held by the returned node will not
765 /// compare greater than that of any other node in `subtree` (as
766 /// determined by the comparator used to organize the red-black subtree
767 /// data).
768 static const RbTreeNode *leftmost(const RbTreeNode *subtree);
769 static RbTreeNode *leftmost( RbTreeNode *subtree);
770
771 /// Return the address of the rightmost node in the specified
772 /// `subtree`, and `subtree` if `subtree` has no right child. The
773 /// behavior is undefined unless `0 != subtree` and `subtree` refers to
774 /// a valid binary tree. Note that the value held by the returned node
775 /// will not compare less than that of any other node in `subtree` (as
776 /// determined by the comparator used to organize the red-black subtree
777 /// data).
778 static const RbTreeNode *rightmost(const RbTreeNode *subtree);
779 static RbTreeNode *rightmost( RbTreeNode *subtree);
780
781 /// Return the address of the node that follows the specified `node` in
782 /// an in-order traversal of the binary tree to which `node` belongs, or
783 /// the tree's sentinel node if `node` is the rightmost node in the
784 /// tree. The behavior is undefined unless `node` is a member of a
785 /// valid binary tree, and is not a sentinel node. Note that if the
786 /// tree does not contain duplicate values, then the returned node will
787 /// have the smallest value greater than that of `node`.
788 static const RbTreeNode *next(const RbTreeNode *node);
789 static RbTreeNode *next( RbTreeNode *node);
790
791 /// Return the address of the node that precedes the specified `node` in
792 /// an in-order traversal of the binary tree to which `node` belongs, or
793 /// the tree's rightmost node if `node` is the sentinel node of the
794 /// tree. The behavior is undefined unless or `node` is a non-leftmost
795 /// member of a valid binary tree or is a sentinel `node`. Note that if
796 /// the tree does not contain duplicate values, then the returned node
797 /// will have the largest value less than that of `node`.
798 static const RbTreeNode *previous(const RbTreeNode *node);
799 static RbTreeNode *previous( RbTreeNode *node);
800
801 // Search
802
803 /// Return the address of the leftmost node holding the specified
804 /// `value` in the specified `tree` (organized according to the
805 /// specified `comparator) if found, and return `tree.sentinel()'
806 /// otherwise. `COMPARATOR` shall be a functor providing two methods
807 /// that can be called as if they had the following signatures:
808 /// @code
809 /// bool operator()(const RbTreeNode&, const VALUE&) const;
810 /// bool operator()(const VALUE&, const RbTreeNode&) const;
811 /// @endcode
812 /// The behavior is undefined unless `comparator` provides a strict
813 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed
814 /// (see `isWellFormed`).
815 template <class NODE_VALUE_COMPARATOR, class VALUE>
816 static const RbTreeNode *find(const RbTreeAnchor& tree,
817 NODE_VALUE_COMPARATOR& comparator,
818 const VALUE& value);
819 template <class NODE_VALUE_COMPARATOR, class VALUE>
820 static RbTreeNode *find(RbTreeAnchor& tree,
821 NODE_VALUE_COMPARATOR& comparator,
822 const VALUE& value);
823
824 /// Return the address of the leftmost node holding the smallest
825 /// value greater-than or equal-to `value` in the specified `tree`
826 /// (organized according to the specified 'comparator) if found, and
827 /// return `tree.sentinel()` if `value` is greater-than the rightmost
828 /// node in `tree`. `COMPARATOR` shall be a functor providing two
829 /// methods that can be called as if they had the following signatures:
830 /// @code
831 /// bool operator()(const RbTreeNode&, const VALUE&) const;
832 /// bool operator()(const VALUE&, const RbTreeNode&) const;
833 /// @endcode
834 /// The behavior is undefined unless `comparator` provides a strict
835 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed
836 /// (`isWellFormed`). Note that this function returns the *first*
837 /// position before which `value` could be inserted into `tree` while
838 /// preserving its ordering.
839 template <class NODE_VALUE_COMPARATOR, class VALUE>
840 static const RbTreeNode *lowerBound(const RbTreeAnchor& tree,
841 NODE_VALUE_COMPARATOR& comparator,
842 const VALUE& value);
843 template <class NODE_VALUE_COMPARATOR, class VALUE>
844 static RbTreeNode *lowerBound(RbTreeAnchor& tree,
845 NODE_VALUE_COMPARATOR& comparator,
846 const VALUE& value);
847
848 /// Return the address of the leftmost node holding the smallest
849 /// value greater-than `value` in the specified `tree` (organized
850 /// according to the specified 'comparator) if found, and return
851 /// `tree.sentinel()` if `value` is greater-than or equal-to the
852 /// rightmost node in `tree`. `COMPARATOR` shall be a functor
853 /// providing two methods that can be called as if they had the
854 /// following signatures:
855 /// @code
856 /// bool operator()(const RbTreeNode&, const VALUE&) const;
857 /// bool operator()(const VALUE&, const RbTreeNode&) const;
858 /// @endcode
859 /// The behavior is undefined unless `comparator` provides a strict
860 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed
861 /// (`isWellFormed`). Note that this function returns the *last*
862 /// position before which `value` could be inserted into `tree` while
863 /// preserving its ordering.
864 template <class NODE_VALUE_COMPARATOR, class VALUE>
865 static const RbTreeNode *upperBound(const RbTreeAnchor& tree,
866 NODE_VALUE_COMPARATOR& comparator,
867 const VALUE& value);
868 template <class NODE_VALUE_COMPARATOR, class VALUE>
869 static RbTreeNode *upperBound(RbTreeAnchor& tree,
870 NODE_VALUE_COMPARATOR& comparator,
871 const VALUE& value);
872
873 // Modification
874
875 /// Load, into the specified `result`, a collection of newly created
876 /// nodes having the same red-black tree structure as that of the
877 /// specified `original` tree, where each node in the returned tree is
878 /// created by invoking `nodeFactory->createNode` on the corresponding
879 /// `original` node; if an exception occurs, use
880 /// `nodeFactory->deleteNode` to destroy any newly created nodes, and
881 /// propagate the exception to the caller (i.e., this operation provides
882 /// the *strong* exception guarantee). `FACTORY` shall be a class
883 /// providing two methods that can be called as if they had the
884 /// following signatures:
885 /// @code
886 /// RbTreeNode *createNode(const RbTreeNode&);
887 /// void deleteNode(RbTreeNode *);
888 /// @endcode
889 /// The behavior is undefined unless `result` is an empty tree,
890 /// `original` is a well-formed (see `isWellFormed`), and
891 /// `nodeFactory->deleteNode` does not throw.
892 template <class FACTORY>
893 static void copyTree(RbTreeAnchor *result,
894 const RbTreeAnchor& original,
895 FACTORY *nodeFactory);
896
897 /// Load into the specified `result`, using the specified `nodeFactory`
898 /// to create and delete nodes, a collection of newly created nodes with
899 /// the same (red-black) tree structure as that of the specified
900 /// `original` tree, which uses the specified `originalNodeFactory` to
901 /// create and delete nodes, where the `value` attribute of each node in
902 /// `result` is constructed from explicitly moving the `value` attribute
903 /// of the corresponding node in `original`. `original` is left in a
904 /// valid but unspecified state. If an exception occurs, both `result`
905 /// and `original` are left in a valid but unspecified state. The
906 /// behavior is undefined unless `result` is an empty tree, `original`
907 /// is well-formed (see `isWellFormed`), and `nodeFactory->deleteNode`
908 /// and `originalNodeFactory->deleteNode` do not throw.
909 template <class FACTORY>
910 static void moveTree(RbTreeAnchor *result,
911 RbTreeAnchor *original,
912 FACTORY *nodeFactory,
913 FACTORY *originalNodeFactory);
914
915 /// Call `nodeFactory->deleteNode` on each node in `tree` and reset
916 /// `tree` to an empty state. `FACTORY` shall be a class providing a
917 /// method that can be called as if it has the following signature:
918 /// @code
919 /// void deleteNode(RbTreeNode *);
920 /// @endcode
921 /// The behavior is undefined unless `tree` is a valid binary tree, and
922 /// `nodeFactory->deleteNode` does not throw.
923 template <class FACTORY>
924 static void deleteTree(RbTreeAnchor *tree, FACTORY *nodeFactory);
925
926 /// Return the address of the node that would be the parent a node
927 /// holding the specified `value`, if it were to be inserted into the
928 /// specified `tree` (organized according to the specified
929 /// `comparator`), and load, into the specified `insertAsLeftChildFlag`,
930 /// `true` if `value` would be held as the returned node's left child,
931 /// and `false` if `value` would be held in its right child, unless
932 /// `tree` is empty, in which case return `tree->sentinel()` and load
933 /// `true` into `insertAsLeftChildFlag`. Optionally specify a `hint`,
934 /// suggesting a node in `tree` that might be the immediate successor of
935 /// a node holding `value` if it were to be inserted into `tree`. If
936 /// the supplied `hint` is the successor, this operation will take
937 /// amortized constant time; otherwise, it will take O(log(N))
938 /// operations, where N is the number of nodes in the tree. If a node
939 /// holding `value` is inserted as suggested by this method, the
940 /// resulting tree will be an ordered binary tree, but may require
941 /// rebalancing (and re-coloring) to again be a valid red-black tree.
942 /// `COMPARATOR` shall be a functor providing two methods that can be
943 /// called as if they have the following signatures:
944 /// @code
945 /// bool operator()(const RbTreeNode&, const VALUE&) const;
946 /// bool operator()(const VALUE&, const RbTreeNode&) const;
947 /// @endcode
948 /// The behavior is undefined unless `comparator` provides a strict
949 /// weak ordering on objects of type `VALUE`, `tree` is well-formed
950 /// (see `isWellFormed`), and `hint`, if supplied, is a node in `tree`.
951 /// Note that this operation is intended to be used in conjunction with
952 /// the `insertAt` method.
953 template <class NODE_VALUE_COMPARATOR, class VALUE>
955 bool *insertAsLeftChildFlag,
956 RbTreeAnchor *tree,
957 NODE_VALUE_COMPARATOR& comparator,
958 const VALUE& value);
959 template <class NODE_VALUE_COMPARATOR, class VALUE>
961 bool *insertAsLeftChildFlag,
962 RbTreeAnchor *tree,
963 NODE_VALUE_COMPARATOR& comparator,
964 const VALUE& value,
965 RbTreeNode *hint);
966
967 /// Return the address of the node holding the specified `value` in the
968 /// specified `tree` (organized according to the specified `comparator`)
969 /// if found, and the address of the node that would be the parent for
970 /// `value` otherwise; load, into the specified `comparisonResult`, 0 if
971 /// `value` is found, a negative number if `value` would be held in its
972 /// left child, and a positive number if `value` would be held in its
973 /// right child, unless `tree` is empty, in which case load a negative
974 /// number into `comparisonResult` and return `tree->sentinel()`.
975 /// Optionally specify a `hint`, suggesting a node in `tree` that might
976 /// be the immediate successor of a node holding `value` if it were to
977 /// be inserted into `tree`. If the supplied `hint` is the successor,
978 /// this operation will take amortized constant time; otherwise, it will
979 /// take O(log(N)) operations, where N is the number of nodes in the
980 /// tree. If a node holding `value` is inserted as suggested by this
981 /// method, the resulting tree will be an ordered binary tree, but may
982 /// require rebalancing (and re-coloring) to again be a valid red-black
983 /// tree. `COMPARATOR` shall be a functor providing two methods that
984 /// can be called as if they have the following signatures:
985 /// @code
986 /// bool operator()(const RbTreeNode&, const VALUE&) const;
987 /// bool operator()(const VALUE&, const RbTreeNode&) const;
988 /// @endcode
989 /// The behavior is undefined unless `comparator` provides a strict
990 /// weak ordering on objects of type `VALUE`, `tree` is well-formed
991 /// (see `isWellFormed`), and `hint`, if supplied, is a node in `tree`.
992 /// Note that this operation is intended to be used in conjunction with
993 /// the `insertAt` method.
994 template <class NODE_VALUE_COMPARATOR, class VALUE>
996 int *comparisonResult,
997 RbTreeAnchor *tree,
998 NODE_VALUE_COMPARATOR& comparator,
999 const VALUE& value);
1000 template <class NODE_VALUE_COMPARATOR, class VALUE>
1002 int *comparisonResult,
1003 RbTreeAnchor *tree,
1004 NODE_VALUE_COMPARATOR& comparator,
1005 const VALUE& value,
1006 RbTreeNode *hint);
1007
1008 /// Insert the specified `newNode` into the specified `tree`, organized
1009 /// according to the specified `comparator`. The resulting tree will
1010 /// be well-formed (see `isWellFormed`). `NODE_COMPARATOR` shall be a
1011 /// functor providing a method that can be called as if it had the
1012 /// following signatures:
1013 /// @code
1014 /// bool operator()(const RbTreeNode&, const RbTreeNode&) const;
1015 /// @endcode
1016 /// The behavior is undefined unless `comparator` provides a strict
1017 /// weak ordering on objects of type `VALUE`, and `tree` is well-formed
1018 /// (see `isWellFormed`).
1019 template <class NODE_COMPARATOR>
1020 static void insert(RbTreeAnchor *tree,
1021 const NODE_COMPARATOR& comparator,
1022 RbTreeNode *newNode);
1023
1024 /// Insert the specified `newNode` into the specified `tree` as either
1025 /// the left or right child of the specified `parentNode`, as indicated
1026 /// by the specified `leftChildFlag`, and then rebalance the tree so
1027 /// that it is a valid red-black tree (see `validateRbTree`). The
1028 /// behavior is undefined unless `tree` is well-formed (see
1029 /// `isWellFormed`), and, if `tree` is empty, `parentNode` is
1030 /// `tree->sentinel()` and `leftChildFlag` is `true`, or, if `tree` is
1031 /// not empty, `parentNode` is a node in `tree` whose left or right
1032 /// child (as indicated by `leftChildFlag`) is 0 where if `newNode` were
1033 /// attached as that child (without rebalancing) `tree` would still
1034 /// form an ordered binary tree (though not necessarily a valid
1035 /// red-black tree). Note that this operation is intended to be used in
1036 /// conjunction with the `findInsertLocation` or
1037 /// `findUniqueInsertLocation` methods.
1038 static void insertAt(RbTreeAnchor *tree,
1039 RbTreeNode *parentNode,
1040 bool leftChildFlag,
1041 RbTreeNode *newNode);
1042
1043 /// Remove the specified `node` from the specified `tree`, and then
1044 /// rebalance `tree` so that it again forms a valid red-black tree (see
1045 /// `validateRbTree`). The behavior is undefined unless `tree` is
1046 /// well-formed (see `isWellFormed`).
1047 static void remove(RbTreeAnchor *tree, RbTreeNode *node);
1048
1049 /// Efficiently exchange the nodes in the specified `a` tree with the
1050 /// nodes in the specified `b` tree. This method provides the no-throw
1051 /// exception-safety guarantee. The behavior is undefined unless `a`
1052 /// and `b` are well-formed (see `isWellFormed`).
1053 static void swap(RbTreeAnchor *a, RbTreeAnchor *b);
1054
1055 // Utility
1056
1057 /// Return `true` if the specified `node` is the left child of its
1058 /// parent, and `false` otherwise. The behavior is undefined unless
1059 /// `0 != node->parent()`.
1060 static bool isLeftChild(const RbTreeNode *node);
1061
1062 /// Return `true` if the specified `node` is the left child of its
1063 /// parent, and `false` otherwise. The behavior is undefined unless
1064 /// `0 != node->parent()`.
1065 static bool isRightChild(const RbTreeNode *node);
1066
1067 /// Perform counter-clockwise rotation on the specified `node`: Rotate
1068 /// the node's right child (the pivot) to be the node's parent, and
1069 /// attach the pivot's left child as the node's right child.
1070 /// @code
1071 /// (node) (pivot)
1072 /// / \ / \.
1073 /// a (pivot) ---> (node) c
1074 /// / \ / \.
1075 /// b c a b
1076 /// @endcode
1077 /// The behavior is undefined unless `node->rightChild()` is not 0,
1078 /// `node->parent()` is not 0, and node's parent refers to `node` as one
1079 /// of its children. Note that this operation maintains the ordering
1080 /// of the subtree rooted at `node`. Also note this operation will
1081 /// successfully rotate the root node of an unbalanced, but otherwise
1082 /// well-formed, tree referred to by a `RbTreeAnchor` object (see
1083 /// `isWellFormed`) because the parent of the root node is the tree's
1084 /// sentinel node (i.e., not 0), which refers to the root node as its
1085 /// left child, and an `RbTreeAnchor` object returns the left child of
1086 /// the sentinel node as the root of the tree.
1087 static void rotateLeft(RbTreeNode *node);
1088
1089 /// Perform clockwise rotation on the specified `node`: Rotate the
1090 /// node's left child (the pivot) to be the node's parent, and attach
1091 /// the pivot's right child as the node's left child.
1092 /// @code
1093 /// (node) (pivot)
1094 /// / \ / \.
1095 /// (pivot) c ---> a (node)
1096 /// / \ / \.
1097 /// a b b c
1098 /// @endcode
1099 /// The behavior is undefined unless `node->leftChild()` is not 0,
1100 /// `node->parent()` is not 0, and node's parent refers to `node` as one
1101 /// of its children. Note that this operation maintains the ordering
1102 /// of the subtree rooted at `node`. Also note this operation will
1103 /// successfully rotate the root node of an unbalanced, but otherwise
1104 /// well-formed, tree referred to by a `RbTreeAnchor` object (see
1105 /// `isWellFormed`) because the parent of the root node is the tree's
1106 /// sentinel node (i.e., not 0), which refers to the root node as its
1107 /// left child, and an `RbTreeAnchor` object returns the left child of
1108 /// the sentinel node as the root of the tree.
1109 static void rotateRight(RbTreeNode *node);
1110
1111 // Testing
1112
1113 /// Write a description of the structure of the specified `subtree` to
1114 /// the specified output `file` in a human-readable format, using the
1115 /// specified `printValueCallback` to render the value of each node.
1116 /// Optionally specify an initial indentation `level`, whose absolute
1117 /// value is incremented recursively for nested objects. If `level` is
1118 /// specified, optionally specify `spacesPerLevel`, whose absolute value
1119 /// indicates the number of spaces per indentation level for this and
1120 /// all of its nested objects. If `level` is negative, suppress
1121 /// indentation of the first line. If `spacesPerLevel` is negative,
1122 /// format the entire output on one line, suppressing all but the
1123 /// initial indentation (as governed by `level`). The behavior
1124 /// is undefined unless `node` is 0, or the root of a valid binary
1125 /// tree. Note that the implementation of this function is recursive
1126 /// and expensive to perform, it is intended for debugging purposes
1127 /// only. Also note that the format is not fully specified, and can
1128 /// change without notice.
1130 FILE *file,
1131 const RbTreeNode *subtree,
1132 void (*printNodeValueCallback)(FILE *, const RbTreeNode *),
1133 int level = 0,
1134 int spacesPerLevel = 4);
1135
1136 /// Return the (common) number of black nodes on each path from the
1137 /// specified `rootNode` to a leaf in the tree, 0 if `rootNode` is 0,
1138 /// and a negative number if `rootNode` does not refer to a valid
1139 /// red-black binary search tree, ordered according to the specified
1140 /// `comparator`. Optionally specify `errorNode` and `errorDescription`
1141 /// in which to load the address of a node violating a red-black tree
1142 /// constraint and a description of that violation, respectively. The
1143 /// behavior is undefined unless `rootNode` is 0, or refers to a valid
1144 /// binary tree.
1145 ///
1146 /// Each node of a red-black tree is colored either red or black; null
1147 /// nodes are considered black. Four requirements must be satisfied
1148 /// for `rootNode` to refer to a valid red-black binary search tree:
1149 ///
1150 /// 1. For each node in the tree, no descendents to the left of that
1151 /// node would order after that node (according to the `comparator`),
1152 /// and no descendents to the right of that node would order before
1153 /// it.
1154 /// 2. For each node in the tree, each non-null child of that node
1155 /// refers to that node as its parent.
1156 /// 3. If a node in the tree is colored red, all its children are
1157 /// colored black or are null (which is considered black).
1158 /// 4. For each node in the tree, every path from that node to a leaf
1159 /// contains the same number of black nodes, where null children are
1160 /// considered black leaf nodes.
1161 ///
1162 /// The behavior is undefined unless `rootNode` is 0, or refers to a
1163 /// valid binary tree. Note that the implementation of this function
1164 /// is recursive and has linear complexity with respect to the number of
1165 /// nodes in `tree`, it is intended for debugging purposes only.
1166 template <class NODE_COMPARATOR>
1167 static int validateRbTree(const RbTreeNode *rootNode,
1168 const NODE_COMPARATOR& comparator);
1169 template <class NODE_COMPARATOR>
1170 static int validateRbTree(const RbTreeNode **errorNode,
1171 const char **errorDescription,
1172 const RbTreeNode *rootNode,
1173 const NODE_COMPARATOR& comparator);
1174
1175 /// Return `true` if the specified `tree` is well-formed and refers to
1176 /// a valid red-black tree, and `false` otherwise. For a
1177 /// `RbTreeAnchor` to be considered well-formed *all* of the following
1178 /// must be true:
1179 ///
1180 /// 1. `tree.rootNode()` must refer to a valid red-black tree, whose
1181 /// nodes are organized according to `comparator` (see
1182 /// `validateRbTree`).
1183 /// 2. `tree.firstNode()` must refer to `tree.sentinel()` if
1184 /// `tree.rootNode()` is 0, and leftmost(tree.rootNode())' otherwise.
1185 /// 3. `tree.nodeCount()` must be the count of nodes in `tree` (not
1186 /// including the sentinel node).
1187 /// 4. `tree.sentinel()->leftchild()` is `tree.rootNode()`, and (if
1188 /// `tree.rootNode()` is not 0) `tree.rootNode()->parent()` is
1189 /// `tree.sentinel()`.
1190 /// 5. `tree.rootNode()` is 0 or `tree.rootNode().isBlack()` is `true`
1191 ///
1192 /// The behavior is undefined unless `tree.rootNode()` is 0 or refers
1193 /// to a valid binary tree. Note that the implementation of this
1194 /// function is recursive and has linear complexity with respect to the
1195 /// number of nodes in `tree`, it is intended for debugging purposes
1196 /// only. Note also that the final condition, that the root node be
1197 /// either 0 or colored black, is not a canonical requirement of a
1198 /// red-black tree but an additional invariant enforced by the methods
1199 /// of `RbTreeUtil` to simplify the implementations.
1200 template <class NODE_COMPARATOR>
1201 static bool isWellFormed(const RbTreeAnchor& tree,
1202 const NODE_COMPARATOR& comparator);
1203};
1204
1205 // ==========================
1206 // class RbTreeUtil_Validator
1207 // ==========================
1208
1209/// This `struct` provides a namespace for auxiliary functions used to
1210/// validate a red-black binary search tree.
1212
1213 // CLASS METHODS
1214
1215 /// Return the (common) number of black nodes on each path from the
1216 /// specified `rootNode` to a leaf in the tree, 0 if `rootNode` is 0,
1217 /// and a negative number if `rootNode` does not refer to a valid
1218 /// red-black binary search tree (ordered according to the specified
1219 /// `comparator`) that contains no nodes whose value is less than the
1220 /// specified `minNodeValue` (if not 0) or greater-than the specified
1221 /// `maxNodeValue` (if not 0). If `rootNode` does not refer to a valid
1222 /// red-black tree containing nodes whose values are between the
1223 /// specified `minNodeValue` and `maxNodeValue` (inclusively) then load
1224 /// `errorNode` and `errorDescription` with the address of a node
1225 /// violating a red-black tree constraint and a description of that
1226 /// violation, respectively. The behavior is undefined unless
1227 /// `rootNode` is 0, or refers to a valid binary tree.
1228 template <class NODE_COMPARATOR>
1229 static int validateRbTree(const RbTreeNode **errorNode,
1230 const char **errorDescription,
1231 const RbTreeNode *rootNode,
1232 const RbTreeNode *minNodeValue,
1233 const RbTreeNode *maxNodeValue,
1234 const NODE_COMPARATOR& comparator);
1235
1236 /// Return `true` if the specified `tree` is well-formed, without
1237 /// confirming that it refers to a valid-red-black tree, and
1238 /// `false` otherwise. This method will return `true` if *all* of the
1239 /// following are true:
1240 ///
1241 /// 1. `tree.firstNode()` must refer to `tree.sentinel()` if
1242 /// `tree.rootNode()` is 0, and leftmost(tree.rootNode())' otherwise.
1243 /// 2. `tree.nodeCount()` must be the count of nodes in `tree` (not
1244 /// including the sentinel node).
1245 /// 3. `tree.sentinel()->leftchild()` is `tree.rootNode()`, and (if
1246 /// `tree.rootNode()` is not 0), `tree.rootNode()->parent()` is
1247 /// 'tree.sentinel().
1248 /// 4. `tree.rootNode()` is 0 or `tree.rootNode().isBlack()` is `true`
1249 ///
1250 /// The behavior is undefined unless `tree.rootNode()` is 0, or refers
1251 /// to a valid binary tree. Note that this function provides a
1252 /// non-templatized implementation for several criteria of a
1253 /// well-formed tree (but not the complete set verified by
1254 /// `RbTreeUtil::isWellFormed`).
1255 static bool isWellFormedAnchor(const RbTreeAnchor& tree);
1256};
1257
1258 // ============================
1259 // struct RbTreeUtilTreeProctor
1260 // ============================
1261
1262/// This class implements a proctor that, unless `release` is called,
1263/// invokes the parameterized `DELETER` on each node in the tree supplied at
1264/// construction.
1265///
1266/// See @ref bslalg_rbtreeutil
1267template <class DELETER>
1269
1270 // DATA
1271 RbTreeAnchor *d_tree_p; // address of root node (held, not owned)
1272
1273 DELETER *d_deleter_p; // address of deleter used to destroy each
1274 // node (held, not owned)
1275
1276 public:
1277 // CREATORS
1278
1279 /// Create a proctor object that, unless `release` is called, will,
1280 /// on destruction, invoke the specified `deleter` on each node in
1281 /// `tree`.
1282 RbTreeUtilTreeProctor(RbTreeAnchor *tree, DELETER *deleter);
1283
1284 /// Unless `release` has been called, invoke the deleter supplied at
1285 /// construction on each node in the tree supplied at construction.
1287
1288 // MANIPULATORS
1289
1290 /// Release from management the tree supplied at construction.
1291 void release();
1292};
1293
1294// ============================================================================
1295// INLINE FUNCTION DEFINITIONS
1296// ============================================================================
1297
1298 // ----------------
1299 // class RbTreeUtil
1300 // ----------------
1301
1302// CLASS METHODS
1303inline
1305{
1306 return const_cast<RbTreeNode *>(
1307 leftmost(const_cast<const RbTreeNode *>(subtree)));
1308}
1309
1310inline
1312{
1313 return const_cast<RbTreeNode *>(
1314 rightmost(const_cast<const RbTreeNode *>(subtree)));
1315}
1316
1317inline
1319{
1320 return const_cast<RbTreeNode *>(
1321 next(const_cast<const RbTreeNode *>(node)));
1322}
1323
1324inline
1326{
1327 return const_cast<RbTreeNode *>(
1328 previous(const_cast<const RbTreeNode *>(node)));
1329}
1330
1331template <class NODE_VALUE_COMPARATOR, class VALUE>
1332inline
1334 NODE_VALUE_COMPARATOR& comparator,
1335 const VALUE& value)
1336{
1337 return const_cast<RbTreeNode *>(
1338 find(const_cast<const RbTreeAnchor&>(tree), comparator, value));
1339}
1340
1341template <class NODE_VALUE_COMPARATOR, class VALUE>
1342inline
1344 NODE_VALUE_COMPARATOR& comparator,
1345 const VALUE& value)
1346{
1347 const RbTreeNode *lowBound = lowerBound(tree, comparator, value);
1348
1349 // Note that a Solaris compiler bug prevents using a ternary ('?:')
1350 // operator here in certain contexts.
1351
1352 if (lowBound != tree.sentinel() && !comparator(value, *lowBound)) {
1353 return lowBound; // RETURN
1354 }
1355 return tree.sentinel();
1356}
1357
1358template <class NODE_VALUE_COMPARATOR, class VALUE>
1360 NODE_VALUE_COMPARATOR& comparator,
1361 const VALUE& value)
1362{
1363 return const_cast<RbTreeNode *>(
1364 lowerBound(const_cast<const RbTreeAnchor&>(tree), comparator, value));
1365}
1366
1367template <class NODE_VALUE_COMPARATOR, class VALUE>
1368inline
1370 NODE_VALUE_COMPARATOR& comparator,
1371 const VALUE& value)
1372{
1373 const RbTreeNode *nextLargestNode = tree.sentinel();
1374 const RbTreeNode *node = tree.rootNode();
1375 while (node) {
1376 if (comparator(*node, value)) {
1377 node = node->rightChild();
1378 }
1379 else {
1380 nextLargestNode = node;
1381 node = node->leftChild();
1382 }
1383 }
1384 return nextLargestNode;
1385}
1386
1387template <class NODE_VALUE_COMPARATOR, class VALUE>
1388inline
1390 NODE_VALUE_COMPARATOR& comparator,
1391 const VALUE& value)
1392{
1393 return const_cast<RbTreeNode *>(
1394 upperBound(const_cast<const RbTreeAnchor&>(tree), comparator, value));
1395}
1396
1397template <class NODE_VALUE_COMPARATOR, class VALUE>
1398inline
1400 NODE_VALUE_COMPARATOR& comparator,
1401 const VALUE& value)
1402{
1403 const RbTreeNode *nextLargestNode = tree.sentinel();
1404 const RbTreeNode *node = tree.rootNode();
1405 while (node) {
1406 if (comparator(value, *node)) {
1407 nextLargestNode = node;
1408 node = node->leftChild();
1409 }
1410 else {
1411 node = node->rightChild();
1412 }
1413 }
1414 return nextLargestNode;
1415}
1416
1417template <class FACTORY>
1419 const RbTreeAnchor& original,
1420 FACTORY *nodeFactory)
1421{
1422 BSLS_ASSERT_SAFE(result);
1423 BSLS_ASSERT_SAFE(0 == result->rootNode());
1424 BSLS_ASSERT_SAFE(nodeFactory);
1425
1426 if (!original.rootNode()) {
1427 result->reset(0, result->sentinel(), 0);
1428 return; // RETURN
1429 }
1430
1431 // Perform an pre-order traversal of the nodes of the tree, invoking
1432 // 'nodeFactory->createNode()' on each node.
1433
1434 const RbTreeNode *originalNode = original.rootNode();
1435
1436 RbTreeNode *copiedRoot = nodeFactory->cloneNode(*originalNode);
1437 RbTreeAnchor tree(copiedRoot, 0, 1);
1438
1439 RbTreeUtilTreeProctor<FACTORY> proctor(&tree, nodeFactory);
1440
1441 RbTreeNode *copiedNode = copiedRoot;
1442
1443 copiedNode->setColor(originalNode->color());
1444 copiedNode->setParent(result->sentinel());
1445 copiedNode->setLeftChild(0);
1446 copiedNode->setRightChild(0);
1447 do {
1448 if (0 != originalNode->leftChild() && 0 == copiedNode->leftChild()) {
1449 originalNode = originalNode->leftChild();
1450 RbTreeNode *newNode = nodeFactory->cloneNode(*originalNode);
1451 copiedNode->setLeftChild(newNode);
1452 newNode->setColor(originalNode->color());
1453 newNode->setParent(copiedNode);
1454 newNode->setLeftChild(0);
1455 newNode->setRightChild(0);
1456
1457 copiedNode = newNode;
1458 }
1459 else if (0 != originalNode->rightChild() &&
1460 0 == copiedNode->rightChild()) {
1461 originalNode = originalNode->rightChild();
1462 RbTreeNode *newNode = nodeFactory->cloneNode(*originalNode);
1463 copiedNode->setRightChild(newNode);
1464 newNode->setColor(originalNode->color());
1465 newNode->setParent(copiedNode);
1466 newNode->setLeftChild(0);
1467 newNode->setRightChild(0);
1468
1469 copiedNode = newNode;
1470 }
1471 else {
1472 originalNode = originalNode->parent();
1473 copiedNode = copiedNode->parent();
1474 }
1475 } while (original.sentinel() != originalNode);
1476
1477 proctor.release();
1478
1479 result->reset(copiedRoot,
1480 leftmost(copiedRoot),
1481 original.numNodes());
1482}
1483
1484template <class FACTORY>
1486 RbTreeAnchor *original,
1487 FACTORY *nodeFactory,
1488 FACTORY *originalNodeFactory)
1489{
1490 BSLS_ASSERT_SAFE(result);
1491 BSLS_ASSERT_SAFE(0 == result->rootNode());
1492 BSLS_ASSERT_SAFE(nodeFactory);
1493 BSLS_ASSERT_SAFE(originalNodeFactory);
1494
1495 if (!original->rootNode()) {
1496 result->reset(0, result->sentinel(), 0);
1497 return; // RETURN
1498 }
1499
1500 // Perform an pre-order traversal of the nodes of the tree, invoking
1501 // 'nodeFactory->createNode()' on each node.
1502
1503 RbTreeNode *originalNode = original->rootNode();
1504
1505 RbTreeNode *copiedRoot = nodeFactory->moveIntoNewNode(originalNode);
1506
1507 RbTreeAnchor tree(copiedRoot, 0, 1);
1508
1509 RbTreeUtilTreeProctor<FACTORY> proctor(&tree, nodeFactory);
1510 RbTreeUtilTreeProctor<FACTORY> oproctor(original, originalNodeFactory);
1511
1512 RbTreeNode *copiedNode = copiedRoot;
1513
1514 copiedNode->setColor(originalNode->color());
1515 copiedNode->setParent(result->sentinel());
1516 copiedNode->setLeftChild(0);
1517 copiedNode->setRightChild(0);
1518 do {
1519 if (0 != originalNode->leftChild() && 0 == copiedNode->leftChild()) {
1520 originalNode = originalNode->leftChild();
1521 RbTreeNode *newNode = nodeFactory->moveIntoNewNode(originalNode);
1522 copiedNode->setLeftChild(newNode);
1523 newNode->setColor(originalNode->color());
1524 newNode->setParent(copiedNode);
1525 newNode->setLeftChild(0);
1526 newNode->setRightChild(0);
1527
1528 copiedNode = newNode;
1529 }
1530 else if (0 != originalNode->rightChild() &&
1531 0 == copiedNode->rightChild()) {
1532 originalNode = originalNode->rightChild();
1533 RbTreeNode *newNode = nodeFactory->moveIntoNewNode(originalNode);
1534 copiedNode->setRightChild(newNode);
1535 newNode->setColor(originalNode->color());
1536 newNode->setParent(copiedNode);
1537 newNode->setLeftChild(0);
1538 newNode->setRightChild(0);
1539
1540 copiedNode = newNode;
1541 }
1542 else {
1543 originalNode = originalNode->parent();
1544 copiedNode = copiedNode->parent();
1545 }
1546 } while (original->sentinel() != originalNode);
1547
1548 proctor.release();
1549
1550 result->reset(copiedRoot,
1551 leftmost(copiedRoot),
1552 original->numNodes());
1553
1554 // 'oproctor' takes care of clearing 'original', even when an exception is
1555 // not thrown, since the tree is no longer valid if the elements have been
1556 // moved from.
1557}
1558
1559template <class FACTORY>
1560void RbTreeUtil::deleteTree(RbTreeAnchor *tree, FACTORY *nodeFactory)
1561{
1562 BSLS_ASSERT_SAFE(tree);
1563 BSLS_ASSERT_SAFE(nodeFactory);
1564
1565 if (0 == tree->rootNode()) {
1566 BSLS_ASSERT_SAFE(tree->sentinel() == tree->firstNode());
1567 return; // RETURN
1568 }
1569
1570 // Perform a post-order traversal of the nodes of the tree, invoking
1571 // 'nodeFactory->deleteNode()' on each node.
1572
1573 RbTreeNode *node = tree->firstNode();
1574 do {
1575 // At each iteration through this loop, we are at a leftmost (i.e.,
1576 // minimum) node of some sub-tree. Note that 'node->leftChild()' may
1577 // not be 0 if we've simply deleted the left sub-tree of this node.
1578
1579 if (node->rightChild()) {
1580 // If this node has a right child, then navigate to the first node
1581 // in the subtree to remove, and set 'node->rightChild()' to 0 so
1582 // we know this sub-tree has been removed when we iterate back up
1583 // parent pointers of the tree to this node.
1584
1585 RbTreeNode *rightChild = node->rightChild();
1586 node->setRightChild(0);
1587 node = leftmost(rightChild);
1588 }
1589 else {
1590 RbTreeNode *parent = node->parent();
1591 nodeFactory->deleteNode(node);
1592 node = parent;
1593 }
1594 } while (tree->sentinel() != node);
1595 tree->reset(0, tree->sentinel(), 0);
1596}
1597
1598template <class NODE_VALUE_COMPARATOR, class VALUE>
1600 bool *insertAsLeftChildFlag,
1601 RbTreeAnchor *tree,
1602 NODE_VALUE_COMPARATOR& comparator,
1603 const VALUE& value)
1604{
1605 BSLS_ASSERT_SAFE(insertAsLeftChildFlag);
1606 BSLS_ASSERT_SAFE(tree);
1607
1608 RbTreeNode *parent = tree->sentinel();
1609 RbTreeNode *node = tree->rootNode();
1610 *insertAsLeftChildFlag = true;
1611 while (node) {
1612 // Find the leaf node that would be the parent of 'newNode'.
1613
1614 parent = node;
1615 *insertAsLeftChildFlag = comparator(value, *node);
1616 if (*insertAsLeftChildFlag) {
1617 node = node->leftChild();
1618 }
1619 else {
1620 node = node->rightChild();
1621 }
1622 }
1623 return parent;
1624}
1625
1626template <class NODE_VALUE_COMPARATOR, class VALUE>
1628 bool *insertAsLeftChildFlag,
1629 RbTreeAnchor *tree,
1630 NODE_VALUE_COMPARATOR& comparator,
1631 const VALUE& value,
1632 RbTreeNode *hint)
1633{
1634 BSLS_ASSERT_SAFE(insertAsLeftChildFlag);
1635 BSLS_ASSERT_SAFE(tree);
1636 BSLS_ASSERT_SAFE(hint);
1637
1638 // 'hint' is valid if it is equal to, or the smallest value greater than,
1639 // 'value'.
1640
1641 if (tree->sentinel() == hint || !comparator(*hint, value)) {
1642 // 'hint' is greater-than or equal-to 'value', if the previous node,
1643 // 'prev' is less-than or equal-to 'value', then we have a valid hint.
1644
1645 RbTreeNode *prev = (tree->firstNode() == hint) ? hint : previous(hint);
1646 if (tree->firstNode() == hint || !comparator(value, *prev)) {
1647 // There will be an empty position for a child node between every
1648 // two consecutive nodes (in an in-order traversal) of a binary
1649 // tree. Determine whether that empty position is the left child
1650 // of 'hint' or the right child of 'prev'.
1651
1652 if (0 == hint->leftChild()) {
1653 *insertAsLeftChildFlag = true;
1654 return hint; // RETURN
1655 }
1656 BSLS_ASSERT_SAFE(prev);
1657 *insertAsLeftChildFlag = false;
1658 return prev; // RETURN
1659 }
1660 // 'prev' is greater than 'value', so this is not a valid hint.
1661
1662 }
1663 // If 'hint' was less than 'value', it is not a valid hint.
1664
1665 // The 'hint' is not valid, fall-back and search the entire tree.
1666
1667 return findInsertLocation(insertAsLeftChildFlag, tree, comparator, value);
1668}
1669
1670template <class NODE_VALUE_COMPARATOR, class VALUE>
1672 int *comparisonResult,
1673 RbTreeAnchor *tree,
1674 NODE_VALUE_COMPARATOR& comparator,
1675 const VALUE& value)
1676{
1677 BSLS_ASSERT_SAFE(comparisonResult);
1678 BSLS_ASSERT_SAFE(tree);
1679
1680 // Note that 'nextSmallestNode' is used, rather than 'nextLargestNode' (as
1681 // seen in 'upperBound' and 'lowerBound') to avoid an unnecessary
1682 // negation.
1683
1684 RbTreeNode *parent = tree->sentinel();
1685 RbTreeNode *nextSmallestNode = 0;
1686 RbTreeNode *node = tree->rootNode();
1687
1688 bool leftChild = true;
1689 while (node) {
1690 // Find the leaf node that would be the parent of 'newNode'.
1691
1692 parent = node;
1693 leftChild = comparator(value, *node);
1694 if (leftChild) {
1695 node = node->leftChild();
1696 }
1697 else {
1698 nextSmallestNode = node;
1699 node = node->rightChild();
1700 }
1701 }
1702
1703 if (nextSmallestNode && !comparator(*nextSmallestNode, value)) {
1704 *comparisonResult = 0;
1705 return nextSmallestNode; // RETURN
1706 }
1707 *comparisonResult = leftChild ? -1 : 1;
1708 return parent;
1709}
1710
1711template <class NODE_VALUE_COMPARATOR, class VALUE>
1713 int *comparisonResult,
1714 RbTreeAnchor *tree,
1715 NODE_VALUE_COMPARATOR& comparator,
1716 const VALUE& value,
1717 RbTreeNode *hint)
1718{
1719 BSLS_ASSERT_SAFE(comparisonResult);
1720 BSLS_ASSERT_SAFE(tree);
1721 BSLS_ASSERT_SAFE(hint);
1722
1723 enum { LEFT_CHILD = -1, NODE_FOUND = 0, RIGHT_CHILD = 1 };
1724
1725 // 'hint' is valid if it is first value greater than 'value' in the tree.
1726
1727 if (tree->sentinel() == hint || comparator(value, *hint)) {
1728 // 'hint' is greater than 'value'. If the previous node, 'prev' is
1729 // less than the value, then we have a valid hint.
1730
1731 RbTreeNode *prev = (tree->firstNode() == hint) ? hint : previous(hint);
1732 if (tree->firstNode() == hint || comparator(*prev, value)) {
1733 // There will be an empty position for a child node between every
1734 // two consecutive nodes (in an in-order traversal) of a binary
1735 // tree. Determine whether that empty position is the left child
1736 // of 'hint' or the right child of 'prev'.
1737
1738 if (0 == hint->leftChild()) {
1739 *comparisonResult = LEFT_CHILD;
1740 return hint; // RETURN
1741 }
1742
1743 BSLS_ASSERT_SAFE(prev);
1744 *comparisonResult = RIGHT_CHILD;
1745 return prev; // RETURN
1746 }
1747 // 'value' is ordered before 'hint', but 'prev' is not ordered before
1748 // 'value', so either: (1) 'value' is equal to 'prev' or (2) 'hint' is
1749 // not a valid hint. Optimize for (1), by handling it as a special
1750 // case, as this may reasonably occur using 'upperBound' on 'value' to
1751 // determine a hint.
1752
1753 if (!comparator(value, *prev)) {
1754 *comparisonResult = NODE_FOUND;
1755 return prev; // RETURN
1756 }
1757
1758 // 'prev' is greater than 'value', so this is not a valid hint.
1759 }
1760 // If 'value' is not ordered before 'hint', either: (1) 'value' is equal
1761 // to 'hint', or (2) 'hint' is not a valid hint. Optimize for (1).
1762
1763 else if (tree->sentinel() != hint && !comparator(*hint, value)) {
1764 *comparisonResult = NODE_FOUND;
1765 return hint; // RETURN
1766 }
1767 // The 'hint' is not valid, fall-back and search the entire tree.
1768
1769 return findUniqueInsertLocation(comparisonResult,
1770 tree,
1771 comparator,
1772 value);
1773}
1774
1775template <class NODE_COMPARATOR>
1777 const NODE_COMPARATOR& comparator,
1778 RbTreeNode *newNode)
1779{
1780 BSLS_ASSERT_SAFE(tree);
1781 BSLS_ASSERT_SAFE(newNode);
1782
1783 // Note that the following logic is the same as 'findInsertLocation'
1784 // except that the comparator required for this operation compares two
1785 // nodes, rather than comparing a value to a node.
1786
1787 RbTreeNode *parent = tree->sentinel();
1788 RbTreeNode *node = tree->rootNode();
1789 bool leftChildFlag = true;
1790 while (node) {
1791 // Find the leaf node that would be the parent of 'newNode'.
1792
1793 parent = node;
1794 leftChildFlag = comparator(*newNode, *node);
1795 if (leftChildFlag) {
1796 node = node->leftChild();
1797 }
1798 else {
1799 node = node->rightChild();
1800 }
1801 }
1802 return insertAt(tree, parent, leftChildFlag, newNode);
1803}
1804
1805inline
1807{
1808 BSLS_ASSERT_SAFE(node);
1809 BSLS_ASSERT_SAFE(node->parent());
1810
1811 return node->parent()->leftChild() == node;
1812}
1813
1814inline
1816{
1817 BSLS_ASSERT_SAFE(node);
1818 BSLS_ASSERT_SAFE(node->parent());
1819
1820 return node->parent()->rightChild() == node;
1821}
1822
1823template <class NODE_COMPARATOR>
1824inline
1826 const NODE_COMPARATOR& comparator)
1827{
1828 const RbTreeNode *errorNode;
1829 const char *errorDescription;
1830 return validateRbTree(&errorNode, &errorDescription, rootNode, comparator);
1831}
1832
1833template <class NODE_COMPARATOR>
1835 const char **errorDescription,
1836 const RbTreeNode *rootNode,
1837 const NODE_COMPARATOR& comparator)
1838{
1839 BSLS_ASSERT(errorNode);
1840 BSLS_ASSERT(errorDescription);
1841
1842 return RbTreeUtil_Validator::validateRbTree(errorNode,
1843 errorDescription,
1844 rootNode,
1845 0,
1846 0,
1847 comparator);
1848}
1849
1850template <class NODE_COMPARATOR>
1851inline
1853 const NODE_COMPARATOR& comparator)
1854{
1856 return false; // RETURN
1857 }
1858 return 0 <= validateRbTree(tree.rootNode(), comparator);
1859}
1860
1861 // --------------------------
1862 // class RbTreeUtil_Validator
1863 // --------------------------
1864
1865// CLASS METHODS
1866template <class NODE_COMPARATOR>
1868 const RbTreeNode **errorNode,
1869 const char **errorDescription,
1870 const RbTreeNode *rootNode,
1871 const RbTreeNode *minNodeValue,
1872 const RbTreeNode *maxNodeValue,
1873 const NODE_COMPARATOR& comparator)
1874{
1875 BSLS_ASSERT_SAFE(errorNode);
1876 BSLS_ASSERT_SAFE(errorDescription);
1877
1878 //: 1 All the descendents to the left of each node are ordered that at or
1879 //: before that node, and all descendents to the right of each node are
1880 //: ordered at or after that node, as determined by 'comparator'.
1881 //:
1882 //: 2 Both children of every node refer to 'node' as a parent.
1883 //:
1884 //: 3 If a node in the tree has no children, it is black.
1885 //:
1886 //: 4 If a node in the tree is red, its children are either black or 0.
1887 //:
1888 //: 5 For each node in the tree, every path from that node to a leaf
1889 //: contains the same number of black nodes.
1890
1891 enum { INVALID_RBTREE = -1};
1892
1893 // 'NIL' nodes are considered black
1894
1895 if (!rootNode) {
1896 return 0; // RETURN
1897 }
1898
1899 // Rule 1.
1900
1901 if ((minNodeValue && comparator(*rootNode, *minNodeValue)) ||
1902 (maxNodeValue && comparator(*maxNodeValue, *rootNode))) {
1903 *errorNode = rootNode;
1904 *errorDescription = "Invalid binary search tree.";
1905 return INVALID_RBTREE; // RETURN
1906 }
1907
1908 const RbTreeNode *left = rootNode->leftChild();
1909 const RbTreeNode *right = rootNode->rightChild();
1910 if ((left != 0 || right != 0) && left == right) {
1911 *errorNode = rootNode;
1912 *errorDescription = "Invalid children";
1913 return INVALID_RBTREE; // RETURN
1914 }
1915
1916 // Rule 2.
1917
1918 if ((left && left->parent() != rootNode) ||
1919 (right && right->parent() != rootNode)) {
1920 *errorNode = rootNode;
1921 *errorDescription = "Invalid parent pointers for children";
1922 return INVALID_RBTREE; // RETURN
1923 }
1924
1925 // Rule 4.
1926
1927 if (RbTreeNode::BSLALG_RED == rootNode->color()) {
1928 if ((left && left->color() != RbTreeNode::BSLALG_BLACK) ||
1929 (right && right->color() != RbTreeNode::BSLALG_BLACK)) {
1930 *errorNode = rootNode;
1931 *errorDescription = "Red node with a red child.";
1932 return INVALID_RBTREE; // RETURN
1933 }
1934 }
1935
1936 int leftDepth = validateRbTree(errorNode,
1937 errorDescription,
1938 rootNode->leftChild(),
1939 minNodeValue,
1940 rootNode,
1941 comparator);
1942 int rightDepth = validateRbTree(errorNode,
1943 errorDescription,
1944 rootNode->rightChild(),
1945 rootNode,
1946 maxNodeValue,
1947 comparator);
1948
1949 if (leftDepth < 0 || rightDepth < 0) {
1950 return INVALID_RBTREE; // RETURN
1951 }
1952
1953 // Rule 5.
1954
1955 if (leftDepth != rightDepth) {
1956 *errorNode = rootNode;
1957 *errorDescription =
1958 "Black violation (unequal black depth from node to leaves).";
1959 return INVALID_RBTREE; // RETURN
1960 }
1961
1962 return (rootNode->color() == RbTreeNode::BSLALG_BLACK)
1963 ? leftDepth + 1
1964 : leftDepth;
1965}
1966
1967 // ----------------------------
1968 // struct RbTreeUtilTreeProctor
1969 // ----------------------------
1970
1971template <class DELETER>
1972inline
1974 DELETER *deleter)
1975: d_tree_p(tree)
1976, d_deleter_p(deleter)
1977{
1978 BSLS_ASSERT_SAFE(deleter);
1979}
1980
1981template <class DELETER>
1982inline
1984{
1985 if (d_tree_p && d_tree_p->rootNode()) {
1986 d_tree_p->rootNode()->setParent(d_tree_p->sentinel());
1987
1988 d_tree_p->setFirstNode(RbTreeUtil::leftmost(d_tree_p->rootNode()));
1989 RbTreeUtil::deleteTree(d_tree_p, d_deleter_p);
1990 }
1991}
1992
1993template <class DELETER>
1994inline
1996{
1997 d_tree_p = 0;
1998}
1999
2000} // close package namespace
2001
2002
2003#endif
2004
2005// ----------------------------------------------------------------------------
2006// Copyright 2013 Bloomberg Finance L.P.
2007//
2008// Licensed under the Apache License, Version 2.0 (the "License");
2009// you may not use this file except in compliance with the License.
2010// You may obtain a copy of the License at
2011//
2012// http://www.apache.org/licenses/LICENSE-2.0
2013//
2014// Unless required by applicable law or agreed to in writing, software
2015// distributed under the License is distributed on an "AS IS" BASIS,
2016// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2017// See the License for the specific language governing permissions and
2018// limitations under the License.
2019// ----------------------------- END-OF-FILE ----------------------------------
2020
2021/** @} */
2022/** @} */
2023/** @} */
Definition bslalg_rbtreeanchor.h:352
RbTreeNode * sentinel()
Definition bslalg_rbtreeanchor.h:533
RbTreeNode * firstNode()
Definition bslalg_rbtreeanchor.h:521
int numNodes() const
Return the numNodes attribute of this object.
Definition bslalg_rbtreeanchor.h:552
RbTreeNode * rootNode()
Definition bslalg_rbtreeanchor.h:527
void reset(RbTreeNode *rootNode, RbTreeNode *firstNode, int numNodes)
Definition bslalg_rbtreeanchor.h:479
Definition bslalg_rbtreenode.h:376
RbTreeNode * rightChild()
Definition bslalg_rbtreenode.h:598
RbTreeNode * leftChild()
Definition bslalg_rbtreenode.h:592
void setRightChild(RbTreeNode *address)
Definition bslalg_rbtreenode.h:552
void setParent(RbTreeNode *address)
Definition bslalg_rbtreenode.h:537
Color color() const
Return the color of this node.
Definition bslalg_rbtreenode.h:635
void setLeftChild(RbTreeNode *address)
Definition bslalg_rbtreenode.h:546
void setColor(Color value)
Set the color of this node to the specified value.
Definition bslalg_rbtreenode.h:558
RbTreeNode * parent()
Definition bslalg_rbtreenode.h:586
@ BSLALG_BLACK
Definition bslalg_rbtreenode.h:382
@ BSLALG_RED
Definition bslalg_rbtreenode.h:381
Definition bslalg_rbtreeutil.h:1268
void release()
Release from management the tree supplied at construction.
Definition bslalg_rbtreeutil.h:1995
~RbTreeUtilTreeProctor()
Definition bslalg_rbtreeutil.h:1983
RbTreeUtilTreeProctor(RbTreeAnchor *tree, DELETER *deleter)
Definition bslalg_rbtreeutil.h:1973
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlc_flathashmap.h:1805
Definition bslalg_rbtreeutil.h:1211
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:1867
static bool isWellFormedAnchor(const RbTreeAnchor &tree)
Definition bslalg_rbtreeutil.h:756
static const RbTreeNode * rightmost(const RbTreeNode *subtree)
static bool isLeftChild(const RbTreeNode *node)
Definition bslalg_rbtreeutil.h:1806
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:1399
static void swap(RbTreeAnchor *a, RbTreeAnchor *b)
static void deleteTree(RbTreeAnchor *tree, FACTORY *nodeFactory)
Definition bslalg_rbtreeutil.h:1560
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:1599
static RbTreeNode * findUniqueInsertLocation(int *comparisonResult, RbTreeAnchor *tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1671
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:1825
static void copyTree(RbTreeAnchor *result, const RbTreeAnchor &original, FACTORY *nodeFactory)
Definition bslalg_rbtreeutil.h:1418
static void moveTree(RbTreeAnchor *result, RbTreeAnchor *original, FACTORY *nodeFactory, FACTORY *originalNodeFactory)
Definition bslalg_rbtreeutil.h:1485
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:1343
static bool isWellFormed(const RbTreeAnchor &tree, const NODE_COMPARATOR &comparator)
Definition bslalg_rbtreeutil.h:1852
static bool isRightChild(const RbTreeNode *node)
Definition bslalg_rbtreeutil.h:1815
static const RbTreeNode * lowerBound(const RbTreeAnchor &tree, NODE_VALUE_COMPARATOR &comparator, const VALUE &value)
Definition bslalg_rbtreeutil.h:1369
static void insert(RbTreeAnchor *tree, const NODE_COMPARATOR &comparator, RbTreeNode *newNode)
Definition bslalg_rbtreeutil.h:1776
static void rotateRight(RbTreeNode *node)