// bslalg_rbtreeanchor.h                                              -*-C++-*-
#ifndef INCLUDED_BSLALG_RBTREEANCHOR
#define INCLUDED_BSLALG_RBTREEANCHOR

#include <bsls_ident.h>
BSLS_IDENT("$Id$ $CSID$")

//@PURPOSE: Encapsulate root, first, and last nodes of a tree with a count.
//
//@CLASSES:
//  bslalg::RbTreeAnchor: (in-core) node-addresses and node count
//
//@SEE_ALSO: bslalg_rbtreenode, bslalg_rbtreeutil
//
//@DESCRIPTION: This component defines a single class, 'RbTreeAnchor',
// providing access to the addresses of the root, first, and sentinel nodes of
// a tree, as well as the count of the number of nodes.  A sentinel node is a
// value-less node, owned by the 'RbTreeAnchor' for the tree, that is used as
// the end-point for iteration over the nodes in a tree.  'RbTreeAnchor'
// provides modifiers for the 'firstNode', 'rootNode', and 'numNodes'
// properties, however the sentinel node for a tree is located at a fixed
// address and cannot be modified.  An 'RbTreeAnchor' is similar to an in-core
// unconstrained attribute class, except that it does not supply
// equality-comparison, copy-construction, and copy-assignment operations.
//
///Sentinel Node
///-------------
// The sentinel node is an 'RbTreeNode' object that does not have a value, and
// provides a fixed end-point for navigation over the tree.  However, a
// sentinel node's attributes have different interpretations than those of
// other 'RbTreeNode' objects.  Specifically, a sentinel node's 'leftChild'
// refers to the root of the tree, and its 'rightChild' refers to the first
// node of the tree.  The following diagram shows the composition of a tree
// with 'RbTreeAnchor' and 'RbTreeNode':
//..
//                        .------------------------.
//                 .------|      RbTreeAnchor      |-------.
//                 |      |                        |       |
//       firstNode |      |    .--------------.    |       | rootNode
//                 |      |    |  RbTreeNode  |    |       |
//                 |      |    |  (sentinel)  |    |       |
//                 |      |    `--------------'    |       |
//                 |      |      /    ^      \     |       |
//                 |      `-----/-----|-------\----'       |
//                 V           /      |        \           V
//                  __________/       |         \__________
//                 |                  |                    |
//                 |                  |                    |
//        sentinel |             root |                    | sentinel
//   *right*-child |       parentNode |                    | *left*-child
//                 |                  |                    |
//                 |           .--------------.            |
//                 |           |  RbTreeNode  | <----------'
//                 |           |    (root)    |
//                 |           `--------------'
//                 |                /   \.
//                 |     .------------. .------------.
//                 |     | RbTreeNode | | RbTreeNode |
//                 |     `------------' `------------'
//                 |         /                \.
//                 |    .-----------------------------.
//                 |    |                             |
//                 |    |    [Tree of RbTreeNodes]    |
//                 |    |                             |
//                 |    |_____________________________|
//                 V   /                               \.
//        .------------.                                .------------.
//        | RbTreeNode |                                | RbTreeNode |
//        |   (first)  |                                |   (last)   |
//        `------------'                                `------------'
//..
// Notice that, counter-intuitively, the sentinel's right-child refers to the
// left-most (first) node of the tree.  Also notice that 'RbTreeAnchor'
// doesn't hold a direct reference to the last (i.e., the right-most) node of
// the tree.
//
///Usage
///-----
// This section illustrates intended usage of this component.
//
///Example 1: Creating a Simple Tree
///- - - - - - - - - - - - - - - - -
// This example demonstrates creating a simple tree of integer values using
// 'RbTreeAnchor'.  Note that, in practice, clients should use associated
// utilities to manage such a tree (see 'bslalg_rbtreeutil').
//
// First, we define a node-type, 'IntTreeNode', that inherits from
// 'RbTreeNode':
//..
//  struct IntTreeNode : public RbTreeNode {
//      // A red-black tree node containing an integer data-value.
//
//      int d_value;  // "payload" value represented by the node
//  };
//..
// Then, we define 'main' for our example, and create three nodes that we'll
// use to construct a tree:
//..
//  int main(int argc, const char *argv[])
//  {
//      IntTreeNode A, B, C;
//..
// Next, we create an 'RbTreeAnchor', 'myTree', which will hold the addresses
// of the root node and the first node of our tree along with a count of nodes,
// and then verify the attribute values of the default constructed object:
//..
//      RbTreeAnchor myTree;
//      assert(0                 == myTree.rootNode());
//      assert(myTree.sentinel() == myTree.firstNode());
//      assert(0                 == myTree.numNodes());
//..
// Then, we describe the structure of the tree we wish to construct.
//..
//
//          A (value: 2, BLACK)
//              /       \.
//             /         \.
//  B (value: 1, RED)   C ( value: 5, RED )
//..
// Next, we set the properties for the nodes 'A', 'B', and 'C' to form a valid
// tree whose structure matches that description:
//..
//      A.d_value = 2;
//      A.makeBlack();
//      A.setParent(myTree.sentinel());
//      A.setLeftChild(&B);
//      A.setRightChild(&C);
//
//      B.d_value = 1;
//      B.makeRed();
//      B.setParent(&A);
//      B.setLeftChild(0);
//      B.setRightChild(0);
//
//      C.d_value = 3;
//      C.makeRed();
//      C.setParent(&A);
//      C.setLeftChild(0);
//      C.setRightChild(0);
//..
// Now, we assign the address of 'A' and 'B' as the root node and the first
// node of 'myTree' respectively and set the number of nodes to 3:
//..
//      myTree.reset(&A, &B, 3);
//..
// Finally, we verify the attributes of 'myTree':
//..
//      assert(&A == myTree.rootNode());
//      assert(&B == myTree.firstNode());
//      assert(3  == myTree.numNodes());
//..
//
///Example 2: Creating an Insert Function for a Binary Tree
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// This example demonstrates creating a function that inserts elements into a
// binary search tree.  Note that, for simplicity, this function does *not*
// create a balanced red-black tree (see 'bslalg_rbtreeutil').
//
// First, we define a comparison functor for 'IntTreeNode' objects used by the
// insertion function:
//..
//  struct IntTreeNodeComparator {
//      // This class defines a comparator providing a comparison operation
//      // between two 'IntTreeNode' objects.
//
//      bool operator()(const RbTreeNode& lhs, const RbTreeNode& rhs)  const
//      {
//          return static_cast<const IntTreeNode&>(lhs).d_value <
//                 static_cast<const IntTreeNode&>(rhs).d_value;
//      }
//  };
//..
// Then, we declare the signature of a function 'insertNode', which takes
// three arguments: (1) the anchor of the tree in which to insert the node (2)
// the new node to insert into the tree, and (3) a comparator, which is used to
// compare the payload values of the tree nodes.  Note that the parameterized
// comparator is needed because a node's value is not accessible through the
// supplied 'RbTreeNode'.
//..
//  template <class NODE_COMPARATOR>
//  void insertNode(RbTreeAnchor           *searchTree,
//                  RbTreeNode             *newNode,
//                  const NODE_COMPARATOR&  comparator)
//      // Insert into the specified 'searchTree', ordered according to the
//      // specified 'comparator', the specified 'newNode'.  If there are
//      // multiple nodes having the same value as 'newNode', insert 'newNode'
//      // in the last position according to an infix traversal of the tree.
//      // The behavior is undefined unless the 'comparator' provides a
//      // strict weak ordering on the nodes in the tree.
//  {
//..
// Next, we find the location where 'newNode' can be inserted into 'searchTree'
// without violating the ordering imposed by 'comparator', and then updates
// 'searchTree' with a potentially updated root node and first node.
//..
//      RbTreeNode *parent = searchTree->sentinel();
//      RbTreeNode *node   = searchTree->rootNode();
//      bool        isLeftChild;
//
//      newNode->setLeftChild(0);
//      newNode->setRightChild(0);
//
//      if (!node) {
//..
// If the root node of 'searchTree' is 0, we use the 'reset' function set the
// root node and the first node of 'searchTree' to 'newNode' and set the number
// of nodes to 1:
//..
//          searchTree->reset(newNode, newNode, 1);
//          newNode->setParent(parent);
//          return;                                                   // RETURN
//      }
//
//      // Find the leaf node that would be a valid parent of 'newNode'.
//
//      do {
//          parent = node;
//          isLeftChild = comparator(*newNode, *node);
//          if (isLeftChild) {
//              node = parent->leftChild();
//          }
//          else {
//              node = parent->rightChild();
//          }
//      } while (node);
//
//      // Insert 'newNode' into 'searchTree' and the location that's been
//      // found.
//..
// Then, we insert 'newNode' into the appropriate position by setting it as a
// child of 'parent':
//..
//      if (isLeftChild) {
//          // If 'newNode' is a left-child, it may be the new first node, but
//          // cannot be the new last node.
//
//          parent->setLeftChild(newNode);
//          newNode->setParent(parent);
//          if (parent == searchTree->firstNode()) {
//              searchTree->setFirstNode(newNode);
//          }
//      }
//      else {
//          parent->setRightChild(newNode);
//          newNode->setParent(parent);
//      }
//..
// Next, we complete the insert function by incrementing the number of nodes in
// the tree:
//..
//      searchTree->incrementNumNodes();
//  }
//..
// Now, we create 5 'IntTreeNode' objects and insert them into a tree using the
// 'insertNode' function.
//..
//  IntTreeNode nodes[5];
//
//  nodes[0].d_value = 3;
//  nodes[1].d_value = 1;
//  nodes[2].d_value = 5;
//  nodes[3].d_value = 2;
//  nodes[4].d_value = 0;
//
//  IntTreeNodeComparator comparator;
//
//  RbTreeAnchor anchor;
//  for (int i = 0; i < 5; ++i) {
//      insertNode(&anchor, nodes + i, comparator);
//  }
//..
// Finally, we verify that the 'RbTreeAnchor' refers to the correct 'TreeNode'
// with its 'firstNode' and 'rootNode' attributes.
//..
//  assert(0 == static_cast<IntTreeNode *>(anchor.firstNode())->d_value);
//  assert(3 == static_cast<IntTreeNode *>(anchor.rootNode())->d_value);
//..

