#ifndef __ZCPPMAIN__ZCTREEDATA_H__ #define __ZCPPMAIN__ZCTREEDATA_H__ #include "ZCppMain/ZtCObjList.H" namespace ZNsMain { namespace ZNsView { template< typename TypeData, typename TypeSize=int > class ZtCViewTreeData //////////////////////////// { private: void ShowDepth(TypeSize AI_Depth) { __for1(TypeSize, i, AI_Depth) cout<<" "; }/* void ShowDepth(TypeSize AI_Depth)*/ public : ZNsMain::ZNsEnum::ZERun OnDataStart(TypeSize AI_Depth) { ShowDepth(AI_Depth); cout<<"▷ OnDataStart:"< class ZtCViewTreeData //////////////////////////*/ }/* namespace ZNsView*/ namespace ZNsType { /*///////////////////////////////////////////////////////////////////////////////////// ■ class ZtCTypeTreeData 템플릿은 정의에서 또 다른 템플릿(list 등의 컨테이너 템플릿)을 포함하고 있음을 눈여겨 보자. 이것을 ZtCTreeData<> 에서 활용하는 부분은 아래처럼 typedef typename TTypeTreeData::template ZtCTypeClass::TypeData ZCNode1List; typedef typename TTypeTreeData::template ZtCTypeClass::TypeData ZCNode2List; 다소 복잡해 보인다. -- 2011-11-01 14:39:00 /////////////////////////////////////////////////////////////////////////////////////*/ template class ZtCTypeTreeData { public: typedef TTypeSize TypeSize; public: template< typename TType , typename TTypeArg =const TType& , typename TTypeAlloc=ZNsMain::ZCAllocator, typename TTypeInit =ZNsMain::ZtCInit > class ZtCTypeClass ///////////////////////////////// { public: typedef TTypeAlloc TypeAlloc; typedef TTypeInit TypeInit ; public: typedef ZNsMain::ZtCObjList TypeList; ///////////////// public: };/* template< typename TType , typename TTypeArg =const TType& , typename TTypeAlloc=ZNsMain::ZCAllocator, typename TTypeInit =ZNsMain::ZtCInit > class ZtCTypeClass ///////////////////////////////*/ public: };/* template class ZtCTypeTreeData*/ }/* namespace ZNsType*/ template< typename TType , typename TTypeTreeData=ZNsType::ZtCTypeTreeData > class ZtCTreeData /*###########################################*/ { public: class ZCNode1; class ZCNode2; class ZCNodeInfo; public: typedef TType TypeData ; typedef TTypeTreeData TypeTreeData; public: typedef typename TTypeTreeData::TypeSize TypeSize ; typedef typename TTypeTreeData::template ZtCTypeClass::TypeList ZCNode1List ; typedef typename TTypeTreeData::template ZtCTypeClass::TypeList ZCNode2List ; public: typedef ZCNode1 ZCNode ; typedef ZCNode1List ZCNodeList ; public: typedef typename ZCNodeList::ZCLink ZCNodeLink; typedef typename ZCNodeList::iterator IterOfNode; public: class ZCNode1 { public : friend class ZCNodeInfo; private: ZCNode* mp_HighNode ; TypeData mo_TypeData ; ZCNode2List mo_CNodeList; public : ZCNode1() { mp_HighNode=0; }/* ZCNode1()*/ ~ZCNode1() { mp_HighNode=0; }/* ~ZCNode1()*/ ZCNode* GetHighNodePtr () {return (ZCNode*)mp_HighNode;} const ZCNode* GetHighNodePtr ()const{return (ZCNode*)mp_HighNode;} TypeData& GetData () {return mo_TypeData;} const TypeData& GetData ()const{return mo_TypeData;} const ZCNodeList& GetCNodeList()const{return (ZCNodeList&)mo_CNodeList;} TypeSize GetNodeCnt(){return mo_CNodeList.size();} void DeleteCNodeList(){mo_CNodeList.DeleteAll();} void clear (){mo_CNodeList.DeleteAll();} ZCNode& AddSubNode() { ZCNode* VP_CNode=(ZCNode*)&(*mo_CNodeList.AddTailDef()); VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode ; }/* ZCNode& AddSubNode()*/ ZCNodeInfo GetHeadNodeIter() { return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); }/* ZCNodeInfo GetHeadNodeIter()*/ /*////////////////////////////////////////////////////////////////////////////// ■ TViewClass 의 interface ZNsMain::ZNsEnum::ZERun OnDataBody(TypeData, TypeSize AI_Depth, TypeSize AI_Index=0) ZNsMain::ZNsEnum::ZERun OnSubNodeStart(int AI_Depth, int AI_NodeCnt) ZNsMain::ZNsEnum::ZERun OnSubNodeClose(int AI_Depth, int AI_NodeCnt) -- 2011-10-31 21:53:00 //////////////////////////////////////////////////////////////////////////////*/ template ZNsMain::ZNsEnum::ZERun IterPreOrder ( TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0 ) /*##############################################################*/ { const bool CB_DoStop = /////////////////////////////// ( AR_CViewClass.OnDataBody (mo_TypeData, AI_StartDepth, AI_NodeIndex) == ZNsMain::ZNsEnum::ZERun_NO ); ////////////////////////////////////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; TypeSize VL_NodeCnt= ((ZCNodeList&)mo_CNodeList).size () ; IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); if ( AR_CViewClass. ////////////////////////////////////// OnSubNodeStart(AI_StartDepth, VL_NodeCnt)== ZNsMain::ZNsEnum::ZERun_NO ) { return ZNsMain::ZNsEnum::ZERun_NO; } ////////////////////// ++AI_StartDepth; { __for1(TypeSize, i, VL_NodeCnt) { const bool CB_DoStop = ( ((ZCNodeList&)mo_CNodeList).ItD(VO_iter_Node).template IterPreOrder (AR_CViewClass, AI_StartDepth, i) == ZNsMain::ZNsEnum::ZERun_NO ); ////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; ((ZCNodeList&)mo_CNodeList).MoveNextIter(RR(VO_iter_Node)); }/* __for1(TypeSize, i, VL_NodeCnt)*/ } --AI_StartDepth; const ZNsMain::ZNsEnum::ZERun CE_ERun = AR_CViewClass.OnSubNodeClose(AI_StartDepth, VL_NodeCnt); if(CE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return ZNsMain::ZNsEnum::ZERun_NO; ///////////////////// return ZNsMain::ZNsEnum::ZERun_OK; }/* template ZNsMain::ZNsEnum::ZERun IterPreOrder (TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0) ################################################################*/ template ZNsMain::ZNsEnum::ZERun IterPostOrder ( TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0 ) /*###############################################################*/ { TypeSize VL_NodeCnt = ((ZCNodeList&)mo_CNodeList).size () ; IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); if(AR_CViewClass.OnSubNodeStart (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } ++AI_StartDepth; /*####################*/ { __for1(TypeSize, i, VL_NodeCnt) { const bool CB_DoStop = ( ((ZCNodeList&)mo_CNodeList).ItD(VO_iter_Node).template IterPostOrder(AR_CViewClass, AI_StartDepth, i) == ZNsMain::ZNsEnum::ZERun_NO ); ////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; ((ZCNodeList&)mo_CNodeList).MoveNextIter(VO_iter_Node); }/* __for1(TypeSize, i, VL_NodeCnt)*/ } --AI_StartDepth; /*####################*/ if(AR_CViewClass.OnSubNodeClose (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } const bool CB_DoStop = ///////////////////////// ( AR_CViewClass.OnDataBody ( mo_TypeData, AI_StartDepth, AI_NodeIndex ) ==ZNsMain::ZNsEnum::ZERun_NO ) ; //////////////////////////////////////////////// if(CB_DoStop) { return ZNsMain::ZNsEnum::ZERun_NO; } return ZNsMain::ZNsEnum::ZERun_OK; }/* template ZNsMain::ZNsEnum::ZERun IterPostOrder (TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0) #################################################################*/ public: };/* class ZCNode1*/ class ZCNode2 { public : friend class ZCNodeInfo; private: ZCNode* mp_HighNode ; TypeData mo_TypeData ; ZCNode1List mo_CNodeList; public : ZCNode2() { mp_HighNode=0; }/* ZCNode2()*/ ~ZCNode2() { mp_HighNode=0; }/* ~ZCNode2()*/ ZCNode* GetHighNodePtr () {return (ZCNode*)mp_HighNode;} const ZCNode* GetHighNodePtr ()const{return (ZCNode*)mp_HighNode;} TypeData& GetData () {return mo_TypeData ;} const TypeData& GetData ()const{return mo_TypeData ;} const ZCNodeList& GetCNodeList()const{return (ZCNodeList&)mo_CNodeList;} TypeSize GetNodeCnt(){return mo_CNodeList.size();} void DeleteCNodeList(){mo_CNodeList.DeleteAll();} void clear (){mo_CNodeList.DeleteAll();} ZCNode& AddSubNode() { ZCNode* VP_CNode=(ZCNode*)&(*mo_CNodeList.AddTailDef()); VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode ; }/* ZCNode& AddSubNode()*/ ZCNodeInfo GetHeadNodeIter() { return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); }/* ZCNodeInfo GetHeadNodeIter()*/ /*////////////////////////////////////////////////////////////////////////////////////////////// ■ ZCNode1 과 ZCNode2 가 동일한 구조이므로, ZCNode2 에서는 IterPreOrder() 와 IterPostOrder() 를 정의할 필요없다. ZCNode2 이 ZCNode1 로 형변환되어서 ZCNode1 의 IterPreOrder() 와 IterPostOrder() 을 사용할 것이기 때문이다. -- 2011-11-01 10:40:00 //////////////////////////////////////////////////////////////////////////////////////////////*/ public: };/* class ZCNode2*/ class ZCNodeInfo { private: ZCNode* mp_NowNodeWrap; ZCNodeLink* mp_NowNodeLink; public : ZCNodeInfo(ZCNode* AP_CNode=0, ZCNodeLink* AP_CNodeLink=0) { mp_NowNodeWrap=AP_CNode; mp_NowNodeLink=AP_CNodeLink; }/* ZCNodeInfo(ZCNode* AP_CNode=0, ZCNodeLink* AP_CNodeLink=0)*/ ZCNode* GetNowNodeWrap(){return mp_NowNodeWrap;} ZCNodeLink* GetNowNodeLink(){return mp_NowNodeLink;} bool DeleteNode() { if(mp_NowNodeWrap==0 || mp_NowNodeLink==0) return false; ((ZCNodeList&)(mp_NowNodeWrap->mo_CNodeList)). DeleteLink(mp_NowNodeLink); mp_NowNodeLink=0; return true; /////////////// }/* bool DeleteNode()*/ ZCNodeInfo& operator ++ (int) {mp_NowNodeWrap->mo_CNodeList.MoveNextIter(mp_NowNodeLink); return *this;} ZCNode& operator*() {return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} const ZCNode& operator*()const{return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} public: };/* class ZCNodeInfo*/ /*public :*/ private: ZCNode mo_RootNode; public : ZCNode& GetRootNode() {return mo_RootNode;} const ZCNode& GetRootNode()const{return mo_RootNode;} void DeleteAll(){mo_RootNode.clear();} void clear (){mo_RootNode.clear();} /*///////////////////////////////////////////////////////////////////////////////////////// ■ 위 clear() 함수는 mo_RootNode.clear() 를 호출하고 있는데, 만약 mo_RootNode.mo_TypeData 가 컨테이너 인 경우, mo_TypeData 를 추가로 초기화하는 코드가 필요할 수 있다. 이에 대해서 는 CXmlInfo_T<>::clear() 을 참고한다. -- 2012-10-12 13:20:00 /////////////////////////////////////////////////////////////////////////////////////////*/ template void IterPreOrder(TViewClass& AR_CViewClass) { mo_RootNode.template IterPreOrder(AR_CViewClass, 0, 0); }/* template void IterPreOrder(TViewClass& AR_CViewClass) */ template void IterPostOrder(TViewClass& AR_CViewClass) { mo_RootNode.template IterPostOrder(AR_CViewClass, 0, 0); }/* template void IterPostOrder(TViewClass& AR_CViewClass) */ public: };/* template< typename TType , typename TTypeTreeData=ZNsType::ZtCTypeTreeData > class ZtCTreeData #############################################*/ /*/////////////////////////////////////////////////////////////// ■ class ZtCTreeData 예제 -- 2015-08-14 14:00 #include #include "ZCppMain/ZtCTreeData.H" using namespace std ; using namespace ZNsMain; typedef ZtCStringBase CStringBase ; typedef ZtCTreeData CStrTreeData ; typedef CStrTreeData::ZCNode CNodeCStr ; typedef ZNsMain::ZNsView:: ZtCViewTreeData CViewTreeData; int main() { CStringBase VO_CStringBase ; CStrTreeData VO_CStrTreeData ; CViewTreeData VO_CViewTreeData; CNodeCStr& VO_CNodeCStr1 = VO_CStrTreeData.GetRootNode().AddSubNode(); CNodeCStr& VO_CNodeCStr2 = VO_CStrTreeData.GetRootNode().AddSubNode(); CNodeCStr& VO_CNodeCStr3 = VO_CStrTreeData.GetRootNode().AddSubNode(); CNodeCStr& VO_CNodeCStr11 = VO_CNodeCStr1 .AddSubNode(); CNodeCStr& VO_CNodeCStr12 = VO_CNodeCStr1 .AddSubNode(); CNodeCStr& VO_CNodeCStr121= VO_CNodeCStr12.AddSubNode(); CNodeCStr& VO_CNodeCStr122= VO_CNodeCStr12.AddSubNode(); CNodeCStr& VO_CNodeCStr21 = VO_CNodeCStr2 .AddSubNode(); CNodeCStr& VO_CNodeCStr22 = VO_CNodeCStr2 .AddSubNode(); VO_CStrTreeData.GetRootNode().GetData()="## Root Node ##"; VO_CNodeCStr1 . GetData()="Node1" ; VO_CNodeCStr2 . GetData()="Node2" ; VO_CNodeCStr3 . GetData()="Node3" ; VO_CNodeCStr11. GetData()="Node11" ; VO_CNodeCStr12. GetData()="Node12" ; VO_CNodeCStr21. GetData()="Node21" ; VO_CNodeCStr22. GetData()="Node22" ; VO_CNodeCStr121.GetData()="Node121"; VO_CNodeCStr122.GetData()="Node122"; cout<<"# Pre Order"<::ZCNode1 에는 mo_TypeData 이 있다면, class ZtCTreeDataEx<>::ZCNode1 에는 mo_CDataList 이 있다. ///////////////////////////////////////////////////////////////*/ template< typename TType, typename TTypeTreeData=ZNsType::ZtCTypeTreeData > class ZtCTreeDataEx /*#########################################*/ { public: typedef TType TypeData ; typedef TTypeTreeData ZCTypeTreeData; public: class ZCNode1; class ZCNode2; class ZCNodeInfo ; public: typedef typename TTypeTreeData::TypeSize TypeSize; public: typedef typename TTypeTreeData:: template ZtCTypeClass::TypeList ZCDataList ; typedef typename TTypeTreeData:: template ZtCTypeClass::TypeList ZCNode1List; typedef typename TTypeTreeData:: template ZtCTypeClass::TypeList ZCNode2List; public: typedef ZCNode1 ZCNode ; typedef ZCNode1List ZCNodeList; typedef typename ZCNodeList::ZCLink ZCNodeLink; typedef typename ZCDataList::ZCLink ZCDataLink; public: typedef typename ZCDataList::iterator IterOfData; typedef typename ZCNodeList::iterator IterOfNode; public: class ZCNode1 { public : friend class ZCNodeInfo; private: ZCNode* mp_HighNode ; ZCDataList mo_CDataList; ZCNode2List mo_CNodeList; public : ZCNode1() { mp_HighNode=0; }/* ZCNode1()*/ ZCNode* GetHighNodePtr() {return (ZCNode*)mp_HighNode;} const ZCNode* GetHighNodePtr()const{return (ZCNode*)mp_HighNode;} ZCDataList& GetZCDataList() {return mo_CDataList;} const ZCDataList& GetZCDataList()const{return mo_CDataList;} const ZCNodeList& GetCNodeList()const{return (ZCNodeList&)mo_CNodeList;} TypeSize GetDataCnt(){return mo_CDataList.size();} TypeSize GetNodeCnt(){return mo_CNodeList.size();} void DeleteCDataList(){mo_CDataList.DeleteAll();} void DeleteCNodeList(){mo_CNodeList.DeleteAll();} void DeleteAll (){mo_CDataList.DeleteAll(); mo_CNodeList.DeleteAll();} void clear (){DeleteAll();} ZCNode& AddSubNode() { ZCNode* VP_CNode=(ZCNode*)&(*mo_CNodeList.AddTailDef()); VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode ; }/* ZCNode& AddSubNode()*/ ZCNodeInfo GetHeadNodeIter() { return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); }/* ZCNodeInfo GetHeadNodeIter()*/ /*////////////////////////////////////////////////////////////////////////////// ■ TViewClass 의 interface ZNsMain::ZNsEnum::ZERun OnDataStart(int AI_Depth) ZNsMain::ZNsEnum::ZERun OnDataBody(TypeData, TypeSize AI_Depth, TypeSize AI_Index) ZNsMain::ZNsEnum::ZERun OnDataClose(int AI_Depth) ZNsMain::ZNsEnum::ZERun OnSubNodeStart(int AI_Depth, int AI_NodeCnt) ZNsMain::ZNsEnum::ZERun OnSubNodeClose(int AI_Depth, int AI_NodeCnt) -- 2011-10-31 21:53:00 //////////////////////////////////////////////////////////////////////////////*/ template ZNsMain::ZNsEnum::ZERun IterPreOrder ( TViewClass& AR_CViewClass , TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex =0 ) /*##############################################################*/ { TypeSize VL_DataCnt= mo_CDataList .size(); TypeSize VL_NodeCnt=((ZCNodeList&)mo_CNodeList).size(); IterOfData VO_iter_Data( mo_CDataList.begin()); IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); if(AR_CViewClass.OnDataStart(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ { __for1(TypeSize, i, VL_DataCnt) { const bool CB_DoStop = ( AR_CViewClass.OnDataBody ( mo_CDataList.ItD(VO_iter_Data), AI_StartDepth, AI_NodeIndex ) == ZNsMain::ZNsEnum::ZERun_NO ); ////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; mo_CDataList.MoveNextIter(VO_iter_Data); /////// }/* __for1(TypeSize, i, VL_DataCnt)*/ } if(AR_CViewClass.OnDataClose(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ if(AR_CViewClass.OnSubNodeStart (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } ++AI_StartDepth; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ { __for1(TypeSize, i, VL_NodeCnt) { const bool CB_DoStop = /////////////////////////////// ( ((ZCNodeList&)mo_CNodeList).ItD(VO_iter_Node). template IterPreOrder (AR_CViewClass, AI_StartDepth. i) == ZNsMain::ZNsEnum::ZERun_NO ); ////////////////////////////////////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; ((ZCNodeList&)mo_CNodeList).MoveNextIter(VO_iter_Node); }/* __for1(TypeSize, i, VL_NodeCnt)*/ } --AI_StartDepth; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ if(AR_CViewClass.OnSubNodeClose (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } return ZNsMain::ZNsEnum::ZERun_OK; ///////////////////////// }/* template ZNsMain::ZNsEnum::ZERun IterPreOrder ( TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0 TypeSize AI_NodeIndex =0 ) */ /*###############################################################*/ template ZNsMain::ZNsEnum::ZERun IterPostOrder ( TViewClass& AR_CViewClass , TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex =0 ) /*###############################################################*/ { TypeSize VL_DataCnt= mo_CDataList. size(); TypeSize VL_NodeCnt=((ZCNodeList&)mo_CNodeList).size(); IterOfData VO_iter_Data( mo_CDataList. begin()); IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); if(AR_CViewClass.OnSubNodeStart (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } ++AI_StartDepth; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ { __for1(TypeSize, i, VL_NodeCnt) { const bool CB_DoStop = //////////////////////////////// ( ((ZCNodeList&)mo_CNodeList). ItD(VO_iter_Node).template IterPostOrder (AR_CViewClass, AI_StartDepth, i) == ZNsMain::ZNsEnum::ZERun_NO ); /////////////////////////////////////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; ((ZCNodeList&)mo_CNodeList).MoveNextIter(VO_iter_Node); }/* __for1(TypeSize, i, VL_NodeCnt)*/ } --AI_StartDepth; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ if(AR_CViewClass.OnSubNodeClose (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } if(AR_CViewClass.OnDataStart(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ { __for1(TypeSize, i, VL_DataCnt) { const bool CB_DoStop = //////////////////// ( AR_CViewClass.OnDataBody ( mo_CDataList.ItD(VO_iter_Data), AI_StartDepth, AI_NodeIndex ) == ZNsMain::ZNsEnum::ZERun_NO ); /////////////////////////////////////////// if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; mo_CDataList.MoveNextIter(VO_iter_Data); /////////////// }/* __for1(TypeSize, i, VL_DataCnt)*/ } if(AR_CViewClass.OnDataClose(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) { return ZNsMain::ZNsEnum::ZERun_NO; } /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ return ZNsMain::ZNsEnum::ZERun_OK; }/* template ZNsMain::ZNsEnum::ZERun IterPostOrder ( TViewClass& AR_CViewClass , TypeSize AI_StartDepth=0 , TypeSize AI_NodeIndex =0 ) #################################################################*/ public: };/* class ZCNode1*/ class ZCNode2 { public : friend class ZCNodeInfo; private: ZCNode* mp_HighNode ; ZCDataList mo_CDataList; ZCNode1List mo_CNodeList; public : ZCNode2() { mp_HighNode=0; }/* ZCNode2()*/ ZCNode* GetHighNodePtr() {return (ZCNode*)mp_HighNode;} const ZCNode* GetHighNodePtr()const{return (ZCNode*)mp_HighNode;} ZCDataList& GetZCDataList() {return mo_CDataList;} const ZCDataList& GetZCDataList()const{return mo_CDataList;} const ZCNodeList& GetCNodeList ()const{return (ZCNodeList&)mo_CNodeList;} TypeSize GetDataCnt(){return mo_CDataList.size();} TypeSize GetNodeCnt(){return mo_CNodeList.size();} void DeleteCDataList(){mo_CDataList.DeleteAll();} void DeleteCNodeList(){mo_CNodeList.DeleteAll();} void DeleteAll (){mo_CDataList.DeleteAll(); mo_CNodeList.DeleteAll();} void clear (){DeleteAll();} ZCNode& AddSubNode() { ZCNode* VP_CNode=(ZCNode*)& ( *mo_CNodeList.AddTailDef() ); VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode; }/* ZCNode& AddSubNode()*/ ZCNodeInfo GetHeadNodeIter() { return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); }/* ZCNodeInfo GetHeadNodeIter()*/ /*////////////////////////////////////////////////////////////////////////////////////////////// ■ ZCNode1 과 ZCNode2 가 동일한 구조이므로, ZCNode2 에서는 IterPreOrder() 와 IterPostOrder() 를 정의할 필요없다. ZCNode2 이 ZCNode1 로 형변환되어서 ZCNode1 의 IterPreOrder() 와 IterPostOrder() 을 사용할 것이기 때문이다. -- 2011-11-01 10:40:00 //////////////////////////////////////////////////////////////////////////////////////////////*/ public: };/* class ZCNode2*/ class ZCNodeInfo { private: ZCNode* mp_NowNodeWrap; ZCNodeLink* mp_NowNodeLink; public : ZCNodeInfo(ZCNode* AP_CNode=0,ZCNodeLink* AP_CNodeLink=0) { mp_NowNodeWrap=AP_CNode; mp_NowNodeLink=AP_CNodeLink; }/* ZCNodeInfo(ZCNode* AP_CNode=0,ZCNodeLink* AP_CNodeLink=0)*/ ZCNode* GetNowNodeWrap(){return mp_NowNodeWrap;} ZCNodeLink* GetNowNodeLink(){return mp_NowNodeLink;} bool DeleteNode() { if(mp_NowNodeWrap==0 || mp_NowNodeLink==0) return false; ((ZCNodeList&)(mp_NowNodeWrap->mo_CNodeList)). DeleteLink(mp_NowNodeLink); mp_NowNodeLink=0; return true; ////////////// }/* bool DeleteNode()*/ ZCNodeInfo& operator++(int) { mp_NowNodeWrap->mo_CNodeList.MoveNextIter(mp_NowNodeLink); return *this; }/* ZCNodeInfo& operator++(int)*/ ZCNode& operator*() {return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} const ZCNode& operator*()const{return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} public: };/* class ZCNodeInfo public :*/ private: ZCNode mo_RootNode; public: ZCNode& GetRootNode() {return mo_RootNode;} const ZCNode& GetRootNode()const{return mo_RootNode;} void DeleteAll(){mo_RootNode.clear();} void clear (){mo_RootNode.clear();} template void IterPreOrder (TViewClass AO_CViewClass) { mo_RootNode.template IterPreOrder(AO_CViewClass, 0); } template void IterPostOrder(TViewClass AO_CViewClass) { mo_RootNode.template IterPostOrder(AO_CViewClass, 0); } public: };/* template< typename TType, typename TTypeTreeData=ZNsType::ZtCTypeTreeData > ZtCTreeDataEx #################################################*/ }/* namespace ZNsMain*/ /*////////////////////////////////////////////////////////////////////////////////////////// ■ 이 파일은 CTreeClass.H 파일을 대체할 것이다. CTreeClass.H 에서는 트리 구조를 표현하는데, 아래 형식의 class CMyNode; { public: TypeData mo_TypeData; ZNsMain::ZtCObjList mo_NodeList; // 하위 노드 리스트. }; 재귀 용법을 구현할 수가 없어서, void* 를 사용하였다. 그러나 이 파일에서는, 똑같은 구조의 두 클래스 ZCNode1, ZCNode2 를 사용함으로써, 멋지게(!!) 재귀를 구현하고 있다. 클래스 ZCNode1 에서는 ZCNode2 의 컨테이너(리스트)를 가지고 있고, 클래스 ZCNode2 에서는 ZCNode1 의 컨테이너(리스트)를 가지고 있다. 아주 깜찍하고, 기발한 방법이라고 아니할 수 없다. 2011-10-29 일 토요일, 저녁 7 시 군포시예술문화회관 공연을 보고 오면서, 먼저 선언된 object 에서, 나중에 선언된 object 의 instance 를 참조하는 경우, 매끄럽게 해결할 수 있을 지도 모 르는 방법이 머릿 속에 그려지면서, 운명은 내편이라는 강한 확신이 들었었다. 그러나 집에 도 착 후, 조사 결과, 기대했던 매끄러운 방법은 아니었음이 드러났다. 실망할 수도 있었던 그 순 간, 트리를 구현할 때, 똑깥은 구조의, 이름만 다른 2 개의 클래스로 트리의 재귀 구조를 구현 할 수 있다는 생각이 번개처럼 떠 오른 것이다. 그 결과물이 이 파일 CTreeData.H 이다. 그래, 운명은 내편이었어. 어느덧 해는 저무는데, 이제는 모든 것을 뒤에 두고 떠날 수 있는 날이, 바로 앞에 성큼 다가왔 다. -- 2011-10-31 23:47:00 -- 현재 CTreeClass.H 는 제거되었다. -- 2013-05-01 17:22:00 //////////////////////////////////////////////////////////////////////////////////////////*/ #endif // __ZCPPMAIN__ZCTREEDATA_H__