00001 //---------------------------------------------------------------------------- 00002 /** @file SgNode.cpp 00003 See SgNode.h. 00004 00005 Implementation details: 00006 ----------------------- 00007 Each node has a pointer to its father, its right brother, and its first 00008 son. Each node also has a pointer to its list of properties, as well as an 00009 extra bit used to efficiently find the shortest path between two nodes. 00010 This data structure assumes that time and not space is the major 00011 performance bottleneck. */ 00012 //---------------------------------------------------------------------------- 00013 00014 #include "SgSystem.h" 00015 #include "SgNode.h" 00016 00017 #include <sstream> 00018 #include "SgPointSet.h" 00019 #include "SgProp.h" 00020 #include "SgVector.h" 00021 00022 using namespace std; 00023 00024 //---------------------------------------------------------------------------- 00025 00026 SgNode::SgNode() 00027 : m_son(0), 00028 m_father(0), 00029 m_brother(0), 00030 m_props(), 00031 m_marked(false) 00032 { 00033 #ifndef NDEBUG 00034 ++s_alloc; 00035 #endif 00036 } 00037 00038 SgNode::~SgNode() 00039 { 00040 if (HasLeftBrother()) 00041 { 00042 SgNode* left = LeftBrother(); 00043 //--- Just link left brother with son. If the son is 0, then the same 00044 // node will be linked to the brother by procedure LinkToBrother. 00045 left->m_brother = m_son; 00046 LinkWithBrother(left); 00047 } 00048 else if (HasFather()) 00049 { 00050 if (HasSon()) 00051 { 00052 //--- Has son: father links up with that son, must link rightmost 00053 // brother of that son to right brother of deleted node. 00054 m_father->m_son = m_son; 00055 m_son->m_father = m_father; 00056 LinkWithBrother(m_son); 00057 } 00058 else 00059 { 00060 //--- Simple case: is leftmost node and has no sons, father 00061 // can just link up with an eventual brother. 00062 m_father->m_son = m_brother; 00063 } 00064 } 00065 else 00066 // --> node is root <-- 00067 // cannot delete the root node if it has a subtree 00068 SG_ASSERT(m_son == 0); 00069 00070 #ifndef NDEBUG 00071 ++s_free; 00072 #endif 00073 } 00074 00075 void SgNode::CopySubtree(const SgNode* node, SgNode* copy) 00076 { 00077 for (const SgNode* son = node->LeftMostSon(); son; 00078 son = son->RightBrother()) 00079 { 00080 SgNode* sonCopy = copy->NewRightMostSon(); 00081 sonCopy->CopyAllPropsFrom(*son); 00082 CopySubtree(son, sonCopy); 00083 } 00084 } 00085 00086 SgNode* SgNode::CopyTree() const 00087 { 00088 SgNode* newNode = new SgNode(); 00089 if (newNode) 00090 { 00091 newNode->CopyAllPropsFrom(*this); 00092 CopySubtree(this, newNode); 00093 } 00094 return newNode; 00095 } 00096 00097 bool SgNode::HasLeftBrother() const 00098 { 00099 return HasFather() && Father()->LeftMostSon() != this; 00100 } 00101 00102 bool SgNode::IsOnMain() const 00103 { 00104 // Move backwards in the tree until the root or a node with a 00105 // left brother is reached. 00106 const SgNode* t = this; 00107 while (true) 00108 { 00109 SgNode* father = t->m_father; 00110 if (father == 0) 00111 return true; 00112 if (father->m_son != t) 00113 return false; 00114 t = father; 00115 } 00116 } 00117 00118 // Links the rightmost brother of the current node with the brother of this 00119 // node that is to be deleted. 00120 void SgNode::LinkWithBrother(SgNode* node) 00121 { 00122 while (node->HasRightBrother()) 00123 { 00124 node = node->RightBrother(); // sons of deleted node ... 00125 node->m_father = m_father; // ... get this new father 00126 } 00127 node->m_brother = m_brother; 00128 } 00129 00130 SgVector<SgPoint> SgNode::VectorProp(SgPropID prop) const 00131 { 00132 SgPropPointList* lp = dynamic_cast<SgPropPointList*>(Get(prop)); 00133 if (lp) 00134 return lp->Value(); 00135 return SgVector<SgPoint>(); 00136 } 00137 00138 int SgNode::NumSons() const 00139 { 00140 int n = 0; 00141 if (HasSon()) 00142 { 00143 SgNode* node = LeftMostSon(); 00144 ++n; 00145 while (node->HasRightBrother()) 00146 { 00147 node = node->RightBrother(); 00148 ++n; 00149 } 00150 } 00151 return n; 00152 } 00153 00154 int SgNode::NumLeftBrothers() const 00155 { 00156 int numBrothers = 0; 00157 SgNode* node = Father(); 00158 if (node) 00159 { 00160 node = node->LeftMostSon(); 00161 while (node != this) 00162 { 00163 node = node->RightBrother(); 00164 ++numBrothers; 00165 } 00166 } 00167 return numBrothers; 00168 } 00169 00170 SgNode* SgNode::Root() const 00171 { 00172 SgNode* node = const_cast<SgNode*>(this); 00173 while (node->HasFather()) 00174 node = node->Father(); 00175 return node; 00176 } 00177 00178 SgNode* SgNode::LeftBrother() const 00179 { 00180 if (! HasFather() || ! HasLeftBrother()) 00181 return 0; 00182 SgNode* node = Father()->LeftMostSon(); // left-most brother 00183 while (node->RightBrother() != this) 00184 node = node->RightBrother(); 00185 return node; 00186 } 00187 00188 SgNode* SgNode::RightMostSon() const 00189 { 00190 SgNode* node = LeftMostSon(); 00191 if (node) 00192 { 00193 while (node->HasRightBrother()) 00194 node = node->RightBrother(); 00195 } 00196 return node; 00197 } 00198 00199 SgNode* SgNode::NextDepthFirst() const 00200 { 00201 if (HasSon()) 00202 return LeftMostSon(); 00203 else 00204 { 00205 SgNode* node = const_cast<SgNode*>(this); 00206 while (node->HasFather() && ! node->HasRightBrother()) 00207 node = node->Father(); 00208 if (node->HasRightBrother()) 00209 node = node->RightBrother(); 00210 return node; 00211 } 00212 } 00213 00214 SgNode* SgNode::PrevDepthFirst() const 00215 { 00216 SgNode* node = const_cast<SgNode*>(this); 00217 if (HasLeftBrother() || ! HasFather()) 00218 { 00219 if (HasLeftBrother()) 00220 node = LeftBrother(); 00221 while (node->HasSon()) 00222 node = node->RightMostSon(); 00223 } 00224 else 00225 node = Father(); 00226 return node; 00227 } 00228 00229 void SgNode::PathToRoot(SgVectorOf<SgNode>* path) const 00230 { 00231 path->Clear(); 00232 for (SgNode* node = const_cast<SgNode*>(this); node; 00233 node = node->Father()) 00234 path->PushBack(node); 00235 } 00236 00237 SgNode* SgNode::NodeInDirection(Direction dir) const 00238 { 00239 SgNode* node = 0; 00240 switch (dir) 00241 { 00242 case PREVIOUS: 00243 node = Father(); 00244 break; 00245 case NEXT: 00246 node = LeftMostSon(); 00247 break; 00248 case NEXT_RIGHTMOST: 00249 node = RightMostSon(); 00250 break; 00251 case PREV_DEPTHFIRST: 00252 node = PrevDepthFirst(); 00253 break; 00254 case NEXT_DEPTHFIRST: 00255 node = NextDepthFirst(); 00256 break; 00257 case PREV_TERMINAL: 00258 node = PrevDepthFirst(); 00259 while (! node->IsTerminal()) 00260 node = node->PrevDepthFirst(); 00261 break; 00262 case NEXT_TERMINAL: 00263 node = NextDepthFirst(); 00264 while (! node->IsTerminal()) 00265 node = node->NextDepthFirst(); 00266 break; 00267 case PREV_BRANCH: 00268 node = Father(); 00269 while (node && node->HasFather() && ! node->IsBranchPoint()) 00270 node = node->Father(); 00271 break; 00272 case NEXT_BRANCH: 00273 node = LeftMostSon(); 00274 while (node && ! node->IsTerminal() && ! node->IsBranchPoint()) 00275 node = node->LeftMostSon(); 00276 break; 00277 case LEFT_BROTHER: 00278 if (HasLeftBrother()) 00279 node = LeftBrother(); 00280 else if (HasBrother()) 00281 node = Father()->RightMostSon(); // wrap around 00282 break; 00283 case RIGHT_BROTHER: 00284 if (HasRightBrother()) 00285 node = RightBrother(); 00286 else if (HasBrother()) 00287 node = Father()->LeftMostSon(); // wrap around 00288 break; 00289 case MAIN_BRANCH: 00290 { 00291 SgNode* t = const_cast<SgNode*>(this); 00292 while (t->HasFather()) 00293 { 00294 if (t->HasLeftBrother()) 00295 node = t->Father(); 00296 t = t->Father(); 00297 } 00298 } 00299 break; 00300 case START_OF_GAME: 00301 node = Root(); 00302 break; 00303 case END_OF_GAME: 00304 node = const_cast<SgNode*>(this); 00305 while (! node->IsTerminal()) 00306 node = node->LeftMostSon(); 00307 break; 00308 default: 00309 SG_ASSERT(false); 00310 } 00311 return node; 00312 } 00313 00314 bool SgNode::ContainsText(const string& findText) 00315 { 00316 // Handle check for special properties outside of this function. 00317 SG_ASSERT(SgProp::ConvertFindTextToPropID(findText) == SG_PROP_NONE); 00318 return m_props.GetPropContainingText(findText) != 0; 00319 } 00320 00321 // add comment to SG_PROP_COMMENT of node 00322 void SgNode::AddComment(const std::string& comment) 00323 { 00324 SgPropText* textProp = static_cast<SgPropText*>(Get(SG_PROP_COMMENT)); 00325 if (textProp) 00326 textProp->AppendText(comment); 00327 else 00328 { 00329 textProp = new SgPropText(SG_PROP_COMMENT, comment); 00330 Add(textProp); 00331 } 00332 } 00333 00334 bool SgNode::HasProp(SgPropID id) const 00335 { 00336 if (id == SG_PROP_TERMINAL) 00337 return IsTerminal(); 00338 else if (id == SG_PROP_BRANCH) 00339 return IsBranchPoint(); 00340 else 00341 return Get(id) != 0; 00342 } 00343 00344 // shortest path between two nodes 00345 // To do this efficiently, we mark all nodes from the two nodes back toward 00346 // the root until we find a node that's already marked. 00347 void SgNode::ShortestPathTo(SgNode* node, int* numBack, 00348 SgVectorOf<SgNode>* path) const 00349 { 00350 //--- Go backwards from both nodes in parallel, marking all nodes, until 00351 // finding a marked node (the common ancestor), or both are 0. 00352 SgNode* x = const_cast<SgNode*>(this); 00353 SgNode* y = node; 00354 SgNode* common = 0; 00355 while (true) 00356 { 00357 if (x) 00358 { 00359 if (x->IsMarked()) 00360 { 00361 common = x; 00362 break; 00363 } 00364 x->Mark(); 00365 x = x->m_father; 00366 } 00367 if (y) 00368 { 00369 if (y->IsMarked()) 00370 { 00371 common = y; 00372 break; 00373 } 00374 y->Mark(); 00375 y = y->m_father; 00376 } 00377 if (! x && ! y) 00378 { 00379 break; 00380 } 00381 } 00382 00383 //--- Unmark all nodes from 'common' toward the root. 00384 00385 for (x = common; x && x->IsMarked(); x = x->m_father) 00386 { 00387 x->Unmark(); 00388 } 00389 00390 //--- Unmark and count all nodes from this node to 'common'. 00391 *numBack = 0; 00392 00393 for (x = const_cast<SgNode*>(this); x != common; x = x->m_father) 00394 { 00395 SG_ASSERT(x->IsMarked()); 00396 x->Unmark(); 00397 ++(*numBack); 00398 } 00399 00400 //--- Unmark and store all nodes from 'node' to 'common'. 00401 path->Clear(); 00402 for (x = node; x != common; x = x->m_father) 00403 { 00404 SG_ASSERT(x->IsMarked()); 00405 x->Unmark(); 00406 path->PushBack(x); 00407 } 00408 path->Reverse(); 00409 } 00410 00411 void SgNode::PromoteNode() 00412 { 00413 if (HasLeftBrother()) 00414 { 00415 SgNode* brotherOfThis = m_brother; 00416 m_brother = m_father->m_son; // first son is brother 00417 m_father->m_son = this; // father has new first son 00418 SgNode* x = this; 00419 while (x->m_brother != this) 00420 x = x->m_brother; 00421 x->m_brother = brotherOfThis; // skip moved node 00422 } 00423 } 00424 00425 void SgNode::PromotePath() 00426 { 00427 SgNode* node = this; 00428 while (node) 00429 { 00430 node->PromoteNode(); // promote all nodes on the path to the root 00431 node = node->Father(); 00432 } 00433 } 00434 00435 void SgNode::DeleteSubtree() 00436 { 00437 // 'delete' does all the work of keeping the tree pointers consistent, so 00438 // can just keep deleting until no nodes below the current node remain. 00439 while (HasSon()) 00440 delete LeftMostSon(); 00441 } 00442 00443 void SgNode::DeleteBranches() 00444 { 00445 SgNode* main = LeftMostSon(); 00446 while (main) 00447 { 00448 SgNode* brother = main->RightBrother(); 00449 while (brother) 00450 { 00451 SgNode* nextToDelete = brother->RightBrother(); 00452 brother->DeleteSubtree(); 00453 delete brother; 00454 brother = nextToDelete; 00455 } 00456 main = main->LeftMostSon(); 00457 } 00458 } 00459 00460 void SgNode::DeleteTree() 00461 { 00462 SgNode* root = Root(); 00463 root->DeleteSubtree(); 00464 delete root; 00465 } 00466 00467 SgNode* SgNode::NewFather() 00468 { 00469 SgNode* n = new SgNode(); 00470 if (HasLeftBrother()) 00471 { 00472 SgNode* left = LeftBrother(); 00473 left->m_brother = n; 00474 } 00475 else 00476 m_father->m_son = n; 00477 n->m_son = this; 00478 n->m_brother = m_brother; 00479 n->m_father = m_father; 00480 m_brother = 0; 00481 m_father = n; 00482 return n; 00483 } 00484 00485 SgNode* SgNode::NewRightBrother() 00486 { 00487 SgNode* n = new SgNode(); 00488 n->m_brother = m_brother; 00489 n->m_father = m_father; 00490 m_brother = n; 00491 return n; 00492 } 00493 00494 SgNode* SgNode::NewLeftMostSon() 00495 { 00496 SgNode* n = new SgNode(); 00497 n->m_father = this; 00498 n->m_brother = m_son; 00499 m_son = n; 00500 return n; 00501 } 00502 00503 SgNode* SgNode::NewRightMostSon() 00504 { 00505 if (HasSon()) 00506 return RightMostSon()->NewRightBrother(); 00507 else 00508 return NewLeftMostSon(); 00509 } 00510 00511 SgNode* SgNode::LinkTrees(const SgVectorOf<SgNode>& roots) 00512 { 00513 SgNode* super = new SgNode(); 00514 SgNode* previous = 0; 00515 for (SgVectorIteratorOf<SgNode> iter(roots); iter; ++iter) 00516 { 00517 SgNode* root = *iter; 00518 SG_ASSERT(! root->HasFather()); 00519 if (previous) 00520 previous->m_brother = root; 00521 else 00522 super->m_son = root; 00523 root->m_father = super; 00524 previous = root; 00525 } 00526 return super; 00527 } 00528 00529 void SgNode::AppendTo(SgNode* n) 00530 { 00531 SG_ASSERT(! HasFather()); 00532 SG_ASSERT(! HasBrother()); 00533 SG_ASSERT(n); 00534 if (n->HasSon()) 00535 { 00536 SgNode* t = n->RightMostSon(); 00537 t->m_brother = this; 00538 } 00539 else 00540 n->m_son = this; 00541 m_father = n; 00542 } 00543 00544 SgNode* SgNode::TopProp(SgPropID id) const 00545 { 00546 SgNode* node = const_cast<SgNode*>(this); 00547 while (node->HasFather() && ! node->Get(id)) 00548 node = node->Father(); 00549 // Return either root node or node with property. 00550 return node; 00551 } 00552 00553 int SgNode::GetIntProp(SgPropID id) const 00554 { 00555 SgPropInt* prop = static_cast<SgPropInt*>(Get(id)); 00556 if (prop) 00557 return prop->Value(); 00558 else 00559 return 0; 00560 } 00561 00562 bool SgNode::GetIntProp(SgPropID id, int* value) const 00563 { 00564 SgPropInt* prop = static_cast<SgPropInt*>(Get(id)); 00565 if (prop) 00566 { *value = prop->Value(); 00567 return true; 00568 } 00569 00570 return false; 00571 } 00572 00573 bool SgNode::HasNodeMove() const 00574 { 00575 return HasProp(SG_PROP_MOVE_BLACK) || HasProp(SG_PROP_MOVE_WHITE); 00576 } 00577 00578 SgBlackWhite SgNode::NodePlayer() const 00579 { 00580 SG_ASSERT(HasNodeMove()); 00581 if (HasProp(SG_PROP_MOVE_BLACK)) 00582 return SG_BLACK; 00583 return SG_WHITE; 00584 } 00585 00586 SgPoint SgNode::NodeMove() const 00587 { 00588 SgPoint p; 00589 if (GetIntProp(SG_PROP_MOVE_BLACK, &p)) 00590 return p; 00591 else if (GetIntProp(SG_PROP_MOVE_WHITE, &p)) 00592 return p; 00593 else 00594 return SG_NULLMOVE; 00595 } 00596 00597 double SgNode::GetRealProp(SgPropID id) const 00598 { 00599 SgPropReal* prop = dynamic_cast<SgPropReal*>(Get(id)); 00600 if (prop) 00601 return prop->Value(); 00602 else 00603 return 0; 00604 } 00605 00606 void SgNode::SetIntProp(SgPropID id, int value) 00607 { 00608 SgPropInt* prop = dynamic_cast<SgPropInt*>(Get(id)); 00609 if (prop) 00610 prop->SetValue(value); 00611 else 00612 { 00613 prop = dynamic_cast<SgPropInt*>(SgProp::CreateProperty(id)); 00614 prop->SetValue(value); 00615 Add(prop); 00616 } 00617 } 00618 00619 void SgNode::SetRealProp(SgPropID id, double value, int precision) 00620 { 00621 SgPropReal* prop = dynamic_cast<SgPropReal*>(Get(id)); 00622 if (prop) 00623 prop->SetValue(value); 00624 else 00625 { 00626 prop = static_cast<SgPropReal*>(SgProp::CreateProperty(id)); 00627 prop->SetValue(value, precision); 00628 Add(prop); 00629 } 00630 } 00631 00632 bool SgNode::GetStringProp(SgPropID id, string* value) const 00633 { 00634 SgPropText* prop = dynamic_cast<SgPropText*>(Get(id)); 00635 if (prop) 00636 { 00637 *value = prop->Value(); 00638 return true; 00639 } 00640 return false; 00641 } 00642 00643 void SgNode::SetStringProp(SgPropID id, const string& value) 00644 { 00645 SgPropText* prop = dynamic_cast<SgPropText*>(Get(id)); 00646 if (prop) 00647 prop->SetValue(value); 00648 else 00649 { 00650 prop = static_cast<SgPropText*>(SgProp::CreateProperty(id)); 00651 prop->SetValue(value); 00652 Add(prop); 00653 } 00654 } 00655 00656 void SgNode::SetListProp(SgPropID id, const SgVector<SgPoint>& value) 00657 { 00658 SgPropPointList* prop = dynamic_cast<SgPropPointList*>(Get(id)); 00659 if (prop) 00660 prop->SetValue(value); 00661 else 00662 { 00663 prop = static_cast<SgPropPointList*>(SgProp::CreateProperty(id)); 00664 prop->SetValue(value); 00665 Add(prop); 00666 } 00667 } 00668 00669 void SgNode::SetListProp(SgPropID id, const SgPointSet& value) 00670 { 00671 SgVector<SgPoint> valueList; 00672 value.ToVector(&valueList); 00673 SetListProp(id, valueList); 00674 } 00675 00676 void SgNode::CopyAllPropsFrom(const SgNode& sourceNode) 00677 { 00678 for (SgPropListIterator it(sourceNode.Props()); it; ++it) 00679 { 00680 SgProp* copy = (*it)->Duplicate(); 00681 Add(copy); 00682 } 00683 } 00684 00685 SgProp* SgNode::CopyPropFrom(const SgNode& sourceNode, SgPropID id) 00686 { 00687 SgProp* sourceProp = sourceNode.Get(id); 00688 if (sourceProp) 00689 { 00690 SgProp* copy = sourceProp->Duplicate(); 00691 Add(copy); 00692 return copy; 00693 } 00694 else 00695 return 0; 00696 } 00697 00698 SgProp* SgNode::AddMoveProp(SgMove move, SgBlackWhite player) 00699 { 00700 SG_ASSERT_BW(player); 00701 SgPropID id = 00702 (player == SG_BLACK) ? SG_PROP_MOVE_BLACK : SG_PROP_MOVE_WHITE; 00703 SgPropMove* moveProp = new SgPropMove(id, move); 00704 Add(moveProp); 00705 return moveProp; 00706 } 00707 00708 SgBlackWhite SgNode::Player() const 00709 { 00710 SG_ASSERT(Get(SG_PROP_PLAYER)); 00711 return static_cast<SgPropPlayer*>(Get(SG_PROP_PLAYER))->Value(); 00712 } 00713 00714 int SgNode::CountNodes(bool fSetPropOnThisNode) 00715 { 00716 int n = 1; 00717 for (SgSonNodeIterator son(this); son; ++son) 00718 n += (*son)->CountNodes(/*fSetPropOnThisNode*/false); 00719 // Set property only on nodes that have at least two sons. 00720 if (fSetPropOnThisNode || IsBranchPoint()) 00721 SetIntProp(SG_PROP_NUM_NODES, n); 00722 return n; 00723 } 00724 00725 #ifndef NDEBUG 00726 int SgNode::s_alloc = 0; 00727 00728 int SgNode::s_free = 0; 00729 00730 void SgNode::GetStatistics(int* numAlloc, int* numUsed) 00731 { 00732 *numAlloc = s_alloc; 00733 *numUsed = s_alloc - s_free; 00734 } 00735 #endif 00736 00737 void SgNode::MemCheck() 00738 { 00739 SG_ASSERT(s_alloc == s_free); 00740 } 00741 00742 string SgNode::TreeIndex(const SgNode* node) 00743 { 00744 ostringstream s; 00745 if (! node) 00746 s << "NIL"; 00747 else 00748 { 00749 SgNode* father = node->Father(); 00750 if (! father) 00751 s << '1'; 00752 else 00753 { 00754 s << TreeIndex(father) << '.'; 00755 SgNode* son = father->LeftMostSon(); 00756 int index = 1; 00757 while ((son != node) && son) 00758 { 00759 ++index; 00760 son = son->RightBrother(); 00761 } 00762 if (son == node) 00763 s << index; 00764 else 00765 SG_ASSERT(false); 00766 } 00767 } 00768 return s.str(); 00769 } 00770 00771 //---------------------------------------------------------------------------- 00772 00773 SgNodeIterator::SgNodeIterator(SgNode* rootOfSubtree, bool postOrder) 00774 : m_postOrder(postOrder), 00775 m_rootOfSubtree(rootOfSubtree) 00776 { 00777 m_nextNode = m_rootOfSubtree; 00778 if (m_postOrder) 00779 { 00780 while (m_nextNode->HasSon()) 00781 m_nextNode = m_nextNode->LeftMostSon(); 00782 } 00783 } 00784 00785 SgNodeConstIterator::SgNodeConstIterator(const SgNode* rootOfSubtree, 00786 bool postOrder) 00787 : m_postOrder(postOrder), 00788 m_rootOfSubtree(rootOfSubtree) 00789 { 00790 m_nextNode = m_rootOfSubtree; 00791 if (m_postOrder) 00792 { 00793 while (m_nextNode->HasSon()) 00794 m_nextNode = m_nextNode->LeftMostSon(); 00795 } 00796 } 00797 00798 bool SgNodeIterator::Next() 00799 { 00800 if (m_nextNode) 00801 { 00802 if (m_postOrder) 00803 { 00804 if (m_nextNode == m_rootOfSubtree) 00805 m_nextNode = 0; 00806 else if (m_nextNode->HasRightBrother()) 00807 { 00808 m_nextNode = m_nextNode->RightBrother(); 00809 while (m_nextNode->HasSon()) 00810 m_nextNode = m_nextNode->LeftMostSon(); 00811 } 00812 else 00813 { 00814 SG_ASSERT(m_nextNode->HasFather()); 00815 m_nextNode = m_nextNode->Father(); 00816 } 00817 } 00818 else 00819 { 00820 m_nextNode = m_nextNode->NextDepthFirst(); 00821 if (m_nextNode == m_rootOfSubtree) 00822 m_nextNode = 0; 00823 } 00824 return true; 00825 } 00826 else 00827 return false; 00828 } 00829 00830 bool SgNodeConstIterator::Next() 00831 { 00832 if (m_nextNode) 00833 { 00834 if (m_postOrder) 00835 { 00836 if (m_nextNode == m_rootOfSubtree) 00837 m_nextNode = 0; 00838 else if (m_nextNode->HasRightBrother()) 00839 { 00840 m_nextNode = m_nextNode->RightBrother(); 00841 while (m_nextNode->HasSon()) 00842 m_nextNode = m_nextNode->LeftMostSon(); 00843 } 00844 else 00845 { 00846 SG_ASSERT(m_nextNode->HasFather()); 00847 m_nextNode = m_nextNode->Father(); 00848 } 00849 } 00850 else 00851 { 00852 m_nextNode = m_nextNode->NextDepthFirst(); 00853 if (m_nextNode == m_rootOfSubtree) 00854 m_nextNode = 0; 00855 } 00856 return true; 00857 } 00858 else 00859 return false; 00860 } 00861 00862 //---------------------------------------------------------------------------- 00863