#include <bslscm_version.h>

#include <bslalg_rbtreenode.h>

#include <bslmf_assert.h>

#include <bsls_assert.h>

namespace BloombergLP {
namespace bslalg {

                        // ==================
                        // class RbTreeAnchor
                        // ==================

class RbTreeAnchor {
    // An 'RbTreeAnchor' provides the addresses of the first and root nodes of
    // a binary search tree.  An 'RbTreeAnchor' is similar to an in-core
    // simply constrained (value-semantic) attribute class, except that it
    // does not supply equality-comparison, copy-construction, and
    // copy-assignment operations.  Note that a node may not be copied because
    // 'sentinel' returns an address unique to each 'RbTreeAnchor' object.
    //
    // This class:
    //: o is *exception-neutral*
    //: o is *alias-safe*
    //: o is 'const' *thread-safe*
    // For terminology see 'bsldoc_glossary'.

    // DATA
    RbTreeNode  d_sentinel;  // sentinel for the tree, holding the root,
                             // first and last tree nodes

    int         d_numNodes;  // number of nodes

  private:
    // NOT IMPLEMENTED
    RbTreeAnchor(const RbTreeAnchor&);
    RbTreeAnchor& operator=(const RbTreeAnchor&);

  public:
    // CREATORS
    RbTreeAnchor();
        // Create a 'RbTree' object having the (default) attribute values:
        //..
        //  rootNode()  == 0
        //  firstNode() == sentinel()
        //  numNodes()  == 0
        //..

