Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgNode.cpp

Go to the documentation of this file.
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 


17 Jun 2010 Doxygen 1.4.7