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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: iterator.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:38:38  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.30
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef ITERATOR__HPP
  10. #define ITERATOR__HPP
  11. /*  $Id: iterator.hpp,v 1000.1 2004/06/01 19:38:38 gouriano Exp $
  12. * ===========================================================================
  13. *
  14. *                            PUBLIC DOMAIN NOTICE
  15. *               National Center for Biotechnology Information
  16. *
  17. *  This software/database is a "United States Government Work" under the
  18. *  terms of the United States Copyright Act.  It was written as part of
  19. *  the author's official duties as a United States Government employee and
  20. *  thus cannot be copyrighted.  This software/database is freely available
  21. *  to the public for use. The National Library of Medicine and the U.S.
  22. *  Government have not placed any restriction on its use or reproduction.
  23. *
  24. *  Although all reasonable efforts have been taken to ensure the accuracy
  25. *  and reliability of the software and data, the NLM and the U.S.
  26. *  Government do not and cannot warrant the performance or results that
  27. *  may be obtained by using this software or data. The NLM and the U.S.
  28. *  Government disclaim all warranties, express or implied, including
  29. *  warranties of performance, merchantability or fitness for any particular
  30. *  purpose.
  31. *
  32. *  Please cite the author in any work or product based on this material.
  33. *
  34. * ===========================================================================
  35. *
  36. * Author: Eugene Vasilchenko
  37. *
  38. * File Description:
  39. *   Iterators through object hierarchy
  40. */
  41. #include <corelib/ncbistd.hpp>
  42. #include <corelib/ncbiutil.hpp>
  43. #include <serial/exception.hpp>
  44. #include <serial/objecttype.hpp>
  45. #include <serial/serialutil.hpp>
  46. #include <serial/serialbase.hpp>
  47. #include <set>
  48. #include <stack>
  49. /** @addtogroup ObjHierarchy
  50.  *
  51.  * @{
  52.  */
  53. BEGIN_NCBI_SCOPE
  54. class CTreeIterator;
  55. // class holding information about root of non-modifiable object hierarchy
  56. // Do not use it directly
  57. class NCBI_XSERIAL_EXPORT CBeginInfo : public pair<TObjectPtr, TTypeInfo>
  58. {
  59.     typedef pair<TObjectPtr, TTypeInfo> CParent;
  60. public:
  61.     typedef CObjectInfo TObjectInfo;
  62.     CBeginInfo(TObjectPtr objectPtr, TTypeInfo typeInfo,
  63.                bool detectLoops = false)
  64.         : CParent(objectPtr, typeInfo), m_DetectLoops(detectLoops)
  65.         {
  66.         }
  67.     CBeginInfo(const CObjectInfo& object,
  68.                bool detectLoops = false)
  69.         : CParent(object.GetObjectPtr(), object.GetTypeInfo()),
  70.           m_DetectLoops(detectLoops)
  71.         {
  72.         }
  73.     CBeginInfo(CSerialObject& object, bool detectLoops = false)
  74.         : CParent(&object, object.GetThisTypeInfo()),
  75.           m_DetectLoops(detectLoops)
  76.         {
  77.         }
  78.     bool m_DetectLoops;
  79. };
  80. // class holding information about root of non-modifiable object hierarchy
  81. // Do not use it directly
  82. class NCBI_XSERIAL_EXPORT CConstBeginInfo : public pair<TConstObjectPtr, TTypeInfo>
  83. {
  84.     typedef pair<TConstObjectPtr, TTypeInfo> CParent;
  85. public:
  86.     typedef CConstObjectInfo TObjectInfo;
  87.     CConstBeginInfo(TConstObjectPtr objectPtr, TTypeInfo typeInfo,
  88.                     bool detectLoops = false)
  89.         : CParent(objectPtr, typeInfo), m_DetectLoops(detectLoops)
  90.         {
  91.         }
  92.     CConstBeginInfo(const CConstObjectInfo& object,
  93.                     bool detectLoops = false)
  94.         : CParent(object.GetObjectPtr(), object.GetTypeInfo()),
  95.           m_DetectLoops(detectLoops)
  96.         {
  97.         }
  98.     CConstBeginInfo(const CSerialObject& object,
  99.                     bool detectLoops = false)
  100.         : CParent(&object, object.GetThisTypeInfo()),
  101.           m_DetectLoops(detectLoops)
  102.         {
  103.         }
  104.     CConstBeginInfo(const CBeginInfo& beginInfo)
  105.         : CParent(beginInfo.first, beginInfo.second),
  106.           m_DetectLoops(beginInfo.m_DetectLoops)
  107.         {
  108.         }
  109.     bool m_DetectLoops;
  110. };
  111. // class describing stack level of traversal
  112. // do not use it directly
  113. class NCBI_XSERIAL_EXPORT CConstTreeLevelIterator {
  114. public:
  115.     typedef CConstBeginInfo TBeginInfo;
  116.     typedef TBeginInfo::TObjectInfo TObjectInfo;
  117.     
  118.     virtual ~CConstTreeLevelIterator(void);
  119.     virtual bool Valid(void) const = 0;
  120.     virtual void Next(void) = 0;
  121.     virtual bool CanGet(void) const
  122.     {
  123.         return true;
  124.     }
  125.     virtual TObjectInfo Get(void) const = 0;
  126.     static CConstTreeLevelIterator* Create(const TObjectInfo& object);
  127.     static CConstTreeLevelIterator* CreateOne(const TObjectInfo& object);
  128.     static bool HaveChildren(const CConstObjectInfo& object);
  129. };
  130. class NCBI_XSERIAL_EXPORT CTreeLevelIterator
  131. {
  132. public:
  133.     typedef CBeginInfo TBeginInfo;
  134.     typedef TBeginInfo::TObjectInfo TObjectInfo;
  135.     virtual ~CTreeLevelIterator(void);
  136.     virtual bool Valid(void) const = 0;
  137.     virtual void Next(void) = 0;
  138.     virtual bool CanGet(void) const
  139.     {
  140.         return true;
  141.     }
  142.     virtual TObjectInfo Get(void) const = 0;
  143.     static CTreeLevelIterator* Create(const TObjectInfo& object);
  144.     static CTreeLevelIterator* CreateOne(const TObjectInfo& object);
  145.     virtual void Erase(void);
  146. };
  147. // CTreeIterator is base class for all iterators over non-modifiable object
  148. // Do not use it directly
  149. template<class LevelIterator>
  150. class CTreeIteratorTmpl
  151. {
  152.     typedef CTreeIteratorTmpl<LevelIterator> TThis;
  153. public:
  154.     typedef typename LevelIterator::TObjectInfo TObjectInfo;
  155.     typedef typename LevelIterator::TBeginInfo TBeginInfo;
  156.     typedef set<TConstObjectPtr> TVisitedObjects;
  157.     // construct object iterator
  158.     CTreeIteratorTmpl(void)
  159.         {
  160.             _DEBUG_ARG(m_LastCall = eNone);
  161.         }
  162.     CTreeIteratorTmpl(const TBeginInfo& beginInfo)
  163.         {
  164.             _DEBUG_ARG(m_LastCall = eNone);
  165.             Init(beginInfo);
  166.         }
  167.     virtual ~CTreeIteratorTmpl(void)
  168.         {
  169.             Reset();
  170.         }
  171.     // get information about current object
  172.     TObjectInfo& Get(void)
  173.         {
  174.             _ASSERT(CheckValid());
  175.             return m_CurrentObject;
  176.         }
  177.     // get information about current object
  178.     const TObjectInfo& Get(void) const
  179.         {
  180.             _ASSERT(CheckValid());
  181.             return m_CurrentObject;
  182.         }
  183.     // get type information of current object
  184.     TTypeInfo GetCurrentTypeInfo(void) const
  185.         {
  186.             return Get().GetTypeInfo();
  187.         }
  188.     // reset iterator to initial state
  189.     void Reset(void)
  190.         {
  191.             m_CurrentObject.Reset();
  192.             m_VisitedObjects.reset(0);
  193.             _DEBUG_ARG(m_LastCall = eNone);
  194.             while ( !m_Stack.empty() )
  195.                 m_Stack.pop();
  196.             _ASSERT(!*this);
  197.         }
  198.     void Next(void)
  199.         {
  200.             _ASSERT(CheckValid());
  201.             m_CurrentObject.Reset();
  202.             _ASSERT(!m_Stack.empty());
  203.             if ( Step(m_Stack.top()->Get()) )
  204.                 Walk();
  205.         }
  206.     void SkipSubTree(void)
  207.         {
  208.             _ASSERT(CheckValid());
  209.             m_Stack.push(AutoPtr<LevelIterator>(LevelIterator::CreateOne(TObjectInfo())));
  210.         }
  211.     // check whether iterator is not finished
  212.     operator bool(void) const
  213.         {
  214.             _DEBUG_ARG(m_LastCall = eValid);
  215.             return CheckValid();
  216.         }
  217.     // check whether iterator is not finished
  218.     bool operator!(void) const
  219.         {
  220.             _DEBUG_ARG(m_LastCall = eValid);
  221.             return !CheckValid();
  222.         }
  223.     // go to next object
  224.     TThis& operator++(void)
  225.         {
  226.             Next();
  227.             return *this;
  228.         }
  229.     // initialize iterator to new root of object hierarchy
  230.     TThis& operator=(const TBeginInfo& beginInfo)
  231.         {
  232.             Init(beginInfo);
  233.             return *this;
  234.         }
  235. protected:
  236.     bool CheckValid(void) const
  237.         {
  238. #if _DEBUG
  239.             if ( m_LastCall != eValid)
  240.                 ReportNonValid();
  241. #endif
  242.             return m_CurrentObject;
  243.         }
  244.     void ReportNonValid(void) const
  245.         {
  246.             ERR_POST("Object iterator was used without checking its validity");
  247.         }
  248.     virtual bool CanSelect(const CConstObjectInfo& obj)
  249.         {
  250.             if ( !obj )
  251.                 return false;
  252.             TVisitedObjects* visitedObjects = m_VisitedObjects.get();
  253.             if ( visitedObjects ) {
  254.                 if ( !visitedObjects->insert(obj.GetObjectPtr()).second ) {
  255.                     // already visited
  256.                     return false;
  257.                 }
  258.             }
  259.             return true;
  260.         }
  261.     virtual bool CanEnter(const CConstObjectInfo& object)
  262.         {
  263.             return CConstTreeLevelIterator::HaveChildren(object);
  264.         }
  265. protected:
  266.     // have to make these methods protected instead of private due to
  267.     // bug in GCC
  268. #ifdef NCBI_OS_MSWIN
  269.     CTreeIteratorTmpl(const TThis&) { NCBI_THROW(CSerialException,eIllegalCall, "cannot copy"); }
  270.     TThis& operator=(const TThis&) { NCBI_THROW(CSerialException,eIllegalCall, "cannot copy"); }
  271. #else
  272.     CTreeIteratorTmpl(const TThis&);
  273.     TThis& operator=(const TThis&);
  274. #endif
  275.     void Init(const TBeginInfo& beginInfo)
  276.         {
  277.             Reset();
  278.             if ( !beginInfo.first || !beginInfo.second )
  279.                 return;
  280.             if ( beginInfo.m_DetectLoops )
  281.                 m_VisitedObjects.reset(new TVisitedObjects);
  282.             m_Stack.push(AutoPtr<LevelIterator>(LevelIterator::CreateOne(beginInfo)));
  283.             Walk();
  284.         }
  285. private:
  286.     bool Step(const TObjectInfo& current)
  287.         {
  288.             if ( CanEnter(current) ) {
  289.                 AutoPtr<LevelIterator> nextLevel(LevelIterator::Create(current));
  290.                 if ( nextLevel && nextLevel->Valid() ) {
  291.                     m_Stack.push(nextLevel);
  292.                     return true;
  293.                 }
  294.             }
  295.             // skip all finished iterators
  296.             _ASSERT(!m_Stack.empty());
  297.             do {
  298.                 m_Stack.top()->Next();
  299.                 if ( m_Stack.top()->Valid() ) {
  300.                     // next child on this level
  301.                     return true;
  302.                 }
  303.                 m_Stack.pop();
  304.             } while ( !m_Stack.empty() );
  305.             return false;
  306.         }
  307.     void Walk(void)
  308.         {
  309.             _ASSERT(!m_Stack.empty());
  310.             TObjectInfo current;
  311.             do {
  312.                 while (!m_Stack.top()->CanGet()) {
  313.                     for(;;) {
  314.                         m_Stack.top()->Next();
  315.                         if (m_Stack.top()->Valid()) {
  316.                             break;
  317.                         }
  318.                         m_Stack.pop();
  319.                         if (m_Stack.empty()) {
  320.                             return;
  321.                         }
  322.                     }
  323.                 }
  324.                 current = m_Stack.top()->Get();
  325.                 if ( CanSelect(current) ) {
  326.                     m_CurrentObject = current;
  327.                     return;
  328.                 }
  329.             } while ( Step(current) );
  330.         }
  331. #if _DEBUG
  332.     mutable enum { eNone, eValid, eNext, eErase } m_LastCall;
  333. #endif
  334.     // stack of tree level iterators
  335.     stack< AutoPtr<LevelIterator> > m_Stack;
  336.     // currently selected object
  337.     TObjectInfo m_CurrentObject;
  338.     auto_ptr<TVisitedObjects> m_VisitedObjects;
  339.     friend class CTreeIterator;
  340. };
  341. typedef CTreeIteratorTmpl<CConstTreeLevelIterator> CTreeConstIterator;
  342. // CTreeIterator is base class for all iterators over modifiable object
  343. class NCBI_XSERIAL_EXPORT CTreeIterator : public CTreeIteratorTmpl<CTreeLevelIterator>
  344. {
  345.     typedef CTreeIteratorTmpl<CTreeLevelIterator> CParent;
  346. public:
  347.     typedef CParent::TObjectInfo TObjectInfo;
  348.     typedef CParent::TBeginInfo TBeginInfo;
  349.     // construct object iterator
  350.     CTreeIterator(void)
  351.         {
  352.         }
  353.     CTreeIterator(const TBeginInfo& beginInfo)
  354.         {
  355.             Init(beginInfo);
  356.         }
  357.     // initialize iterator to new root of object hierarchy
  358.     CTreeIterator& operator=(const TBeginInfo& beginInfo)
  359.         {
  360.             Init(beginInfo);
  361.             return *this;
  362.         }
  363.     // delete currently pointed object (throws exception if failed)
  364.     void Erase(void);
  365. };
  366. // template base class for CTypeIterator<> and CTypeConstIterator<>
  367. // Do not use it directly
  368. template<class Parent>
  369. class CTypeIteratorBase : public Parent
  370. {
  371.     typedef Parent CParent;
  372. protected:
  373.     typedef typename CParent::TBeginInfo TBeginInfo;
  374.     CTypeIteratorBase(TTypeInfo needType)
  375.         : m_NeedType(needType)
  376.         {
  377.         }
  378.     CTypeIteratorBase(TTypeInfo needType, const TBeginInfo& beginInfo)
  379.         : m_NeedType(needType)
  380.         {
  381.             Init(beginInfo);
  382.         }
  383.     virtual bool CanSelect(const CConstObjectInfo& object)
  384.         {
  385.             return CParent::CanSelect(object) &&
  386.                 object.GetTypeInfo()->IsType(m_NeedType);
  387.         }
  388.     virtual bool CanEnter(const CConstObjectInfo& object)
  389.         {
  390.             return CParent::CanEnter(object) &&
  391.                 object.GetTypeInfo()->MayContainType(m_NeedType);
  392.         }
  393.     TTypeInfo GetIteratorType(void) const
  394.         {
  395.             return m_NeedType;
  396.         }
  397. private:
  398.     TTypeInfo m_NeedType;
  399. };
  400. // template base class for CTypeIterator<> and CTypeConstIterator<>
  401. // Do not use it directly
  402. template<class Parent>
  403. class CLeafTypeIteratorBase : public CTypeIteratorBase<Parent>
  404. {
  405.     typedef CTypeIteratorBase<Parent> CParent;
  406. protected:
  407.     typedef typename CParent::TBeginInfo TBeginInfo;
  408.     CLeafTypeIteratorBase(TTypeInfo needType)
  409.         : CParent(needType)
  410.         {
  411.         }
  412.     CLeafTypeIteratorBase(TTypeInfo needType, const TBeginInfo& beginInfo)
  413.         : CParent(needType)
  414.         {
  415.             Init(beginInfo);
  416.         }
  417.     virtual bool CanSelect(const CConstObjectInfo& object);
  418. };
  419. // template base class for CTypesIterator and CTypesConstIterator
  420. // Do not use it directly
  421. template<class Parent>
  422. class CTypesIteratorBase : public Parent
  423. {
  424.     typedef Parent CParent;
  425. public:
  426.     typedef typename CParent::TBeginInfo TBeginInfo;
  427.     typedef list<TTypeInfo> TTypeList;
  428.     CTypesIteratorBase(void)
  429.         {
  430.         }
  431.     CTypesIteratorBase(TTypeInfo type)
  432.         {
  433.             m_TypeList.push_back(type);
  434.         }
  435.     CTypesIteratorBase(TTypeInfo type1, TTypeInfo type2)
  436.         {
  437.             m_TypeList.push_back(type1);
  438.             m_TypeList.push_back(type2);
  439.         }
  440.     CTypesIteratorBase(const TTypeList& typeList)
  441.         : m_TypeList(typeList)
  442.         {
  443.         }
  444.     CTypesIteratorBase(const TTypeList& typeList, const TBeginInfo& beginInfo)
  445.         : m_TypeList(typeList)
  446.         {
  447.             Init(beginInfo);
  448.         }
  449.     const TTypeList& GetTypeList(void) const
  450.         {
  451.             return m_TypeList;
  452.         }
  453.     CTypesIteratorBase<Parent>& AddType(TTypeInfo type)
  454.         {
  455.             m_TypeList.push_back(type);
  456.             return *this;
  457.         }
  458.     CTypesIteratorBase<Parent>& operator=(const TBeginInfo& beginInfo)
  459.         {
  460.             Init(beginInfo);
  461.             return *this;
  462.         }
  463.     typename CParent::TObjectInfo::TObjectPtrType GetFoundPtr(void) const
  464.         {
  465.             return this->Get().GetObjectPtr();
  466.         }
  467.     TTypeInfo GetFoundType(void) const
  468.         {
  469.             return this->Get().GetTypeInfo();
  470.         }
  471.     TTypeInfo GetMatchType(void) const
  472.         {
  473.             return m_MatchType;
  474.         }
  475. protected:
  476. #if 0
  477. // There is an (unconfirmed) opinion that putting these two functions
  478. // into source (iterator.cpp) reduces the size of an executable.
  479. // Still, keeping them there is reported as bug by
  480. // Metrowerks Codewarrior 9.0 (Mac OSX)
  481.     virtual bool CanSelect(const CConstObjectInfo& object);
  482.     virtual bool CanEnter(const CConstObjectInfo& object);
  483. #else
  484.     virtual bool CanSelect(const CConstObjectInfo& object)
  485.     {
  486.         if ( !CParent::CanSelect(object) )
  487.             return false;
  488.         m_MatchType = 0;
  489.         TTypeInfo type = object.GetTypeInfo();
  490.         ITERATE ( TTypeList, i, GetTypeList() ) {
  491.             if ( type->IsType(*i) ) {
  492.                 m_MatchType = *i;
  493.                 return true;
  494.             }
  495.         }
  496.         return false;
  497.     }
  498.     virtual bool CanEnter(const CConstObjectInfo& object)
  499.     {
  500.         if ( !CParent::CanEnter(object) )
  501.             return false;
  502.         TTypeInfo type = object.GetTypeInfo();
  503.         ITERATE ( TTypeList, i, GetTypeList() ) {
  504.             if ( type->MayContainType(*i) )
  505.                 return true;
  506.         }
  507.         return false;
  508.     }
  509. #endif
  510. private:
  511.     TTypeList m_TypeList;
  512.     TTypeInfo m_MatchType;
  513. };
  514. // template class for iteration on objects of class C
  515. template<class C, class TypeGetter = C>
  516. class CTypeIterator : public CTypeIteratorBase<CTreeIterator>
  517. {
  518.     typedef CTypeIteratorBase<CTreeIterator> CParent;
  519. public:
  520.     typedef typename CParent::TBeginInfo TBeginInfo;
  521.     CTypeIterator(void)
  522.         : CParent(TypeGetter::GetTypeInfo())
  523.         {
  524.         }
  525.     CTypeIterator(const TBeginInfo& beginInfo)
  526.         : CParent(TypeGetter::GetTypeInfo(), beginInfo)
  527.         {
  528.         }
  529.     explicit CTypeIterator(CSerialObject& object)
  530.         : CParent(TypeGetter::GetTypeInfo(), TBeginInfo(object))
  531.         {
  532.         }
  533.     CTypeIterator<C, TypeGetter>& operator=(const TBeginInfo& beginInfo)
  534.         {
  535.             Init(beginInfo);
  536.             return *this;
  537.         }
  538.     C& operator*(void)
  539.         {
  540.             return *CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  541.         }
  542.     const C& operator*(void) const
  543.         {
  544.             return *CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  545.         }
  546.     C* operator->(void)
  547.         {
  548.             return CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  549.         }
  550.     const C* operator->(void) const
  551.         {
  552.             return CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  553.         }
  554. };
  555. // template class for iteration on objects of class C (non-medifiable version)
  556. template<class C, class TypeGetter = C>
  557. class CTypeConstIterator : public CTypeIteratorBase<CTreeConstIterator>
  558. {
  559.     typedef CTypeIteratorBase<CTreeConstIterator> CParent;
  560. public:
  561.     typedef typename CParent::TBeginInfo TBeginInfo;
  562.     CTypeConstIterator(void)
  563.         : CParent(TypeGetter::GetTypeInfo())
  564.         {
  565.         }
  566.     CTypeConstIterator(const TBeginInfo& beginInfo)
  567.         : CParent(TypeGetter::GetTypeInfo(), beginInfo)
  568.         {
  569.         }
  570.     explicit CTypeConstIterator(const CSerialObject& object)
  571.         : CParent(TypeGetter::GetTypeInfo(), TBeginInfo(object))
  572.         {
  573.         }
  574.     CTypeConstIterator<C, TypeGetter>& operator=(const TBeginInfo& beginInfo)
  575.         {
  576.             Init(beginInfo);
  577.             return *this;
  578.         }
  579.     const C& operator*(void) const
  580.         {
  581.             return *CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  582.         }
  583.     const C* operator->(void) const
  584.         {
  585.             return CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  586.         }
  587. };
  588. // template class for iteration on objects of class C
  589. template<class C>
  590. class CLeafTypeIterator : public CLeafTypeIteratorBase<CTreeIterator>
  591. {
  592.     typedef CLeafTypeIteratorBase<CTreeIterator> CParent;
  593. public:
  594.     typedef typename CParent::TBeginInfo TBeginInfo;
  595.     CLeafTypeIterator(void)
  596.         : CParent(C::GetTypeInfo())
  597.         {
  598.         }
  599.     CLeafTypeIterator(const TBeginInfo& beginInfo)
  600.         : CParent(C::GetTypeInfo(), beginInfo)
  601.         {
  602.         }
  603.     explicit CLeafTypeIterator(CSerialObject& object)
  604.         : CParent(C::GetTypeInfo(), TBeginInfo(object))
  605.         {
  606.         }
  607.     CLeafTypeIterator<C>& operator=(const TBeginInfo& beginInfo)
  608.         {
  609.             Init(beginInfo);
  610.             return *this;
  611.         }
  612.     C& operator*(void)
  613.         {
  614.             return *CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  615.         }
  616.     const C& operator*(void) const
  617.         {
  618.             return *CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  619.         }
  620.     C* operator->(void)
  621.         {
  622.             return CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  623.         }
  624.     const C* operator->(void) const
  625.         {
  626.             return CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  627.         }
  628. };
  629. // template class for iteration on objects of class C (non-medifiable version)
  630. template<class C>
  631. class CLeafTypeConstIterator : public CLeafTypeIteratorBase<CTreeConstIterator>
  632. {
  633.     typedef CLeafTypeIteratorBase<CTreeConstIterator> CParent;
  634. public:
  635.     typedef typename CParent::TBeginInfo TBeginInfo;
  636.     CLeafTypeConstIterator(void)
  637.         : CParent(C::GetTypeInfo())
  638.         {
  639.         }
  640.     CLeafTypeConstIterator(const TBeginInfo& beginInfo)
  641.         : CParent(C::GetTypeInfo(), beginInfo)
  642.         {
  643.         }
  644.     explicit CLeafTypeConstIterator(const CSerialObject& object)
  645.         : CParent(C::GetTypeInfo(), TBeginInfo(object))
  646.         {
  647.         }
  648.     CLeafTypeConstIterator<C>& operator=(const TBeginInfo& beginInfo)
  649.         {
  650.             Init(beginInfo);
  651.             return *this;
  652.         }
  653.     const C& operator*(void) const
  654.         {
  655.             return *CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  656.         }
  657.     const C* operator->(void) const
  658.         {
  659.             return CTypeConverter<C>::SafeCast(Get().GetObjectPtr());
  660.         }
  661. };
  662. // template class for iteration on objects of standard C++ type T
  663. template<typename T>
  664. class CStdTypeIterator : public CTypeIterator<T, CStdTypeInfo<T> >
  665. {
  666.     typedef CTypeIterator<T, CStdTypeInfo<T> > CParent;
  667. public:
  668.     typedef typename CParent::TBeginInfo TBeginInfo;
  669.     CStdTypeIterator(void)
  670.         {
  671.         }
  672.     CStdTypeIterator(const TBeginInfo& beginInfo)
  673.         : CParent(beginInfo)
  674.         {
  675.         }
  676.     explicit CStdTypeIterator(CSerialObject& object)
  677.         : CParent(object)
  678.         {
  679.         }
  680.     CStdTypeIterator<T>& operator=(const TBeginInfo& beginInfo)
  681.         {
  682.             Init(beginInfo);
  683.             return *this;
  684.         }
  685. };
  686. // template class for iteration on objects of standard C++ type T
  687. // (non-modifiable version)
  688. template<typename T>
  689. class CStdTypeConstIterator : public CTypeConstIterator<T, CStdTypeInfo<T> >
  690. {
  691.     typedef CTypeConstIterator<T, CStdTypeInfo<T> > CParent;
  692. public:
  693.     typedef typename CParent::TBeginInfo TBeginInfo;
  694.     CStdTypeConstIterator(void)
  695.         {
  696.         }
  697.     CStdTypeConstIterator(const TBeginInfo& beginInfo)
  698.         : CParent(beginInfo)
  699.         {
  700.         }
  701.     explicit CStdTypeConstIterator(const CSerialObject& object)
  702.         : CParent(object)
  703.         {
  704.         }
  705.     CStdTypeConstIterator<T>& operator=(const TBeginInfo& beginInfo)
  706.         {
  707.             Init(beginInfo);
  708.             return *this;
  709.         }
  710. };
  711. // get special typeinfo of CObject
  712. class NCBI_XSERIAL_EXPORT CObjectGetTypeInfo
  713. {
  714. public:
  715.     static TTypeInfo GetTypeInfo(void);
  716. };
  717. // class for iteration on objects derived from class CObject
  718. typedef CTypeIterator<CObject, CObjectGetTypeInfo> CObjectIterator;
  719. // class for iteration on objects derived from class CObject
  720. // (non-modifiable version)
  721. typedef CTypeConstIterator<CObject, CObjectGetTypeInfo> CObjectConstIterator;
  722. // class for iteration on objects of list of types
  723. typedef CTypesIteratorBase<CTreeIterator> CTypesIterator;
  724. // class for iteration on objects of list of types (non-modifiable version)
  725. typedef CTypesIteratorBase<CTreeConstIterator> CTypesConstIterator;
  726. // enum flag for turning on loop detection in object hierarchy
  727. enum EDetectLoops {
  728.     eDetectLoops
  729. };
  730. // get starting point of object hierarchy
  731. template<class C>
  732. inline
  733. CBeginInfo Begin(C& obj)
  734. {
  735.     return CBeginInfo(&obj, C::GetTypeInfo(), false);
  736. }
  737. // get starting point of non-modifiable object hierarchy
  738. template<class C>
  739. inline
  740. CConstBeginInfo ConstBegin(const C& obj)
  741. {
  742.     return CConstBeginInfo(&obj, C::GetTypeInfo(), false);
  743. }
  744. template<class C>
  745. inline
  746. CConstBeginInfo Begin(const C& obj)
  747. {
  748.     return CConstBeginInfo(&obj, C::GetTypeInfo(), false);
  749. }
  750. // get starting point of object hierarchy with loop detection
  751. template<class C>
  752. inline
  753. CBeginInfo Begin(C& obj, EDetectLoops)
  754. {
  755.     return CBeginInfo(&obj, C::GetTypeInfo(), true);
  756. }
  757. // get starting point of non-modifiable object hierarchy with loop detection
  758. template<class C>
  759. inline
  760. CConstBeginInfo ConstBegin(const C& obj, EDetectLoops)
  761. {
  762.     return CConstBeginInfo(&obj, C::GetTypeInfo(), true);
  763. }
  764. template<class C>
  765. inline
  766. CConstBeginInfo Begin(const C& obj, EDetectLoops)
  767. {
  768.     return CConstBeginInfo(&obj, C::GetTypeInfo(), true);
  769. }
  770. /* @} */
  771. //#include <serial/iterator.inl>
  772. END_NCBI_SCOPE
  773. #endif  /* ITERATOR__HPP */
  774. /*
  775.  * ---------------------------------------------------------------------------
  776. * $Log: iterator.hpp,v $
  777. * Revision 1000.1  2004/06/01 19:38:38  gouriano
  778. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.30
  779. *
  780. * Revision 1.30  2004/04/26 16:40:59  ucko
  781. * Tweak for GCC 3.4 compatibility.
  782. *
  783. * Revision 1.29  2003/09/30 17:12:30  gouriano
  784. * Modified TypeIterators to skip unset optional members
  785. *
  786. * Revision 1.28  2003/09/15 20:01:15  gouriano
  787. * fixed the definition of CTypesIteratorBase to eliminate compilation warnings
  788. *
  789. * Revision 1.27  2003/04/15 14:15:21  siyan
  790. * Added doxygen support
  791. *
  792. * Revision 1.26  2003/03/26 16:13:32  vasilche
  793. * Removed TAB symbols. Some formatting.
  794. *
  795. * Revision 1.25  2003/03/10 18:52:37  gouriano
  796. * use new structured exceptions (based on CException)
  797. *
  798. * Revision 1.24  2003/02/04 16:05:48  dicuccio
  799. * Header file clean-up - removed redundant includes
  800. *
  801. * Revision 1.23  2002/12/23 19:02:30  dicuccio
  802. * Moved template function bodies from .cpp -> .hpp to make MSVC happy.  Added an
  803. * #ifdef'd wrapper to unimplemented protected ctors - MSVC doesn't like these.
  804. * Log to end
  805. *
  806. * Revision 1.21  2002/06/13 15:15:19  ucko
  807. * Add [explicit] CSerialObject-based constructors, which should get rid
  808. * of the need for [Const]Begin() in the majority of cases.
  809. *
  810. * Revision 1.20  2001/05/17 14:56:45  lavr
  811. * Typos corrected
  812. *
  813. * Revision 1.19  2000/11/09 15:21:25  vasilche
  814. * Fixed bugs in iterators.
  815. * Added iterator constructors from CObjectInfo.
  816. * Added CLeafTypeIterator.
  817. *
  818. * Revision 1.18  2000/11/08 19:24:17  vasilche
  819. * Added CLeafTypeIterator<Type> and CLeafTypeConstIterator<Type>.
  820. *
  821. * Revision 1.17  2000/10/20 15:51:23  vasilche
  822. * Fixed data error processing.
  823. * Added interface for constructing container objects directly into output stream.
  824. * object.hpp, object.inl and object.cpp were split to
  825. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  826. *
  827. * Revision 1.16  2000/10/03 17:22:32  vasilche
  828. * Reduced header dependency.
  829. * Reduced size of debug libraries on WorkShop by 3 times.
  830. * Fixed tag allocation for parent classes.
  831. * Fixed CObject allocation/deallocation in streams.
  832. * Moved instantiation of several templates in separate source file.
  833. *
  834. * Revision 1.15  2000/09/19 20:16:52  vasilche
  835. * Fixed type in CStlClassInfo_auto_ptr.
  836. * Added missing include serialutil.hpp.
  837. *
  838. * Revision 1.14  2000/09/18 20:00:02  vasilche
  839. * Separated CVariantInfo and CMemberInfo.
  840. * Implemented copy hooks.
  841. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  842. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  843. *
  844. * Revision 1.13  2000/07/03 18:42:33  vasilche
  845. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  846. * Reduced header dependency.
  847. *
  848. * Revision 1.12  2000/06/07 19:45:42  vasilche
  849. * Some code cleaning.
  850. * Macros renaming in more clear way.
  851. * BEGIN_NAMED_*_INFO, ADD_*_MEMBER, ADD_NAMED_*_MEMBER.
  852. *
  853. * Revision 1.11  2000/06/01 19:06:55  vasilche
  854. * Added parsing of XML data.
  855. *
  856. * Revision 1.10  2000/05/24 20:08:12  vasilche
  857. * Implemented XML dump.
  858. *
  859. * Revision 1.9  2000/05/09 16:38:32  vasilche
  860. * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce possible errors.
  861. * Added write context to CObjectOStream.
  862. * Inlined most of methods of helping class Member, Block, ByteBlock etc.
  863. *
  864. * Revision 1.8  2000/05/05 17:59:02  vasilche
  865. * Unfortunately MSVC doesn't support explicit instantiation of template methods.
  866. *
  867. * Revision 1.7  2000/05/05 16:26:51  vasilche
  868. * Simplified iterator templates.
  869. *
  870. * Revision 1.6  2000/05/05 13:08:16  vasilche
  871. * Simplified CTypesIterator interface.
  872. *
  873. * Revision 1.5  2000/05/04 16:23:09  vasilche
  874. * Updated CTypesIterator and CTypesConstInterator interface.
  875. *
  876. * Revision 1.4  2000/04/10 21:01:38  vasilche
  877. * Fixed Erase for map/set.
  878. * Added iteratorbase.hpp header for basic internal classes.
  879. *
  880. * Revision 1.3  2000/03/29 18:02:39  vasilche
  881. * Workaround of bug in MSVC: abstract member in template.
  882. *
  883. * Revision 1.2  2000/03/29 17:22:34  vasilche
  884. * Fixed ambiguity in Begin() template function.
  885. *
  886. * Revision 1.1  2000/03/29 15:55:19  vasilche
  887. * Added two versions of object info - CObjectInfo and CConstObjectInfo.
  888. * Added generic iterators by class -
  889. *  CTypeIterator<class>, CTypeConstIterator<class>,
  890. *  CStdTypeIterator<type>, CStdTypeConstIterator<type>,
  891. *  CObjectsIterator and CObjectsConstIterator.
  892. *
  893. * ===========================================================================
  894. */