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 #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 


Sun Mar 13 2011 Doxygen 1.7.1