Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

general_tree.hh

00001 /*
00002 *  Name:      general_tree.hh
00003 *  Author:    Rafael Jesus Alcantara Perez
00004 *  Summary:   General tree class
00005 *  Date:      $Date: 2003/04/14 00:18:35 $
00006 *  Revision:  $Revision: 1.1 $
00007 *
00008 *  Copyright (C) 2000-2001  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00009 *
00010 *  This program is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  This program is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with this program; if not, write to the Free Software
00022 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00023 *  MA 02111-1307, USA.
00024 */
00025 
00026 #ifndef _MPCL_UTIL_COLLECTION_GENERAL_TREE__
00027 #define _MPCL_UTIL_COLLECTION_GENERAL_TREE__
00028 
00029 #include <algorithm>
00030 #include <cstddef>
00031 #include <functional>
00032 #include <iterator>
00033 #include <memory>
00034 #include <utility>
00035 #include "../../exceptions.hh"
00036 #include "../../memory/alloc_smart_pointer.hh"
00037 #include "../../memory/smart_pointer.hh"
00038 #include "../general-functions.hh"
00039 
00040 
00042 namespace mpcl
00043 {
00044 
00046   namespace util
00047   {
00048 
00050     namespace collection
00051     {
00052 
00054       template < typename TItem                                               ,
00055                  template <typename TItemA> class TAllocator = std::allocator >
00056       class TTreeNode
00057       {
00058 
00059         public:
00060 
00062           typedef
00063             memory::TAllocSmartPointer<TTreeNode, TAllocator>
00064             alloc_smart_pointer;
00065 
00067           typedef
00068             const TItem&
00069             const_reference;
00070 
00072           typedef
00073             TItem*
00074             pointer;
00075 
00077           typedef
00078             TItem&
00079             reference;
00080 
00082           typedef
00083             TItem
00084             value_type;
00085 
00087           typedef
00088             std::size_t
00089             size_type;
00090 
00091 
00092         public:
00093 
00095           TItem   tItem;
00096 
00098           TTreeNode*   ptLeftNode;
00099 
00101           TTreeNode*   ptParentNode;
00102 
00104           alloc_smart_pointer   qtFirstChildNode;
00105 
00107           alloc_smart_pointer   qtRightNode;
00108 
00109 
00110         public:
00111 
00112           //
00113           //  C O N S T R U C T O R S
00114           //
00115 
00121           static alloc_smart_pointer _copy ( const alloc_smart_pointer& rkqtNODE     ,
00122                                              TTreeNode*&                rptNODE_HEAP );
00123 
00131           static alloc_smart_pointer _copy ( alloc_smart_pointer&       rqtTARGET_NODE ,
00132                                              const alloc_smart_pointer& rkqtNODE       ,
00133                                              TTreeNode*&                rptNODE_HEAP   )
00134             throw (TConstraintException);
00135 
00142           static alloc_smart_pointer _copySiblings ( const alloc_smart_pointer& rkqtNODE       ,
00143                                                      const TTreeNode*           pktPARENT_NODE ,
00144                                                      TTreeNode*&                rptNODE_HEAP   );
00145 
00153           static TTreeNode* _create (const TItem& rktITEM, TTreeNode* ptNODE_HEAP)
00154           {
00155             TAllocator<TTreeNode>().construct (ptNODE_HEAP, rktITEM);
00156             return ptNODE_HEAP;
00157           }
00158 
00167           static void _link ( alloc_smart_pointer& qtLEFT_NODE  ,
00168                               alloc_smart_pointer& qtRIGHT_NODE )
00169           {
00170             qtRIGHT_NODE->ptParentNode = qtLEFT_NODE->ptParentNode;
00171             qtRIGHT_NODE->ptLeftNode   = qtLEFT_NODE;
00172             qtLEFT_NODE->qtRightNode   = qtRIGHT_NODE;
00173           }
00174 
00185           static void _link ( alloc_smart_pointer& qtLEFT_NODE   ,
00186                               alloc_smart_pointer& qtMIDDLE_NODE ,
00187                               alloc_smart_pointer& qtRIGHT_NODE  )
00188           {
00189             qtMIDDLE_NODE->ptParentNode = qtLEFT_NODE->ptParentNode;
00190             qtMIDDLE_NODE->ptLeftNode   = qtLEFT_NODE;
00191             qtMIDDLE_NODE->qtRightNode  = qtRIGHT_NODE;
00192             qtLEFT_NODE->qtRightNode    = qtMIDDLE_NODE;
00193             qtRIGHT_NODE->ptLeftNode    = qtMIDDLE_NODE;
00194           }
00195 
00203           static void _unlink (TTreeNode* ptTARGET_NODE)
00204             throw (TConstraintException);
00205 
00206 
00207         public:
00208 
00209           //
00210           //  C O N S T R U C T O R S
00211           //
00212 
00217           TTreeNode (const TItem& rktITEM) :
00218             tItem            (rktITEM)     ,
00219             ptLeftNode       (NULL)        ,
00220             ptParentNode     (NULL)        ,
00221             qtFirstChildNode ()            ,
00222             qtRightNode      ()            {}
00223 
00230           void insert (alloc_smart_pointer& rqtTARGET_NODE)
00231             throw (TConstraintException);
00232 
00233 
00234         public:
00235 
00236           //
00237           //  S E L E C T O R S
00238           //
00239 
00244           size_type height (void) const;
00245 
00250           const TTreeNode* parent (void) const
00251           {
00252             return ptParentNode;
00253           }
00254 
00259           size_type size (void) const;
00260 
00261       };  // class TTreeNode
00262 
00267       template < typename TItem                                                 ,
00268                  template <typename TItemA> class TAllocator = std::allocator   ,
00269                  typename TNode                              = TTreeNode<TItem> >
00270       class TGeneralTree;
00271 
00273       template <typename TItem, template <typename TItemA> class TAllocator = std::allocator>
00274       class TGeneralTreeSideIterator;
00275 
00277       template <typename TItem, template <typename TItemA> class TAllocator = std::allocator>
00278       class TGeneralTreePreIterator;
00279 
00281       template <typename TItem, template <typename TItemA> class TAllocator>
00282       class TGeneralTreePreIterator :
00283         public std::iterator<std::forward_iterator_tag, TItem>
00284       {
00285 
00287           template < typename TItemB                              ,
00288                      template <typename TItemC> class TAllocatorB ,
00289                      typename TNodeB                              >
00290           friend class TGeneralTree;
00291 
00293           template <typename TItemB, template <typename TItemC> class TAllocatorB>
00294           friend class TGeneralTreeSideIterator;
00295 
00296 
00297         private:
00298 
00300           TTreeNode<TItem, TAllocator>*   ptCurrentNode;
00301 
00302 
00303         public:
00304 
00306           typedef
00307             typename std::iterator<std::forward_iterator_tag, TItem>::difference_type
00308             difference_type;
00309 
00311           typedef
00312             typename std::iterator<std::forward_iterator_tag, TItem>::iterator_category
00313             iterator_category;
00314 
00316           typedef
00317             typename std::iterator<std::forward_iterator_tag, TItem>::pointer
00318             pointer;
00319 
00321           typedef
00322             typename std::iterator<std::forward_iterator_tag, TItem>::reference
00323             reference;
00324 
00326           typedef
00327             typename std::iterator<std::forward_iterator_tag, TItem>::value_type
00328             value_type;
00329 
00330 
00331         public:
00332 
00333           //
00334           //  C O N S T R U C T O R S
00335           //
00336 
00338           TGeneralTreePreIterator (void)                           :
00339             std::iterator<std::forward_iterator_tag, TItem> ()     ,
00340             ptCurrentNode                                   (NULL) {}
00341 
00346           TGeneralTreePreIterator (const TTreeNode<TItem, TAllocator>* pktNODE)                                   :
00347             std::iterator<std::forward_iterator_tag, TItem> ()                                                    ,
00348             ptCurrentNode                                   (const_cast<TTreeNode<TItem, TAllocator>*> (pktNODE)) {}
00349 
00355           TGeneralTreePreIterator (const TGeneralTreeSideIterator<TItem, TAllocator>& rktSIDE_ITERATOR) :
00356             std::iterator<std::forward_iterator_tag, TItem> ()                                          ,
00357             ptCurrentNode                                   (rktSIDE_ITERATOR.ptCurrentNode)            {}
00358 
00365           TGeneralTreePreIterator& operator ++ (void)
00366             throw (TConstraintException);
00367 
00373           TGeneralTreePreIterator operator ++ (int)
00374           {
00375             TGeneralTreePreIterator   tCopy (*this);
00376 
00377             operator ++();
00378             return tCopy;
00379           }
00380 
00386           TGeneralTreePreIterator&
00387           operator = (const TGeneralTreePreIterator<TItem, TAllocator>& rktPRE_ITERATOR)
00388           {
00389             ptCurrentNode = rktPRE_ITERATOR.ptCurrentNode;
00390             return *this;
00391           }
00392 
00398           TGeneralTreePreIterator&
00399           operator = (const TGeneralTreeSideIterator<TItem, TAllocator>& rktSIDE_ITERATOR)
00400           {
00401             ptCurrentNode = rktSIDE_ITERATOR.ptCurrentNode;
00402             return *this;
00403           }
00404 
00405 
00406         public:
00407 
00408           //
00409           //  S E L E C T O R S
00410           //
00411 
00417           TGeneralTreePreIterator leftChild (void) const
00418           {
00419             if ( !ptCurrentNode )
00420             {
00421               throw TConstraintException ("empty node", __FILE__, __LINE__);
00422             }
00423             return TGeneralTreePreIterator (ptCurrentNode->qtFirstChildNode.get());
00424           }
00425 
00426           pointer operator -> (void) const
00427             throw (TConstraintException)
00428           {
00429             if ( !ptCurrentNode )
00430             {
00431               throw TConstraintException ("empty node", __FILE__, __LINE__);
00432             }
00433             return &(ptCurrentNode->tItem);
00434           }
00435 
00436           bool operator == (const TGeneralTreePreIterator& rktITERATOR) const
00437           {
00438             return ( ptCurrentNode == rktITERATOR.ptCurrentNode );
00439           }
00440 
00447           bool operator == (const TGeneralTreeSideIterator<TItem, TAllocator>& rktSIDE_ITERATOR) const
00448           {
00449             return ( ptCurrentNode == rktSIDE_ITERATOR.ptCurrentNode );
00450           }
00451 
00458           bool operator != (const TGeneralTreeSideIterator<TItem, TAllocator>& rktSIDE_ITERATOR) const
00459           {
00460             return ( ptCurrentNode != rktSIDE_ITERATOR.ptCurrentNode );
00461           }
00462 
00463           reference operator * (void) const
00464             throw (TConstraintException)
00465           {
00466             if ( !ptCurrentNode )
00467             {
00468               throw TConstraintException ("empty node", __FILE__, __LINE__);
00469             }
00470             return ptCurrentNode->tItem;
00471           }
00472 
00478           TGeneralTreePreIterator rightSibling (void) const
00479           {
00480             if ( !ptCurrentNode )
00481             {
00482               throw TConstraintException ("empty node", __FILE__, __LINE__);
00483             }
00484             return TGeneralTreePreIterator (ptCurrentNode->qtRightNode);
00485           }
00486 
00487       };  // class TGeneralTreePreIterator
00488 
00490       template <typename TItem, template <typename TItemA> class TAllocator>
00491       class TGeneralTreeSideIterator :
00492         public std::iterator<std::forward_iterator_tag, TItem>
00493       {
00494 
00496           template < typename TItemB                              ,
00497                      template <typename TItemA> class TAllocatorB ,
00498                      typename TNodeB                              >
00499           friend class TGeneralTree;
00500 
00502           template <typename TItemB, template <typename TItemC> class TAllocatorB>
00503           friend class TGeneralTreePreIterator;
00504 
00505 
00506         public:
00507 
00509           typedef
00510             typename std::iterator<std::forward_iterator_tag, TItem>::difference_type
00511             difference_type;
00512 
00514           typedef
00515             typename std::iterator<std::forward_iterator_tag, TItem>::iterator_category
00516             iterator_category;
00517 
00519           typedef
00520             typename std::iterator<std::forward_iterator_tag, TItem>::pointer
00521             pointer;
00522 
00524           typedef
00525             typename std::iterator<std::forward_iterator_tag, TItem>::reference
00526             reference;
00527 
00529           typedef
00530             typename std::iterator<std::forward_iterator_tag, TItem>::value_type
00531             value_type;
00532 
00533 
00534         private:
00535 
00537           TTreeNode<TItem, TAllocator>*   ptCurrentNode;
00538 
00539 
00540         public:
00541 
00542           //
00543           //  C O N S T R U C T O R S
00544           //
00545 
00547           TGeneralTreeSideIterator (void)                          :
00548             std::iterator<std::forward_iterator_tag, TItem> ()     ,
00549             ptCurrentNode                                   (NULL) {}
00550 
00555           TGeneralTreeSideIterator (const TTreeNode<TItem, TAllocator>* pktNODE)                                  :
00556             std::iterator<std::forward_iterator_tag, TItem> ()                                                    ,
00557             ptCurrentNode                                   (const_cast<TTreeNode<TItem, TAllocator>*> (pktNODE)) {}
00558 
00564           TGeneralTreeSideIterator (const TGeneralTreePreIterator<TItem, TAllocator>& rktPRE_ITERATOR) :
00565             std::iterator<std::forward_iterator_tag, TItem> ()                                         ,
00566             ptCurrentNode                                   (rktPRE_ITERATOR.ptCurrentNode)            {}
00567 
00574           TGeneralTreeSideIterator& operator ++ (void)
00575             throw (TConstraintException);
00576 
00582           TGeneralTreeSideIterator operator ++ (int)
00583           {
00584             TGeneralTreeSideIterator   tCopy (*this);
00585 
00586             operator ++();
00587             return tCopy;
00588           }
00589 
00595           TGeneralTreeSideIterator&
00596           operator = (const TGeneralTreeSideIterator<TItem, TAllocator>& rktSIDE_ITERATOR)
00597           {
00598             ptCurrentNode = rktSIDE_ITERATOR.ptCurrentNode;
00599             return *this;
00600           }
00601 
00607           TGeneralTreeSideIterator& operator = (const TGeneralTreePreIterator<TItem, TAllocator>& rktPRE_ITERATOR)
00608           {
00609             ptCurrentNode = rktPRE_ITERATOR.ptCurrentNode;
00610             return *this;
00611           }
00612 
00613 
00614         public:
00615 
00616           //
00617           //  S E L E C T O R S
00618           //
00619 
00625           TGeneralTreeSideIterator leftChild (void) const
00626           {
00627             if ( !ptCurrentNode )
00628             {
00629               throw TConstraintException ("empty node", __FILE__, __LINE__);
00630             }
00631             return TGeneralTreeSideIterator (ptCurrentNode->qtFirstChildNode.get());
00632           }
00633 
00634           pointer operator -> (void) const
00635             throw (TConstraintException)
00636           {
00637             if ( !ptCurrentNode )
00638             {
00639               throw TConstraintException ("empty node", __FILE__, __LINE__);
00640             }
00641             return &(ptCurrentNode->tItem);
00642           }
00643 
00644           bool operator == (const TGeneralTreeSideIterator& rktITERATOR) const
00645           {
00646             return ( ptCurrentNode == rktITERATOR.ptCurrentNode );
00647           }
00648 
00655           bool operator == (const TGeneralTreePreIterator<TItem, TAllocator>& rktPRE_ITERATOR) const
00656           {
00657             return ( ptCurrentNode == rktPRE_ITERATOR.ptCurrentNode );
00658           }
00659 
00666           bool operator != (const TGeneralTreePreIterator<TItem, TAllocator>& rktPRE_ITERATOR) const
00667           {
00668             return ( ptCurrentNode != rktPRE_ITERATOR.ptCurrentNode );
00669           }
00670 
00671           reference operator * (void) const
00672             throw (TConstraintException)
00673           {
00674             if ( !ptCurrentNode )
00675             {
00676               throw TConstraintException ("empty node", __FILE__, __LINE__);
00677             }
00678             return ptCurrentNode->tItem;
00679           }
00680 
00686           TGeneralTreeSideIterator rightSibling (void) const
00687           {
00688             if ( !ptCurrentNode )
00689             {
00690               throw TConstraintException ("empty node", __FILE__, __LINE__);
00691             }
00692             return TGeneralTreeSideIterator (ptCurrentNode->qtRightNode);
00693           }
00694 
00695       };  // class TGeneralTreeSideIterator
00696 
00701       template < typename TItem                              ,
00702                  template <typename TItemA> class TAllocator ,
00703                  typename TNode                              >
00704       class TGeneralTree : private virtual TAllocator<TNode>
00705       {
00706 
00707         public:
00708 
00710           typedef
00711             typename TNode::alloc_smart_pointer
00712             QTNode;
00713 
00715           typedef
00716             memory::TAllocSmartPointer<TGeneralTree, TAllocator>
00717             QTTree;
00718 
00720           typedef
00721             TGeneralTreePreIterator<const TItem, TAllocator>
00722             const_iterator;
00723 
00725           typedef
00726             TGeneralTreeSideIterator<const TItem, TAllocator>
00727             const_side_iterator;
00728 
00730           typedef
00731             TGeneralTreePreIterator<TItem, TAllocator>
00732             iterator;
00733 
00735           typedef
00736             TGeneralTreeSideIterator<TItem, TAllocator>
00737             side_iterator;
00738 
00740           typedef
00741             typename TNode::size_type
00742             size_type;
00743 
00745           typedef
00746             TItem
00747             value_type;
00748 
00749 
00750         private:
00751 
00753           QTNode   qtRootNode;
00754 
00755 
00756         private:
00757 
00762           TGeneralTree (const QTNode& rkqtNODE) :
00763             TAllocator<TNode> ()                ,
00764             qtRootNode        (rkqtNODE)        {}
00765 
00766 
00767         public:
00768 
00769           //
00770           //  C O N S T R U C T O R S
00771           //
00772 
00777           TGeneralTree (void)    :
00778             TAllocator<TNode> () ,
00779             qtRootNode        () {}
00780 
00786           TGeneralTree (const TItem& rktITEM)                          :
00787             TAllocator<TNode> ()                                       ,
00788             qtRootNode        (TNode::_create (rktITEM, allocate (1))) {}
00789 
00795           TGeneralTree (const TGeneralTree& rktGENERAL_TREE) :
00796             TAllocator<TNode> ()                             ,
00797             qtRootNode        ()
00798           {
00799             TNode*               ptNodeHeap;
00800             register size_type   zSourceTreeSize = rktGENERAL_TREE.size();
00801 
00802             if ( zSourceTreeSize )
00803             {
00804               ptNodeHeap = allocate (zSourceTreeSize);
00805               qtRootNode = TNode::_copy (rktGENERAL_TREE.qtRootNode, ptNodeHeap);
00806             }
00807           }
00808 
00810           virtual ~TGeneralTree (void)
00811           {
00812             clear();
00813           }
00814 
00819           void clear (void)
00820           {
00821             qtRootNode = NULL;
00822           }
00823 
00829           TGeneralTree& copy (const TGeneralTree& rktGENERAL_TREE)
00830           {
00831             if ( this != &rktGENERAL_TREE )
00832             {
00833               TNode*               ptNodeHeap;
00834               register size_type   zSourceTreeSize = rktGENERAL_TREE.size();
00835 
00836               if ( !qtRootNode )
00837               {
00838                 if ( zSourceTreeSize )
00839                 {
00840                   ptNodeHeap = allocate (zSourceTreeSize);
00841                   qtRootNode = TNode::_copy (rktGENERAL_TREE.qtRootNode, ptNodeHeap);
00842                 }
00843               }
00844               else
00845               {
00846                 if ( !zSourceTreeSize )
00847                 {
00848                   qtRootNode = NULL;
00849                 }
00850                 else
00851                 {
00852                   ptNodeHeap = ( zSourceTreeSize > 1 ) ? allocate (zSourceTreeSize - 1) : NULL;
00853                   TNode::_copy (qtRootNode, rktGENERAL_TREE.qtRootNode, ptNodeHeap);
00854                 }
00855               }
00856             }
00857             return *this;
00858           }
00859 
00868           template <typename TIterator>
00869           TIterator erase (TIterator tPOSITION)
00870           {
00871             TIterator   tNEXT_POSITION (tPOSITION);
00872 
00873             ++tNEXT_POSITION;
00874             TNode::_unlink (tPOSITION.ptCurrentNode);
00875             return tNEXT_POSITION;
00876           }
00877 
00887           template <typename TIterator>
00888           TIterator erase (TIterator tBEGIN, TIterator tEND)
00889           {
00890             for (; ( tBEGIN != tEND ) ;)
00891             {
00892               //
00893               //  Post-increments the iterator so, firstly,  it gets the pointer to
00894               //  the node,  then it increments the  value of the iterator,  and at
00895               //  last, it unlinks the former node.
00896               //
00897               TNode::_unlink ((tBEGIN++).ptCurrentNode);
00898             }
00899             return tEND;
00900           }
00901 
00911           void insert (QTTree& rqtGENERAL_TREE)
00912             throw (TConstraintException)
00913           {
00914             if ( !qtRootNode || !rqtGENERAL_TREE )
00915             {
00916               throw TConstraintException ("empty tree", __FILE__, __LINE__);
00917             }
00918             qtRootNode->insert (rqtGENERAL_TREE->qtRootNode);
00919           }
00920 
00929           void insert (const TItem& rktITEM)
00930             throw (TConstraintException)
00931           {
00932             if ( !qtRootNode )
00933             {
00934               throw TConstraintException ("empty tree", __FILE__, __LINE__);
00935             }
00936             else
00937             {
00938               QTNode   qtNewNode (TNode::_create (rktITEM, allocate (1)));
00939 
00940               qtRootNode->insert (qtNewNode);
00941             }
00942           }
00943 
00956           template <class TIterator>
00957           void insert ( TIterator tPOSITION       ,
00958                         QTTree&   rqtGENERAL_TREE )
00959             throw (TConstraintException)
00960           {
00961             if ( !qtRootNode || !rqtGENERAL_TREE )
00962             {
00963               throw TConstraintException ("empty tree", __FILE__, __LINE__);
00964             }
00965             if ( !tPOSITION.ptCurrentNode )
00966             {
00967               throw TConstraintException ("null iterator", __FILE__, __LINE__);
00968             }
00969             tPOSITION.ptCurrentNode->insert (rqtGENERAL_TREE->qtRootNode);
00970           }
00971 
00983           template <class TIterator>
00984           void insert ( TIterator    tPOSITION ,
00985                         const TItem& rktITEM   )
00986             throw (TConstraintException)
00987           {
00988             if ( !qtRootNode )
00989             {
00990               throw TConstraintException ("empty tree", __FILE__, __LINE__);
00991             }
00992             else if ( !tPOSITION.ptCurrentNode )
00993             {
00994               throw TConstraintException ("null iterator", __FILE__, __LINE__);
00995             }
00996             else
00997             {
00998               QTNode   qtNewNode (TNode::_create (rktITEM, allocate (1)));
00999 
01000               tPOSITION.ptCurrentNode->insert (qtNewNode);
01001             }
01002           }
01003 
01010           TGeneralTree&
01011           operator = (const TGeneralTree& rktGENERAL_TREE)
01012           {
01013             return copy (rktGENERAL_TREE);
01014           }
01015 
01021           void setRoot (const TItem& rktITEM)
01022           {
01023             if ( !qtRootNode )
01024             {
01025               qtRootNode = TNode::_create (rktITEM, allocate (1));
01026             }
01027             else
01028             {
01029               qtRootNode->tItem = rktITEM;
01030             }
01031           }
01032 
01033 
01034         public:
01035 
01036           //
01037           //  S E L E C T O R S
01038           //
01039 
01044           iterator begin (void)
01045           {
01046             return iterator (qtRootNode.get());
01047           }
01048 
01053           const_iterator begin (void) const
01054           {
01055             return const_iterator (qtRootNode.get());
01056           }
01057 
01063           side_iterator beginChild (void)
01064             throw (TConstraintException)
01065           {
01066             if ( !qtRootNode )
01067             {
01068               throw TConstraintException ("empty tree", __FILE__, __LINE__);
01069             }
01070             return side_iterator (qtRootNode->qtFirstChildNode.get());
01071           }
01072 
01078           const_side_iterator beginChild (void) const
01079             throw (TConstraintException)
01080           {
01081             if ( !qtRootNode )
01082             {
01083               throw TConstraintException ("empty tree", __FILE__, __LINE__);
01084             }
01085             return const_side_iterator (qtRootNode->qtFirstChildNode);
01086           }
01087 
01092           bool empty (void) const
01093           {
01094             return ( !qtRootNode );
01095           }
01096 
01102           iterator end (void)
01103           {
01104             return iterator();
01105           }
01106 
01112           const_iterator end (void) const
01113           {
01114             return const_iterator();
01115           }
01116 
01122           side_iterator endChild (void)
01123           {
01124             return side_iterator();
01125           }
01126 
01132           const_side_iterator endChild (void) const
01133           {
01134             return const_side_iterator();
01135           }
01136 
01142           const TItem& getRoot (void) const
01143             throw (TConstraintException)
01144           {
01145             if ( !qtRootNode )
01146             {
01147               throw TConstraintException ("empty tree", __FILE__, __LINE__);
01148             }
01149             return qtRootNode->tItem;
01150           }
01151 
01157           TItem& getRoot (void)
01158             throw (TConstraintException)
01159           {
01160             if ( !qtRootNode )
01161             {
01162               throw TConstraintException ("empty tree", __FILE__, __LINE__);
01163             }
01164             return qtRootNode->tItem;
01165           }
01166 
01171           size_type height (void) const
01172           {
01173             return ( qtRootNode.isNull() ) ? 0 : qtRootNode->height();
01174           }
01175 
01182           TGeneralTree leftChild (void) const
01183           {
01184             if ( !qtRootNode )
01185             {
01186               throw TConstraintException ("empty tree", __FILE__, __LINE__);
01187             }
01188             return TGeneralTree (qtRootNode->qtFirstChildNode);
01189           }
01190 
01195           size_type max_size (void) const
01196           {
01197             return size_type (-1);
01198           }
01199 
01206           TGeneralTree rightSibling (void) const
01207           {
01208             if ( !qtRootNode )
01209             {
01210               throw TConstraintException ("empty tree", __FILE__, __LINE__);
01211             }
01212             return TGeneralTree (qtRootNode->qtRightNode);
01213           }
01214 
01219           size_type size (void) const
01220           {
01221             register size_type   zSize = 0;
01222 
01223             if ( !qtRootNode.isNull() )
01224             {
01225               zSize = qtRootNode->size();
01226             }
01227             return zSize;
01228           }
01229 
01236           void swap (TGeneralTree& rtTREE)
01237           {
01238             std::swap<QTNode> (qtRootNode, rtTREE.qtRootNode);
01239           }
01240 
01241       };  // class TGeneralTree
01242 
01243 
01244       //
01245       //  C O N S T R U C T O R S
01246       //
01247 
01248       template <typename TItem, template <typename TItemA> class TAllocator>
01249       inline typename TTreeNode<TItem, TAllocator>::alloc_smart_pointer TTreeNode<TItem, TAllocator>::
01250       _copy (const alloc_smart_pointer& rkqtNODE, TTreeNode*& rptNODE_HEAP)
01251       {
01252 
01253         alloc_smart_pointer   qtNewNode;
01254 
01255         if ( rkqtNODE.get() )
01256         {
01257           //
01258           //  Takes the space for the node from the heap, and the construct the new
01259           //  instance on it. Finally, it copies the child nodes.
01260           //
01261           qtNewNode = rptNODE_HEAP;
01262           TAllocator<TTreeNode>().construct (rptNODE_HEAP++, rkqtNODE->tItem);
01263           qtNewNode->qtFirstChildNode =
01264             _copySiblings (rkqtNODE->qtFirstChildNode, qtNewNode.get(), rptNODE_HEAP);
01265         }
01266         return qtNewNode;
01267 
01268       }  // TTreeNode::_copy()
01269 
01270       template <typename TItem, template <typename TItemA> class TAllocator>
01271       inline typename TTreeNode<TItem, TAllocator>::alloc_smart_pointer TTreeNode<TItem, TAllocator>::
01272       _copy ( alloc_smart_pointer&       rqtTARGET_NODE ,
01273               const alloc_smart_pointer& rkqtNODE       ,
01274               TTreeNode*&                rptNODE_HEAP   )
01275         throw (TConstraintException)
01276       {
01277 
01278         if ( !rqtTARGET_NODE )
01279         {
01280           throw TConstraintException ("target node is null", __FILE__, __LINE__);
01281         }
01282         if ( !rkqtNODE.isNull() )
01283         {
01284           TTreeNode*   ptChildNode = rqtTARGET_NODE->qtFirstChildNode.get();
01285 
01286           //
01287           //  Detaches target node children from the parent node.
01288           //
01289           while ( ptChildNode )
01290           {
01291             ptChildNode->ptParentNode = NULL;
01292             ptChildNode               = ptChildNode->qtRightNode.get();
01293           }
01294 
01295           //
01296           //  Makes a copy of the source nodes.
01297           //
01298           rqtTARGET_NODE->tItem            = rkqtNODE->tItem;
01299           rqtTARGET_NODE->qtFirstChildNode =
01300             _copySiblings (rkqtNODE->qtFirstChildNode, rqtTARGET_NODE.get(), rptNODE_HEAP);
01301         }
01302         return rqtTARGET_NODE;
01303 
01304       }  // TTreeNode::_copy()
01305 
01306       template <typename TItem, template <typename TItemA> class TAllocator>
01307       inline typename TTreeNode<TItem, TAllocator>::alloc_smart_pointer TTreeNode<TItem, TAllocator>::
01308       _copySiblings ( const alloc_smart_pointer& rkqtNODE       ,
01309                       const TTreeNode*           pktPARENT_NODE ,
01310                       TTreeNode*&                rptNODE_HEAP   )
01311       {
01312 
01313         alloc_smart_pointer   qtFirstNode;
01314 
01315         if ( !rkqtNODE.isNull() )
01316         {
01317           alloc_smart_pointer   qtNewNode;
01318           alloc_smart_pointer   qtOldNode;
01319           alloc_smart_pointer   qtSourceNode (rkqtNODE);
01320 
01321           //
01322           //  Copies the first node of source sibling nodes.
01323           //
01324           qtFirstNode               = _copy (qtSourceNode, rptNODE_HEAP);
01325           qtFirstNode->ptParentNode = const_cast<TTreeNode*> (pktPARENT_NODE);
01326           qtSourceNode              = qtSourceNode->qtRightNode;
01327 
01328           //
01329           //  Copies rest of source siblings nodes.
01330           //
01331           for (qtOldNode = qtFirstNode; ( !qtSourceNode.isNull() ) ;)
01332           {
01333             //
01334             //  Creates  a new node and  attaches  to the parent node,  then it
01335             //  connects left and right newly created nodes.
01336             //
01337             qtNewNode               = _copy (qtSourceNode, rptNODE_HEAP);
01338             qtNewNode->ptParentNode = const_cast<TTreeNode*> (pktPARENT_NODE);
01339             qtNewNode->ptLeftNode   = qtOldNode.get();
01340             qtOldNode->qtRightNode  = qtNewNode;
01341             qtOldNode               = qtNewNode;
01342             qtSourceNode            = qtSourceNode->qtRightNode;
01343           }
01344         }
01345         return qtFirstNode;
01346 
01347       }  // TTreeNode::_copySiblings()
01348 
01349       template <typename TItem, template <typename TItemA> class TAllocator>
01350       inline void TTreeNode<TItem, TAllocator>::_unlink (TTreeNode* ptTARGET_NODE)
01351         throw (TConstraintException)
01352       {
01353 
01354         if ( !ptTARGET_NODE )
01355         {
01356           throw TConstraintException ("node is null", __FILE__, __LINE__);
01357         }
01358         if ( ptTARGET_NODE->ptParentNode )
01359         {
01361           alloc_smart_pointer   qtTargetNode;
01362 
01363           //
01364           //  Unlinks  from parent node. There is no need to  unlink  from  sibling
01365           //  nodes because if there is no parent, then there are no sibling nodes.
01366           //
01367           if ( ptTARGET_NODE->ptLeftNode )
01368           {
01369             //
01370             //  This is not the first sibling node.
01371             //
01372             //  Warning:  Cause  node  ptTARGET_NODE  is  holded  by  (possibly) an
01373             //            unique  smart-pointer,  (left node  smart-pointer to  its
01374             //            right sibling  node)  it must  point  to  another  smart-
01375             //            pointer instance pointing to the former node.
01376             //
01377             qtTargetNode = ptTARGET_NODE->ptLeftNode->qtRightNode;
01378             if ( !ptTARGET_NODE->qtRightNode )
01379             {
01380               //
01381               //  This is the last node.
01382               //
01383               ptTARGET_NODE->ptLeftNode->qtRightNode = NULL;
01384             }
01385             else
01386             {
01387               //
01388               //  This is an inner node.
01389               //
01390               ptTARGET_NODE->qtRightNode->ptLeftNode = ptTARGET_NODE->ptLeftNode;
01391               ptTARGET_NODE->ptLeftNode->qtRightNode = ptTARGET_NODE->qtRightNode;
01392             }
01393           }
01394           else
01395           {
01396             //
01397             //  Node ptTARGET_NODE is the first sibling node.
01398             //
01399             //  Warning:  Cause  node   ptTARGET_NODE  is   holded by (possibly) an
01400             //            unique smart-pointer,  (parent node  smart-pointer to its
01401             //            first child node) it must point  to another smart-pointer
01402             //            instance pointing to the former node.
01403             //
01404             qtTargetNode = ptTARGET_NODE->ptParentNode->qtFirstChildNode;
01405             if ( !ptTARGET_NODE->qtRightNode )
01406             {
01407               //
01408               //  This is the unique child node,  so it removes the pointer to this
01409               //  node.   If  there   is  no   other   smart-pointer   pointing  to
01410               //  ptTARGET_NODE, then it may  automatically destroyed before we can
01411               //  finish all operations over it.
01412               //
01413               ptTARGET_NODE->ptParentNode->qtFirstChildNode = NULL;
01414             }
01415             else
01416             {
01417               //
01418               //  There are sibling nodes,  so it  re-connects the parent node with
01419               //  its right node.
01420               //
01421               ptTARGET_NODE->qtRightNode->ptLeftNode        = NULL;
01422               ptTARGET_NODE->ptParentNode->qtFirstChildNode = ptTARGET_NODE->qtRightNode;
01423               ptTARGET_NODE->qtRightNode                    = NULL;
01424             }
01425           }
01426           //
01427           //  Erases pointer to parent node.
01428           //
01429           ptTARGET_NODE->ptParentNode = NULL;
01430         }
01431 
01432       }  // TTreeNode::_unlink()
01433 
01434       template <typename TItem, template <typename TItemA> class TAllocator>
01435       inline void TTreeNode<TItem, TAllocator>::
01436       insert (alloc_smart_pointer& rqtTARGET_NODE)
01437         throw (TConstraintException)
01438       {
01439 
01440         if ( !rqtTARGET_NODE )
01441         {
01442           throw TConstraintException ("empty node", __FILE__, __LINE__);
01443         }
01444         if ( !qtFirstChildNode )
01445         {
01446           //
01447           //  There is no child nodes.
01448           //
01449           qtFirstChildNode           = rqtTARGET_NODE;
01450           rqtTARGET_NODE->ptLeftNode = NULL;
01451         }
01452         else
01453         {
01454           alloc_smart_pointer   qtNode (qtFirstChildNode);
01455 
01456           //
01457           //  Iterates through the nodes to the last one.
01458           //
01459           while ( !qtNode->qtRightNode.isNull() )
01460           {
01461             qtNode = qtNode->qtRightNode;
01462           }
01463           qtNode->qtRightNode        = rqtTARGET_NODE;
01464           rqtTARGET_NODE->ptLeftNode = qtNode.get();
01465         }
01466 
01467         //
01468         //  Isolates  the  new node as the only node at last,  and  then makes this
01469         //  instance to 'adopt' that node.
01470         //
01471         rqtTARGET_NODE->qtRightNode  = NULL;
01472         rqtTARGET_NODE->ptParentNode = this;
01473 
01474       }  // TTreeNode::insert()
01475 
01476       template <typename TItem, template <typename TItemA> class TAllocator>
01477       inline TGeneralTreePreIterator<TItem, TAllocator>& TGeneralTreePreIterator<TItem, TAllocator>::
01478       operator ++ (void)
01479         throw (TConstraintException)
01480       {
01481 
01482         if ( !ptCurrentNode )
01483         {
01484           throw TConstraintException ("iterator past the end", __FILE__, __LINE__);
01485         }
01486         if ( !ptCurrentNode->qtFirstChildNode.isNull() )
01487         {
01488           //
01489           //  The node has at least one child, so take the that node.
01490           //
01491           ptCurrentNode = ptCurrentNode->qtFirstChildNode.get();
01492         }
01493         else
01494         {
01495           //
01496           //  Node has no child nodes.
01497           //
01498           if ( !ptCurrentNode->qtRightNode.isNull() )
01499           {
01500             //
01501             //  The node has at least one sibling node.
01502             //
01503             ptCurrentNode = ptCurrentNode->qtRightNode.get();
01504           }
01505           else
01506           {
01507             //
01508             //  The Node has no  sibling nodes,  so the searches  for the first
01509             //  parent node with sibling nodes.
01510             //
01511             while ( ptCurrentNode && !ptCurrentNode->qtRightNode )
01512             {
01513               ptCurrentNode = ptCurrentNode->ptParentNode;
01514             }
01515             if ( ptCurrentNode )
01516             {
01517               //
01518               //  There  has been found a node with  right sibling node,  so it
01519               //  points to this one.
01520               //
01521               ptCurrentNode = ptCurrentNode->qtRightNode.get();
01522             }
01523           }
01524         }
01525         return *this;
01526 
01527       }  // TGeneralTreePreIterator::operator ++()
01528 
01529       template <typename TItem, template <typename TItemA> class TAllocator>
01530       inline TGeneralTreeSideIterator<TItem, TAllocator>& TGeneralTreeSideIterator<TItem, TAllocator>::
01531       operator ++ (void)
01532         throw (TConstraintException)
01533       {
01534 
01535         if ( !ptCurrentNode )
01536         {
01537           throw TConstraintException ("empty node", __FILE__, __LINE__);
01538         }
01539         if ( !ptCurrentNode->qtRightNode )
01540         {
01541           //
01542           //  Node is empty.
01543           //
01544           ptCurrentNode = NULL;
01545         }
01546         else
01547         {
01548           //
01549           //  The node has at least one sibling node.
01550           //
01551           ptCurrentNode = ptCurrentNode->qtRightNode.get();
01552         }
01553         return *this;
01554 
01555       }  // TGeneralTreeSideIterator::operator ++()
01556 
01557 
01558       //
01559       //  S E L E C T O R S
01560       //
01561 
01562       template <typename TItem, template <typename TItemA> class TAllocator>
01563       inline typename TTreeNode<TItem, TAllocator>::size_type TTreeNode<TItem, TAllocator>::
01564       height (void) const
01565       {
01566 
01567         alloc_smart_pointer   qtNode  = qtFirstChildNode;
01568         size_type             zHeight = 0;
01569 
01570         //
01571         //  Computes the maximum height.
01572         //
01573         while ( qtNode.get() )
01574         {
01575           zHeight = std::max<size_type> (zHeight, qtNode->height());
01576           qtNode  = qtNode->qtRightNode;
01577         }
01578         return (1 + zHeight);
01579 
01580       }  // TTreeNode::height()
01581 
01582       template <typename TItem, template <typename TItemA> class TAllocator>
01583       inline typename TTreeNode<TItem, TAllocator>::size_type TTreeNode<TItem, TAllocator>::
01584       size (void) const
01585       {
01586 
01587         alloc_smart_pointer   qtNode = qtFirstChildNode;
01588         register size_type    zSize  = 1;
01589 
01590         while ( !qtNode.isNull() )
01591         {
01592           zSize  += qtNode->size();
01593           qtNode  = qtNode->qtRightNode;
01594         }
01595         return zSize;
01596 
01597       }  // TTreeNode::size()
01598 
01599     }  // namespace collection
01600 
01601   }  // namespace util
01602 
01603 }  // namespace mpcl
01604 
01605 
01607 namespace std
01608 {
01609 
01610   using mpcl::util::collection::TGeneralTree;
01611 
01612   template < typename TItem                              ,
01613              template <typename TItemA> class TAllocator ,
01614              typename TNode                              >
01615   inline void swap ( TGeneralTree<TItem, TAllocator, TNode>& rtTREE1 , 
01616                      TGeneralTree<TItem, TAllocator, TNode>& rtTREE2 )
01617   {
01618     rtTREE1.swap (rtTREE2);
01619   }
01620 
01621 }  // namespace std
01622 
01623 
01624 #endif  // not _MPCL_UTIL_COLLECTION_GENERAL_TREE__

Generated on Mon Oct 13 02:35:23 2003 for MPCL by doxygen1.2.18