Follow this link to skip to the main content

tree.h

Go to the documentation of this file.
00001 // -*-c++-*-
00002 //---------------------------< /-/ CLARAty /-/ >------------------------------
00003 /**
00004  * @file  tree.h
00005  *
00006  * Standard Template Library (STL)-like tree class.
00007  *
00008  * <br>@b Designer(s):    Hari Das Nayar
00009  * <br>@b Author(s):      Hari Das Nayar
00010  * <br>@b Date:           October 2, 2004 
00011  *
00012  * <b>Software License:</b><br>
00013  * <code> http://claraty.jpl.nasa.gov/license/open_src/  or 
00014  *        file: license/open_src.txt </code>
00015  *
00016  * &copy; 2006, Jet Propulsion Laboratory, California Institute of Technology<br><br>
00017  *
00018  * $Revision: 1.8 $
00019  */
00020 //-----------------------------------------------------------------------------
00021 
00022 #ifndef  TREE_H
00023 #define  TREE_H
00024 
00025 #include "claraty/share.h"
00026 #include <algorithm>
00027 
00028 /************************************************************************** 
00029   For the following tree below, an example of the pre-order iteration
00030     sequence for pre_order_iterator is as follows:
00031 
00032                                    --------1------
00033                                  /         |       \
00034                                 /          |         \
00035                                2           7          13
00036                               / \        / | \
00037                              /   \     /   |   \
00038                             3     6   8    9    10
00039                            / \                 /  \
00040                           /    \              11   12
00041                          4      5
00042 
00043     Algorithm:
00044         pre-order(v)
00045         {
00046             visit(v)
00047             for    each child w of v
00048                 pre-order(w)
00049         }
00050 
00051 
00052 For the following tree below, an example of the post-order iteration
00053     sequence for post_order_iterator is as follows:
00054 
00055                                    --------13------
00056                                  /         |       \
00057                                 /          |         \
00058                                5          11          12
00059                               / \        / | \
00060                              /   \     /   |   \
00061                             3     4   6    7    10
00062                            / \                 /  \
00063                           /    \              8    9
00064                          1      2
00065 
00066     Algorithm:
00067         post-order(v)
00068         {
00069             for    each child w of v
00070                 post-order(w)
00071             visit(v)
00072         }
00073 
00074 For the following tree below, an example of the sibling iteration
00075     sequence for sibling_iterator is as follows:
00076 
00077                                   ---------x------
00078                                  /         |       \
00079                                 /          |         \
00080                                x           x          x
00081                               / \        / | \
00082                              /   \     /   |   \
00083                             x     x   1    2    3
00084                            / \                 /  \
00085                           /    \              x    x
00086                          x      x
00087 
00088 
00089 
00090 
00091 For the following tree below, an example of the chain iteration
00092     sequence (where a begin (node #1) and an end (node #6) are previously
00093     defined to specify the chain) for a chain_iterator is as follows:
00094 
00095                                   ---------3------
00096                                  /         |       \
00097                                 /          |         \
00098                                2           4          x
00099                               / \        / | \
00100                              /   \     /   |   \
00101                             x     1   x    x    5
00102                            / \                 /  \
00103                           /    \              6    x
00104                          x      x
00105 
00106 
00107 
00108 */
00109 //-------------------------------------------------------------------------
00110 //-------------------------<< Tree Class >>---------------------------
00111 //-------------------------------------------------------------------------
00112 //
00113 // NOTE: Tree_Node and Iterator classes are defined within the
00114 //            Tree class definition.
00115 //
00116 
00117 template < class T >
00118 class Tree {
00119 public:
00120   typedef T value_type;
00121   typedef ptrdiff_t difference_type;
00122   typedef T* pointer;
00123   typedef T& reference;
00124 
00125   //------------------------------------------------------------------
00126   //    Define the Tree_Node class here
00127   //------------------------------------------------------------------
00128   class Tree_Node {    
00129   public:
00130     Tree_Node *p_parent;
00131     Tree_Node *p_previous_sibling, *p_next_sibling;
00132     Tree_Node *p_first_child, *p_last_child;
00133     T *data;
00134 
00135     /**
00136      * Constructor: Add a new child to parent node specified in arg. This also
00137      * serves as a copy constructor when the parent arg. is not included.
00138      * @param[in] new_child  Reference to tree node data type.
00139      * @param[in] parent     Pointer to the parent node.
00140      */
00141     Tree_Node(T * new_child, Tree_Node* parent = 0);
00142 
00143     /**
00144      * Default constructor
00145      */
00146     Tree_Node();
00147 
00148 
00149     /**
00150      * Destructor: Note that as in std::vector, the elements are allocated
00151      * outside tree but destroyed within it when the tree is cleared.
00152      */
00153     ~Tree_Node();
00154 
00155     /**
00156      * Equals operator: sets the data of a Tree_Node to the
00157      * data of another Tree_Node.
00158      * @param[in] x  Reference to Tree_Node.
00159      * @return Reference to Tree_Node.
00160      */
00161     Tree_Node &  operator=(const Tree_Node & x);
00162   
00163   };
00164 
00165   //------------------------------------------------------------------
00166         // This is a special node that is used to bracket a set of elements in
00167   // the tree. It is used as a ficticous node to indicate that an iterator
00168   // is pointing beyond the end of the tree or before the beginning. By
00169   // convention, the end() iterator point to a location beyond the last
00170   // element and begin() points to the first zero-indexed element.
00171   //------------------------------------------------------------------
00172   class Tree_Terminal_Node {    
00173   public:
00174 
00175     /**
00176      * Default constructor
00177      */
00178     Tree_Terminal_Node():p_previous(0), p_next(0){}
00179 
00180     /**
00181      * Copy constructor
00182      * @param[in] a  Reference to Tree_Terminal_Node.
00183      */
00184     Tree_Terminal_Node(const Tree_Terminal_Node & a) : p_previous(a.p_previous), p_next(a.p_next)
00185     {}
00186 
00187     /**
00188      * Public members of Tree_Terminal_Node to point to the adjacent
00189      * elements of the tree.
00190      */
00191     Tree_Node *p_previous, *p_next;
00192         };
00193 
00194 
00195 
00196 
00197 private:
00198 
00199   Tree_Node *_root_node; // Pointer to the root node always exists.
00200                                 // However the root node must be allocated
00201                                 // when the first node is added to the tree
00202 
00203         Tree_Node *_start_node; // Pointer to indicate the node before the first
00204                                                         // node of the tree.
00205 
00206         Tree_Node *_end_node;   // Pointer to indicate the node after the last
00207                                                         // node of the tree.
00208 
00209   size_t _number_of_nodes;    // The number of nodes in the tree
00210 
00211 public:
00212 
00213     //------------------------------------------------------------------
00214     //    Begin define the iterator class here
00215     //    This is the base iterator class. Other iterators are derived
00216     //    from this.
00217     //------------------------------------------------------------------
00218   class Iterator {
00219   public:
00220     Tree_Node * current; // pointer to current node
00221     typedef std::bidirectional_iterator_tag iterator_category;
00222 
00223     typedef T value_type;
00224     typedef T* pointer;
00225     typedef T& reference;
00226     typedef size_t size_type;
00227     typedef ptrdiff_t difference_type;
00228 
00229     Tree_Terminal_Node start;   // The node before the begin() iterator
00230     Tree_Terminal_Node end;     // The node at the end() iterator
00231     bool at_start, at_end;      // Flags to indicate if the iterator is at the
00232                                 // start or end nodes respectively.
00233 
00234    /**
00235     * Default constructor
00236     * @param[in] init  Pointer to node.
00237     */
00238     Iterator(Tree_Node* init = 0);
00239 
00240    /**
00241     * Copy constructor
00242     * @param[in] a  Reference to the base iterator.
00243     */
00244     Iterator(const Iterator& a);
00245 
00246    /**
00247     * Template type constructor
00248     * @param[in] a  Reference to the template type.
00249     */
00250     Iterator(T & a);
00251      /**
00252     * Destructor
00253     */
00254     virtual ~Iterator() {};
00255 
00256    /**
00257     * Dereferencing data: allows access to data with the *iterator statement
00258     * @return Reference to node data type
00259     */
00260     T& operator*() const;
00261 
00262    /**
00263     * Returns the address of data: Allows calling public member functions of
00264     * data with the iterator->data_public_function() call
00265     * @return Pointer to node data type
00266     */
00267     T*  operator->() const;
00268 
00269    /**
00270     * Equals operator: sets the current position of an iterator to the
00271     * current position of another iterator.
00272     * @param[in] x  Reference to base iterator.
00273     * @return Reference to base iterator class.
00274     */
00275     template <typename Iterator_Type>
00276       Iterator& operator=(const Iterator_Type & x);
00277 
00278    /**
00279     * Set_Current function: sets the current position of this iterator to
00280     * the position new_current. This always returns true. This prototype is
00281     * used because it is overridden for the chain iterator where a check that
00282     * new_current is on the chain (see below) is performed.
00283     * @param[in] new_current  Pointer to node.
00284     * @return Always returns true.
00285     */
00286     bool set_current(Tree_Node * new_current);
00287 
00288    /**
00289     * == operator: Tests for equality between two iterators
00290                 * NOTE: This only checks if the current nodes match to allow
00291                 * comparison between different types of iterators.
00292     * @param[in] x  Reference to base iterator.
00293     * @return Result of test
00294     */
00295     bool operator==(const Iterator& x) const;
00296 
00297    /**
00298     * != operator: Tests for inequality between two iterators
00299                 * NOTE: This only checks if the current nodes do not match to allow
00300                 * comparison between different types of iterators.
00301     * @param[in] x  Reference to base iterator type.
00302     * @return       Result of test.
00303     */
00304     bool operator!=(const Iterator& x) const;
00305 
00306    /**
00307     * < operator: Tests for this less than rhs
00308     * @param[in] x  Unsigned int to specify the decrement.
00309     * @return       True if less than, false otherwise.
00310     */
00311     template <typename Iterator_Type>
00312       bool operator<(const Iterator_Type& x) const;
00313 
00314    /**
00315     * > operator: Tests for this greater than rhs
00316     * @param[in] x  Unsigned int to specify the decrement.
00317     * @return       True if greater than, false otherwise.
00318     */
00319     template <typename Iterator_Type>
00320       bool operator>(const Iterator_Type& x) const;
00321    /**
00322     * <= operator: Tests for this less than or equal to rhs
00323     * @param[in] x  Unsigned int to specify the decrement
00324     * @return       True if less than or equal to, false otherwise
00325     */
00326     template <typename Iterator_Type>
00327       bool operator<=(const Iterator_Type& x) const;
00328 
00329    /**
00330     * >= operator: Tests for this greater than or equal to rhs
00331     * @param[in] x   Unsigned int to specify the decrement
00332     * @return        True if greater than or equal to, false otherwise
00333     */
00334     template <typename Iterator_Type>
00335       bool operator>=(const Iterator_Type& x) const;
00336 
00337    /**
00338     * Determines the number of children the node at the current position has.
00339     * @return unsigned int number of children
00340     */
00341     unsigned int get_number_of_children() const;      
00342     /**
00343      * Return the iterator that points to the first child of this iterator's
00344      * node
00345      * @return Base or derived iterator 
00346      */
00347     Iterator get_first_child() const;
00348     
00349     /**
00350     * Tests if the node pointed to by the arg. iterator is a child
00351     * of this iterator.
00352     * @param[in] a  Reference to base iterator.
00353     * @return       Result of test.
00354     */
00355     bool is_child(const Iterator& a) const;
00356 
00357    /**
00358     * Tests if the node pointed to by the arg. iterator is a parent
00359     * of this iterator.
00360     * @param[in] a  Reference to base iterator.
00361     * @result       Result of test.
00362     */
00363     bool is_parent(const Iterator& a) const;
00364 
00365    /**
00366     * Tests if the node pointed to by the arg. iterator is a sibling
00367     * of this iterator. If the same node, return false.
00368     * @param[in] a  Reference to base iterator.
00369     * @result       Result of test.
00370     */
00371     bool is_sibling(const Iterator& a) const;
00372 
00373    /**
00374     * Tests if the node pointed to by the arg. iterator is a descendent
00375     * of this iterator.
00376     * @param[in] a  Reference to base iterator.
00377     * @result       Result of test
00378     */
00379     bool is_descendent(const Iterator& a) const;
00380 
00381    /**
00382     * Tests if the node pointed to by the arg. iterator is an ancestor
00383     * of this iterator.
00384     * @result bool result of test
00385     */
00386     bool is_ancestor(const Iterator& a) const;
00387 
00388     virtual int get_index_position() const {return 0;}
00389 
00390   private:
00391     virtual void _initialize() {};
00392 
00393   };
00394 
00395   //------------------------------------------------------------------
00396   //  Begin define the Sibling_Iterator class here
00397   //  This is derived from the base iterator class.
00398   //------------------------------------------------------------------
00399   class Sibling_Iterator : public Iterator {
00400   public:
00401    /**
00402     * Default constructor
00403     * @param[in] init  Pointer to node.
00404     */
00405     Sibling_Iterator(Tree_Node * init = 0);
00406 
00407 
00408          /**
00409     * Copy constructor
00410     * @param[in] a  Reference to base or derived iterator classes.
00411     */
00412     template <typename Iterator_Type>
00413       Sibling_Iterator(const Iterator_Type& a);
00414 
00415    /**
00416     * Template type constructor
00417     * @param[in] a  Reference to the template type.
00418     */
00419     Sibling_Iterator(T & a);
00420 
00421    /**
00422     * pre-fix increment operator
00423     * @return Reference to sibling iterator
00424     */
00425     Sibling_Iterator& operator++();
00426 
00427    /**
00428     * pre-fix decrement operator
00429     * @return Reference to sibling iterator
00430     */
00431     Sibling_Iterator& operator--();
00432 
00433    /**
00434     * post-fix increment operator
00435     * @return Sibling iterator
00436     */
00437     Sibling_Iterator operator++(int);
00438     
00439    /**
00440     * post-fix decrement operator
00441     * @return Sibling iterator
00442     */
00443     Sibling_Iterator operator--(int);
00444 
00445    /**
00446     * increment by specified value operator
00447     * @param[in] a   Unsigned int to specify the increment
00448     * @return Reference to sibling iterator
00449     */
00450     Sibling_Iterator& operator+=(unsigned int a);
00451 
00452    /**
00453     * decrement by specified value operator
00454     * @param[in] a   Unsigned int to specify the decrement
00455     * @return Reference to sibling iterator
00456     */
00457     Sibling_Iterator& operator-=(unsigned int a);
00458 
00459    /**
00460     * Zero-referenced index from begin.
00461     */
00462     int get_index_position() const;
00463 
00464   private:
00465     /**
00466      * Initialize sibling iterator parameters
00467      */
00468     void _initialize();
00469     
00470   };
00471 
00472 
00473   //------------------------------------------------------------------
00474   //  Begin define the Pre_Order_Iterator class here
00475   //  This is derived from the base iterator class.
00476   //------------------------------------------------------------------
00477   class Pre_Order_Iterator : public Iterator {
00478   public:
00479    /**
00480     * Default constructor
00481     */
00482     Pre_Order_Iterator(Tree_Node * init = 0);
00483 
00484    /**
00485     * Copy constructor
00486     * @param[in] a  Reference to base or derived iterator classes.
00487     */
00488     template <typename Iterator_Type>
00489       Pre_Order_Iterator(const Iterator_Type& a);
00490 
00491    /**
00492     * Template type constructor
00493     * @param[in] a  Reference to the template type.
00494     */
00495     Pre_Order_Iterator(T & a);
00496 
00497    /**
00498     * pre-fix increment operator
00499     * @return Reference to pre-order iterator
00500     */
00501     Pre_Order_Iterator& operator++();
00502     
00503    /**
00504     * pre-fix decrement operator
00505     * @return Reference to pre-order iterator
00506     */
00507     Pre_Order_Iterator& operator--();
00508 
00509    /**
00510     * post-fix increment operator
00511     * @return Pre-order iterator
00512     */
00513     Pre_Order_Iterator operator++(int);
00514     
00515    /**
00516     * post-fix decrement operator
00517     * @return Pre-order iterator
00518     */
00519     Pre_Order_Iterator operator--(int);
00520 
00521    /**
00522     * increment by specified value operator
00523     * @param[in] a   Unsigned int to specify the increment
00524     * @return Reference to pre-order iterator
00525     */
00526     Pre_Order_Iterator& operator+=(unsigned int a);
00527 
00528    /**
00529     * decrement by specified value operator
00530     * @param[in] a   Unsigned into to specify the decrement
00531     * @return Reference to pre-order iterator
00532     */
00533     Pre_Order_Iterator& operator-=(unsigned int a);
00534 
00535     int get_index_position() const;
00536 
00537     void _initialize() {}               // No need to do anything here.
00538   };
00539 
00540   //------------------------------------------------------------------
00541   //  Begin define the Post_Order_Iterator class here
00542   //  This is derived from the base iterator class.
00543   //------------------------------------------------------------------
00544   class Post_Order_Iterator : public Iterator {
00545   public:
00546    /**
00547     * Default constructor
00548     * @param[in] init  Pointer to tree node.
00549     */
00550     Post_Order_Iterator(Tree_Node * init = 0);
00551 
00552    /**
00553     * Copy constructor
00554     * @param[in] a  Reference to base or derived iterator classes.
00555     */
00556     template <typename Iterator_Type>
00557       Post_Order_Iterator(const Iterator_Type& a);
00558 
00559    /**
00560     * Template type constructor
00561     * @param[in] a  Reference to the template type.
00562     */
00563     Post_Order_Iterator(T & a);
00564 
00565    /**
00566     * pre-fix increment operator
00567     * @return Reference to post-order iterator
00568     */
00569     Post_Order_Iterator& operator++();
00570    /**
00571     * pre-fix decrement operator
00572     * @return Reference to post-order iterator
00573     */
00574     Post_Order_Iterator& operator--();
00575 
00576    /**
00577     * post-fix increment operator
00578     * @return Post-order iterator
00579     */
00580     Post_Order_Iterator operator++(int);
00581     
00582    /**
00583     * post-fix decrement operator
00584     * @return Post-order iterator
00585     */
00586     Post_Order_Iterator operator--(int);
00587 
00588    /**
00589     * increment by specified value operator
00590     * @param[in] a   Unsigned int to specify the increment
00591     * @return Reference to post-order iterator
00592     */
00593     Post_Order_Iterator& operator+=(unsigned int a);
00594 
00595    /**
00596     * decrement by specified value operator
00597     * @param[in] a   Unsigned int to specify the decrement
00598     * @return Reference to post-order iterator
00599     */
00600     Post_Order_Iterator& operator-=(unsigned int a);
00601 
00602 
00603    /**
00604     * Zero-referenced index from begin.
00605     */
00606     int get_index_position() const;
00607   };
00608 
00609   //------------------------------------------------------------------
00610   //  Begin define the Chain_Iterator class here
00611   //  This is derived from the base iterator class.
00612   //------------------------------------------------------------------
00613   class Chain_Iterator : public Iterator {
00614   public:
00615    /**
00616     * Constructor
00617     * @param[in] begin_chain  Pointer to node that specifies the beginning of
00618     *                         the chain
00619     * @param[in] end_chain    Pointer to node that specifies the end of the
00620     *                         chain
00621     */
00622     Chain_Iterator( Tree_Node* begin_chain, Tree_Node* end_chain);
00623 
00624    /**
00625     * Constructor
00626     * @param[in] begin_chain  Pointer to node that specifies the beginning of
00627     *                         the chain
00628     * @param[in] end_chain    Pointer to node that specifies the end of the
00629     *                         chain
00630     */
00631     Chain_Iterator( Iterator begin_chain, Iterator end_chain);
00632 
00633    /**
00634     * Copy constructor
00635     */
00636     Chain_Iterator(const Chain_Iterator & a);
00637 
00638    /**
00639     * Destructor
00640     */
00641     ~Chain_Iterator();
00642 
00643    /**
00644     * Equals operator: sets the current position of a non-chain iterator to the
00645     * current position of this iterator if the arg. iterator's current node is
00646     * on the chain
00647     * @param[in] x  Reference to base iterator.
00648     * @return       Reference to base iterator class
00649     */
00650     template <typename Iterator_Type>
00651       Chain_Iterator &  operator=(const Iterator_Type & x);
00652 
00653 
00654    /**
00655     * Equals operator: sets the variables of the arg chain iterator to the
00656     * this chain iterator. The built-in equals operator does the same thing.
00657     * This is provided in case the class is extended in the future
00658     * to have allocated variables.
00659     * @param[in] x  Reference to base iterator.
00660     * @return       Reference to base iterator class
00661     */
00662     Chain_Iterator &  operator=(const Chain_Iterator & x);
00663 
00664    /**
00665     * Return beginning node of chain
00666     * @return Pointer to node
00667     */
00668     Tree_Node * get_first_node();
00669 
00670    /**
00671     * Return the ending node of the chain
00672     * @return Pointer to node
00673     */
00674     Tree_Node * get_last_node();
00675 
00676    /**
00677     * Set Chain_Iterator to begin node of chain
00678     */
00679     void set_begin();
00680 
00681    /**
00682     * Set Chain_Iterator to past end node of chain
00683     */
00684     void set_end();
00685    /**
00686     * pre-fix increment operator
00687     * @return Reference to chain iterator
00688     */
00689     Chain_Iterator& operator++();
00690 
00691    /**
00692     * pre-fix decrement operator
00693     * @return Reference to chain iterator
00694     */
00695     Chain_Iterator& operator--();
00696 
00697    /**
00698     * post-fix increment operator
00699     * @return Chain iterator
00700     */
00701     Chain_Iterator operator++(int);
00702     
00703    /**
00704     * post-fix decrement operator
00705     * @return Chain iterator
00706     */
00707     Chain_Iterator operator--(int);
00708 
00709 
00710    /**
00711     * increment by specified value operator
00712     * @param[in] a   Unsigned int to specify the increment
00713     * @return Reference to chain iterator
00714     */
00715     Chain_Iterator& operator+=(unsigned int a);
00716 
00717     /**
00718     * decrement by specified value operator
00719     * @param[in] a   Unsigned int to specify the decrement
00720     * @return Reference to chain iterator
00721     */
00722     Chain_Iterator& operator-=(unsigned int a);
00723 
00724    /**
00725     * Set current node, Check that the new current node is in the chain
00726     * @param[in] new_current  Pointer to specify the new node to point to.
00727     * @return                 Tree if successful, false if failed
00728     */
00729     bool set_current(Tree_Node * new_current);
00730 
00731 
00732    /**
00733     * Check if a node is on the chain of this chain iterator
00734     * @param[in] a  Pointer to node to test for.
00735     * @return       True if on chain, false if not on chain
00736     */
00737     bool on_chain(const Tree_Node * a) const;
00738 
00739     int get_index_position() const;
00740 
00741     void _initialize() {}
00742 
00743   };
00744 
00745   //------------------------------------------------------------------
00746   //  Define Tree functions here.
00747   //------------------------------------------------------------------
00748 
00749  /**
00750   * Default constructor
00751   */
00752   Tree();
00753 
00754  /**
00755   * Copy constructor
00756   * @param[in] a  Reference to another tree.
00757   */
00758   Tree(const Tree<T>& a);
00759 
00760  /**
00761   * Destructor
00762   */
00763   ~Tree();
00764 
00765  /**
00766   * initialize the start_node and end_node
00767         */
00768         void _initialize_tree();
00769 
00770  /**
00771   * get the number of the nodes on the tree
00772   * @return unsigned int number of nodes
00773   */
00774   unsigned int size();
00775 
00776  /**
00777   * Determine if tree is empty
00778   * @return bool true if tree is empty
00779   */
00780   bool empty();
00781 
00782  /**
00783   * Check if the current node of an iterator is on the tree
00784   * @param[in] d_iterator  Reference to base or derived iterator classes.
00785   * @return                True if on tree, false if not on tree
00786   */
00787   template <typename Iterator_Type> 
00788     bool on_tree(const Iterator_Type & d_iterator);
00789 
00790 
00791  /**
00792   * Clear the tree of nodes
00793   */
00794   void clear_tree();
00795 
00796  /**
00797   * Delete the node and all its descendents pointed to by the iterator
00798   * @param[in] a  Reference to base or derived iterator class.
00799   */
00800   template <typename Iterator_Type> 
00801     void delete_descendents(const Iterator_Type& a);
00802 
00803  /**
00804   * Delete this iterator's node only if it is valid, has no children and
00805   * is on this tree
00806   * @param[in] d_iter  Reference to base or derived iterator classes.
00807   */
00808   template <typename Iterator_Type> 
00809     void delete_node(const Iterator_Type d_iter);
00810 
00811  /**
00812   * Copy a specified tree into this tree
00813   * @param[in] a  Reference to a tree.
00814   */
00815   bool copy(const Tree<T>& a);
00816 
00817  /**
00818   * Copy the node and its descendents onto this tree at the specified node
00819   * @param[in] dest_itr  Reference to base or derived iterator classes to
00820   *                       copy to
00821   * @param[in] src_itr   Reference to base or derived iterator classes to
00822   *                      copy from
00823   */
00824   template <typename Iterator_Type1, typename Iterator_Type2> 
00825     bool copy_descendents(
00826     Iterator_Type1 dest_itr, Iterator_Type2 src_itr);
00827 
00828  /**
00829   * tree equal operator
00830   * @param[in] a  Reference to the tree to copy from.
00831   */
00832   Tree<T> &  operator=(const Tree<T> & a);
00833 
00834   template <typename Iterator_Type> 
00835   bool has_parent(const Iterator_Type& child) const;
00836 
00837  /**
00838   * Return the iterator that points to the parent of this iterator's node
00839   * @param[in] child  Reference to base or derived iterator classes.
00840   * @return           Base or derived iterator 
00841   */
00842   template <typename Iterator_Type> Iterator_Type
00843     get_parent(const Iterator_Type& child) const;
00844    
00845  /**
00846   * Return the iterator that points to the first child of this iterator's node
00847   * @param[in] child  Reference to base or derived iterator classes.
00848   * @return           Base or derived iterator 
00849   */
00850   template <typename Iterator_Type> Iterator_Type
00851     get_first_child(const Iterator_Type& child) const;
00852 
00853  /**
00854   * Return the iterator that points to the last child of this iterator's node
00855   * @param[in] child  Reference to base or derived iterator classes.
00856   * @return           Base or derived iterator 
00857   */
00858   template <typename Iterator_Type> Iterator_Type
00859     get_last_child(const Iterator_Type& child) const;
00860   
00861  /**
00862   * Return the iterator that points to the previous sibling of this
00863   * iterator's node
00864   * @param[in] child  Reference to base or derived iterator classes.
00865   * @return           Base or derived iterator 
00866   */
00867   template <typename Iterator_Type> Iterator_Type
00868     get_previous_sibling(const Iterator_Type& child) const;
00869   
00870  /**
00871   * Return the iterator that points to the next sibling of this iterator's node
00872   * @param[in] child  Reference to base or derived iterator classes.
00873   * @return           Base or derived iterator 
00874   */
00875   template <typename Iterator_Type> Iterator_Type
00876     get_next_sibling(const Iterator_Type& child) const;
00877 
00878 
00879  /**
00880   * Append the data as a new child of the parent node. Note that a new
00881   * copy of the node data type is made
00882   * @param[in] parent      Reference to base or derived iterator classes.
00883   * @param[in] child_data  Reference to node data type to be appended
00884   * @return                Base or derived iterator 
00885   */
00886   template <typename Iterator_Type> Iterator_Type append_child(
00887     Iterator_Type parent, T * child_data);
00888 
00889  /**
00890   * Insert the new node data at the specified location and displace the
00891   * specified location to be the next sibling. Note that a new
00892   * copy of the node data type is made.
00893   * @param[in] location      Reference to base or derived iterator classes
00894   * @param[in] element_data  Reference to node data type to be inserted
00895   * @return                  Base or derived iterator 
00896   */
00897   template <typename Iterator_Type> Iterator_Type insert(
00898     Iterator_Type location, T * element_data);
00899 
00900 
00901  /**
00902   * Insert the new node data after the specified location and displace the
00903   * specified location to be the previous sibling. Note that a new
00904   * copy of the node data type is made.
00905   * @param[in] location      Reference to base or derived iterator classes
00906   * @param[in] element_data  Reference to node data type to be inserted
00907   * @return                  Base or derived iterator 
00908   */
00909   template <typename Iterator_Type> Iterator_Type insert_after(
00910     Iterator_Type location, T * element_data);
00911 
00912 
00913  /**
00914   * Returns the depth of the node in the tree
00915   * @param[in] a  Reference to base or derived iterator classes.
00916   * @return       Depth; -1 if error; root node depth = 0
00917   */
00918   template <typename Iterator_Type> 
00919     int get_depth(const Iterator_Type& a);
00920 
00921  /**
00922   * Tests if the iterator is pointing at the root node
00923   * @param[in] a  Reference to base or derived iterator classes.
00924   * @return       True if is the root, false if not the root
00925   */
00926   template <typename Iterator_Type> bool is_root(const Iterator_Type& a) const;
00927  
00928  /**
00929   * Return a sibling iterator that points to the beginning of the siblings
00930   * @param[in] a  Reference to base or derived iterator classes.
00931   * @return       Sibling iterator
00932   */
00933   template <typename Iterator_Type> Sibling_Iterator
00934     begin_sibling(const Iterator_Type & a);
00935   
00936  /**
00937   * Return a pre-order iterator that points to the beginning of the pre-ordered
00938   * tree
00939   * @return Pre-order iterator
00940   */
00941   Pre_Order_Iterator begin_pre_order() const;
00942 
00943  /**
00944   * Return a post-order iterator that points to the beginning of the
00945   * post-ordered tree
00946   * @return Post-order iterator
00947   */
00948   Post_Order_Iterator begin_post_order() const;
00949 
00950  /**
00951   * Return a new chain iterator that points to the beginning of the chain
00952   * @param[in] a  Reference to a chain iterator.
00953   * @return       Chain iterator
00954   */
00955   Chain_Iterator begin_chain(Chain_Iterator & a) const;
00956   
00957  /**
00958   * Return a sibling iterator that points to the end (1 beyond the last)
00959   * sibling
00960   * @param[in] a  Reference to base or derived iterator classes.
00961   * @return       Sibling iterator
00962   */
00963   template <typename Iterator_Type>  Sibling_Iterator
00964     end_sibling(const Iterator_Type & a);
00965   
00966  /**
00967   * Return a pre-order iterator that points to the end of the pre-ordered tree
00968   * @return Pre-order iterator
00969   */
00970   Pre_Order_Iterator end_pre_order() const;
00971   
00972  /**
00973   * Return a post_order_iterator that points to the end of the post-ordered
00974   * tree
00975   * @return Post-order iterator
00976   */
00977   Post_Order_Iterator end_post_order() const;
00978    
00979  /**
00980   * Return a chain iterator that points to the end of this chain
00981   * @return Chain iterator
00982   */
00983   Chain_Iterator end_chain(Chain_Iterator & a) const;
00984 
00985 };
00986 
00987 
00988 /**************************************************************************/
00989 /**************************************************************************/
00990 /*                           TREE_NODE functions                          */
00991 /**************************************************************************/
00992 /**************************************************************************/
00993 //------------------------------------------------------------------------
00994 /**
00995  * Constructor: Add a new child to parent node specified in arg. This also
00996  * serves as a copy constructor when the parent arg. is not included.
00997  * @param[in] new_child  Reference to tree node data type.
00998  * @param[in] parent     Pointer to the parent node.
00999  */
01000 template <class T>
01001 inline Tree<T>::Tree_Node::Tree_Node(T * new_child, Tree_Node* parent)
01002     : data(0)
01003 {
01004   if (new_child)                        // if new_child is valid, assign data to it
01005   {                                             // if new_child is not valid, data remains NULL
01006     data = new_child;
01007 
01008   }
01009 
01010   if (parent) // if parent is valid
01011   {
01012     p_parent = parent;    // set parent pointer to parent
01013     if (p_parent->p_last_child) // if parent already has a child, 
01014     {                            // add a new last sibling
01015 
01016       p_previous_sibling = p_parent->p_last_child;
01017       p_previous_sibling->p_next_sibling = this;
01018       p_parent->p_last_child = this;
01019     }
01020     else // otherwise add a new first/last child
01021     {
01022       p_parent->p_first_child = this;
01023       p_previous_sibling = 0;
01024       p_next_sibling = 0;
01025       p_parent->p_last_child = this;
01026     }
01027     p_parent->p_last_child = this;
01028   }
01029   else    // if parent is not valid, this is the first node so give it
01030           // root node properties
01031   {
01032     p_parent = 0;    // the root node does not have a parent nor siblings
01033     p_previous_sibling = 0;
01034   }
01035 
01036   // The new node doesn't have any children
01037   p_first_child = 0;
01038   p_last_child = 0;
01039 
01040   // The new node doesn't have a next sibling
01041   p_next_sibling = 0;
01042 }
01043 
01044 //------------------------------------------------------------------------
01045 /**
01046  * Default constructor
01047  */
01048 template <class T>
01049 inline Tree<T>::Tree_Node::Tree_Node() : data(0)                // Data is NULL
01050 {
01051   p_parent = 0;                // no parent specified so create a node
01052   p_previous_sibling = 0;        // that does't have any attachment to other
01053   p_next_sibling = 0;            // nodes
01054   p_first_child = 0;
01055   p_last_child = 0;
01056 }
01057 
01058 //------------------------------------------------------------------------
01059 /**
01060  * Destructor: Note that as in std::vector, the elements are allocated
01061  * outside tree but destroyed within it when the tree is cleared.
01062  */
01063 template <class T>
01064 inline Tree<T>::Tree_Node::~Tree_Node()
01065 {
01066   if (data != 0)
01067   {
01068     delete data;    // Clear the allocated memory
01069 
01070   }
01071 }
01072 
01073 //------------------------------------------------------------------------
01074 /**
01075  * Equals operator: sets the data of a Tree_Node to the
01076  * data of another Tree_Node.
01077  * @param[in] x  Reference to Tree_Node.
01078  * @return       Reference to Tree_Node
01079  */
01080 template <class T>
01081 inline typename Tree<T>::Tree_Node & Tree<T>::Tree_Node::operator=(const Tree_Node & x)
01082 {
01083   if (data)
01084     delete data;
01085 
01086   data = new T(x.data);
01087 
01088   return *this;
01089 }
01090 
01091 /**************************************************************************/
01092 /**************************************************************************/
01093 /*                           Iterator functions                           */
01094 /*                                                                        */
01095 /* This is the base iterator class. Other iterators are derived from this.*/
01096 /**************************************************************************/
01097 /**************************************************************************/
01098 //------------------------------------------------------------------------
01099 /**
01100  * Default constructor
01101  * @param[in] init  Pointer to node.
01102  */
01103 template <class T>
01104 inline Tree<T>::Iterator::Iterator(Tree_Node* init)
01105 {
01106   current = init;
01107   end.p_previous = 0;
01108   start.p_next = 0;
01109   at_start = false;
01110   at_end = false;
01111 }
01112 
01113 //------------------------------------------------------------------------
01114 /**
01115  * Copy constructor
01116  * @param[in] a  Reference to the base iterator.
01117  */
01118 template <class T>
01119 inline Tree<T>::Iterator::Iterator(const Iterator& a)
01120   : current(a.current), 
01121     start (a.start), 
01122     end   (a.end),
01123     at_start (a.at_start), 
01124     at_end   (a.at_end)
01125 {
01126 }
01127 
01128 //------------------------------------------------------------------------
01129 /**
01130  * Template type constructor
01131  * @param[in] a  Reference to the template type.
01132  */
01133 template <class T>
01134 inline Tree<T>::Iterator::Iterator(T & a)
01135 {
01136   current->data = &a;
01137   end.p_previous = 0;
01138   start.p_next = 0;
01139   at_start = false;
01140   at_end = false;
01141 }
01142 
01143 //------------------------------------------------------------------------
01144 /**
01145  * Destructor
01146  */
01147 //template <class T>
01148 //virtual inline Tree<T>::Iterator::~Iterator()
01149 //{
01150 //}
01151 
01152 //------------------------------------------------------------------------
01153 /**
01154  * Dereferencing data: allows access to data with the *iterator statement
01155  * @return Reference to node data type
01156  */
01157 template <class T>
01158 inline T&  Tree<T>::Iterator::operator*() const
01159 {
01160   return *(current->data);  // Possible problem here if current is not valid
01161 }
01162 
01163 //------------------------------------------------------------------------
01164 /**
01165  * Returns the address of data: Allows calling public member functions of
01166  * data with the iterator->data_public_function() call
01167  * @return Pointer to node data type
01168  */
01169 template <class T>
01170 inline T*  Tree<T>::Iterator::operator->() const
01171 {
01172   return current->data;  // Possible problem here if current is not valid
01173 }
01174 
01175 //------------------------------------------------------------------------
01176 /**
01177  * Equals operator: sets the current position of an iterator to the
01178  * current position of another iterator.
01179  * @param[in] x  Reference to base iterator.
01180  * @return       Reference to base iterator class.
01181  */
01182 template <class T>
01183 template <typename Iterator_Type>
01184 inline typename Tree<T>::Iterator&  Tree<T>::Iterator::operator=(const Iterator_Type & x)
01185 {
01186   current = x.current;
01187   end.p_previous = x.end.p_previous;
01188   start.p_next = x.start.p_next;
01189   at_start = x.at_start;
01190   at_end = x.at_end;
01191   return *this;
01192 }
01193 
01194 //------------------------------------------------------------------------
01195 /**
01196  * Set_Current function: sets the current position of this iterator to
01197  * the position new_current. This always returns true. This prototype is
01198  * used because it is overridden for the chain iterator where a check that
01199  * new_current is on the chain (see below) is performed.
01200  * @param[in] new_current  Pointer to node.
01201  * @return                 Always true.
01202  */
01203 template <class T>
01204 inline bool  Tree<T>::Iterator::set_current(Tree_Node * new_current)
01205 {
01206   current = new_current;
01207   at_end = false;
01208   at_start = false;
01209   
01210   return true;
01211 }
01212 
01213 //------------------------------------------------------------------------
01214 /**
01215  * == operator: Tests for equality between two iterators
01216  * NOTE: This only checks if the current nodes match to allow
01217  * comparison between different types of iterators.
01218  * @param[in] x  Reference to base iterator.
01219  * @return       Result of test 
01220  */
01221 template <class T>
01222 inline bool  Tree<T>::Iterator::operator==(const Iterator& x) const
01223 {
01224   return (current == x.current);
01225 }
01226 
01227 //------------------------------------------------------------------------
01228 /**
01229  * != operator: Tests for inequality between two iterators
01230  * NOTE: This only checks if the current nodes do not match to allow
01231  * comparison between different types of iterators.
01232  * @param[in] x  Reference to base iterator type.
01233  * @reture       Result of test
01234  */
01235 template <class T>
01236 inline bool  Tree<T>::Iterator::operator!=(const Iterator& x) const
01237 {
01238   return (current != x.current);
01239 }
01240 
01241 //------------------------------------------------------------------------
01242 /**
01243  * < operator: Tests for this less than rhs
01244  * @param[in] x   Unsigned int to specify the decrement
01245  * @return        True if less than, false otherwise
01246  */
01247 template <class T>
01248 template <typename Iterator_Type>
01249 inline bool  Tree<T>::Iterator::operator<(const Iterator_Type& x) const
01250 {
01251   return (this->get_index_position() < x.get_index_position());
01252 }
01253 
01254 //------------------------------------------------------------------------
01255 /**
01256  * > operator: Tests for this greater than rhs
01257  * @param[in] x   Unsigned int to specify the decrement
01258  * @return        True if greater than, false otherwise
01259  */
01260 template <class T>
01261 template <typename Iterator_Type>
01262 inline bool  Tree<T>::Iterator::operator>(const Iterator_Type& x) const
01263 {
01264   return (this->get_index_position() > x.get_index_position());
01265 }
01266 
01267 //------------------------------------------------------------------------
01268 /**
01269  * <= operator: Tests for this less than or equal to rhs
01270  * @param[in] x   Unsigned int to specify the decrement
01271  * @return        True if less than or equal to, false otherwise
01272  */
01273 template <class T>
01274 template <typename Iterator_Type>
01275 inline bool  Tree<T>::Iterator::operator<=(const Iterator_Type& x) const
01276 {
01277   return (this->get_index_position() <= x.get_index_position());
01278 }
01279 
01280 //------------------------------------------------------------------------
01281 /**
01282  * >= operator: Tests for this greater than or equal to rhs
01283  * @param[in] x   Unsigned int to specify the decrement
01284  * @return        True if greater than or equal to, false otherwise
01285  */
01286 template <class T>
01287 template <typename Iterator_Type>
01288 inline bool  Tree<T>::Iterator::operator>=(const Iterator_Type& x) const
01289 {
01290   return (this->get_index_position() >= x.get_index_position());
01291 }
01292 
01293 //------------------------------------------------------------------------
01294 /**
01295  * Determines the number of children the node at the current position has.
01296  * @return unsigned int number of children
01297  */
01298 template <class T>
01299 inline unsigned int  Tree<T>::Iterator::get_number_of_children() const      // return the number of children of current 
01300 {
01301   Tree_Node *first = current->p_first_child;
01302   
01303   if (first == 0)
01304   {
01305     return 0;
01306   }
01307   
01308   unsigned int ret=1;
01309   
01310   while ((first = first->p_next_sibling))  // p_next_sibling = 0 for last sibling
01311     ++ret;  
01312   
01313   return ret;
01314 }
01315 
01316 //------------------------------------------------------------------------
01317 /**
01318  * Return the iterator that points to the first child of this iterator's node
01319  * @return Base or derived iterator 
01320  */
01321 template <class T>
01322 inline typename Tree<T>::Iterator Tree<T>::Iterator::get_first_child() const
01323 {
01324   // NOTE: Potential problem here if current points to an invalid node
01325   return Iterator(current->p_first_child);
01326 }
01327 
01328 //------------------------------------------------------------------------
01329 /**
01330  * Tests if the node pointed to by the arg. iterator is a child
01331  * of this iterator.
01332  * @param[in] a  Reference to base iterator.
01333  * @return       Result of test.
01334  */
01335 template <class T>
01336 inline bool Tree<T>::Iterator::is_child(const Iterator& a) const
01337 {
01338   if (!current)
01339   {
01340     return false;
01341   }
01342   return (current->p_parent == a.current);
01343 }
01344 
01345 //------------------------------------------------------------------------
01346 /**
01347  * Tests if the node pointed to by the arg. iterator is a parent
01348  * of this iterator.
01349  * @param[in] a  Reference to base iterator.
01350  * @result       Result of test
01351  */
01352 template <class T>
01353 inline bool Tree<T>::Iterator::is_parent(const Iterator& a) const
01354 {
01355   if (!a.current)
01356   {
01357     return false;
01358   }
01359   return (a.current->p_parent == current);
01360 }
01361 
01362 //------------------------------------------------------------------------
01363 /**
01364  * Tests if the node pointed to by the arg. iterator is a sibling
01365  * of this iterator. If the same node, return false.
01366  * @param[in] a  Reference to base iterator.
01367  * @result       Result of test
01368  */
01369 template <class T>
01370 inline bool Tree<T>::Iterator::is_sibling(const Iterator& a) const
01371 {
01372   if (!current)
01373   {
01374     return false;
01375   }
01376   if (current->p_parent == 0)  // The root node does not have siblings
01377   {
01378     return false;
01379   }
01380   if (*this == a)
01381   {
01382     return false;  // A node cannot be its own sibling
01383     // Using operator== overloaded function 
01384   }
01385   
01386   Tree_Node *first = current->p_parent->p_first_child;
01387   
01388   do
01389   {
01390     if (first == a.current)
01391     {
01392       return true;
01393     }
01394     first = first->p_next_sibling;
01395   } while (first);
01396   
01397   return false;
01398 }
01399 
01400 //------------------------------------------------------------------------
01401 /**
01402  * Tests if the node pointed to by the arg. iterator is a descendent
01403  * of this iterator.
01404  * @param[in] a  Reference to base iterator.
01405  * @result       Result of test
01406  */
01407 template <class T>
01408 inline bool Tree<T>::Iterator::is_descendent(const Iterator& a) const
01409 {
01410   if (!current)
01411   {
01412     return false;
01413   }
01414   Iterator tmp(current);
01415   while (tmp.current)
01416   {
01417     tmp.current = tmp.current->p_parent;
01418     if (tmp == a)    // Using operator== overloaded function 
01419     {
01420       return true;
01421     }
01422     
01423   }
01424   return false;
01425 }
01426 
01427 //------------------------------------------------------------------------
01428 /**
01429  * Tests if the node pointed to by the arg. iterator is an ancestor
01430  * of this iterator.
01431  * @result bool result of test
01432  */
01433 template <class T>
01434 inline bool Tree<T>::Iterator::is_ancestor(const Iterator& a) const
01435 {
01436   if (!current)
01437   {
01438     return false;
01439   }
01440   return a.is_descendent(*this);
01441 }
01442 
01443 
01444 
01445 /**************************************************************************/
01446 /**************************************************************************/
01447 /*                           Sibling Iterator functions                   */
01448 /**************************************************************************/
01449 /**************************************************************************/
01450 //------------------------------------------------------------------------
01451 /**
01452  * Default constructor
01453  * @param[in] init  Pointer to node.
01454  */
01455 template <class T>
01456 inline Tree<T>::Sibling_Iterator::Sibling_Iterator(Tree_Node * init)
01457   : Iterator(init)
01458 {
01459   _initialize();
01460 }
01461 
01462 
01463 //------------------------------------------------------------------------
01464 /**
01465  * Copy constructor
01466  * @param[in] a  Reference to base or derived iterator classes.
01467  */
01468 template <class T>
01469 template <typename Iterator_Type>
01470 inline Tree<T>::Sibling_Iterator::Sibling_Iterator(const Iterator_Type& a)  
01471 : Iterator(a)
01472 {
01473   _initialize();
01474 }
01475 
01476 //------------------------------------------------------------------------
01477 /**
01478  * Template type constructor
01479  */
01480 template <class T>
01481 inline Tree<T>::Sibling_Iterator::Sibling_Iterator(T & a) : Iterator(a)
01482 {
01483   _initialize();
01484 }
01485 
01486 //------------------------------------------------------------------------
01487 /**
01488  * pre-fix increment operator
01489  * @return Reference to sibling iterator
01490  */
01491 template <class T>
01492 inline typename Tree<T>::Sibling_Iterator& Tree<T>::Sibling_Iterator::operator++()
01493 {
01494   if (this->current == 0)  // do nothing if this is not a valid node
01495   {
01496     return *this;
01497   }
01498   if (this->at_start)
01499   {
01500     this->current = this->start.p_next;
01501     this->at_start = false;
01502   }
01503   else
01504   {
01505     if (this->current->p_next_sibling != 0)
01506                 {
01507       this->current = this->current->p_next_sibling;
01508                 }
01509                 else
01510       this->at_end = true;
01511   }
01512   
01513   return *this;  // return the next sibling
01514 }
01515 
01516 //------------------------------------------------------------------------
01517 /**
01518  * pre-fix decrement operator
01519  * @return Reference to sibling iterator
01520  */
01521 template <class T>
01522 inline typename Tree<T>::Sibling_Iterator& Tree<T>::Sibling_Iterator::operator--()
01523 {
01524   if (this->current == 0)  // do nothing if this is not a valid node
01525   {
01526     return * this;
01527   }
01528   if (this->at_end)
01529   {
01530     this->current = this->end.p_previous;
01531     this->at_end = false;
01532   }
01533   else
01534   {
01535     if (this->current->p_previous_sibling != 0)
01536                 {
01537       this->current = this->current->p_previous_sibling;
01538                 }
01539                 else
01540       this->at_start = true;
01541   }
01542   
01543   return *this;  // return the previous sibling
01544 }
01545 
01546 //------------------------------------------------------------------------
01547 /**
01548  * post-fix increment operator
01549  * @param[in] Dummy int parameter to provide a unique prototype for the
01550  *            function
01551  * @return    Sibling iterator
01552  */
01553 template <class T>      // post-fix increment
01554 inline typename Tree<T>::Sibling_Iterator Tree<T>::Sibling_Iterator::operator++(int)  
01555 {
01556   Sibling_Iterator temp = *this;
01557   ++(*this);
01558   return temp;
01559 }
01560 
01561 //------------------------------------------------------------------------
01562 /**
01563  * post-fix decrement operator
01564  * @param[in] Dummy int param to provide a unique prototype for the function
01565  * @return    Sibling iterator
01566  */
01567 template <class T>  // post-fix decrement
01568 inline typename Tree<T>::Sibling_Iterator Tree<T>::Sibling_Iterator::operator--(int)  
01569 {
01570   Sibling_Iterator temp = *this;
01571   --(*this);
01572   return temp;
01573 }
01574 
01575 //------------------------------------------------------------------------
01576 /**
01577  * increment by specified value operator
01578  * @param[in] x   Unsigned int to specify the increment
01579  * @return Reference to sibling iterator
01580  */
01581 template <class T>
01582 inline typename Tree<T>::Sibling_Iterator& Tree<T>::Sibling_Iterator::operator+=(unsigned int a)
01583 {
01584   while (a > 0)
01585   {
01586     ++(*this);
01587     if (this->current == 0)
01588     {
01589       break;
01590     }
01591     --a;
01592   }
01593   return *this;
01594 }
01595 
01596 //------------------------------------------------------------------------
01597 /**
01598  * decrement by specified value operator
01599  * @param[in] x   Unsigned int to specify the decrement
01600  * @return Reference to sibling iterator
01601  */
01602 template <class T>
01603 inline typename Tree<T>::Sibling_Iterator& Tree<T>::Sibling_Iterator::operator-=(unsigned int a)
01604 {
01605   while (a > 0)
01606   {
01607     --(*this);
01608     if (this->current == 0)
01609     {
01610       break;
01611     }
01612     --a;
01613   }
01614   return *this;
01615 }
01616 
01617 //------------------------------------------------------------------------
01618 /**
01619  * Zero-referenced index from begin.
01620  */
01621 template <class T>
01622 inline int Tree<T>::Sibling_Iterator::get_index_position() const
01623 {
01624   int index = -1;
01625   Sibling_Iterator temp_itr(*this);
01626   if (this->at_start)
01627     return index;
01628   
01629   while (!temp_itr.at_start)
01630   {
01631     --temp_itr;
01632     ++index;
01633   }
01634   return index;
01635 }
01636 
01637 //------------------------------------------------------------------------
01638 /**
01639  * Initialize sibling iterator parameters
01640  */
01641 template <class T>
01642 inline void Tree<T>::Sibling_Iterator::_initialize()
01643 {
01644   if (this->current != 0)
01645   {
01646     Tree_Node * start_current = this->current;
01647     
01648     // Move to start of sibling chain
01649     while (this->current->p_previous_sibling != 0)
01650     {
01651       this->current = this->current->p_previous_sibling;
01652     }
01653     this->start.p_next = this->current; // Set the start.p_next ptr to pointer
01654     // to the first element in the chain
01655     
01656     // Reset and move to end of sibling chain
01657     this->current = start_current;
01658     while (this->current->p_next_sibling != 0)
01659     {
01660       this->current = this->current->p_next_sibling;
01661     }
01662     
01663     this->end.p_previous = this->current; // Set the end.p_previous ptr to pointe
01664     // to the last element in the chain
01665     
01666     this->current = start_current;      // Reset the current pointer
01667     // to its original location
01668   }
01669 }
01670 
01671 /**************************************************************************/
01672 /**************************************************************************/
01673 /*                         Pre-Order Iterator functions                   */
01674 /**************************************************************************/
01675 /**************************************************************************/
01676 //------------------------------------------------------------------------
01677 /**
01678  * Default constructor
01679  */
01680 template <class T>
01681 inline Tree<T>::Pre_Order_Iterator::Pre_Order_Iterator(Tree_Node * init)
01682 : Iterator(init)
01683 {
01684 }
01685 
01686 //------------------------------------------------------------------------
01687 /**
01688  * Copy constructor
01689  * @param[in] a  Reference to base or derived iterator classes.
01690  */
01691 template <class T>
01692 template <typename Iterator_Type>
01693 inline Tree<T>::Pre_Order_Iterator::Pre_Order_Iterator(const Iterator_Type& a) : Iterator(a)
01694 {
01695 }
01696 
01697 //------------------------------------------------------------------------
01698 /**
01699  * Template type constructor
01700  * @param[in] a  Reference to the template type.
01701  */
01702 template <class T>
01703 inline Tree<T>::Pre_Order_Iterator::Pre_Order_Iterator(T & a) : Iterator(a)
01704 {
01705 }
01706 
01707 //------------------------------------------------------------------------
01708 /**
01709   * pre-fix increment operator
01710  * @return Reference to pre-order iterator
01711  */
01712 template <class T>
01713 inline typename    //pre-fix increment
01714 Tree<T>::Pre_Order_Iterator& Tree<T>::Pre_Order_Iterator::operator++()  
01715 {
01716   if (this->current == 0)  // do nothing if this is not a valid node
01717   {
01718     return *this;  
01719   }
01720   Tree_Node * tmp_current = this->current;
01721   if (this->current->p_first_child != 0)  // if this node has a child, point to it
01722   {
01723     this->current = this->current->p_first_child;
01724   }
01725   
01726   else              // if this node doesn't have a child,
01727   {    // while the node doesn't have siblings 
01728     while (this->current->p_next_sibling == 0)  
01729     {
01730       if (this->current->p_parent != 0)
01731       {
01732         this->current = this->current->p_parent;// point to the parent
01733       }
01734     }
01735     // the node has a sibling so point to it
01736     this->current = this->current->p_next_sibling;  
01737   }
01738   if (this->current->p_parent == 0)     // We're at the root node or its siblings
01739   {
01740                 if (this->current->p_next_sibling == 0) // At end so set end condition pointer
01741     {                                                                   // and flag
01742       this->end.p_previous = tmp_current;
01743       this->at_end = true;
01744     }
01745   }
01746   if (this->at_start)                   // Was at start so reset flag 
01747                 this->at_start = false; // to indicate that no longer at start
01748   
01749   return *this;       // return the new node that's pointed to.
01750 }
01751     
01752 //------------------------------------------------------------------------
01753 /**
01754   * pre-fix decrement operator
01755  * @return Reference to pre-order iterator
01756  */
01757 template <class T>
01758 inline typename    // pre-fix decrement
01759 Tree<T>::Pre_Order_Iterator& Tree<T>::Pre_Order_Iterator::operator--()  
01760 {
01761   if (this->current == 0)  // do nothing if this is not a valid node
01762   {
01763     return *this;
01764   }
01765   
01766   Tree_Node * tmp_current = this->current;
01767   if (this->current->p_previous_sibling != 0)  // if this node has a previous sibling
01768   {  // go down the sibling chain to find the last child
01769     this->current = this->current->p_previous_sibling;  
01770     while (this->current->p_last_child != 0)  // 
01771     {
01772       this->current = this->current->p_last_child;
01773     }
01774   }
01775   else             // this node doesn't have a previous sibling
01776   {
01777     if (this->current->p_parent != 0)
01778       this->current = this->current->p_parent;  // point to its parent
01779   }
01780   if (this->current->p_parent == 0)     // We're at the root node or its siblings
01781   {
01782                 if (this->current->p_previous_sibling == 0)     // At start so set start condition
01783     {                                                                           // pointer and flag
01784       this->start.p_next = tmp_current;
01785       this->at_start = true;
01786     }
01787   }
01788   if (this->at_end)                             // Was at end to reset flag
01789           this->at_end = false;         // to indicate that no longer at end
01790   
01791   return *this;       // return the new node that's pointed to.
01792 }
01793 
01794 //------------------------------------------------------------------------
01795 /**
01796   * post-fix increment operator
01797  * @param[in] Dummy int parameter to provide a unique prototype for the
01798  *            function
01799  * @return    Pre-order iterator
01800  */
01801 template <class T>
01802 inline typename    // post-fix increment
01803 Tree<T>::Pre_Order_Iterator Tree<T>::Pre_Order_Iterator::operator++(int)  
01804 {
01805   Pre_Order_Iterator temp = *this;
01806   ++(*this);
01807   return temp;
01808 }
01809     
01810 //------------------------------------------------------------------------
01811 /**
01812   * post-fix decrement operator
01813  * @param[in] Dummy int parameter to provide a unique prototype for the
01814  *            function
01815  * @return     Pre-order iterator
01816  */
01817 template <class T>
01818 inline typename    // post-fix decrement
01819 Tree<T>::Pre_Order_Iterator Tree<T>::Pre_Order_Iterator::operator--(int)  
01820 {
01821   Pre_Order_Iterator temp = *this;
01822   --(*this);
01823   return temp;
01824 }
01825 
01826 //------------------------------------------------------------------------
01827 /**
01828   * increment by specified value operator
01829  * @param[in] x   Unsigned int to specify the increment
01830  * @return Reference to pre-order iterator
01831  */
01832 template <class T>
01833 inline typename Tree<T>::Pre_Order_Iterator&
01834 Tree<T>::Pre_Order_Iterator::operator+=(unsigned int a)
01835 {
01836   while (a > 0)
01837   {
01838     ++(*this);
01839     if (this->current == 0)
01840     {
01841       break;
01842     }
01843     --a;
01844   }
01845   return *this;
01846 }
01847 
01848 //------------------------------------------------------------------------
01849 /**
01850  * decrement by specified value operator
01851  * @param[in] x   Unsigned into to specify the decrement
01852  * @return Reference to pre-order iterator
01853  */
01854 template <class T>
01855 inline typename Tree<T>::Pre_Order_Iterator&
01856 Tree<T>::Pre_Order_Iterator::operator-=(unsigned int a)
01857 {
01858   while (a > 0)
01859   {
01860     --(*this);
01861     if (this->current == 0)
01862     {
01863       break;
01864     }
01865     --a;
01866   }
01867   return *this;
01868 }
01869 
01870 template <class T>
01871 inline int Tree<T>::Pre_Order_Iterator::get_index_position() const
01872 {
01873   if ((this->current == 0) && (!this->at_end) && (!this->at_start))     // If current is invalid
01874     return 0;           // and not at start or end, the only possibility is that
01875   // we're at an un-allocated root node i.e. empty tree
01876   
01877   int index = -1;
01878   Pre_Order_Iterator temp_itr = *this;
01879 
01880   // Point a pre-order iterator at the current location
01881   while (!temp_itr.at_start)    
01882   {                                                             // decrenment the iterator and increment the index
01883     --temp_itr;                         // to determine the current index position.
01884     ++index;
01885   }
01886   return index;
01887 }
01888 
01889 
01890 
01891 /**************************************************************************/
01892 /**************************************************************************/
01893 /*                        Post-Order Iterator functions                   */
01894 /**************************************************************************/
01895 /**************************************************************************/
01896 //------------------------------------------------------------------------
01897 /**
01898  * Default constructor
01899  * @param[in] init  Pointer to tree node.
01900  */
01901 template <class T>
01902 inline Tree<T>::Post_Order_Iterator::Post_Order_Iterator(Tree_Node * init)
01903 : Iterator(init)
01904 {
01905 }
01906 
01907 //------------------------------------------------------------------------
01908 /**
01909  * Copy constructor
01910  * @param[in] a  Reference to base or derived iterator classes.
01911  */
01912 template <class T>
01913 template <typename Iterator_Type>
01914 inline Tree<T>::Post_Order_Iterator::Post_Order_Iterator(const Iterator_Type& a)
01915 : Iterator(a)
01916 {
01917 }
01918 
01919 //------------------------------------------------------------------------
01920 /**
01921  * Template type constructor
01922  * @param[in] a  Reference to the template type.
01923  */
01924 template <class T>
01925 inline Tree<T>::Post_Order_Iterator::Post_Order_Iterator(T & a)
01926 : Iterator(a)
01927 {
01928 }
01929 
01930 //------------------------------------------------------------------------
01931 /**
01932   * pre-fix increment operator
01933  * @return Reference to post-order iterator
01934  */
01935 template <class T>
01936 inline typename Tree<T>::Post_Order_Iterator&
01937 Tree<T>::Post_Order_Iterator::operator++()  // pre-fix increment
01938 {
01939   if (this->current == 0)  // do nothing if this is not a valid node
01940   {
01941     return *this;
01942   }
01943   
01944   Tree_Node * tmp_current = this->current;
01945   if (this->current->p_next_sibling != 0)
01946   {
01947     this->current = this->current->p_next_sibling;
01948     while (this->current->p_first_child != 0)
01949     {
01950       this->current = this->current->p_first_child;
01951     }
01952   }
01953   else
01954   {
01955     if (this->current->p_parent != 0)
01956       this->current = this->current->p_parent;
01957   }
01958   if (this->current->p_parent == 0)     // We're at the root node or its siblings
01959   {
01960     if (this->current->p_next_sibling == 0)
01961     {
01962       this->end.p_previous = tmp_current;// At end so set end condition pointer
01963       this->at_end = true;                                      // and set flag
01964     }
01965   }
01966   if (this->at_start)                   // Was at start to reset flag to indicate no longer
01967     this->at_start = false;     // at start
01968   return *this;
01969 }
01970 
01971 //------------------------------------------------------------------------
01972 /**
01973   * pre-fix decrement operator
01974  * @return Reference to post-order iterator
01975  */
01976 template <class T>
01977 inline typename Tree<T>::Post_Order_Iterator&
01978 Tree<T>::Post_Order_Iterator::operator--()  // pre-fix decrement
01979 {
01980   if (this->current == 0)  // do nothing if this is not a valid node
01981   {
01982     return *this;
01983   }
01984   
01985   Tree_Node * tmp_current = this->current;
01986   if (this->current->p_last_child != 0)
01987   {
01988     this->current = this->current->p_last_child;
01989   }
01990   else
01991   {
01992     while (this->current->p_previous_sibling == 0)
01993     {
01994       this->current = this->current->p_parent;
01995       if (this->current == 0)
01996       {
01997         return *this;
01998       }
01999     }
02000     this->current = this->current->p_previous_sibling;
02001   }
02002   if (this->current->p_parent == 0)     // We're at the root node or its siblings
02003   {
02004                                 if (this->current->p_previous_sibling == 0)
02005         {
02006           this->start.p_next = tmp_current;// At start so set start condition pointer
02007           this->at_start = true;                        // and flag
02008         }
02009   }
02010   if (this->at_end)
02011                                 this->at_end = false;// Was at end to reset flag to indicate no longer at end
02012   
02013   return *this;
02014 }
02015 
02016 //------------------------------------------------------------------------
02017 /**
02018   * post-fix increment operator
02019  * @param[in] Dummy int parameter to provide a unique prototype for the
02020  *            function
02021  * @return    Post-order iterator
02022  */
02023 template <class T>
02024 inline typename Tree<T>::Post_Order_Iterator
02025 Tree<T>::Post_Order_Iterator::operator++(int)  // pree-fix increment
02026 {
02027   Post_Order_Iterator temp = *this;
02028   ++(*this);
02029   return temp;
02030 }
02031     
02032 //------------------------------------------------------------------------
02033 /**
02034   * post-fix decrement operator
02035  * @param[in] Dummy int parameter to provide a unique prototype for the
02036  *            function
02037  * @return    Post-order iterator
02038  */
02039 template <class T>
02040 inline typename Tree<T>::Post_Order_Iterator
02041 Tree<T>::Post_Order_Iterator::operator--(int)  // pree-fix decrement
02042 {
02043   Post_Order_Iterator temp = *this;
02044   --(*this);
02045   return temp;
02046 }
02047 
02048 //------------------------------------------------------------------------
02049 /**
02050   * increment by specified value operator
02051  * @param[in] x   Unsigned int to specify the increment
02052  * @return Reference to post-order iterator
02053  */
02054 template <class T>
02055 inline typename Tree<T>::Post_Order_Iterator&
02056 Tree<T>::Post_Order_Iterator::operator+=(unsigned int a)
02057 {
02058   while (a > 0)
02059   {
02060     ++(*this);
02061     if (this->current == 0)
02062     {
02063       break;
02064     }
02065     --a;
02066   }
02067   return *this;
02068 }
02069 
02070 //------------------------------------------------------------------------
02071 /**
02072   * decrement by specified value operator
02073  * @param[in] x   Unsigned int to specify the decrement
02074  * @return Reference to post-order iterator
02075  */
02076 template <class T>
02077 inline typename Tree<T>::Post_Order_Iterator&
02078 Tree<T>::Post_Order_Iterator::operator-=(unsigned int a)
02079 {
02080   while (a > 0)
02081   {
02082     --(*this);
02083     if (this->current == 0)
02084     {
02085       break;
02086     }
02087     --a;
02088   }
02089   return *this;
02090 }
02091 
02092 
02093 //------------------------------------------------------------------------
02094 /**
02095  * Zero-referenced index from begin.
02096  * @param[in] x   Unsigned int to specify the decrement
02097  * @return        True if less than, false otherwise
02098  */
02099 template <class T>
02100 inline int Tree<T>::Post_Order_Iterator::get_index_position() const
02101 {
02102   if ((this->current == 0) && (!this->at_end) && (!this->at_start))
02103     return 0;
02104   
02105   int index = -1;
02106   Post_Order_Iterator temp_itr = *this; // Point a post-order iterator
02107   // at the current location
02108   while (temp_itr.current->p_parent != 0
02109     || temp_itr.current->p_previous_sibling != 0)
02110   {
02111     --temp_itr;         // decrenment the iterator and increment the index
02112     ++index;                    // to determine the current index position.
02113   }
02114   return index;
02115 }
02116 
02117 
02118 /**************************************************************************/
02119 /**************************************************************************/
02120 /*                           Chain Iterator functions                     */
02121 /**************************************************************************/
02122 /**************************************************************************/
02123 //------------------------------------------------------------------------
02124 /**
02125  * Constructor
02126  * @param[in] begin_chain Pointer to node that specifies the beginning of the
02127  *                        chain
02128  * @param[in] end_chaing   Pointer to node that specifies the end of the chain
02129  */
02130 template <class T>
02131 inline  Tree<T>::Chain_Iterator::Chain_Iterator(
02132             Tree_Node* begin_chain, Tree_Node* end_chain) :
02133 Iterator(begin_chain)
02134 {
02135   this->start.p_next = begin_chain;
02136   this->end.p_previous = end_chain;
02137 }
02138 
02139 //------------------------------------------------------------------------
02140 /**
02141  * Constructor
02142  * @param[in] begin_chain Pointer to node that specifies the beginning of the
02143  *                        chain
02144  * @param[in] end_chain   Pointer to node that specifies the end of the chain
02145  */
02146 template <class T>
02147 inline  Tree<T>::Chain_Iterator::Chain_Iterator(
02148             Iterator begin_chain, Iterator end_chain) :
02149 Iterator(begin_chain)
02150 {
02151   this->start.p_next = begin_chain.current;
02152   this->end.p_previous = end_chain.current;
02153 }
02154 
02155 //------------------------------------------------------------------------
02156 /**
02157  * Copy constructor
02158  */
02159 template <class T>
02160 inline  Tree<T>::Chain_Iterator::Chain_Iterator(const Chain_Iterator & a)
02161 : Iterator(a)
02162 {
02163 }
02164 
02165 //------------------------------------------------------------------------
02166 /**
02167  * Destructor
02168  */
02169 template <class T>
02170 inline  Tree<T>::Chain_Iterator::~Chain_Iterator()
02171 {
02172 }
02173 
02174 //------------------------------------------------------------------------
02175 /**
02176  * Equals operator: sets the current position of a non-chain iterator to the
02177  * current position of this iterator if the arg. iterator's current node is on
02178  * the chain
02179  * @param[in] x  Reference to base iterator
02180  * @return       Reference to base iterator class
02181  */
02182 template <class T>
02183 template <typename Iterator_Type>
02184 inline typename Tree<T>::Chain_Iterator&
02185 Tree<T>::Chain_Iterator::operator=(const Iterator_Type & x)
02186 {
02187   if (on_chain(x.current))      // before setting, check that the
02188   {                    // x node is on the chain
02189     this->current = x.current;
02190   }
02191   return *this;
02192 }
02193 
02194 
02195 //------------------------------------------------------------------------
02196 /**
02197  * Equals operator: sets the variables of the arg chain iterator to the
02198  * this chain iterator. The built-in equals operator does the same thing.
02199  * This is provided in case the class is extended in the future
02200  * to have allocated variables.
02201  * @param[in] x  Reference to base iterator.
02202  * @return       Reference to base iterator class
02203  */
02204 template <class T>
02205 inline typename Tree<T>::Chain_Iterator & 
02206 Tree<T>::Chain_Iterator::operator=(const Chain_Iterator & x)
02207 {
02208   this->current = x.current;
02209   this->start.p_next = x.start.p_next;
02210   this->end.p_previous = x.end.p_previous;
02211   this->at_start = x.at_start;
02212   this->at_end = x.at_end;
02213   
02214   return *this;
02215 }
02216 
02217 //------------------------------------------------------------------------
02218 /**
02219  * Return beginning node of chain
02220  * @return Pointer to node
02221  */
02222 template <class T>
02223 inline typename Tree<T>::Tree_Node* Tree<T>::Chain_Iterator::get_first_node()
02224 {
02225   return this->start.p_next;
02226 }
02227 
02228 //------------------------------------------------------------------------
02229 /**
02230  * Return the ending node of the chain
02231  * @return Pointer to node
02232  */
02233 template <class T>
02234 inline typename Tree<T>::Tree_Node* Tree<T>::Chain_Iterator::get_last_node()
02235 {
02236   return this->end.p_previous;
02237 }
02238 
02239 //------------------------------------------------------------------------
02240 /**
02241  * Set Chain_Iterator to begin node of chain
02242  */
02243 template <class T>
02244 inline void Tree<T>::Chain_Iterator::set_begin()
02245 {
02246   this->current =  this->start.p_next;
02247   this->at_start = false;
02248   this->at_end = false;
02249 }
02250 
02251 //------------------------------------------------------------------------
02252 /**
02253  * Set Chain_Iterator to past end node of chain
02254  */
02255 template <class T>
02256 inline void Tree<T>::Chain_Iterator::set_end()
02257 {
02258   this->current =  this->end.p_previous;
02259   this->at_start = false;
02260   this->at_end = true;
02261 }
02262 
02263 //------------------------------------------------------------------------
02264 /**
02265  * pre-fix increment operator
02266  * @return Reference to chain iterator
02267  */
02268 template <class T>
02269 inline typename Tree<T>::Chain_Iterator&
02270 Tree<T>::Chain_Iterator::operator++()
02271 {
02272   if (this->current == 0)
02273   {
02274     return *this;
02275   }
02276   if (this->at_start)
02277   {
02278         this->current = this->start.p_next;
02279         this->at_start = false;
02280         return *this;
02281   }
02282   
02283   if (this->current == this->end.p_previous)
02284   {
02285                                 this->at_end = true;
02286         return *this;
02287   }
02288   
02289   if (is_ancestor(Iterator(this->end.p_previous))) // Move down the tree towards _end
02290   {                            
02291     this->current = this->current->p_first_child;  // determine which child 
02292     // is ancestor 
02293     while (!is_ancestor(Iterator(this->end.p_previous))) // iterate through siblings
02294     {                              
02295       if (this->current == this->end.p_previous)  // At end of chain 
02296       {
02297         return *this;            // so return this
02298       }
02299       this->current = this->current->p_next_sibling;
02300     }
02301   }
02302   else  // Move up the tree towards _end or an ancestor of _end
02303   {
02304     this->current = this->current->p_parent;
02305   }
02306   
02307   return *this;
02308 }
02309 
02310 //------------------------------------------------------------------------
02311 /**
02312  * pre-fix decrement operator
02313  * @return Reference to chain iterator
02314  */
02315 template <class T>
02316 inline typename Tree<T>::Chain_Iterator&
02317 Tree<T>::Chain_Iterator::operator--()
02318 {
02319   if (this->current == 0)
02320   {
02321     return *this;
02322   }
02323   
02324   if (this->at_end)
02325   {
02326     this->current = this->end.p_previous;
02327         this->at_end = false;
02328         return *this;
02329   }
02330   
02331   if (this->current == this->start.p_next)
02332   {
02333                                 this->at_start = true;
02334         return *this;
02335   }
02336   
02337   
02338   if (is_ancestor(Iterator(this->start.p_next))) // Move down the tree towards _begin
02339   {   // determine which child is ancestor of _begin
02340     this->current = this->current->p_first_child;
02341     while (!is_ancestor(Iterator(this->start.p_next))) 
02342     {
02343       if (this->current == this->start.p_next)  // At _begin of chain
02344       {
02345         return *this;            // so return this
02346       }
02347       this->current = this->current->p_next_sibling;
02348       
02349     }
02350   }
02351   else  // Move up the tree towards _begin or an ancestor of _begin
02352   {
02353     this->current = this->current->p_parent;
02354   }
02355   return *this;
02356 }
02357 
02358 //------------------------------------------------------------------------
02359 /**
02360  * post-fix increment operator
02361  * @param[in] Dummy int parameter to provide a unique prototype for the
02362  *            function
02363  * @return    Chain iterator
02364  */
02365 template <class T>
02366 inline typename Tree<T>::Chain_Iterator
02367 Tree<T>::Chain_Iterator::operator++(int)  // post-fix increment
02368 {
02369   Chain_Iterator temp = *this;
02370   ++(*this);
02371   return temp;
02372 }
02373     
02374 //------------------------------------------------------------------------
02375 /**
02376  * post-fix decrement operator
02377  * @param[in] Dummy int parameter to provide a unique prototype for the
02378  *            function
02379  * @return    Chain iterator
02380  */
02381 template <class T>
02382 inline typename Tree<T>::Chain_Iterator
02383 Tree<T>::Chain_Iterator::operator--(int)  // post-fix decrement
02384 {
02385   Chain_Iterator temp = *this;
02386   --(*this);
02387   return temp;
02388 }
02389 
02390 
02391 //------------------------------------------------------------------------
02392 /**
02393  * increment by specified value operator
02394  * @param[in] x   Unsigned int to specify the increment
02395  * @return Reference to chain iterator
02396  */
02397 template <class T>
02398 inline typename Tree<T>::Chain_Iterator&
02399 Tree<T>::Chain_Iterator::operator+=(unsigned int a)
02400 {
02401   while (a > 0)
02402   {
02403     ++(*this);
02404     if (this->current == 0)
02405     {
02406       break;
02407     }
02408     a--;
02409   }
02410   return *this;
02411 }
02412 
02413 //------------------------------------------------------------------------
02414 /**
02415  * decrement by specified value operator
02416  * @param[in] x   Unsigned int to specify the decrement
02417  * @return Reference to chain iterator
02418  */
02419 template <class T>
02420 inline typename Tree<T>::Chain_Iterator&
02421 Tree<T>::Chain_Iterator::operator-=(unsigned int a)
02422 {
02423   while (a > 0)
02424   {
02425     --(*this);
02426     if (this->current == 0)
02427     {
02428       break;
02429     }
02430     a--;
02431   }
02432   return *this;
02433 }
02434 
02435 //------------------------------------------------------------------------
02436 /**
02437  * Set current node, Check that the new current node is in the chain
02438  * @param[in] new_current  Pointer to specify the new node to point to.
02439  * @return                 True if successful, false if failed
02440  */
02441 template <class T>    // Override the base class function
02442 inline bool Tree<T>::Chain_Iterator::set_current(Tree_Node * new_current)  
02443 {
02444   if (on_chain(new_current))      // before setting, check that the
02445   {
02446     this->current = new_current;          // new_current is on the chain
02447                                 this->at_end = false;
02448         this->at_start = false;
02449         return true;
02450   }
02451   return false;
02452 }
02453 
02454 
02455 //------------------------------------------------------------------------
02456 /**
02457  * Check if a node is on the chain of this chain iterator
02458  * @param[in] a  Pointer to node to test for.
02459  * @return       True if on chain, false if not on chain
02460  */
02461 template <class T>
02462 inline bool Tree<T>::Chain_Iterator::on_chain(const Tree_Node * a) const
02463 {
02464   Chain_Iterator local_iterator(*this);
02465   
02466   local_iterator.set_begin();
02467   
02468   while (!local_iterator.at_end)
02469   {
02470     if (a == local_iterator.current)
02471     {
02472       return true;
02473     }
02474     ++local_iterator;
02475   }
02476   return false;
02477 }
02478 
02479 
02480 //------------------------------------------------------------------------
02481 /**
02482  * Zero-referenced index from begin.
02483  * @return        Index
02484  */
02485 template <class T>
02486 inline int Tree<T>::Chain_Iterator::get_index_position() const
02487 {
02488   int index = -1;
02489   Chain_Iterator temp_itr(*this);
02490   if (temp_itr.at_start)
02491     return index;
02492   
02493   while (!temp_itr.at_start)
02494   {
02495     --temp_itr;
02496     ++index;
02497   }
02498   return index;
02499   
02500 }
02501 
02502 /**************************************************************************/
02503 /**************************************************************************/
02504 /*                             TREE functions                             */
02505 /**************************************************************************/
02506 /**************************************************************************/
02507 //------------------------------------------------------------------------
02508 /**
02509  * Default constructor
02510  */
02511 template <class T>
02512 inline Tree<T>::Tree()
02513 : _root_node(0), _start_node(0), _end_node(0), _number_of_nodes(0)
02514 {
02515                 _initialize_tree();
02516 };
02517 
02518 //------------------------------------------------------------------------
02519 /**
02520  * Copy constructor
02521  * @param[in] a  Reference to another tree.
02522  */
02523 template <class T>
02524 inline Tree<T>::Tree(const Tree<T>& a)
02525 : _root_node(0), _start_node(0), _end_node(0), _number_of_nodes(0)
02526 {
02527   _root_node = 0;
02528   _number_of_nodes = 0;
02529                 _initialize_tree();
02530     copy(a);
02531 }
02532 
02533 //------------------------------------------------------------------------
02534 /**
02535  * Destructor
02536  */
02537 template <class T>
02538 inline Tree<T>::~Tree()
02539 {
02540   clear_tree();    // Clear the tree of nodes
02541   delete _end_node;
02542   delete _start_node;
02543 }
02544 
02545 //------------------------------------------------------------------------
02546 /**
02547  * initialize the start_node and end_node
02548  */
02549 template <class T>
02550 inline void Tree<T>::_initialize_tree()
02551 {
02552   _start_node = new Tree_Node();
02553   _start_node->p_next_sibling = _root_node;
02554   _end_node = new Tree_Node();
02555   _end_node->p_previous_sibling = _root_node;
02556   
02557 }
02558 
02559 //------------------------------------------------------------------------
02560 /*
02561  * get the number of the nodes on the tree
02562  * @return unsigned int number of nodes
02563  */
02564 template <class T>
02565 inline unsigned int Tree<T>::size()
02566 {
02567   return _number_of_nodes;
02568 }
02569 
02570 //------------------------------------------------------------------------
02571 /**
02572  * Determine if tree is empty
02573  * @return bool true if tree is empty
02574  */
02575 template <class T>
02576 inline bool Tree<T>::empty()
02577 {
02578   return (_number_of_nodes == 0);
02579 }
02580 
02581 //------------------------------------------------------------------------
02582 /**
02583  * Check if the current node of an iterator is on the tree
02584  * @param[in] d_iterator  Reference to base or derived iterator classes.
02585  * @return                True if on tree, false if not on tree
02586  */
02587 template <class T>
02588 template <typename Iterator_Type> 
02589 inline bool Tree<T>::on_tree(const Iterator_Type & d_iterator)
02590 {
02591   if (!d_iterator.current)
02592   {
02593     return false;
02594   }
02595   
02596   // If no nodes; return false
02597   if (size() == 0)
02598     {
02599       return false;
02600     }
02601 
02602   // Start at the pre-ordered begin of the tree
02603   Pre_Order_Iterator  check_iterator(begin_pre_order()); 
02604   
02605   // Iterate through the tree; if the node is found, return true
02606   while (check_iterator < end_pre_order())
02607   {
02608     if (check_iterator == d_iterator)
02609     {
02610       return true;
02611     }
02612     ++check_iterator;
02613   }
02614   
02615   // Node was not found so return false
02616   return false;
02617 }
02618 
02619 
02620 //------------------------------------------------------------------------
02621 /**
02622  * Clear the tree of nodes
02623  */
02624 template <class T>
02625 inline void Tree<T>::clear_tree()
02626 {
02627   if (!_root_node)  // If the root node isn't valid, the tree already
02628   {
02629     return;      // doesn't have any nodes to return
02630   }
02631   
02632   // Begin clearing the tree of nodes at the first post-order node.
02633   Iterator p_tmp;
02634   Post_Order_Iterator  clr_iterator(begin_post_order());
02635   
02636   while (size() > 0)  // While there are still valid nodes
02637   {
02638     p_tmp = clr_iterator;  // Point to the current node
02639     
02640     ++clr_iterator;        // Increment to the next post-order node
02641     
02642     delete_node(p_tmp);      // Delete the previous node
02643     
02644   }
02645   _root_node = 0;  // Set the root node to 0
02646 }
02647 
02648 //------------------------------------------------------------------------
02649 /**
02650  * Delete the node and all its descendents pointed to by the iterator
02651  * @param[in] a  Reference to base or derived iterator class.
02652  */
02653 template <class T>
02654 template <typename Iterator_Type> 
02655 inline void Tree<T>::delete_descendents(const Iterator_Type& a)
02656 {
02657   if (!a.current)  // If the node isn't valid, return
02658   {
02659     return;
02660   }
02661   
02662   Iterator p_tmp;
02663   Post_Order_Iterator stop_iterator(a);
02664   Post_Order_Iterator delete_iterator(a);
02665   
02666   // Stop deleting at the node after the node that's pointed to
02667   ++stop_iterator;  
02668   
02669   --delete_iterator;  // Find the start node to begin deleting
02670   while (delete_iterator.is_descendent(a))
02671   {
02672     --delete_iterator;
02673   }
02674   if (delete_iterator.current)
02675   {
02676     // Increment by 1 to point to the first node to be deleted
02677     ++delete_iterator;  
02678   }
02679   else
02680   {
02681     delete_iterator = begin_post_order(); // start at the beginning
02682   }
02683   
02684   while (delete_iterator != stop_iterator)  // delete in post_order until the
02685   {                      // stop node is reached
02686     p_tmp = delete_iterator;
02687     ++delete_iterator;
02688     delete_node(p_tmp);
02689   }
02690 }
02691 
02692 //------------------------------------------------------------------------
02693 /**
02694  * Delete this iterator's node only if it is valid, has no children and
02695  * is on this tree
02696  * @param[in] d_iter  Reference to base or derived iterator classes.
02697  */
02698 template <class T>
02699 template <typename Iterator_Type> 
02700 inline void Tree<T>::delete_node(Iterator_Type d_iter)
02701 {
02702   if (!d_iter.current)  // should have a valid node
02703   {
02704     return;
02705   }
02706   
02707   if (d_iter.current->p_first_child)
02708   {
02709     return;  // this node should not have any children
02710   }
02711   
02712   if (!on_tree(d_iter))  // The node should be on the tree
02713   {
02714     return;
02715   }
02716   
02717   if (d_iter.current->p_parent)  // This is not the root node
02718   {
02719     // First reset pointers to isolate the node to be deleted
02720     
02721     // If it is the first child
02722     if (d_iter.current == d_iter.current->p_parent->p_first_child)  
02723     {
02724       if (!d_iter.current->p_next_sibling)      // if it is the only child
02725       {
02726         // detach its links to its parent
02727         d_iter.current->p_parent->p_first_child = 0;  
02728         d_iter.current->p_parent->p_last_child = 0;
02729       }
02730       else  // it has a next sibling, make the next sibling the first sibling
02731       {
02732         d_iter.current->p_parent->p_first_child
02733           = d_iter.current->p_next_sibling;
02734         d_iter.current->p_next_sibling->p_previous_sibling = 0;
02735       }
02736     }
02737     else  // it is not the first child
02738     {
02739       // If it is the last child
02740       if (d_iter.current == d_iter.current->p_parent->p_last_child)  
02741       {
02742         d_iter.current->p_parent->p_last_child
02743           = d_iter.current->p_previous_sibling; // detach it from its parent
02744         d_iter.current->p_previous_sibling->p_next_sibling = 0;
02745       }
02746       else  // this is a middle child
02747       {
02748         d_iter.current->p_previous_sibling->p_next_sibling
02749           = d_iter.current->p_next_sibling;
02750         d_iter.current->p_next_sibling->p_previous_sibling
02751           = d_iter.current->p_previous_sibling;
02752       }
02753     }
02754     
02755   }
02756   
02757   d_iter.current = 0;
02758   --_number_of_nodes;  // Reduce the number of nodes by 1
02759 }
02760 
02761 //------------------------------------------------------------------------
02762 /**
02763  * Copy a specified tree into this tree
02764  * @param[in] a  Reference to a tree.
02765  */
02766 template <class T>
02767 inline bool Tree<T>::copy(const Tree<T>& a)
02768 {
02769   if (this == &a)    // A tree cannot copy itself
02770   {
02771     return false;
02772   }
02773   
02774   if (!a._root_node)  // the tree to be copied must have nodes
02775   {
02776     return false;
02777   }
02778   
02779   clear_tree();  // Clear this tree
02780   
02781   //_root_node = new Tree_Node(*(a._root_node->data));  // copy a's root node
02782   
02783   Pre_Order_Iterator a_iterator(a.begin_pre_order());
02784   Pre_Order_Iterator local_iterator(begin_pre_order());
02785   
02786   copy_descendents(local_iterator, a_iterator);
02787   
02788   return true;
02789   
02790 }
02791 
02792 //------------------------------------------------------------------------
02793 /**
02794  * Copy the node and its descendents onto this tree at the specified node
02795  * @param[in] dest_itr Reference to base or derived iterator classes to copy
02796  *                     to.
02797  * @param[in] src_itr  Reference to base or derived iterator classes to copy
02798  *                     from
02799  */
02800 template <class T>
02801 template <typename Iterator_Type1, typename Iterator_Type2> 
02802 inline bool Tree<T>::copy_descendents(
02803                       Iterator_Type1 dest_itr, Iterator_Type2 src_itr)
02804 {
02805 
02806   // Src node must be valid
02807   if (!src_itr.current)
02808   {
02809     return false;
02810   }
02811   
02812   // Dest node must either be on the tree or the
02813   // root node (when the tree is empty)
02814   if (!on_tree(dest_itr) && !is_root(dest_itr))
02815   {
02816     return false;
02817   }
02818   
02819   // Source and destination cannot be identical; 
02820   if (src_itr == dest_itr)
02821   {
02822     return false;
02823   }
02824   
02825   // Destination cannot be a descendent of the source
02826   if (dest_itr.is_descendent(src_itr))
02827   {
02828     return false;
02829   }
02830   
02831   
02832   typename Tree<T>::Iterator src_itr_local(src_itr);
02833   typename Tree<T>::Pre_Order_Iterator new_parent;
02834 
02835 
02836   // T should have a copy constructor
02837   T * new_data = new T(*(src_itr.current->data)); 
02838   
02839   // First append the current node
02840   new_parent = append_child(dest_itr, new_data);
02841   
02842   // Now copy the children of the current node
02843   // If the current node of a has children
02844   if (src_itr_local.current->p_first_child)  
02845   {
02846     // point to first child
02847     src_itr.current = src_itr_local.current->p_first_child;    
02848     src_itr_local.current = src_itr.current;
02849     
02850     // add the first child and its descendents
02851     copy_descendents(new_parent, src_itr);  
02852     
02853     // while there are additional siblings of the current node
02854     while (src_itr_local.current->p_next_sibling)  
02855     {
02856       src_itr.current = src_itr_local.current->p_next_sibling;
02857       
02858       // add the descendents of the new node
02859       copy_descendents(new_parent, src_itr);  
02860       src_itr_local.current = src_itr_local.current->p_next_sibling;
02861     }
02862   }
02863   return true;
02864 }
02865 
02866 //------------------------------------------------------------------------
02867 /**
02868  * tree equal operator
02869  * @param[in] a  Reference to the tree to copy from.
02870  */
02871 template <class T>
02872 inline Tree<T> &  Tree<T>::operator=(const Tree<T> & a)
02873 {
02874   copy(a);
02875   return *this;
02876 }
02877 
02878 //------------------------------------------------------------------------
02879 /**
02880  * Return the iterator that points to the parent of this iterator's node
02881  * @paramp[in] a  Reference to base or derived iterator classes.
02882  * @return        Base or derived iterator .
02883  */
02884 template <class T>
02885 template <typename Iterator_Type> Iterator_Type
02886 inline Tree<T>::get_parent(const Iterator_Type& child) const
02887 {
02888   
02889   // NOTE: Potential problem here if current points to an invalid node
02890   return Iterator_Type(child.current->p_parent);
02891 }
02892 
02893 //------------------------------------------------------------------------
02894 /**
02895  * Query if the node pointed to has a parent
02896  * @param[in] child  Reference to base or derived iterator classes.
02897  * @return           True if has a parent, false if not
02898  */
02899 template <class T>
02900 template <typename Iterator_Type> 
02901 inline bool Tree<T>::has_parent(const Iterator_Type& child) const
02902 {
02903   
02904   // NOTE: Potential problem here if current points to an invalid node
02905   return (child.current->p_parent==0)?false:true;
02906 }
02907 
02908 //------------------------------------------------------------------------
02909 /**
02910  * Return the iterator that points to the first child of this iterator's node
02911  * @param[in] child  Reference to base or derived iterator classes.
02912  * @return           Base or derived iterator 
02913  */
02914 template <class T>
02915 template <typename Iterator_Type> Iterator_Type 
02916 inline  Tree<T>::get_first_child(const Iterator_Type& child) const
02917 {
02918   
02919   // NOTE: Potential problem here if current points to an invalid node
02920   return Iterator_Type(child.current->p_first_child);
02921 }
02922 
02923 //------------------------------------------------------------------------
02924 /**
02925  * Return the iterator that points to the last child of this iterator's node
02926  * @param[in] child  Reference to base or derived iterator classes.
02927  * @return           Base or derived iterator 
02928  */
02929 template <class T>
02930 template <typename Iterator_Type> Iterator_Type 
02931 inline  Tree<T>::get_last_child(const Iterator_Type& child) const
02932 {
02933   
02934   // NOTE: Potential problem here if current points to an invalid node
02935   return Iterator_Type(child.current->p_last_child);
02936 }
02937 
02938 //------------------------------------------------------------------------
02939 /**
02940  * Return the iterator that points to the previous sibling of
02941  * this iterator's node
02942  * @param[in] child  Reference to base or derived iterator classes.
02943  * @return           Base or derived iterator 
02944  */
02945 template <class T>
02946 template <typename Iterator_Type> Iterator_Type 
02947 inline  Tree<T>::get_previous_sibling(const Iterator_Type& child) const
02948 {
02949   
02950   // NOTE: Potential problem here if current points to an invalid node
02951   return Iterator_Type(child.current->p_previous_sibling);
02952 }
02953   
02954 //------------------------------------------------------------------------
02955 /**
02956  * Return the iterator that points to the next sibling of this iterator's node
02957  * @param[in] child  Reference to base or derived iterator classes.
02958  * @return           Base or derived iterator 
02959  */
02960 template <class T>
02961 template <typename Iterator_Type> Iterator_Type 
02962 inline  Tree<T>::get_next_sibling(const Iterator_Type& child) const
02963 {
02964   
02965   // NOTE: Potential problem here if current points to an invalid node
02966   return Iterator_Type(child.current->p_next_sibling);
02967 }
02968 
02969 
02970 //------------------------------------------------------------------------
02971 /**
02972  * Append the data as a new child of the parent node. Note that a new
02973  * copy of the node data type is made
02974  * @param[in] parent       Reference to base or derived iterator classes.
02975  * @param[in] child_data   Reference to node data type to be appended
02976  * @return                 Base or derived iterator 
02977  */
02978 template <class T>
02979 template <typename Iterator_Type> Iterator_Type 
02980 inline Tree<T>::append_child(
02981                 Iterator_Type parent, T * child_data)
02982 {
02983   Tree_Node * new_child = 0;
02984   
02985   if ((parent.current)&&(on_tree(parent))) // parent is valid and on tree
02986   {
02987     new_child = new Tree_Node(child_data, parent.current);
02988   }
02989   else 
02990   {  // if root node exists attach to root node
02991     if (_root_node)
02992     {
02993       Iterator_Type root_parent(_root_node);
02994       new_child = new Tree_Node(child_data, root_parent.current);
02995     }
02996     else  // if root node does not exist, make this the root node
02997     {
02998       // don't need to change root node pointers
02999       _root_node = new Tree_Node(child_data);  
03000       new_child = _root_node;
03001       //parent.current = _root_node;  // point parent to root node
03002       _start_node->p_next_sibling = _root_node;
03003       _end_node->p_previous_sibling = _root_node;
03004       _root_node->p_previous_sibling = _start_node;
03005       _root_node->p_next_sibling = _end_node;
03006     }
03007   }
03008   Iterator_Type tmp(new_child);
03009   ++_number_of_nodes;
03010   return tmp;
03011 }
03012 
03013 //------------------------------------------------------------------------
03014 /**
03015  * Insert the new node data at the specified location and displace the
03016  * specified location to be the next sibling. Note that a new
03017  * copy of the node data type is made.
03018  * @param[in] location       Reference to base or derived iterator classes
03019  * @param[in] element_data   Reference to node data type to be inserted
03020  * @return                   Base or derived iterator 
03021  */
03022 template <class T>
03023 template <typename Iterator_Type> Iterator_Type 
03024 inline Tree<T>::insert(
03025                   Iterator_Type location, T * element_data)
03026 {
03027   Tree_Node * new_node;
03028   Iterator_Type new_location;
03029   
03030   // location is valid and on tree
03031   if ((location.current!= 0)&&(on_tree(location)) 
03032     ||(size() == 0))  
03033   {
03034     new_location = location;
03035   }
03036   else
03037   {
03038     
03039     // put the new node at the
03040     return insert_after(--end_pre_order(), element_data); 
03041     // end of the pre-ordered tree
03042   }
03043   new_node = new Tree_Node(element_data);
03044   
03045   if (new_location.current!=0)  // if this is not the root node
03046   {
03047     new_node->p_parent = new_location.current->p_parent;
03048 
03049     // new_location is a first child
03050     if (!new_location.current->p_previous_sibling)  
03051       new_location.current->p_parent->p_first_child = new_node;
03052     
03053     // new_location is a last child
03054     if (!new_location.current->p_next_sibling)  
03055       new_location.current->p_parent->p_last_child = new_node;
03056     
03057     if (new_location.current->p_previous_sibling)
03058       new_location.current->p_previous_sibling->p_next_sibling = new_node;
03059     
03060     new_node->p_previous_sibling = new_location.current->p_previous_sibling;
03061     new_node->p_next_sibling = new_location.current;
03062     new_location.current->p_previous_sibling = new_node;
03063     
03064     
03065   }
03066   else  // if this is the root node, it doesn't have a parent
03067   {
03068     new_node->p_parent = 0;
03069     new_node->p_previous_sibling = 0;
03070     new_node->p_next_sibling = 0;
03071     _root_node = new_node;
03072     _start_node->p_next_sibling = _root_node;
03073     _end_node->p_previous_sibling = _root_node;
03074     _root_node->p_previous_sibling = _start_node;
03075     _root_node->p_next_sibling = _end_node;
03076     
03077   }
03078   
03079   new_node->p_first_child = 0;
03080   new_node->p_last_child = 0;
03081   new_location.current = new_node;
03082   
03083   ++_number_of_nodes;
03084   
03085   return new_location;
03086 }
03087 
03088 
03089 //------------------------------------------------------------------------
03090 /**
03091  * Insert the new node data after the specified location and displace the
03092  * specified location to be the previous sibling. Note that a new
03093  * copy of the node data type is made.
03094  * @param[in] location      Reference to base or derived iterator classes.
03095  * @param[in] element_data  Reference to node data type to be inserted.
03096  * @return                  Base or derived iterator 
03097  */
03098 template <class T>
03099 template <typename Iterator_Type> Iterator_Type 
03100 inline Tree<T>::insert_after(
03101               Iterator_Type location, T * element_data)
03102 {
03103   Tree_Node * new_node;
03104   Iterator_Type new_location;
03105   
03106   // location is valid and on tree
03107   if ((location.current!= 0)&&(on_tree(location)))  
03108   {
03109     new_location = location;
03110   }
03111   else if (size() != 0)
03112   {
03113     new_location = --end_pre_order(); // put the new node at the end
03114     // of the pre-ordered tree
03115   }
03116   new_node = new Tree_Node(element_data);
03117   
03118   if (new_location.current != 0)  // if this is not the root node
03119   {
03120     new_node->p_parent = new_location.current->p_parent;
03121     
03122     if (!new_location.current->p_next_sibling)  // new_location is a last child
03123     {
03124       new_location.current->p_parent->p_last_child = new_node;
03125     }
03126     
03127     if (new_location.current->p_next_sibling)
03128     {
03129       new_location.current->p_next_sibling->p_previous_sibling = new_node;
03130     }
03131     
03132     new_node->p_previous_sibling = new_location.current;
03133     new_node->p_next_sibling = new_location.current->p_next_sibling;
03134     new_location.current->p_next_sibling = new_node;
03135   }
03136   else  // if this is the root node, it doesn't have a parent
03137   {
03138     new_node->p_parent = 0;
03139     new_node->p_previous_sibling = 0;
03140     new_node->p_next_sibling = 0;
03141     _root_node = new_node;
03142     _start_node->p_next_sibling = _root_node;
03143     _end_node->p_previous_sibling = _root_node;
03144     _root_node->p_previous_sibling = _start_node;
03145     _root_node->p_next_sibling = _end_node;
03146   }
03147   
03148   new_node->p_first_child = 0;
03149   new_node->p_last_child = 0;
03150   new_location.current = new_node;
03151   
03152   //location.current = new_node;
03153   ++_number_of_nodes;
03154   
03155   
03156   return new_location;
03157 }
03158 
03159 
03160 //------------------------------------------------------------------------
03161 /**
03162  * Returns the depth of the node in the tree
03163  * @param[in] a  Reference to base or derived iterator classes.
03164  * @return       Depth; -1 if error; root node depth = 0
03165  */
03166 template <class T>
03167 template <typename Iterator_Type> 
03168 inline int Tree<T>::get_depth(const Iterator_Type& a)
03169 {
03170   if (a.current == 0) // If iterator current position is invalid
03171   {
03172     return -1;    // return -1
03173   }
03174   if (!on_tree(a))  // If iterator does not point to a node on this tree
03175   {
03176     return -1;    // return -1
03177   }
03178   
03179   
03180   typename Tree<T>::Tree_Node * a_position = a.current;
03181   unsigned int return_value=0;
03182   
03183   while(a_position->p_parent != 0) // While not at the root node
03184   {
03185     a_position = a_position->p_parent;  // Iterate towards root
03186     ++return_value;            // and increment depth counter
03187   }
03188   return return_value;
03189 }
03190 
03191 //------------------------------------------------------------------------
03192 /**
03193  * Tests if the iterator is pointing at the root node
03194  * @param[in] a  Reference to base or derived iterator classes.
03195  * @return       True if is the root, false if not the root.
03196  */
03197 template <class T>
03198 template <typename Iterator_Type>
03199 inline bool Tree<T>::is_root(const Iterator_Type& a) const
03200 {
03201   return (a.current == _root_node);
03202 }
03203 
03204 //------------------------------------------------------------------------
03205 /**
03206  * Return a sibling iterator that points to the beginning of the siblings
03207  * @param[in] a  Reference to base or derived iterator classes.
03208  * @return       Sibling iterator
03209  */
03210 template <class T>
03211 template <typename Iterator_Type>
03212 inline typename Tree<T>::Sibling_Iterator Tree<T>::begin_sibling(const Iterator_Type & a)
03213 {
03214                 Sibling_Iterator sib_itr(a.current);
03215     sib_itr.current = sib_itr.start.p_next;
03216     return sib_itr;
03217 }
03218   
03219 //------------------------------------------------------------------------
03220 /**
03221  * Return a pre-order iterator that points to the beginning of the
03222  * pre-ordered tree
03223  * @return Pre-order iterator
03224  */
03225 template <class T>
03226 inline typename Tree<T>::Pre_Order_Iterator Tree<T>::begin_pre_order() const
03227 {
03228   
03229   Pre_Order_Iterator begin_pre_itr(_root_node);
03230   begin_pre_itr.at_end = false;
03231   begin_pre_itr.at_start = false;
03232   
03233   return begin_pre_itr;
03234 }
03235   
03236 //------------------------------------------------------------------------
03237 /**
03238  * Return a post-order iterator that points to the beginning of the
03239  * post-ordered tree
03240  * @return Post-order iterator
03241  */
03242 template <class T>
03243 inline typename Tree<T>::Post_Order_Iterator Tree<T>::begin_post_order() const
03244 {
03245   Tree_Node * p_tmp = begin_pre_order().current;
03246   
03247   if (!p_tmp)
03248     return Post_Order_Iterator(p_tmp);
03249   
03250   while (p_tmp->p_first_child)
03251     p_tmp = p_tmp->p_first_child;
03252   
03253   Post_Order_Iterator begin_post_itr(p_tmp);
03254   begin_post_itr.at_end = false;
03255   begin_post_itr.at_start = false;
03256   
03257   return begin_post_itr;
03258 }
03259   
03260 //------------------------------------------------------------------------
03261 /**
03262  * Return a new chain iterator that points to the beginning of the chain
03263  * @param[in] a  Reference to a chain iterator.
03264  * @return       Chain iterator
03265  */
03266 template <class T>
03267 inline typename Tree<T>::Chain_Iterator
03268 Tree<T>::begin_chain(Chain_Iterator & a) const
03269 {
03270   Chain_Iterator chain_itr(a);
03271   chain_itr.set_current(a.get_first_node());
03272   chain_itr.at_start = false;
03273   chain_itr.at_end = false;
03274   
03275   return chain_itr;
03276 }
03277   
03278 //------------------------------------------------------------------------
03279 /**
03280  * Return a sibling iterator that points to the end (1 beyond the last)
03281  * sibling
03282  * @param[in] a  Reference to base or derived iterator classes.
03283  * @return       Sibling iterator
03284  */
03285 template <class T>
03286 template <typename Iterator_Type> 
03287 inline typename Tree<T>::Sibling_Iterator
03288 Tree<T>::end_sibling(const Iterator_Type & a)
03289 {
03290   Sibling_Iterator sib_itr(a.current);
03291   
03292   sib_itr.current = sib_itr.end.p_previous;
03293   sib_itr.at_end = true;                // end_sibling points to a fictious 
03294   sib_itr.at_start = false;     // node beyone the last sibling
03295   
03296   return sib_itr;
03297 }
03298   
03299 //------------------------------------------------------------------------
03300 /**
03301  * Return a pre-order iterator that points to the end of the pre-ordered tree
03302  * @return Pre-order iterator
03303  */
03304 template <class T>
03305 inline typename Tree<T>::Pre_Order_Iterator Tree<T>::end_pre_order() const
03306 {
03307   Pre_Order_Iterator end_pre_itr(_end_node);
03308   end_pre_itr.at_end = true;
03309   end_pre_itr.at_start = false;
03310   
03311   return Pre_Order_Iterator(end_pre_itr);
03312 }
03313   
03314 //------------------------------------------------------------------------
03315 /**
03316  * Return a post_order_iterator that points to the end of the post-ordered tree
03317  * @return Post-order iterator
03318  */
03319 template <class T>
03320 inline typename Tree<T>::Post_Order_Iterator Tree<T>::end_post_order() const
03321 {
03322   Post_Order_Iterator end_post_itr(_end_node);
03323   end_post_itr.end.p_previous = _end_node->p_previous_sibling;
03324   end_post_itr.at_end = true;
03325   end_post_itr.at_start = false;
03326   
03327   return Post_Order_Iterator(end_post_itr);
03328 }
03329   
03330 //------------------------------------------------------------------------
03331 /**
03332  * Return a chain iterator that points to the end of this chain
03333  * @return Chain iterator
03334  */
03335 template <class T>
03336 inline typename Tree<T>::Chain_Iterator
03337 Tree<T>::end_chain(Chain_Iterator & a) const
03338 {
03339   Chain_Iterator chain_itr(a);
03340   chain_itr.set_current(a.get_last_node());
03341   chain_itr.at_start = false;
03342   chain_itr.at_end = true;
03343   
03344   return chain_itr;
03345   
03346 }
03347 
03348 
03349 
03350 #endif // __TREE_H