    RbTreeAnchor(RbTreeNode *rootNode,
                 RbTreeNode *firstNode,
                 int         numNodes);
        // Create a 'RbTreeAnchor' object having the specified 'rootNode',
        // 'firstNode', and 'numNodes' attribute values.

    ~RbTreeAnchor();
        // Destroy this object.

    // MANIPULATORS
    void reset(RbTreeNode *rootNode,
               RbTreeNode *firstNode,
               int         numNodes);
        // Set the 'rootNode', 'firstNode', and 'numNodes'
        // attributes to the specified 'rootNodeValue', 'firstNodeValue',
        // and 'numNodes' respectively.

    void setFirstNode(RbTreeNode *value);
        // Set the 'firstNode' attribute of this object to the specified
        // 'value'.

    void setRootNode(RbTreeNode *value);
        // Set the 'rootNode' attribute of this object to the specified
        // 'value'.

    void setNumNodes(int value);
        // Set the 'numNodes' attribute of this object to the specified
        // 'value'.  The behavior is undefined unless '0 <= value'.

    void incrementNumNodes();
        // Increment, by 1, the 'numNodes' attribute of this object.  The
        // behavior is undefined unless 'numNodes <= INT_MAX - 1'.

    void decrementNumNodes();
        // Decrement, by 1, the 'numNodes' attribute of this object.  The
        // behavior is undefined unless '1 <= numNodes'.

