00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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
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 };
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
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
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 };
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
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
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 };
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
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
00894
00895
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
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 };
01242
01243
01244
01245
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
01259
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 }
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
01288
01289 while ( ptChildNode )
01290 {
01291 ptChildNode->ptParentNode = NULL;
01292 ptChildNode = ptChildNode->qtRightNode.get();
01293 }
01294
01295
01296
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 }
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
01323
01324 qtFirstNode = _copy (qtSourceNode, rptNODE_HEAP);
01325 qtFirstNode->ptParentNode = const_cast<TTreeNode*> (pktPARENT_NODE);
01326 qtSourceNode = qtSourceNode->qtRightNode;
01327
01328
01329
01330
01331 for (qtOldNode = qtFirstNode; ( !qtSourceNode.isNull() ) ;)
01332 {
01333
01334
01335
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 }
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
01365
01366
01367 if ( ptTARGET_NODE->ptLeftNode )
01368 {
01369
01370
01371
01372
01373
01374
01375
01376
01377 qtTargetNode = ptTARGET_NODE->ptLeftNode->qtRightNode;
01378 if ( !ptTARGET_NODE->qtRightNode )
01379 {
01380
01381
01382
01383 ptTARGET_NODE->ptLeftNode->qtRightNode = NULL;
01384 }
01385 else
01386 {
01387
01388
01389
01390 ptTARGET_NODE->qtRightNode->ptLeftNode = ptTARGET_NODE->ptLeftNode;
01391 ptTARGET_NODE->ptLeftNode->qtRightNode = ptTARGET_NODE->qtRightNode;
01392 }
01393 }
01394 else
01395 {
01396
01397
01398
01399
01400
01401
01402
01403
01404 qtTargetNode = ptTARGET_NODE->ptParentNode->qtFirstChildNode;
01405 if ( !ptTARGET_NODE->qtRightNode )
01406 {
01407
01408
01409
01410
01411
01412
01413 ptTARGET_NODE->ptParentNode->qtFirstChildNode = NULL;
01414 }
01415 else
01416 {
01417
01418
01419
01420
01421 ptTARGET_NODE->qtRightNode->ptLeftNode = NULL;
01422 ptTARGET_NODE->ptParentNode->qtFirstChildNode = ptTARGET_NODE->qtRightNode;
01423 ptTARGET_NODE->qtRightNode = NULL;
01424 }
01425 }
01426
01427
01428
01429 ptTARGET_NODE->ptParentNode = NULL;
01430 }
01431
01432 }
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
01448
01449 qtFirstChildNode = rqtTARGET_NODE;
01450 rqtTARGET_NODE->ptLeftNode = NULL;
01451 }
01452 else
01453 {
01454 alloc_smart_pointer qtNode (qtFirstChildNode);
01455
01456
01457
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
01469
01470
01471 rqtTARGET_NODE->qtRightNode = NULL;
01472 rqtTARGET_NODE->ptParentNode = this;
01473
01474 }
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
01490
01491 ptCurrentNode = ptCurrentNode->qtFirstChildNode.get();
01492 }
01493 else
01494 {
01495
01496
01497
01498 if ( !ptCurrentNode->qtRightNode.isNull() )
01499 {
01500
01501
01502
01503 ptCurrentNode = ptCurrentNode->qtRightNode.get();
01504 }
01505 else
01506 {
01507
01508
01509
01510
01511 while ( ptCurrentNode && !ptCurrentNode->qtRightNode )
01512 {
01513 ptCurrentNode = ptCurrentNode->ptParentNode;
01514 }
01515 if ( ptCurrentNode )
01516 {
01517
01518
01519
01520
01521 ptCurrentNode = ptCurrentNode->qtRightNode.get();
01522 }
01523 }
01524 }
01525 return *this;
01526
01527 }
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
01543
01544 ptCurrentNode = NULL;
01545 }
01546 else
01547 {
01548
01549
01550
01551 ptCurrentNode = ptCurrentNode->qtRightNode.get();
01552 }
01553 return *this;
01554
01555 }
01556
01557
01558
01559
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
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 }
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 }
01598
01599 }
01600
01601 }
01602
01603 }
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 }
01622
01623
01624 #endif // not _MPCL_UTIL_COLLECTION_GENERAL_TREE__