ctreecont.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:27k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ctreecont.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:35:13  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: ctreecont.cpp,v 1000.1 2004/06/01 19:35:13 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * File Name:  CTreeCont.cpp
  35. *
  36. * Author:  Vladimir Soussov, Yuri Sadykov, Michael Domrachev
  37. *
  38. * File Description:  General purpose tree container implementation
  39. *
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include "ctreecont.hpp"
  43. BEGIN_NCBI_SCOPE
  44. BEGIN_objects_SCOPE
  45. bool CTreeIterator::BelongSubtree(const CTreeContNodeBase* subtree_root)
  46. {
  47.     if(m_node == subtree_root)
  48.         return true;
  49.     for(CTreeContNodeBase* pN= m_node->m_parent; pN != 0; pN= pN->m_parent) {
  50.         if(pN == subtree_root)
  51.             return true;
  52.     }
  53.     return false;
  54. }
  55. bool CTreeIterator::AboveNode(CTreeContNodeBase* node)
  56. {
  57.     if(node == 0) return false;
  58.     do {
  59.         if(node->m_parent == m_node) return true;
  60.     }
  61.     while((node= node->m_parent) != 0);
  62.     return false;
  63. }
  64. // move cursor to the nearest common ancestor
  65. bool CTreeIterator::GoAncestor(CTreeContNodeBase* node)
  66. {
  67.     if(BelongSubtree(node)) {
  68.         m_node= node;
  69.         return true;
  70.     }
  71.     CTreeContNodeBase* pN= m_node;;
  72.     while(!AboveNode(node)) {
  73.         if(m_node->m_parent == 0) {
  74.             m_node= pN;
  75.             return false;
  76.         }
  77.         m_node= m_node->m_parent;
  78.     }
  79.     return true;
  80. }
  81. // add child to a node pointed by cursor
  82. bool CTreeIterator::AddChild(CTreeContNodeBase* new_node)
  83. {
  84.     if(new_node) {
  85.         m_tree->AddChild(m_node);
  86.         new_node->m_parent= m_node;
  87.         new_node->m_sibling= m_node->m_child;
  88.         new_node->m_child= 0;
  89.         m_node->m_child= new_node;
  90.         m_tree->Done(new_node);
  91.         return true;
  92.     }
  93.     return false;
  94. }
  95. // add sibling to a node pointed by cursor
  96. bool CTreeIterator::AddSibling(CTreeContNodeBase* new_node)
  97. {
  98.     if(new_node && m_node->m_parent) {
  99.         m_tree->AddChild(m_node->m_parent);
  100.         new_node->m_parent= m_node->m_parent;
  101.         new_node->m_sibling= m_node->m_sibling;
  102.         new_node->m_child= 0;
  103.         m_node->m_sibling= new_node;
  104.         m_tree->Done(new_node);
  105.         return true;
  106.     }
  107.     return false;
  108. }
  109. bool CTreeIterator::MoveNode(CTreeContNodeBase* to_node)
  110. {
  111.     if((to_node == 0) || AboveNode(to_node)) {
  112.         return false;
  113.     }
  114.     if(m_node->m_parent == to_node) return true;
  115.     // notify the spies
  116.     m_tree->MoveNode(m_node, to_node);
  117.     // detach the node
  118.     if(m_node->m_parent->m_child == m_node) { // this is a first child
  119.         m_node->m_parent->m_child= m_node->m_sibling;
  120.     }
  121.     else {
  122.         CTreeContNodeBase* pN;
  123.         for( pN= m_node->m_parent->m_child;
  124.              pN->m_sibling != m_node;
  125.              pN= pN->m_sibling );
  126.         pN->m_sibling= m_node->m_sibling;
  127.     }
  128.     // attach it
  129.     m_node->m_sibling= to_node->m_child;
  130.     m_node->m_parent= to_node;
  131.     to_node->m_child= m_node;
  132.     // notify the spies
  133.     m_tree->Done(m_node);
  134.     return true;
  135. }
  136. bool CTreeIterator::MoveChildren(CTreeContNodeBase* to_node)
  137. {
  138.     if((to_node == 0) || AboveNode(to_node)) {
  139.         return false;
  140.     }
  141.     if((m_node == to_node) || (m_node->m_child == 0)) return true;
  142.     // notify the spies
  143.     m_tree->MoveChildren(m_node, to_node);
  144.     CTreeContNodeBase* pN= m_node->m_child;
  145.     do {
  146.         pN->m_parent= to_node;
  147.         if(pN->m_sibling == 0) break;
  148.     }
  149.     while((pN= pN->m_sibling) != 0);
  150.     pN->m_sibling= to_node->m_child;
  151.     to_node->m_child= m_node->m_child;
  152.     m_node->m_child= 0;
  153.     // notify the spies
  154.     m_tree->Done(m_node);
  155.     return true;
  156. }
  157. void CTreeCont::DelNodeInternal(CTreeContNodeBase* pN)
  158. {
  159.     CTreeContNodeBase* pNxt;
  160.     for(CTreeContNodeBase* pChild= pN->m_child; pChild != 0; pChild= pNxt) {
  161.         pNxt= pChild->m_sibling;
  162.         DelNodeInternal(pChild);
  163.     }
  164.     delete pN;
  165. }
  166. bool CTreeIterator::DeleteSubtree()
  167. {
  168.     if(m_node->m_parent == 0) return false; // can't delete the whole tree
  169.     // notify the spies
  170.     m_tree->DeleteSubtree(m_node, this);
  171.     CTreeContNodeBase* pN;
  172.     // detach the node
  173.     if(m_node->m_parent->m_child == m_node) { // this is a first child
  174.         m_node->m_parent->m_child= m_node->m_sibling;
  175.     }
  176.     else {
  177.         for(pN= m_node->m_parent->m_child;
  178.             pN->m_sibling != m_node;
  179.             pN= pN->m_sibling);
  180.         pN->m_sibling= m_node->m_sibling;
  181.     }
  182.     pN= m_node->m_parent;
  183.     m_tree->DelNodeInternal(m_node);
  184.     // notify the spies
  185.     m_node= pN;
  186.     m_tree->Done(m_node);
  187.     return true;
  188. }
  189. bool CTreeIterator::DeleteNode()
  190. {
  191.     if(m_node->m_parent == 0) return false; // can't delete the root
  192.     if(m_node->m_child) {
  193.         MoveChildren(m_node->m_parent);
  194.     }
  195.     return DeleteSubtree();
  196. }
  197. bool CTreeIterator::Merge(CTreeContNodeBase* to_node)
  198. {
  199.     if(MoveChildren(to_node)) {
  200.         m_tree->Merge(m_node, to_node, this);
  201.         to_node->Merge(m_node);
  202.         // detach the node
  203.         if(m_node->m_parent->m_child == m_node) { // this is a first child
  204.             m_node->m_parent->m_child= m_node->m_sibling;
  205.         }
  206.         else {
  207.             CTreeContNodeBase* pN;
  208.             for(pN= m_node->m_parent->m_child;
  209.                 pN->m_sibling != m_node;
  210.                 pN= pN->m_sibling);
  211.             pN->m_sibling= m_node->m_sibling;
  212.         }
  213.         delete m_node;
  214.         m_node= to_node;
  215.         m_tree->Done(m_node);
  216.         return true;
  217.     }
  218.     return false;
  219. }
  220. CTreeIterator::EAction
  221. CTreeIterator::ForEachDownward(C4Each& cb)
  222. {
  223.     switch( cb.Execute(m_node) ) {
  224.     default:
  225.     case eCont:
  226.         if(!m_node->IsTerminal()) {
  227.             switch( cb.LevelBegin(m_node) ) {
  228.             case eStop: return eStop;
  229.             default:
  230.             case eCont:
  231.                 if(GoChild()) {
  232.                     do {
  233.                         if(ForEachDownward(cb)==eStop)
  234.                             return eStop;
  235.                     } while(GoSibling());
  236.                 }
  237.             case eSkip: // Means skip this level
  238.                 break;
  239.             }
  240.             GoParent();
  241.             if( cb.LevelEnd(m_node) == eStop )
  242.                 return eStop;
  243.         }
  244.     case eSkip: break;
  245.     case eStop: return eStop;
  246.     }
  247.     return eCont;
  248. }
  249. CTreeIterator::EAction
  250. CTreeIterator::ForEachDownward(ForEachFunc ucb, void* user_data)
  251. {
  252.     switch( (*ucb)(m_node, user_data) ) {
  253.     default:
  254.     case eCont:
  255.         if(GoChild()) {
  256.             do {
  257.                 if(ForEachDownward(ucb, user_data)==eStop)
  258.                     return eStop;
  259.             } while(GoSibling());
  260.             GoParent();
  261.         }
  262.     case eSkip: break;
  263.     case eStop: return eStop;
  264.     }
  265.     return eCont;
  266. }
  267. CTreeIterator::EAction
  268. CTreeIterator::ForEachDownwardLimited(C4Each& cb, int levels)
  269. {
  270.     if(levels > 0) {
  271.         switch( cb.Execute(m_node) ) {
  272.         default:
  273.         case eCont:
  274.             if(!m_node->IsTerminal()) {
  275.                 switch( cb.LevelBegin(m_node) ) {
  276.                 case eStop: return eStop;
  277.                 default:
  278.                 case eCont:
  279.                     if(GoChild()) {
  280.                         do {
  281.                             if(ForEachDownwardLimited(cb, levels-1)==eStop)
  282.                                 return eStop;
  283.                         } while(GoSibling());
  284.                     }
  285.                 case eSkip: // Means skip this level
  286.                     break;
  287.                 }
  288.                 GoParent();
  289.                 if( cb.LevelEnd(m_node) == eStop )
  290.                     return eStop;
  291.             }
  292.         case eSkip: break;
  293.         case eStop: return eStop;
  294.         }
  295.     }
  296.     return eCont;
  297. }
  298. CTreeIterator::EAction
  299. CTreeIterator::ForEachDownwardLimited(ForEachFunc ucb, void* user_data,
  300.                                       int levels)
  301. {
  302.     if(levels > 0) {
  303.         switch( (*ucb)(m_node, user_data) ) {
  304.         default:
  305.         case eCont:
  306.             if(GoChild()) {
  307.                 do {
  308.                     if(ForEachDownwardLimited(ucb, user_data,
  309.                                               levels-1)==eStop)
  310.                         return eStop;
  311.                 } while(GoSibling());
  312.                 GoParent();
  313.             }
  314.         case eSkip: break;
  315.         case eStop: return eStop;
  316.         }
  317.     }
  318.     return eCont;
  319. }
  320. ///////////////////////////////////////////////////////
  321. // Get iterators
  322. ///////////////////////////////////////////////////////
  323. CTreeIterator*
  324. CTreeCont::GetIterator()
  325. {
  326.     return new CTreeIterator(this);
  327. }
  328. CTreeConstIterator*
  329. CTreeCont::GetConstIterator() const
  330. {
  331.     return new CTreeConstIterator(this);
  332. }
  333. ///////////////////////////////////////////////////////
  334. // delete subtree notification (private method)
  335. ///////////////////////////////////////////////////////
  336. void
  337. CTreeCont::DeleteSubtree(CTreeContNodeBase*, CTreeIterator*)
  338. {
  339.     //     int i;
  340.     //     if((n= m_cursorPot.nof()) > 1) {
  341.     //  // move all cursors out of deleted subtree
  342.     //  CTreeIterator* iCursor;
  343.     //  for(i= 0; i < n; i++) {
  344.     //      iCursor= (CTreeIterator*)(m_cursorPot.get(i));
  345.     //      if((iCursor != pCursor) && iCursor->belongSubtree(stroot)) {
  346.     //  iCursor->GoNode(stroot->m_parent); // move it up
  347.     //      }
  348.     //  }
  349.     //     }
  350. }
  351. ////////////////////////////////////////////////////////////
  352. // notify others that operation completed (private method)
  353. ////////////////////////////////////////////////////////////
  354. void CTreeCont::Done(CTreeContNodeBase* /*node*/)
  355. {
  356.     //     int n= m_spyPot.nof();
  357.     //     if(n > 0) { // notify all spies about delSubtree operation
  358.     //  int i;
  359.     //  CTreeContSpy* pSpy;
  360.     //  for(i= 0; i < n; i++) {
  361.     //      pSpy= (CTreeContSpy*)(m_spyPot.get(i));
  362.     //      pSpy->Done(node);
  363.     //  }
  364.     //     }
  365. }
  366. ///////////////////////////////////////////////////////////
  367. // move node notification (private method)
  368. ///////////////////////////////////////////////////////////
  369. void CTreeCont::MoveNode(CTreeContNodeBase*, CTreeContNodeBase*)
  370. {
  371.     //     int n= m_spyPot.nof();
  372.     //     if(n > 0) { // notify all spies about delSubtree operation
  373.     //  int i;
  374.     //  CTreeContSpy* pSpy;
  375.     //  for(i= 0; i < n; i++) {
  376.     //      pSpy= (CTreeContSpy*)(m_spyPot.get(i));
  377.     //      pSpy->node_move(node2move, new_parent);
  378.     //  }
  379.     //     }
  380. }
  381. //////////////////////////////////////////////////////////////
  382. // move children (private method)
  383. //////////////////////////////////////////////////////////////
  384. void CTreeCont::MoveChildren(CTreeContNodeBase*, CTreeContNodeBase*)
  385. {
  386.     //     int n= m_spyPot.nof();
  387.     //     if(n > 0) { // notify all spies about delSubtree operation
  388.     //  int i;
  389.     //  CTreeContSpy* pSpy;
  390.     //  for(i= 0; i < n; i++) {
  391.     //      pSpy= (CTreeContSpy*)(m_spyPot.get(i));
  392.     //      pSpy->children_move(old_parent, new_parent);
  393.     //  }
  394.     //     }
  395. }
  396. ///////////////////////////////////////////////////////////////
  397. // add child notification (private method)
  398. ///////////////////////////////////////////////////////////////
  399. void CTreeCont::AddChild(CTreeContNodeBase*)
  400. {
  401.     //     int n= m_spyPot.nof();
  402.     //     if(n > 0) { // notify all spies about delSubtree operation
  403.     //  int i;
  404.     //  CTreeContSpy* pSpy;
  405.     //  for(i= 0; i < n; i++) {
  406.     //      pSpy= (CTreeContSpy*)(m_spyPot.get(i));
  407.     //      pSpy->child_add(parent);
  408.     //  }
  409.     //     }
  410. }
  411. //////////////////////////////////////////////////////
  412. // merge nodes notification (private method)
  413. //////////////////////////////////////////////////////
  414. void CTreeCont::Merge(CTreeContNodeBase* , CTreeContNodeBase* ,
  415.                       CTreeIterator* )
  416. {
  417.     //     int i;
  418.     //     int n= m_spyPot.nof();
  419.     //     if(n > 0) { // notify all spies about delSubtree operation
  420.     //  CTreeContSpy* pSpy;
  421.     //  for(i= 0; i < n; i++) {
  422.     //      pSpy= (CTreeContSpy*)(m_spyPot.get(i));
  423.     //      pSpy->node_merge(src, dst);
  424.     //  }
  425.     //     }
  426.     //     if((n= m_cursorPot.nof()) > 1) {
  427.     //  // move all cursors out of src
  428.     //  CTreeIterator* iCursor;
  429.     //  for(i= 0; i < n; i++) {
  430.     //      iCursor= (CTreeIterator*)(m_cursorPot.get(i));
  431.     //      if((iCursor != pCursor) && (iCursor->getNode() == src)) {
  432.     //  iCursor->GoNode(dst); // move it to merged node
  433.     //      }
  434.     //  }
  435.     //     }
  436. }
  437. CTreeCont::~CTreeCont()
  438. {
  439.     //     int i, n;
  440.     //     // delete all cursors
  441.     //     if((n= m_cursorPot.nof()) > 1) {
  442.     //  // move all cursors out of deleted subtree
  443.     //  CTreeIterator* iCursor;
  444.     //  for(i= 0; i < n; i++) {
  445.     //      iCursor= (CTreeIterator*)(m_cursorPot.get(i));
  446.     //      delete iCursor;
  447.     //  }
  448.     //     }
  449.     if(m_root)
  450.         DelNodeInternal(m_root);
  451. }
  452. bool CTreeCont::AddNode(CTreeContNodeBase* pParentNode,
  453.                         CTreeContNodeBase* pNewNode)
  454. {
  455.     if(pNewNode && pParentNode) {
  456.         pNewNode->m_parent = pParentNode;
  457.         pNewNode->m_sibling = pParentNode->m_child;
  458.         pNewNode->m_child = 0;
  459.         pParentNode->m_child = pNewNode;
  460.         return true;
  461.     }
  462.     return false;
  463. }
  464. bool CTreeConstIterator::BelongSubtree(const CTreeContNodeBase* subtree_root)
  465.     const
  466. {
  467.     if(m_node == subtree_root)
  468.         return true;
  469.     for(const CTreeContNodeBase* pN= m_node->m_parent; pN != 0;
  470.         pN= pN->m_parent) {
  471.         if(pN == subtree_root)
  472.             return true;
  473.     }
  474.     return false;
  475. }
  476. bool CTreeConstIterator::AboveNode(const CTreeContNodeBase* node) const
  477. {
  478.     if(node == 0)
  479.         return false;
  480.     do {
  481.         if(node->m_parent == m_node)
  482.             return true;
  483.     }
  484.     while((node= node->m_parent) != 0);
  485.     return false;
  486. }
  487. // move cursor to the nearest common ancestor
  488. bool CTreeConstIterator::GoAncestor(const CTreeContNodeBase* node)
  489. {
  490.     if(BelongSubtree(node)) {
  491.         m_node= node;
  492.         return true;
  493.     }
  494.     const CTreeContNodeBase* pN= m_node;;
  495.     while(!AboveNode(node)) {
  496.         if(m_node->m_parent == 0) {
  497.             m_node= pN;
  498.             return false;
  499.         }
  500.         m_node= m_node->m_parent;
  501.     }
  502.     return true;
  503. }
  504. // CTreeConstIterator::EAction
  505. // CTreeConstIterator::ForEachDownward(C4Each& cb)
  506. // {
  507. //     switch( cb.Execute(m_node) ) {
  508. //     default:
  509. //     case eCont:
  510. //         if(!m_node->IsTerminal()) {
  511. //             switch( cb.LevelBegin(m_node) ) {
  512. //             case eStop: return eStop;
  513. //             default:
  514. //             case eCont:
  515. //                 if(GoChild()) {
  516. //                     do {
  517. //                         if(ForEachDownward(cb)==eStop) return eStop;
  518. //                     } while(GoSibling());
  519. //                 }
  520. //             case eSkip: // Means skip this level
  521. //                 break;
  522. //             }
  523. //             GoParent();
  524. //             if( cb.LevelEnd(m_node) == eStop )
  525. //                 return eStop;
  526. //         }
  527. //     case eSkip: break;
  528. //     case eStop: return eStop;
  529. //     }
  530. //     return eCont;
  531. // }
  532. // CTreeConstIterator::EAction
  533. // CTreeConstIterator::ForEachDownward(ForEachFunc ucb, void* user_data)
  534. // {
  535. //     switch( (*ucb)(m_node, user_data) ) {
  536. //     default:
  537. //     case eCont:
  538. //         if(GoChild()) {
  539. //             do {
  540. //                 if(ForEachDownward(ucb, user_data)==eStop) return eStop;
  541. //             } while(GoSibling());
  542. //             GoParent();
  543. //         }
  544. //     case eSkip: break;
  545. //     case eStop: return eStop;
  546. //     }
  547. //     return eCont;
  548. // }
  549. // CTreeConstIterator::EAction
  550. // CTreeConstIterator::ForEachDownwardLimited(C4Each& cb, int levels)
  551. // {
  552. //     if(levels > 0) {
  553. //         switch( cb.Execute(m_node) ) {
  554. //         default:
  555. //         case eCont:
  556. //             if(!m_node->IsTerminal()) {
  557. //                 switch( cb.LevelBegin(m_node) ) {
  558. //                 case eStop: return eStop;
  559. //                 default:
  560. //                 case eCont:
  561. //                     if(GoChild()) {
  562. //                         do {
  563. //                             if(ForEachDownwardLimited(cb, levels-1)==eStop)
  564. //                                 return eStop;
  565. //                         } while(GoSibling());
  566. //                     }
  567. //                 case eSkip: // Means skip this level
  568. //                     break;
  569. //                 }
  570. //                 GoParent();
  571. //                 if( cb.LevelEnd(m_node) == eStop )
  572. //                     return eStop;
  573. //             }
  574. //         case eSkip: break;
  575. //         case eStop: return eStop;
  576. //         }
  577. //     }
  578. //     return eCont;
  579. // }
  580. // CTreeConstIterator::EAction
  581. // CTreeConstIterator::ForEachDownwardLimited( ForEachFunc ucb,
  582. //                                             void* user_data, int levels)
  583. // {
  584. //     if(levels > 0) {
  585. //         switch( (*ucb)(m_node, user_data) ) {
  586. //         default:
  587. //         case eCont:
  588. //             if(GoChild()) {
  589. //                 do {
  590. //                     if(ForEachDownwardLimited(ucb, user_data,
  591. //                                               levels-1)==eStop)
  592. //                         return eStop;
  593. //                 } while(GoSibling());
  594. //                 GoParent();
  595. //             }
  596. //         case eSkip: break;
  597. //         case eStop: return eStop;
  598. //         }
  599. //     }
  600. //     return eCont;
  601. // }
  602. // add child preserving the sorting order
  603. bool CTreeIterator::AddChild(CTreeContNodeBase* new_node, 
  604.                              CTreeIterator::CSortPredicate& pred )
  605. {
  606.     // Temporary 
  607.     CTreeContNodeBase* prev;
  608.     CTreeContNodeBase* next;
  609.     
  610.     if( GoChild() ) {
  611.         new_node->m_child = 0;
  612.         new_node->m_parent = m_node->Parent();
  613.         prev = 0;
  614.         next = GetNode();
  615.         while( next && pred.Execute( next, new_node ) ) {
  616.             prev = next;
  617.             next = prev->Sibling();
  618.         }
  619.         new_node->m_sibling = next;
  620.         if( prev ) { // insert after prevtmp
  621.             prev->m_sibling = new_node;
  622.         } else { // insert as first child
  623.             prev->Parent()->m_child = next;
  624.         }
  625.         // Restore state
  626.         GoParent();
  627.     } else {
  628.         return AddChild( new_node );
  629.     }
  630.     return true;
  631. }
  632. void CTreeIterator::SortChildren( CTreeIterator::CSortPredicate& pred )
  633. {
  634.     // Sorting the list by insertion
  635.     CTreeContNodeBase* prev;
  636.     CTreeContNodeBase* next;
  637.     CTreeContNodeBase* tmp;
  638.     CTreeContNodeBase* prevtmp;
  639.     
  640.     if( GoChild() ) {
  641.         prev = GetNode();
  642.         if( GoSibling() ) {
  643.             next = GetNode();
  644.             while( next ) {
  645.                 if( !pred.Execute( prev, next ) ) { // The order is not right
  646.                     tmp = prev->Parent()->Child();
  647.                     prevtmp = 0;
  648.                     while( tmp != prev && pred.Execute( tmp, next ) &&
  649.                            (prevtmp = tmp) && (tmp = tmp->Sibling()) );
  650.                     if( tmp ) {
  651.                         // Move from prev place
  652.                         prev->m_sibling = next->m_sibling;
  653.                         if( prevtmp ) { // insert after prevtmp
  654.                             next->m_sibling = prevtmp->m_sibling;
  655.                             prevtmp->m_sibling = next;
  656.                         } else { // insert as first child
  657.                             next->m_sibling = prev->Parent()->Child();
  658.                             prev->Parent()->m_child = next;
  659.                         }
  660.                     }
  661.                 } else { // the oreder is right, move to the next
  662.                     prev = next;
  663.                 }
  664.                 next = prev->Sibling();
  665.             }
  666.         }
  667.         // Restore state
  668.         GoParent();
  669.     }
  670. }
  671. class CLevelSort : public CTreeIterator::C4Each {
  672. public:
  673.     CLevelSort( CTreeIterator::CSortPredicate& pred, CTreeCont* tree )
  674.         : m_pred(pred), m_tree(tree) {}
  675.     virtual CTreeIterator::EAction Execute(CTreeContNodeBase* pNode) {
  676.         CTreeIterator::EAction retc = CTreeIterator::eCont;
  677.         CTreeIterator* it = m_tree->GetIterator();
  678.         if( it->GoNode( pNode ) ) {
  679.             it->SortChildren( m_pred );
  680.         } else {
  681.             retc = CTreeIterator::eSkip;
  682.         }
  683.         delete it;
  684.         return retc;
  685.     }
  686. private:
  687.     CTreeIterator::CSortPredicate& m_pred;
  688.     CTreeCont*                     m_tree;
  689. };
  690. void
  691. CTreeIterator::SortAllChildrenInSubtree( CTreeIterator::CSortPredicate& pred )
  692. {
  693.     CLevelSort sorter( pred, m_tree );
  694.     ForEachDownward( sorter );
  695. }
  696. CTreeIterator::EAction
  697. CTreeIterator::ForEachUpward(C4Each& cb)
  698. {
  699.     if(!m_node->IsTerminal()) {
  700.         switch( cb.LevelBegin(m_node) ) {
  701.         case eStop: return eStop;
  702.         default:
  703.         case eCont:
  704.             if(GoChild()) {
  705.                 do {
  706.                     if(ForEachUpward(cb)==eStop)
  707.                         return eStop;
  708.                 } while(GoSibling());
  709.             }
  710.         case eSkip: // Means skip this level
  711.             break;
  712.         }
  713.         GoParent();
  714.         if( cb.LevelEnd(m_node) == eStop )
  715.             return eStop;
  716.     }
  717.     return cb.Execute(m_node);
  718. }
  719. CTreeIterator::EAction
  720. CTreeIterator::ForEachUpward(ForEachFunc ucb, void* user_data)
  721. {
  722.     if(GoChild()) {
  723.         do {
  724.             if(ForEachUpward(ucb, user_data)==eStop)
  725.                 return eStop;
  726.         } while(GoSibling());
  727.         GoParent();
  728.     }
  729.     return (*ucb)(m_node, user_data);
  730. }
  731. CTreeIterator::EAction
  732. CTreeIterator::ForEachUpwardLimited(C4Each& cb, int levels)
  733. {
  734.     if(levels > 0) {
  735.         if(!m_node->IsTerminal()) {
  736.             switch( cb.LevelBegin(m_node) ) {
  737.             case eStop: return eStop;
  738.             default:
  739.             case eCont:
  740.                 if(GoChild()) {
  741.                     do {
  742.                         if(ForEachUpwardLimited(cb, levels-1)==eStop)
  743.                             return eStop;
  744.                     } while(GoSibling());
  745.                 }
  746.             case eSkip: // Means skip this level
  747.                 break;
  748.             }
  749.             GoParent();
  750.             if( cb.LevelEnd(m_node) == eStop )
  751.                 return eStop;
  752.         }
  753.         return cb.Execute(m_node);
  754.     }
  755.     return eCont;
  756. }
  757. CTreeIterator::EAction
  758. CTreeIterator::ForEachUpwardLimited(ForEachFunc ucb, void* user_data,
  759.                                     int levels)
  760. {
  761.     if(levels > 0) {
  762.         if(GoChild()) {
  763.             do {
  764.                 if(ForEachUpwardLimited(ucb, user_data,
  765.                                         levels-1)==eStop)
  766.                     return eStop;
  767.             } while(GoSibling());
  768.             GoParent();
  769.         }
  770.         return (*ucb)(m_node, user_data);
  771.     }
  772.     return eCont;
  773. }
  774. // CTreeConstIterator::EAction
  775. // CTreeConstIterator::ForEachUpward(C4Each& cb)
  776. // {
  777. //     if(!m_node->IsTerminal()) {
  778. //         switch( cb.LevelBegin(m_node) ) {
  779. //         case eStop: return eStop;
  780. //         default:
  781. //         case eCont:
  782. //             if(GoChild()) {
  783. //                 do {
  784. //                     if(ForEachUpward(cb)==eStop)
  785. //                         return eStop;
  786. //                 } while(GoSibling());
  787. //             }
  788. //         case eSkip: // Means skip this level
  789. //             break;
  790. //         }
  791. //         GoParent();
  792. //         if( cb.LevelEnd(m_node) == eStop )
  793. //             return eStop;
  794. //     }
  795. //     return cb.Execute(m_node);
  796. // }
  797. // CTreeConstIterator::EAction
  798. // CTreeConstIterator::ForEachUpward(ForEachFunc ucb, void* user_data)
  799. // {
  800. //     if(GoChild()) {
  801. //         do {
  802. //             if(ForEachUpward(ucb, user_data)==eStop)
  803. //                 return eStop;
  804. //         } while(GoSibling());
  805. //         GoParent();
  806. //     }
  807. //     return (*ucb)(m_node, user_data);
  808. // }
  809. // CTreeConstIterator::EAction
  810. // CTreeConstIterator::ForEachUpwardLimited(C4Each& cb, int levels)
  811. // {
  812. //     if(levels > 0) {
  813. //         if(!m_node->IsTerminal()) {
  814. //             switch( cb.LevelBegin(m_node) ) {
  815. //             case eStop: return eStop;
  816. //             default:
  817. //             case eCont:
  818. //                 if(GoChild()) {
  819. //                     do {
  820. //                         if(ForEachUpwardLimited(cb, levels-1)==eStop)
  821. //                             return eStop;
  822. //                     } while(GoSibling());
  823. //                 }
  824. //             case eSkip: // Means skip this level
  825. //                 break;
  826. //             }
  827. //             GoParent();
  828. //             if( cb.LevelEnd(m_node) == eStop )
  829. //                 return eStop;
  830. //         }
  831. //         return cb.Execute(m_node);
  832. //     }
  833. //     return eCont;
  834. // }
  835. // CTreeConstIterator::EAction
  836. // CTreeConstIterator::ForEachUpwardLimited(ForEachFunc ucb, void* user_data,
  837. //                                          int levels)
  838. // {
  839. //     if(levels > 0) {
  840. //         if(GoChild()) {
  841. //             do {
  842. //                 if(ForEachUpwardLimited(ucb, user_data,
  843. //                                         levels-1)==eStop)
  844. //                     return eStop;
  845. //             } while(GoSibling());
  846. //             GoParent();
  847. //         }
  848. //         return (*ucb)(m_node, user_data);
  849. //     }
  850. //     return eCont;
  851. // }
  852. END_objects_SCOPE
  853. END_NCBI_SCOPE
  854. /*
  855.  * $Log: ctreecont.cpp,v $
  856.  * Revision 1000.1  2004/06/01 19:35:13  gouriano
  857.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.5
  858.  *
  859.  * Revision 6.5  2004/05/19 17:27:10  gorelenk
  860.  * Added include of PCH - ncbi_pch.hpp
  861.  *
  862.  * Revision 6.4  2003/05/06 19:53:53  domrach
  863.  * New functions and interfaces for traversing the cached partial taxonomy tree introduced. Convenience functions GetDivisionName() and GetRankName() were added
  864.  *
  865.  * Revision 6.3  2002/10/22 22:15:41  vakatov
  866.  * Get rid of a compilation warning
  867.  *
  868.  * Revision 6.2  2002/01/31 00:31:26  vakatov
  869.  * Follow the renaming of "CTreeCont.hpp" to "ctreecont.hpp".
  870.  * Get rid of "std::" which is unnecessary and sometimes un-compilable.
  871.  * Also done some source identation/beautification.
  872.  *
  873.  * Revision 6.1  2002/01/30 16:13:37  domrach
  874.  * Changes made to pass through MSVC compiler. Some src files renamed
  875.  *
  876.  * Revision 6.1  2002/01/28 19:56:11  domrach
  877.  * Initial checkin of the library implementation files
  878.  *
  879.  */