    RbTreeNode *rootNode();
        // Return the address of the (modifiable) node referred to by the
        // 'rootNode' attribute of this object.

    RbTreeNode *firstNode();
        // Return the address of the (modifiable) node referred to by the
        // 'firstNode' attribute of this object.

    RbTreeNode *sentinel();
        // Return the address of the (modifiable) node referred to by the
        // 'sentinel' node for this tree.

    // ACCESSORS
    const RbTreeNode *firstNode() const;
        // Return the address referred to by the 'firstNode' attribute of this
        // object.

    const RbTreeNode *rootNode() const;
        // Return the address referred to by the 'rootNode' attribute of this
        // object.

    const RbTreeNode *sentinel() const;
        // Return the address referred to by the 'sentinel' node for this tree.

    int numNodes() const;
        // Return the 'numNodes' attribute of this object.
};

// ============================================================================
//                      INLINE FUNCTION DEFINITIONS
// ============================================================================

                        // ------------------
                        // class RbTreeAnchor
                        // ------------------

// CREATORS
inline
RbTreeAnchor::RbTreeAnchor()
: d_numNodes(0)
{
    d_sentinel.setRightChild(&d_sentinel);
    d_sentinel.setLeftChild(0);
}

inline
RbTreeAnchor::RbTreeAnchor(RbTreeNode *rootNode,
                           RbTreeNode *firstNode,
                           int         numNodes)
: d_numNodes(numNodes)
{
    d_sentinel.setRightChild(firstNode);
    d_sentinel.setLeftChild(rootNode);
}

inline
RbTreeAnchor::~RbTreeAnchor()
{
    BSLS_ASSERT_SAFE(sentinel()->leftChild() == rootNode());
    BSLS_ASSERT_SAFE(sentinel()->rightChild() == firstNode());
}

// MANIPULATORS
inline
void RbTreeAnchor::reset(RbTreeNode *rootNode,
                         RbTreeNode *firstNode,
                         int         numNodes)
{
    d_sentinel.setLeftChild(rootNode);
    d_sentinel.setRightChild(firstNode);
    d_numNodes = numNodes;
}

inline
void RbTreeAnchor::setFirstNode(RbTreeNode *value)
{
    d_sentinel.setRightChild(value);
}

inline
void RbTreeAnchor::setRootNode(RbTreeNode *value)
{
    d_sentinel.setLeftChild(value);
}

inline
void RbTreeAnchor::setNumNodes(int value)
{
    BSLS_ASSERT_SAFE(0 <= value);

    d_numNodes = value;
}

inline
void RbTreeAnchor::incrementNumNodes()
{
    ++d_numNodes;
}

inline
void RbTreeAnchor::decrementNumNodes()
{
    --d_numNodes;
}

inline
RbTreeNode *RbTreeAnchor::firstNode()
{
    return d_sentinel.rightChild();
}

inline
RbTreeNode *RbTreeAnchor::rootNode()
{
    return d_sentinel.leftChild();
}

inline
RbTreeNode *RbTreeAnchor::sentinel()
{
    return &d_sentinel;
}

// ACCESSORS
inline
const RbTreeNode *RbTreeAnchor::firstNode() const
{
    return d_sentinel.rightChild();
}

inline
const RbTreeNode *RbTreeAnchor::rootNode() const
{
    return d_sentinel.leftChild();
}

inline
int RbTreeAnchor::numNodes() const
{
    return d_numNodes;
}

inline
const RbTreeNode *RbTreeAnchor::sentinel() const
{
    return &d_sentinel;
}

}  // close package namespace
}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------