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