#ifndef __ZCPPMAIN__ZTCOBJLIST_H__ #define __ZCPPMAIN__ZTCOBJLIST_H__ #include "ZCppMain/ZMainHead.H" namespace ZNsMain { template ////////////////////////////////////////////////////// < typename TType , typename TTypArgu , typename TTypCAlloc , typename TTypeInit , typename TTypSize , typename TMoveObj , typename TFeeeHeap > class ZtCObjList; ///////////////////////////////////////////// namespace ZNsIFaceEx { template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double > { public: template class ZtCBody { public : typedef typename TObjList::TypeSize TypeSize; typedef typename TObjList::TypeInit TypeInit; typedef typename TObjList::ZCLink ZCLink ; public : template ////////////////////////////////////////////////////// < typename TType , typename TTypArgu , typename TTypCAlloc , typename TTypeInit , typename TTypSize , typename TMoveObj , typename TFeeeHeap > friend class ZNsMain::ZtCObjList; ///////////////////////////// private: TypeSize ml_UseSize ; ZCLink* mp_NoUseHead ; ZCLink* mp_NoUseTail ; private: ZCLink* SendFreeOut() { if(ml_UseSize==0) { ZCLink* VP_TempLink = new ZCLink ; if(TypeInit::ZEUseInit>0) TypeInit::OnInit(*VP_TempLink, *this); return VP_TempLink; }/* if(ml_UseSize==0)*/ ZCLink* VP_TempLink=mp_NoUseHead; if(VP_TempLink==mp_NoUseTail) { mp_NoUseHead=0; mp_NoUseTail=0; } else { mp_NoUseHead = mp_NoUseHead->GetNextPtr(); } //else --ml_UseSize; return VP_TempLink; }/* ZCLink* SendFreeOut()*/ void SendFreeOut /*#####################################################*/ ( TypeSize AL_NeedCnt, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) /*######################################################################*/ { #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(mp_NoUseHead==0) { MakeLink(AL_NeedCnt, RR(APR_HeadLink), RR(APR_TailLink)); } else if(AL_NeedCnt==ml_UseSize) { ZCLink* VP_Temp = mp_NoUseHead; while(true) { if(TypeInit::ZEUseInit>0) TypeInit::OnInit(**VP_Temp, *this); if(VP_Temp==mp_NoUseTail) { break; } VP_Temp = VP_Temp->GetNextPtr(); }/* while(true)*/ APR_HeadLink = mp_NoUseHead ; APR_TailLink = mp_NoUseTail ; mp_NoUseHead =0 ; mp_NoUseTail =0 ; ml_UseSize =0 ; } else if(AL_NeedCnt0) TypeInit::OnInit(**mp_NoUseHead, *this); for(TypeSize VL_Count=2; VL_Count<=AL_NeedCnt; ++VL_Count) { // VL_Count 가 2 부터 시작함으로 AL_NeedCnt-1 번 순환한다. // 그래야지 AL_NeedCnt 개의 링크를 자를 수 있다. mp_NoUseHead = mp_NoUseHead->GetNextPtr(); if(TypeInit::ZEUseInit>0) TypeInit::OnInit(**mp_NoUseHead, *this); }/* for(TypeSize VL_Count=2; VL_Count<=AL_NeedCnt; ++VL_Count)*/ APR_TailLink = mp_NoUseHead ; mp_NoUseHead = mp_NoUseHead->GetNextPtr(); ml_UseSize -= AL_NeedCnt ; } else // AL_NeedCnt > ml_UseSize { ZCLink* VP_Temp=mp_NoUseHead; while(true) { if(VP_Temp==mp_NoUseTail) { break; } VP_Temp=VP_Temp->GetNextPtr() ; }/* while(true)*/ APR_HeadLink = mp_NoUseHead; // MakeLink() 에서 TypeInit::OnInit() 가 호출됨. MakeLink /////////////////////////////////////// ( AL_NeedCnt - ml_UseSize , RR(mp_NoUseTail->mp_NextLink) , RR(APR_TailLink) ); //////////////////////////////////////////////// mp_NoUseHead= 0 ; mp_NoUseTail= 0 ; ml_UseSize = 0 ; }/* else // AL_NeedCnt > ml_UseSize*/ }/* void SendFreeOut ######################################################## ( TypeSize AL_NeedCnt, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) ########################################################################*/ void SendFreeOutCopy /*////////////////////////////*/ ( ZCLink* AP_LinkOrgin, TypeSize AL_FarNum , ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) /*/////////////////////////////////////////////////*/ { // AL_FarNum > 0 // AP_LinkOrgin 링크부터, // AP_LinkOrgin 에서 AL_FarNum 만큼 떨어진 링크까지를 복사하여 // 복사생성된 처음 링크 포인터를 APR_HeadCopy 에, // 마지막 링크를 APR_TailCopy 에 대입한다. // AP_LinkOrgin 링크에서 그 다음 링크로 접근하면서 링크를 복사할 것이다. // 따라서 총 AL_FarNum + 1 개의 링크가 만들어진다. // 이 함수는 각 링크를 새로 생성하는 MakeLinkCopy() 함수와는 달리 // 기존에 있는 ml_UseSize 개의 링크를 먼저 사용한다. if(mp_NoUseHead==0) { MakeLinkCopy ///////////////////////////// ( AP_LinkOrgin , AL_FarNum , RR(APR_HeadCopy), RR(APR_TailCopy) ); ////////////////////////////////////////// } else if( AL_FarNum < ml_UseSize) // ( (AL_FarNum<0 ? -AL_FarNum : AL_FarNum)+1 <= ml_UseSize) { ml_UseSize -= AL_FarNum+1 ; **mp_NoUseHead = **AP_LinkOrgin ; APR_HeadCopy = mp_NoUseHead ; while(--AL_FarNum>=0) { mp_NoUseHead = mp_NoUseHead->GetNextPtr() ; AP_LinkOrgin = AP_LinkOrgin->GetNextPtr() ; **mp_NoUseHead = **AP_LinkOrgin ; } //while(--AL_FarNum>=0) APR_TailCopy = mp_NoUseHead ; // 이 부분에서 mp_NoUseHead 는 잘려나가는 마지막 링크가 된다. // 그러므로 다시 다음 링크로 초기화한다. mp_NoUseHead = mp_NoUseHead->GetNextPtr(); if(mp_NoUseHead==0) { mp_NoUseTail=0; // mp_NoUseHead == 0 인데 mp_NoUseTail !=0 이라면 // 나중에 자칫 무한루프에 빠질 수 있다. // 따라서 위 코드를 두었다. }/* if(mp_NoUseHead==0)*/ } else // AL_FarNum > ml_UseSize { **mp_NoUseHead = **AP_LinkOrgin ; APR_HeadCopy = mp_NoUseHead ; while(mp_NoUseHead!=mp_NoUseTail) { mp_NoUseHead = mp_NoUseHead->GetNextPtr() ; AP_LinkOrgin = AP_LinkOrgin->GetNextPtr() ; **mp_NoUseHead = **AP_LinkOrgin ; }/* while(mp_NoUseHead!=mp_NoUseTail)*/ MakeLinkCopy /*++++++++++++++++++++++++++++++++++++++++++++*/ ( AP_LinkOrgin->GetNextPtr() , AL_FarNum-ml_UseSize, RR(mp_NoUseTail->mp_NextLink), RR(APR_TailCopy) ); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ mp_NoUseHead = mp_NoUseTail = 0; ml_UseSize = 0; } //else // AL_FarNum > ml_UseSize }/* void SendFreeOutCopy //////////////////////////////// ( ZCLink* AP_LinkOrgin, TypeSize AL_FarNum , ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) ///////////////////////////////////////////////////*/ void MakeLink /////////////////////////////////////// ( TypeSize AL_MakeSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) ///////////////////////////////////////////////////*/ { APR_HeadLink = new ZCLink; if(APR_HeadLink==0) { //add codes for memory over DeleteHeap(); return; }/* if(APR_HeadLink==0)*/ if(TypeInit::ZEUseInit>0) TypeInit::OnInit(**APR_HeadLink, *this); ZCLink* VP_MakeLink = 0 ; ZCLink* VP_TempLink = APR_HeadLink; bool VB_IsHeapOver= false ; // bool VB_IsHeapOver 은 new 연산자가 NULL 포인터를 반환했을 때 // true 를 대입받는다. 이 값을 조사함으로써 heap overflow 를 처리한다. // bool VB_IsHeapOver 변수를 두지 않고 // 아래 for 문에서 직접 메모리 처리를 하는 코드를 둘 수 있으나 // for 문 안에 if 문 속에서 또 for 문을 써야 함으로 // 가독성이 떨어질 수가 있다. // 그래서 heap over 에 대한 예외처리 코드를 // for 문 바깥으로 빼려는 것이다. while(--AL_MakeSize>0) // AL_MakeSize - 1 번 순환 { // AL_MakeSize - 1 번 순환 VP_MakeLink = new ZCLink; if(VP_MakeLink==0) { VB_IsHeapOver = true; break; }/* if(VP_MakeLink==0)*/ if(TypeInit::ZEUseInit>0) TypeInit::OnInit(**VP_MakeLink, *this); ZCLink::JoinLink (VP_TempLink, VP_MakeLink); VP_TempLink = VP_MakeLink ; }/* while(--AL_MakeSize>0)*/ APR_TailLink = VP_TempLink; // 메모리를 더 이상 할당할 수 없었다면 // 이미 만들어진 VL_Count 개의 비원형 이중 링크를 지운다. if(VB_IsHeapOver==true) { VP_TempLink=APR_HeadLink; // 이 시점에서 최소한 APR_HeadLink 하나는 // heap 에 생성되어 있다. do ////// { delete VP_TempLink; if(VP_TempLink==APR_TailLink) { // Add extra codes for memory over return; }/* if(VP_TempLink==APR_TailLink)*/ APR_HeadLink=APR_HeadLink->GetNextPtr(); } while(true); }/* if(VB_IsHeapOver==true)*/ }/* void MakeLink /////////////////////////////////////// ( TypeSize AL_MakeSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) ///////////////////////////////////////////////////*/ void MakeLinkCopy /////////////////////////////////// ( ZCLink* AP_LinkOrgin, TypeSize AL_FarNum , ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) ///////////////////////////////////////////////////*/ { // AP_LinkOrgin 링크부터, // AP_LinkOrgin 에서 AL_FarNum 만큼 떨어진 링크까지를 복사하여 // 복사생성된 처음 링크 포인터를 APR_HeadCopy 에, // 마지막 링크를 APR_TailCopy 에 대입한다. // AL_FarNum > 0 , 총 AL_FarNum + 1 개의 링크가 만들어진다. ZCLink* VP_MakeLink = 0 ; ZCLink* VP_TailLink = 0 ; bool VB_IsHeapOver= false; VP_TailLink = VP_MakeLink = new ZCLink(**AP_LinkOrgin) ; if(VP_MakeLink==0) { //add codes for memory over DeleteHeap(); return ; }/* if(VP_MakeLink==0)*/ APR_HeadCopy = VP_MakeLink; while(--AL_FarNum >= 0) { AP_LinkOrgin= AP_LinkOrgin->GetNextPtr() ; VP_MakeLink = new ZCLink(**AP_LinkOrgin) ; if(VP_MakeLink==0) { APR_TailCopy = VP_TailLink ; VB_IsHeapOver= true ; break; }/* if(VP_MakeLink==0)*/ ZCLink::JoinLink (VP_TailLink, VP_MakeLink); VP_TailLink = VP_MakeLink; }/* while(--AL_FarNum >= 0)*/ APR_TailCopy=VP_TailLink; // 메모리를 더 이상 할당할 수 없었다면 // 이미 만들어진 비원형 이중 링크를 지운다. if(VB_IsHeapOver==true) { do ////// { delete APR_HeadCopy; if(APR_HeadCopy==APR_TailCopy) { DeleteHeap(); return; }/* if(APR_HeadCopy==APR_TailCopy)*/ APR_HeadCopy = APR_HeadCopy->mp_NextLink; } while(true); }/* if(VB_IsHeapOver==true)*/ }/* void MakeLinkCopy /////////////////////////////////// ( ZCLink* AP_LinkOrgin, TypeSize AL_FarNum, ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) ///////////////////////////////////////////////////*/ void RecvFreeIn(ZCLink* AP_CutLink) { if(++ml_UseSize==1) // ml_UseSize 이 0 일때 { mp_NoUseHead = mp_NoUseTail = AP_CutLink ; } else { // 새로운 링크는 mp_NoUseTail 다음에 붙인다. ZCLink::JoinLink (mp_NoUseTail, AP_CutLink); mp_NoUseTail = AP_CutLink; } //else if(TypeInit::ZEUseFini>0) TypeInit::OnFini(**AP_CutLink, *this); }/* void RecvFreeIn(ZCLink* AP_Link)*/ void RecvFreeIn /////////////////////////////////////////////////// ( TypeSize AL_Count, ZCLink* AP_HeadLink, ZCLink* AP_TailLink ) /////////////////////////////////////////////////////////////////// { if(TypeInit::ZEUseFini>0) { ZCLink* VP_NowLink = AP_HeadLink; __for1(TypeSize, i, AL_Count) { TypeInit::OnFini(**VP_NowLink, *this) ; VP_NowLink = VP_NowLink->GetNextPtr() ; } /*=========================*/ }/* if(TypeInit::ZEUseFini>0)*/ if(ml_UseSize==0) { mp_NoUseHead = AP_HeadLink ; mp_NoUseTail = AP_TailLink ; } else { // 새로운 링크는 mp_NoUseTail 다음에 붙인다. ZCLink::JoinLink (mp_NoUseTail, AP_HeadLink); mp_NoUseTail = AP_TailLink; } //else ml_UseSize += AL_Count ; }/* void RecvFreeIn /////////////////////////////////////////////////// ( TypeSize AL_Count, ZCLink* AP_HeadLink, ZCLink* AP_TailLink ) /////////////////////////////////////////////////////////////////*/ /*private :*/ public : ZtCBody() { ml_UseSize = 0 ; mp_NoUseHead = mp_NoUseTail = 0 ; }/* ZtCBody()*/ ~ZtCBody() { DeleteHeap(); }/* ~ZtCBody()*/ ZtCBody(const ZtCBody& rhs) { ml_UseSize = 0 ; mp_NoUseHead = mp_NoUseTail = 0 ; }/* ZtCBody(const ZtCBody& rhs)*/ ZtCBody& operator=(const ZtCBody& rhs) { return *this; }/* ZtCBody& operator=(const ZtCBody& rhs)*/ void DeleteHeap() { if(ml_UseSize<1) return ; ZCLink* VP_DelLink = mp_NoUseHead; TypeSize VI_UseSize = ml_UseSize ; do /*++++++++++++++++++++++++++++*/ { mp_NoUseHead = mp_NoUseHead->GetNextPtr() ; delete VP_DelLink; VP_DelLink = mp_NoUseHead ; } while(--VI_UseSize>0); /*++++++++*/ ml_UseSize = 0 ; mp_NoUseHead = mp_NoUseTail = 0 ; }/* void DeleteHeap()*/ TypeSize DeleteHeap(TypeSize AI_DelCnt) { if(ml_UseSize<1) return 0; if(AI_DelCnt <1) return 0; if(AI_DelCnt >= size()) { AI_DelCnt=size(); DeleteHeap(); return AI_DelCnt; }/* if(AI_DelCnt >= size())*/ TypeSize VI_DelCntCopy = AI_DelCnt ; ZCLink* VP_DelLink = mp_NoUseHead ; do /*+++++++++++++++++++++++++++*/ { mp_NoUseHead = mp_NoUseHead->GetNextPtr() ; delete VP_DelLink; VP_DelLink = mp_NoUseHead ; } while(--VI_DelCntCopy>0); /*++++*/ ml_UseSize -= AI_DelCnt; return AI_DelCnt; }/* TypeSize DeleteHeap(TypeSize AI_DelCnt)*/ void AddHeap(TypeSize AI_AddCnt) { if(AI_AddCnt<1) return; if(size() < 1) { MakeLink (AI_AddCnt, RR(mp_NoUseHead), RR(mp_NoUseTail)); } else { ZCLink* VP_MakeHead = 0; ZCLink* VP_MakeTail = 0; MakeLink (AI_AddCnt, RR(VP_MakeHead), RR(VP_MakeTail)); ZCLink::JoinLink(mp_NoUseTail, VP_MakeHead); mp_NoUseTail = VP_MakeTail ; }/* else*/ ml_UseSize += AI_AddCnt; }/* void AddHeap(TypeSize AI_AddCnt)*/ void Fetch(ZtCBody& rhs) { if(this==&rhs ) return; if(rhs.size()<1) return; if(this->size()<1) this->mp_NoUseHead = rhs.mp_NoUseHead; else { ZCLink::JoinLink (this->mp_NoUseTail, rhs.mp_NoUseHead); } this->mp_NoUseTail = rhs.mp_NoUseTail; this->ml_UseSize += rhs.ml_UseSize ; rhs.ml_UseSize = 0 ; rhs.mp_NoUseHead = 0 ; rhs.mp_NoUseTail = 0 ; }/* void Fetch(ZtCBody& rhs)*/ TypeSize Fetch(ZtCBody& rhs, TypeSize AI_FetchSize) { // rhs 의 앞에서 AI_FetchSize 개를 가져온다. if(this==&rhs ) return 0; if(AI_FetchSize<1 ) return 0; if(rhs.size() <1 ) return 0; if(AI_FetchSize>= rhs.size()) { AI_FetchSize = rhs.size(); Fetch(rhs); return AI_FetchSize; }/* if(AI_FetchSize>= rhs.size())*/ ZCLink* VP_RhsCutTail = rhs.mp_NoUseHead->GetNextPtr( AI_FetchSize-1 ) ; ZCLink* VP_RhsNewHead = VP_RhsCutTail->GetNextPtr( ); if(ml_UseSize<1) { // mp_NoUseHead, mp_NoUseTail 이 0 this->mp_NoUseHead = rhs.mp_NoUseHead ; } else { // mp_NoUseHead 고정. ZCLink::JoinLink (this->mp_NoUseTail, rhs.mp_NoUseHead); } this->ml_UseSize += AI_FetchSize ; this->mp_NoUseTail = VP_RhsCutTail; rhs. ml_UseSize -= AI_FetchSize ; rhs. mp_NoUseHead = VP_RhsNewHead; return AI_FetchSize; }/* TypeSize Fetch(ZtCBody& rhs, TypeSize AI_FetchSize)*/ void MakeEqual(ZtCBody& rhs) { // 갯수만 맞춘다. if(this==&rhs) return; if(this->size() > rhs.size()) DeleteHeap( this->size() - rhs. size() ); else AddHeap ( rhs. size() - this->size() ); }/* void MakeEqual(ZtCBody& rhs)*/ TypeSize GetUseHeapSize() const { return ml_UseSize; }/* TypeSize GetUseHeapSize() const*/ TypeSize size() const { return ml_UseSize; }/* TypeSize size() const*/ public: };/* template class ZtCBody*/ public: };/* template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >*/ }/* namespace ZNsIFaceEx*/ /*///////////////////////////////////////////////////////////////// ■ typename TTypeInit 는 별다른 역할을 하지 않고 있다. 다른 리스트 클래스와 템플릿 인수를 비슷하게 맞추기 위해, 그리고 차후의 설계 를 위해 일단 이대로 두자. ■ typename ZtCInit 가 필요한지 모르겠다. 일단 주석으로 막는다. -- 2025-08-11 14:47 ZtCTreeData.H 에서 ZtCObjList<> 에서 TTypeInit 자리에 형을 지정 하고 있다. 쓰긴 쓰니까 주석을 해제하자. -- 2025-08-14 13:43 아, 일종의 TType 생성자의 다형성을 위해서 필요하겠네. 생성자에는 가상 함수가 없으니까. -- 2025-10-03 19:15 /////////////////////////////////////////////////////////////////*/ template class ZtCSortObjList; template< typename TType /////////////////////////////////////////////////// , typename TTypArgu = const TType& , typename TTypCAlloc = ZCAllocator , typename TTypeInit = ZtCInit , typename TTypSize = ZTypLong , typename TMoveObj = ZtCMoveObj , typename TFeeeHeap = ZNsIFaceEx:: ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double > > class ZtCObjList ////////////////////////////////////////////////////////////// { public: template friend class ZtCSortObjList; public: typedef TType Type ; typedef TType TypeData ; typedef TTypArgu TypeArg ; typedef TTypCAlloc TypeAlloc ; typedef TTypeInit TypeInit ; typedef TTypSize TypeSize ; typedef TMoveObj TypeMoveObj; public: typedef ZtCObjList TypeThis ; public: class ZCIterator; class ZCLink ; public: typedef ZCLink* IterEasy; // 가장 대표적으로 쓰일 수 있는 반복자. typedef ZCIterator iterator; typedef const ZCIterator const_iterator; public: typedef typename TFeeeHeap:: template ZtCBody ZCFreeHeap; public: typedef ZtCObjOpt ZCLinkOpt; typedef ZtCObjOpt ZCDataOpt; public: class ZCLink : public TypeAlloc { public : template friend class ZtCSortObjList; /*++++++++++++++++++++++++++*/ friend class ZtCObjList ; public : template friend class ZNsIFaceEx::ZtCFreeHeapCDL ; private: TypeData mo_DataObjt; ZCLink* mp_NextLink; ZCLink* mp_PrevLink; private: static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink) { AP_PrevLink->mp_NextLink=AP_NextLink; AP_NextLink->mp_PrevLink=AP_PrevLink; }/* static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink)*/ static void MakeRing(ZCLink* AP_HeadLink, ZCLink* AP_TailLink) { AP_HeadLink->mp_PrevLink=AP_TailLink; AP_TailLink->mp_NextLink=AP_HeadLink; }/* static void MakeRing(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)*/ /*private:*/ public : ZCLink() { mp_NextLink =0 ; mp_PrevLink =0 ; }/* ZCLink()*/ ZCLink(TypeArg AR_Type) { mp_NextLink = 0 ; mp_PrevLink = 0 ; mo_DataObjt = AR_Type ; }/* ZCLink(TypeArg AR_Type)*/ ZCLink(const ZCLink& rhs) { mp_NextLink =0 ; mp_PrevLink =0 ; mo_DataObjt = rhs.mo_DataObjt ; }/* ZCLink(const ZCLink& rhs)*/ ZCLink& operator=(const ZCLink& rhs) { mo_DataObjt = rhs.mo_DataObjt; return *this; }/* ZCLink& operator=(const ZCLink& rhs)*/ operator Type& (){return mo_DataObjt;} operator Type (){return mo_DataObjt;} Type& GetData (){return mo_DataObjt;} Type& operator*(){return mo_DataObjt;} operator const Type& () const{return mo_DataObjt;} const Type& GetData () const{return mo_DataObjt;} const Type& operator*() const{return mo_DataObjt;} ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) // AL_FarNum 은 0 이거나 음수일 수 있다. { ZCLink* VP_TmpLink=this; if(AL_FarNum>=0) { while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink; } else // AL_FarNum<0 인 경우. { while(++AL_FarNum<=0) VP_TmpLink=VP_TmpLink->mp_PrevLink; }/* else*/ return VP_TmpLink; }/* ZCLink* GetNextPrevPtr(TypeSize AL_FarNum)*/ const ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) const // or ZCLink const * const GetNextPrevPtr(TypeSize AL_FarNum) const { ZCLink* VP_TmpLink=const_cast(this); if(AL_FarNum>=0) { while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink; } else // AL_FarNum<0 인 경우. { while(++AL_FarNum<=0) VP_TmpLink=VP_TmpLink->mp_PrevLink; }/* else*/ return VP_TmpLink; }/* const ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) const*/ ZCLink* GetNextPtr(){return mp_NextLink;} ZCLink* GetPrevPtr(){return mp_PrevLink;} const ZCLink* GetNextPtr() const{return mp_NextLink;} const ZCLink* GetPrevPtr() const{return mp_PrevLink;} ZCLink* GetNextPtr(TypeSize AL_Distance) { TypeSize VL_LoopIndex=0 ; ZCLink* VP_TmpLink =this; while(VL_LoopIndex++ < AL_Distance) VP_TmpLink = VP_TmpLink->mp_NextLink ; return VP_TmpLink; }/* ZCLink* GetNextPtr(TypeSize AL_Distance)*/ ZCLink* GetPrevPtr(TypeSize AL_Distance) { TypeSize VL_LoopIndex=0 ; ZCLink* VP_TmpLink =this; while(VL_LoopIndex++ < AL_Distance) VP_TmpLink = VP_TmpLink->mp_PrevLink ; return VP_TmpLink; }/* ZCLink* GetPrevPtr(TypeSize AL_Distance)*/ const ZCLink* GetNextPtr(TypeSize AL_Distance) const { TypeSize VL_LoopIndex=0 ; ZCLink* VP_TmpLink =const_cast(this); while(VL_LoopIndex++ < AL_Distance) VP_TmpLink = VP_TmpLink->mp_NextLink ; return VP_TmpLink; }/* const ZCLink* GetNextPtr(TypeSize AL_Distance) const*/ const ZCLink* GetPrevPtr(TypeSize AL_Distance) const { TypeSize VL_LoopIndex=0 ; ZCLink* VP_TmpLink = const_cast(this) ; while(VL_LoopIndex++ < AL_Distance) VP_TmpLink = VP_TmpLink->mp_PrevLink ; return VP_TmpLink; }/* const ZCLink* GetPrevPtr(TypeSize AL_Distance) const*/ ZCLink& operator+(TypeSize AL_Distance) { if(AL_Distance>=0) return *GetNextPtr(AL_Distance); else return *GetPrevPtr(AL_Distance); }/* ZCLink& operator+(TypeSize AL_Distance)*/ ZCLink& operator-(TypeSize AL_Distance) { if(AL_Distance>=0) return *GetPrevPtr(AL_Distance); else return *GetNextPtr(AL_Distance); }/* ZCLink& operator-(TypeSize AL_Distance)*/ const ZCLink& operator+(TypeSize AL_Distance) const { if(AL_Distance>=0) return *GetNextPtr(AL_Distance); else return *GetPrevPtr(AL_Distance); }/* const ZCLink& operator+(TypeSize AL_Distance) const*/ const ZCLink& operator-(TypeSize AL_Distance) const { if(AL_Distance>=0) return *GetPrevPtr(AL_Distance); else return *GetNextPtr(AL_Distance); }/* const ZCLink& operator-(TypeSize AL_Distance) const*/ public: };/* class ZCLink*/ /*public :*/ protected: ZCLink* mp_HeadLink; TypeSize ml_LinkSize; mutable ZCFreeHeap mo_FreeObjt; protected: void JoinAfter(ZCLink* AP_LinkNew, ZCLink* AP_LinkStd) { // AP_LinkNew 를 AP_LinkStd 뒤에 삽입한다. // AL_PosStd==0 이면 맨 앞에 삽입한다. if(AP_LinkStd==0) { // 맨 앞에 삽입. if(++ml_LinkSize==1) { mp_HeadLink =AP_LinkNew ; mp_HeadLink->mp_NextLink=mp_HeadLink ; mp_HeadLink->mp_PrevLink=mp_HeadLink ; } else { ZCLink* VP_TailLink = mp_HeadLink->mp_PrevLink ; ZCLink::JoinLink(AP_LinkNew, mp_HeadLink); ZCLink::MakeRing(AP_LinkNew, VP_TailLink); mp_HeadLink=AP_LinkNew; }/* else*/ } else { ++ml_LinkSize; ZCLink* AP_NextStd = AP_LinkStd->mp_NextLink ; ZCLink::JoinLink(AP_LinkStd, AP_LinkNew); ZCLink::JoinLink(AP_LinkNew, AP_NextStd); }/* else*/ }/* void JoinAfter(ZCLink* AP_LinkNew, ZCLink* AP_LinkStd)*/ void JoinBefore(ZCLink* AP_LinkNew, ZCLink* AP_LinkStd) { // AP_LinkNew 를 AP_LinkStd 앞에 삽입한다. // AL_PosStd==0 이면 맨 뒤에 삽입한다. if(AP_LinkStd==0) { // 맨 뒤에 삽입. if(++ml_LinkSize==1) { mp_HeadLink =AP_LinkNew ; mp_HeadLink->mp_NextLink=mp_HeadLink; mp_HeadLink->mp_PrevLink=mp_HeadLink; } else { ZCLink* VP_TailLink = mp_HeadLink->mp_PrevLink ; ZCLink::JoinLink(VP_TailLink, AP_LinkNew); ZCLink::MakeRing(mp_HeadLink, AP_LinkNew); }/* else*/ } else { ++ml_LinkSize; ZCLink* AP_PrevStd = AP_LinkStd->mp_PrevLink ; ZCLink::JoinLink(AP_PrevStd, AP_LinkNew); ZCLink::JoinLink(AP_LinkNew, AP_LinkStd); }/* else*/ }/* void JoinBefore(ZCLink* AP_LinkNew, ZCLink* AP_LinkStd)*/ /*protected:*/ public : void JoinAfter(ZtCObjList& rhs, ZCLinkOpt AO_StdOpt) { if(this == &rhs ) return; if(rhs.ml_LinkSize<1) return; if(!bool(AO_StdOpt)) // 맨 앞에 삽입 { if(ml_LinkSize==0) { mp_HeadLink = rhs.mp_HeadLink ; ml_LinkSize = rhs.ml_LinkSize ; } else { ZCLink* VP_TailLink = rhs.mp_HeadLink->mp_PrevLink; ZCLink::MakeRing(rhs.mp_HeadLink, mp_HeadLink->mp_PrevLink); ZCLink::JoinLink( VP_TailLink, mp_HeadLink ); mp_HeadLink = rhs.mp_HeadLink ; ml_LinkSize += rhs.ml_LinkSize ; }/* else*/ } else // bool(AO_StdOpt) { ZCLink* VP_RhsTail= rhs.mp_HeadLink->mp_PrevLink ; ZCLink* VP_LinkStd= &AO_StdOpt.value() ; ZCLink* VP_StdNext= VP_LinkStd->mp_NextLink ; ZCLink::JoinLink(VP_LinkStd, rhs.mp_HeadLink); ZCLink::JoinLink(VP_RhsTail, VP_StdNext ); ml_LinkSize += rhs.ml_LinkSize ; }/* else // bool(AO_StdOpt)*/ rhs.mp_HeadLink = 0; rhs.ml_LinkSize = 0; }/* void JoinAfter (ZtCObjList& rhs, ZCLinkOpt AO_StdOpt)*/ void JoinBefore(ZtCObjList& rhs, ZCLinkOpt AO_StdOpt) { if(this == &rhs ) return; if(rhs.ml_LinkSize<1) return; if(!bool(AO_StdOpt)) // 맨 뒤에 삽입 { if(ml_LinkSize==0) { mp_HeadLink = rhs.mp_HeadLink ; ml_LinkSize = rhs.ml_LinkSize ; } else { ZCLink* VP_RhsTail = rhs.mp_HeadLink->mp_PrevLink ; ZCLink* VP_LhsTail = mp_HeadLink->mp_PrevLink ; ZCLink::JoinLink(VP_LhsTail , rhs.mp_HeadLink); ZCLink::MakeRing(mp_HeadLink, VP_RhsTail ); ml_LinkSize += rhs.ml_LinkSize ; }/* else*/ } else // bool(AO_StdOpt) { ZCLink* VP_RhsHead = rhs.mp_HeadLink ; ZCLink* VP_RhsTail = rhs.mp_HeadLink->mp_PrevLink; ZCLink* VP_LinkStd= &AO_StdOpt.value() ; ZCLink* VP_PrevStd = VP_LinkStd ->mp_PrevLink; ZCLink::JoinLink(VP_PrevStd, VP_RhsHead); ZCLink::JoinLink(VP_RhsTail, VP_LinkStd); ml_LinkSize += rhs.ml_LinkSize ; }/* else // bool(AO_StdOpt)*/ rhs.mp_HeadLink = 0; rhs.ml_LinkSize = 0; }/* void JoinBefore(ZtCObjList& rhs, ZCLinkOpt AO_StdOpt)*/ /*public :*/ protected: ZCLink* CutLink(ZCLink* AP_CutLink) { if(AP_CutLink==mp_HeadLink) { if(mp_HeadLink==mp_HeadLink->mp_PrevLink) mp_HeadLink=0; else { ZCLink::MakeRing //////////////////////////// ( mp_HeadLink=mp_HeadLink->mp_NextLink, AP_CutLink->mp_PrevLink ); ///////////////////////////////////////////// }/* else*/ } else if(AP_CutLink==mp_HeadLink->mp_PrevLink) ZCLink::MakeRing(mp_HeadLink , AP_CutLink->mp_PrevLink); else ZCLink::JoinLink(AP_CutLink->mp_PrevLink, AP_CutLink->mp_NextLink); return (--ml_LinkSize, AP_CutLink); }/* protected: ZCLink* CutLink(ZCLink* AP_CutLink)*/ TypeThis& CutLink /*##########################################################*/ ( ZCLink* AP_CutHead , ZCLink* AP_CutTail , TypeSize AL_CutSize , TypeThis& ARR_StoreList ) /*#############################################################################*/ { // AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크 // AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크 // ARR_StoreList 은 비어 있어야 한다. if(this==&ARR_StoreList) return *this ; if(ml_LinkSize<1) return ARR_StoreList; ZCLink* VP_TailLink = mp_HeadLink->mp_PrevLink; if(AP_CutHead==mp_HeadLink && AP_CutTail==VP_TailLink) { mp_HeadLink=0; // 모든 링크를 삭제할 때. } else if(AP_CutHead==mp_HeadLink) { ZCLink::MakeRing ( mp_HeadLink=AP_CutTail->mp_NextLink, VP_TailLink ); //////////////// } else if(AP_CutTail==VP_TailLink) { ZCLink::MakeRing ( mp_HeadLink, AP_CutHead->mp_PrevLink ); //////////////// } else { ZCLink::JoinLink ( AP_CutHead->mp_PrevLink, AP_CutTail->mp_NextLink ); //////////////// } ml_LinkSize -= AL_CutSize; // ARR_StoreList 은 비어 있어야 한다. ZCLink::MakeRing(AP_CutHead, AP_CutTail); ARR_StoreList.mp_HeadLink = AP_CutHead ; ARR_StoreList.ml_LinkSize = AL_CutSize ; return ARR_StoreList; }/* TypeThis& CutLink ############################################################## ( ZCLink* AP_CutHead , ZCLink* AP_CutTail , TypeSize AL_CutSize , TypeThis& ARR_StoreList ) ###############################################################################*/ TypeThis& CutLinkRangeOut /*##################################################*/ ( ZCLink* AP_CutHead , ZCLink* AP_CutTail , TypeSize AL_CutSize , TypeThis& rhs , ZCLink* AP_RhsStd , bool AB_After=true ) /*#############################################################################*/ { /*////////////////////////////////////////////////// ■ AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크 AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크 이 범위의 링크를 AP_RhsStd 뒤에 붙인다. AP_RhsStd 이 0 이면, rhs 의 앞에 붙인다. ■ bool AB_After 추가. -- 2025-10-07 09:36 AB_After==true 이면, AP_RhsStd 의 뒤에 연결. AB_After==false 이면, AP_RhsStd 의 앞에 연결. //////////////////////////////////////////////////*/ if(this==&rhs ) return *this; if(ml_LinkSize<1) return rhs ; ZCLink* VP_TailLink = mp_HeadLink->mp_PrevLink; if(AP_CutHead==mp_HeadLink && AP_CutTail==VP_TailLink) { mp_HeadLink=0; // 모든 링크를 삭제할 때. } else if(AP_CutHead==mp_HeadLink) { ZCLink::MakeRing /////////////// ( mp_HeadLink = AP_CutTail->mp_NextLink, VP_TailLink ); //////////////////////////////// } else if(AP_CutTail==VP_TailLink) { ZCLink::MakeRing /////////////// ( mp_HeadLink, AP_CutHead->mp_PrevLink ); //////////////////////////////// } else { ZCLink::JoinLink /////////////// ( AP_CutHead->mp_PrevLink, AP_CutTail->mp_NextLink ); //////////////////////////////// } ml_LinkSize -= AL_CutSize; if(rhs.size()<1) { ZCLink::MakeRing ( AP_CutHead, AP_CutTail ) ; rhs.mp_HeadLink = AP_CutHead ; } else if(AB_After) { if(AP_RhsStd==0) // 맨 앞에 삽입. { ZCLink* VP_RhsHead = rhs.mp_HeadLink ; ZCLink* VP_RhsTail = rhs.mp_HeadLink->mp_PrevLink ; ZCLink::JoinLink(AP_CutTail, VP_RhsHead); ZCLink::MakeRing(AP_CutHead, VP_RhsTail); rhs.mp_HeadLink = AP_CutHead; } else // AP_RhsStd 의 뒤에 삽입. { ZCLink* VP_RhsStdNext = AP_RhsStd->mp_NextLink ; ZCLink::JoinLink(AP_RhsStd , AP_CutHead ); ZCLink::JoinLink(AP_CutTail, VP_RhsStdNext); } } else // !AB_After { if(AP_RhsStd==0) // 맨 뒤에 삽입. { ZCLink* VP_RhsHead = rhs.mp_HeadLink ; ZCLink* VP_RhsTail = rhs.mp_HeadLink->mp_PrevLink ; ZCLink::JoinLink(VP_RhsTail, AP_CutHead); ZCLink::MakeRing(VP_RhsHead, AP_CutTail); } else // AP_RhsStd 의 앞에 삽입. { ZCLink* VP_RhsStdPrev = AP_RhsStd->mp_PrevLink ; ZCLink::JoinLink(VP_RhsStdPrev, AP_CutHead); ZCLink::JoinLink(AP_CutTail , AP_RhsStd ); if(AP_RhsStd==rhs.mp_HeadLink) rhs.mp_HeadLink = AP_CutHead ; } }/* else // !AB_After*/ rhs.ml_LinkSize += AL_CutSize; return rhs; }/* TypeThis& CutLinkRangeOut ###################################################### ( ZCLink* AP_CutHead , ZCLink* AP_CutTail , TypeSize AL_CutSize , TypeThis& rhs , ZCLink* AP_RhsStd , bool AB_After=true ) ###############################################################################*/ ZtCObjList& CopyLink /*########################################################*/ ( const ZCLink* AP_CopyLink , TypeSize AL_FarNum , ZtCObjList& ARR_StoreList ) const /*#############################################################################*/ { /*///////////////////////////////////////////////////////// ■ AP_CopyLink 부터 AP_CopyLink->GetNextPrevPtr(AL_FarNum) 링크까지를 복사한다. AL_FarNum 은 0 이거나 음수일 수 있다. 총 (FarNum의 절대값) + 1 개의 링크가 만들어진다. ARR_StoreList 은 비어 있어야 한다. -- 2025-10-06 13:01 /////////////////////////////////////////////////////////*/ if(ARR_StoreList.IsEmpty()!=true) { return ARR_StoreList; }/* if(ARR_StoreList.IsEmpty()!=true)*/ ZCLink* VP_HeadLink=0; ZCLink* VP_TailLink=0; GetManyLinkCopy ///////////////////////////// ( const_cast(AP_CopyLink), AL_FarNum , VP_HeadLink , VP_TailLink ); ///////////////////////////////////////////// ZCLink::MakeRing(VP_HeadLink, VP_TailLink); ARR_StoreList.mp_HeadLink = VP_HeadLink; ARR_StoreList.ml_LinkSize = (AL_FarNum<0 ? -AL_FarNum : AL_FarNum)+1 ; return ARR_StoreList; }/* ZtCObjList& CopyLink ########################################################### ( const ZCLink* AP_CopyLink , TypeSize AL_FarNum , ZtCObjList& ARR_StoreList ) const ###############################################################################*/ ZtCObjList& CopyThis(ZtCObjList& ARR_StoreList) const { return CopyLink(mp_HeadLink, ml_LinkSize-1, RR(ARR_StoreList)); }/* ZtCObjList& CopyThis(ZtCObjList& ARR_StoreList) const*/ ZtCObjList& MakeDefault (TypeSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const { // must AL_DefaultSize > 0 ZCLink* VP_HeadLink=0; ZCLink* VP_TailLink=0; GetManyLink (AL_DefaultSize, RR(VP_HeadLink), RR(VP_TailLink)); ZCLink::MakeRing(VP_HeadLink, VP_TailLink); ARR_StoreList.mp_HeadLink= VP_HeadLink ; ARR_StoreList.ml_LinkSize= AL_DefaultSize ; return ARR_StoreList; }/* ZtCObjList& MakeDefault (TypeSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const*/ void GetManyLink( TypeSize AL_LinkSize, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink) const { mo_FreeObjt.SendFreeOut (AL_LinkSize, RR(APR_HeadLink), RR(APR_TailLink)); }/* void GetManyLink( TypeSize AL_LinkSize, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink) const */ void GetManyLinkCopy /*#######################################################*/ ( ZCLink* AP_CopyLink , TypeSize AL_FarNum , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) const /*#############################################################################*/ { // AL_FarNum 의 절대값 + 1 개의 링크가 생성된다. mo_FreeObjt.SendFreeOutCopy (AP_CopyLink, AL_FarNum, RR(APR_HeadLink), RR(APR_TailLink)); }/* void GetManyLinkCopy ########################################################### ( ZCLink* AP_CopyLink , TypeSize AL_FarNum , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) const ###############################################################################*/ /*protected:*/ public : ZtCObjList() { mp_HeadLink = 0; ml_LinkSize = 0; }/* ZtCObjList()*/ ZtCObjList(const ZtCObjList& rhs):mp_HeadLink(0),ml_LinkSize(0) { *this=rhs; }/* ZtCObjList(const ZtCObjList& rhs)*/ virtual ~ZtCObjList() { DeleteAll(); #if(_CODE_NEW_) mo_FreeObjt.DeleteHeap(); #endif }/* virtual ~ZtCObjList()*/ ZtCObjList& operator=(const ZtCObjList& rhs) { if(rhs.ml_LinkSize<1) { return DeleteAll(); } if(ml_LinkSize<=rhs.ml_LinkSize) { AddDefault(rhs.ml_LinkSize-ml_LinkSize, ml_LinkSize+1); } else // ml_LinkSize > rhs.ml_LinkSize { ZtCObjList VO_StoreList; CutLink //////////////////////////////////////////////// ( GetLinkPtr(rhs.ml_LinkSize+1), GetLinkPtr( ml_LinkSize ), ml_LinkSize - rhs.ml_LinkSize, RR(VO_StoreList) ). DeleteAll(); ///////////////////////////////////////////////////////// }/* else*/ ZCLink* pRhsLink = rhs.mp_HeadLink; ZCLink* pLhsLink = mp_HeadLink; __for1(TypeSize, i, ml_LinkSize) { **pLhsLink = ** pRhsLink ; pLhsLink = pLhsLink->mp_NextLink; pRhsLink = pRhsLink->mp_NextLink; }/* __for1(TypeSize, i, ml_LinkSize)*/ return *this; }/* ZtCObjList& operator=(const ZtCObjList& rhs)*/ bool IsEmpty() const{ return mp_HeadLink==0 ; } bool empty () const{ return mp_HeadLink==0 ; } TypeSize GetSize () const{return ml_LinkSize;} TypeSize size () const{return ml_LinkSize;} TypeSize capacity() const { return size()+mo_FreeObjt.size(); } TypeSize GetFreeSize() const { return mo_FreeObjt.size(); } TypeSize size_free () const { return mo_FreeObjt.size(); } ZCLink* GetHeadLinkPtr(){return mp_HeadLink;} ZCLink* GetTailLinkPtr() { return mp_HeadLink==0 ? 0 : mp_HeadLink->mp_PrevLink ; }/* ZCLink* GetTailLinkPtr()*/ const ZCLink* GetHeadLinkPtr() const{return mp_HeadLink;} const ZCLink* GetTailLinkPtr() const { return mp_HeadLink==0 ? 0 : mp_HeadLink->mp_PrevLink ; }/* const ZCLink* GetTailLinkPtr() const*/ ZCLinkOpt GetHeadLinkOpt(){return ZCLinkOpt(mp_HeadLink);} ZCLinkOpt GetTailLinkOpt() { if(mp_HeadLink==0) return ZCLinkOpt(0); return ZCLinkOpt(*mp_HeadLink->mp_PrevLink); }/* ZCLinkOpt GetTailLinkOpt()*/ const ZCLinkOpt GetHeadLinkOpt() const{return ZCLinkOpt(mp_HeadLink);} const ZCLinkOpt GetTailLinkOpt() const { if(mp_HeadLink==0) return ZCLinkOpt(0); return ZCLinkOpt(*mp_HeadLink->mp_PrevLink); }/* const ZCLinkOpt GetTailLinkOpt()*/ Type& operator[](TypeSize AL_Index) // start by 1 { return GetLinkPtr(AL_Index)->GetData(); }/* Type& operator[](TypeSize AL_Index)*/ const Type& operator[](TypeSize AL_Index) const { return GetLinkPtr(AL_Index)->GetData(); }/* Type& operator[](TypeSize AL_Index) const*/ ZCFreeHeap& GetCFreeHeap() const { return mo_FreeObjt; }/* ZCFreeHeap& GetCFreeHeap() const*/ TypeSize Find /*###############################################################*/ ( TypeArg AR_SearchType , TypeSize AL_FirstFindIndex =1 , bool AB_DoFindFromFront=true ) const /*#############################################################################*/ { // AB_DoFindFromFront==true 이면 AL_FirstFindIndex 번째 링크부터 // 다음 링크로 순회하면서 GetData() == AR_SearchType 이 되는 // 최초의 위치를 반환한다. const bool CB_IsTrue = ////////////////// ( mp_HeadLink == 0 || AL_FirstFindIndex < 1 || AL_FirstFindIndex > ml_LinkSize ) ; if(CB_IsTrue) return 0; //////////////// TypeSize VL_FindIndex=AL_FirstFindIndex; const ZCLink* VP_TempLink =GetLinkPtr(AL_FirstFindIndex); if(AB_DoFindFromFront==true) { do ///////// { if(VP_TempLink->GetData()==AR_SearchType) return VL_FindIndex; if(VL_FindIndex ==ml_LinkSize ) return 0 ; VP_TempLink=VP_TempLink->mp_NextLink; ++VL_FindIndex; } while(true); } else // AB_DoFindFromFront!=true { do ///////// { if(VP_TempLink->GetData()==AR_SearchType) return VL_FindIndex; if(VL_FindIndex ==1 ) return 0 ; VP_TempLink=VP_TempLink->mp_PrevLink; --VL_FindIndex; } while(true); }/* else // AB_DoFindFromFront!=true*/ return 0; }/* TypeSize Find ################################################################### ( TypeArg AR_SearchType , TypeSize AL_FirstFindIndex =1 , bool AB_DoFindFromFront=true ) const ###############################################################################*/ TypeSize Find /*##############################################################*/ ( const ZCLink& AR_SearchLink , TypeSize AL_FirstFindIndex =1, bool AB_DoFindFromFront=true ) const /*#############################################################################*/ { if(mp_HeadLink==0 || AL_FirstFindIndex<1 || AL_FirstFindIndex>ml_LinkSize) return 0; ////////////////////////////////////////////////////////////////////////// TypeSize VL_FindIndex= AL_FirstFindIndex; ZCLink* VP_TempLink = const_cast ( GetLinkPtr(AL_FirstFindIndex) ); if(AB_DoFindFromFront==true) { do /**/ { if(VP_TempLink ==&AR_SearchLink) return VL_FindIndex; if(VL_FindIndex==ml_LinkSize ) return 0 ; VP_TempLink=VP_TempLink->mp_NextLink; ++VL_FindIndex; } while(true); } else // AB_DoFindFromFront!=true { do /**/ { if(VP_TempLink ==&AR_SearchLink) return VL_FindIndex; if(VL_FindIndex==1 ) return 0 ; VP_TempLink=VP_TempLink->mp_PrevLink; --VL_FindIndex; } while(true); }/* else // AB_DoFindFromFront!=true*/ return 0; }/* TypeSize Find ################################################################## ( ZCLink& AR_SearchLink , TypeSize AL_FirstFindIndex =1 , bool AB_DoFindFromFront=true ) const /*#############################################################################*/ /*//////////////////////////////////////////////////////////////////////////////////////// ■ FindData(TypeArg, ~) 함수가 없다면, TypeArg 이 const Type& 으로 정의되어 있는 경우, const Type& 에 대해서만 찾기를 수행할 수 있고, Type& 에 대해서는 찾기를 수행할 수 없다. -- 2010-05-29 21:31:00 ////////////////////////////////////////////////////////////////////////////////////////*/ TypeSize FindData( TypeArg AR_SearchType, TypeSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const { return Find(AR_SearchType, AL_FirstFindIndex, AB_DoFindFromFront); }/* TypeSize FindData( TypeArg AR_SearchType, TypeSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const*/ ZCLink* GetLinkPtr(TypeSize AL_Index) { TypeSize VI_LeftDistance =AL_Index-1 ; TypeSize VI_RightDistance=ml_LinkSize-AL_Index+1; TypeSize VI_ShortDistance= (VI_LeftDistance<=VI_RightDistance ? VI_LeftDistance : -VI_RightDistance); return mp_HeadLink->GetNextPrevPtr(VI_ShortDistance); }/* ZCLink* GetLinkPtr(TypeSize AL_Index)*/ const ZCLink* GetLinkPtr(TypeSize AL_Index) const // or 'ZCLink const * const GetLinkPtr(TypeSize AL_Index) const' { TypeSize VI_LeftDistance = AL_Index-1 ; TypeSize VI_RightDistance= ml_LinkSize -AL_Index+1; TypeSize VI_ShortDistance= (VI_LeftDistance<=VI_RightDistance ? VI_LeftDistance : -VI_RightDistance); return mp_HeadLink->GetNextPrevPtr(VI_ShortDistance); }/* const ZCLink* GetLinkPtr(TypeSize AL_Index) const*/ ZCLinkOpt GetLinkOpt(TypeSize AL_Index) { if(mp_HeadLink==0) return ZCLinkOpt(0); return ZCLinkOpt(*GetLinkPtr(AL_Index)); }/* ZCLinkOpt GetLinkOpt(TypeSize AL_Index)*/ const ZCLinkOpt GetLinkOpt(TypeSize AL_Index) const { if(mp_HeadLink==0) return ZCLinkOpt(0); return ZCLinkOpt(*GetLinkPtr(AL_Index)); }/* const ZCLinkOpt GetLinkOpt(TypeSize AL_Index) const*/ ZtCObjList& DeleteAll() { if(mp_HeadLink==0) return *this; mo_FreeObjt.RecvFreeIn ( ml_LinkSize, mp_HeadLink, mp_HeadLink->mp_PrevLink ); mp_HeadLink= 0; ml_LinkSize= 0; return *this; }/* ZtCObjList& DeleteAll()*/ ZtCObjList& clear() { return this->DeleteAll(); }/* ZtCObjList& clear()*/ ZtCObjList& DeleteHeap() { mo_FreeObjt.DeleteHeap(); return *this; }/* ZtCObjList& DeleteHeap()*/ ZtCObjList& DeleteLink(ZCLink& AR_DeleteLink) { #if(_CODE_NEW_) mo_FreeObjt.RecvFreeIn ( this->CutLink(&AR_DeleteLink) ); #else delete this->CutLink(&AR_DeleteLink); #endif return *this; }/* ZtCObjList& DeleteLink(ZCLink& AR_DeleteLink)*/ ZtCObjList& Delete(ZCLink& AR_DeleteLink) { return DeleteLink(&AR_DeleteLink); }/* ZtCObjList& Delete(ZCLink& AR_DeleteLink)*/ ZtCObjList& Delete(TypeSize AL_DeletePos) { if(AL_DeletePos<1 || this->ml_LinkSize>AL_DeletePos) { return *this; } Delete(this->GetLinkPtr(AL_DeletePos)); return *this; }/* ZtCObjList& Delete(TypeSize AL_DeletePos)*/ ZtCObjList& DeleteHead() { if(ml_LinkSize>0) #if(_CODE_NEW_) mo_FreeObjt.RecvFreeIn ( this->CutLink(mp_HeadLink) ); #else delete this->CutLink(mp_HeadLink) ; #endif return *this; }/* ZtCObjList& DeleteHead()*/ void DeleteHead(TypeSize AL_DelSize) { // AL_DelSize 개의 링크를 앞 부분에서 삭제 if(ml_LinkSize<1 || AL_DelSize<1){ return; } if(AL_DelSize> ml_LinkSize){ AL_DelSize=ml_LinkSize; } if(AL_DelSize==ml_LinkSize) { GetCFreeHeap().RecvFreeIn (ml_LinkSize, mp_HeadLink, mp_HeadLink->mp_PrevLink); mp_HeadLink=0 ; ml_LinkSize=0 ; return; }/* if(AL_DelSize==ml_LinkSize)*/ ZCLink* VP_TailLink= mp_HeadLink->mp_PrevLink ; ZCLink* VP_NewHead = &((*mp_HeadLink)+AL_DelSize); GetCFreeHeap().RecvFreeIn (AL_DelSize, mp_HeadLink, VP_NewHead->mp_PrevLink); mp_HeadLink = VP_NewHead ; ml_LinkSize -= AL_DelSize ; ZCLink::MakeRing(mp_HeadLink, VP_TailLink); }/* void DeleteHead(TypeSize AL_DelSize)*/ ZtCObjList& DeleteTail() { if(ml_LinkSize>0) #if(_CODE_NEW_) mo_FreeObjt.RecvFreeIn ( this->CutLink(mp_HeadLink->mp_PrevLink) ); #else delete this->CutLink(mp_HeadLink->mp_PrevLink) ; #endif return *this; }/* ZtCObjList& DeleteTail()*/ void DeleteTail(TypeSize AL_DelSize) { if(ml_LinkSize==0 || AL_DelSize<1){ return; } if(AL_DelSize> ml_LinkSize){ AL_DelSize=ml_LinkSize; } if(AL_DelSize==ml_LinkSize) { GetCFreeHeap().RecvFreeIn (ml_LinkSize, mp_HeadLink, mp_HeadLink->mp_PrevLink); mp_HeadLink=0 ; ml_LinkSize=0 ; return; }/* if(AL_DelSize==ml_LinkSize)*/ ZCLink* VP_TailLink= mp_HeadLink->mp_PrevLink ; ZCLink* VP_NewTail = &((*VP_TailLink)-AL_DelSize); GetCFreeHeap().RecvFreeIn (AL_DelSize, VP_NewTail->mp_NextLink, VP_TailLink); ml_LinkSize -= AL_DelSize ; ZCLink::MakeRing(mp_HeadLink, VP_NewTail); }/* void DeleteTail(TypeSize AL_DelSize)*/ ZCLink& AddDefault(TypeSize AL_DefSize, TypeSize AL_AddPos) { if(AL_DefSize<1) AL_DefSize= 1; if(AL_AddPos <1) AL_AddPos = 1; ZtCObjList VO_StoreList; MakeDefault ( AL_DefSize, RR(VO_StoreList) ) ; ZCLink* VP_HeadLink= VO_StoreList.mp_HeadLink; if(AL_AddPos==1) JoinAfter(VO_StoreList, ZCLinkOpt(0) ); else JoinAfter(VO_StoreList, GetLinkOpt(AL_AddPos-1)); return *VP_HeadLink; }/* ZCLink& AddDefault(TypeSize AL_DefSize, TypeSize AL_AddPos)*/ ZtCObjList& AddHead(TypeArg AR_Type) { #if(_CODE_NEW_) ZCLink* VP_NewNode = mo_FreeObjt.SendFreeOut(); #else ZCLink* VP_NewNode = new ZCLink ; #endif #if(_CODE_NEW_) if(TypeMoveObj::ZEUseMoveObj>0) //////////////////// { TypeMoveObj::Exec(**VP_NewNode, AR_Type); JoinAfter(VP_NewNode, 0); return *this ; } //////////////////////////////////////////////////// #endif **VP_NewNode = AR_Type; JoinAfter(VP_NewNode, 0); return *this; }/* ZtCObjList& AddHead(TypeArg AR_Type)*/ ZtCObjList& AddHead(const ZtCObjList& rhs) { if(this==&rhs) return *this ; ZtCObjList VO_StoreList(rhs); JoinAfter(VO_StoreList, 0); return *this; }/* ZtCObjList& AddHead(const ZtCObjList& rhs)*/ ZtCObjList& AddTail(TypeArg AR_Type) { #if(_CODE_NEW_) ZCLink* VP_NewNode = mo_FreeObjt.SendFreeOut(); #else ZCLink* VP_NewNode = new ZCLink ; #endif #if(_CODE_NEW_) if(TypeMoveObj::ZEUseMoveObj>0) //////////////////// { TypeMoveObj::Exec(**VP_NewNode, AR_Type); JoinAfter(VP_NewNode, GetTailLinkPtr()); return *this; } //////////////////////////////////////////////////// #endif **VP_NewNode = AR_Type; JoinAfter (VP_NewNode, GetTailLinkPtr()); return *this ; }/* ZtCObjList& AddTail(TypeArg AR_Type)*/ ZtCObjList& AddTail(const ZtCObjList& rhs) { ZtCObjList VO_StoreList(rhs); return JoinTail(VO_StoreList); }/* ZtCObjList& AddTail(const ZtCObjList& rhs)*/ /*/////////////////////////////////////////////////////////////////// ■ ZCLink* AddHeadDef() 함수의 코드 중 return 문이 return *this 라고 되어 있었다. 10 여년간 이를 모른 것이다. 자그마치 10 여년간! -- 2015-02-21- 21:36:00 ///////////////////////////////////////////////////////////////////*/ ZCLink& AddHeadDef() { #if(_CODE_NEW_) ZCLink* VP_NewLink = mo_FreeObjt.SendFreeOut(); #else ZCLink* VP_NewLink = new ZCLink ; #endif JoinAfter(VP_NewLink, 0); return *VP_NewLink; } ZCLink& AddTailDef() { #if(_CODE_NEW_) ZCLink* VP_NewLink = mo_FreeObjt.SendFreeOut(); #else ZCLink* VP_NewLink = new ZCLink ; #endif JoinAfter(VP_NewLink, GetTailLinkPtr()); return *VP_NewLink; } ZtCObjList& pop_back (TypeArg AR_Type){return AddHead(AR_Type);} ZtCObjList& push_back(TypeArg AR_Type){return AddTail(AR_Type);} ZtCObjList& JoinHead(ZtCObjList& rhs) { if(this==&rhs) return *this; JoinAfter(rhs, 0); return *this; }/* ZtCObjList& JoinHead(ZtCObjList& rhs)*/ ZtCObjList& JoinHead(ZtCObjList& rhs, ZCLink& AR_CLink) { // rhs 의 AP_CLink 를 앞으로 연결한다. if(this==&rhs) return *this; JoinAfter (rhs.CutLink(&AR_CLink), 0); return *this; }/* ZtCObjList& JoinHead(ZtCObjList& rhs, ZCLink& AR_CLink)*/ ZtCObjList& JoinTail(ZtCObjList& rhs) { if(this==&rhs) return *this; JoinAfter(rhs, GetTailLinkPtr()); return *this; }/* ZtCObjList& JoinTail(ZtCObjList& rhs)*/ ZtCObjList& JoinTail(ZtCObjList& rhs, ZCLink& AR_CLink) { // rhs 의 AR_CLink 를 뒤로 연결한다. if(this==&rhs) return *this; JoinAfter ////////////////////////////////////// ( rhs.CutLink(&AR_CLink), GetTailLinkPtr() ); return *this; ////////////////////////////////// }/* ZtCObjList& JoinTail(ZtCObjList& rhs, ZCLink& AR_CLink)*/ ZtCObjList& JoinAfter /*######################################################*/ ( ZtCObjList& rhs , ZCLink& AR_LinkOfRhs, ZCLinkOpt AO_StdOpt ) /*#############################################################################*/ { // rhs 의 AP_LinkOfRhs 링크를 잘라서 AO_StdOpt 뒤에 붙인다. if(this==&rhs) return *this; JoinAfter( rhs.CutLink(&AR_LinkOfRhs), AO_StdOpt.Raw() ); return *this; }/* ZtCObjList& JoinAfter ########################################################## ( ZtCObjList& rhs , ZCLink& AR_LinkOfRhs, ZCLinkOpt AO_StdOpt ) ###############################################################################*/ void SendOutAfter (ZCLink& AR_CutLink, TypeThis& rhs, ZCLink& AR_StdLink) { // AR_CutLink 를 잘라서 rhs 의 AR_StdLink 뒤에 연결한다. CutLink(&AR_CutLink); rhs.JoinAfter(&AR_CutLink, &AR_StdLink); }/* void SendOutAfter (ZCLink& AR_CutLink, TypeThis& rhs, ZCLink& AR_StdLink)*/ void SendOutBefore(ZCLink& AR_CutLink, TypeThis& rhs, ZCLink& AR_StdLink) { // AR_CutLink 를 잘라서 rhs 의 AR_StdLink 앞에 연결한다. CutLink(&AR_CutLink); rhs.JoinBefore(&AR_CutLink, &AR_StdLink); }/* void SendOutBefore(ZCLink& AR_CutLink, TypeThis& rhs, ZCLink& AR_StdLink)*/ void SendOutHead(ZCLink& AR_CutLink, TypeThis& rhs) { CutLink(&AR_CutLink); rhs.JoinAfter (&AR_CutLink, 0); } void SendOutTail(ZCLink& AR_CutLink, TypeThis& rhs) { CutLink(&AR_CutLink); rhs.JoinBefore(&AR_CutLink, 0); } TypeThis& SendRangeOut ////////////////////////////////////////////////// ( ZCLink& AR_CutHead, ZCLink& AR_CutTail, TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt, bool AB_After ) /*#####################################################################*/ { return CutLinkRangeOut ( &AR_CutHead, &AR_CutTail, AI_CutSize, rhs, AO_LinkOpt.Raw(), AB_After ); ////////////////////// }/* TypeThis& SendRangeOutAfter ///////////////////////////////////////////// ( ZCLink& AR_CutHead, ZCLink& AR_CutTail, TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt ) /*#####################################################################*/ TypeThis& SendRangeOutAfter ///////////////////////////////////////////// ( ZCLink& AR_CutHead, ZCLink& AR_CutTail, TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt ) /*#####################################################################*/ { // AR_CutHead 부터 AR_CutTail 까지를 잘라서 rhs 의 AO_ObjOpt 뒤에 연결한다. return CutLinkRangeOut ( &AR_CutHead, &AR_CutTail, AI_CutSize, rhs, AO_LinkOpt.Raw(), true ); ////////////////////// } TypeThis& SendRangeOutBefore //////////////////////////////////////////// ( ZCLink& AR_CutHead, ZCLink& AR_CutTail, TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt ) /*#####################################################################*/ { // AR_CutHead 부터 AR_CutTail 까지를 잘라서 rhs 의 AO_ObjOpt 뒤에 연결한다. return CutLinkRangeOut ( &AR_CutHead, &AR_CutTail, AI_CutSize, rhs, AO_LinkOpt.Raw(), false ); ////////////////////// }/* TypeThis& SendRangeOutAfter ///////////////////////////////////////////// ( ZCLink& AR_CutHead, ZCLink& AR_CutTail, TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt ) /*#####################################################################*/ operator Type&() { return AddDefault(1, ml_LinkSize+1)->GetData(); }/* operator Type&()*/ Type& GetData(TypeSize AI_Index) { return GetLinkPtr(AI_Index)->GetData(); }/* Type& GetData(TypeSize AI_Index)*/ const Type& GetData(TypeSize AI_Index) const { return GetLinkPtr(AI_Index)->GetData(); }/* const Type& GetData(TypeSize AI_Index) const*/ Type& GetHeadData() { return mp_HeadLink->GetData(); }/* Type& GetHeadData()*/ Type& GetTailData() { return mp_HeadLink->mp_PrevLink->GetData(); }/* Type& GetTailData()*/ const Type& GetHeadData() const { return mp_HeadLink->GetData(); }/* const Type& GetHeadData() const*/ const Type& GetTailData() const { return mp_HeadLink->mp_PrevLink->GetData(); }/* const Type& GetTailData() const*/ ZCDataOpt GetHeadDataOpt() { if(mp_HeadLink==0) return ZCDataOpt(0); return ZCDataOpt(**mp_HeadLink); }/* ZCDataOpt GetHeadDataOpt()*/ ZCDataOpt GetTailDataOpt() { if(mp_HeadLink==0) return ZCDataOpt(0); return ZCDataOpt(**mp_HeadLink->mp_PrevLink); }/* ZCDataOpt GetTailDataOpt()*/ const ZCDataOpt GetHeadDataOpt() const { if(mp_HeadLink==0) return ZCDataOpt(0); return ZCDataOpt(**mp_HeadLink); }/* const ZCDataOpt GetHeadDataOpt() const*/ const ZCDataOpt GetTailDataOpt() const { if(mp_HeadLink==0) return ZCDataOpt(0); return ZCDataOpt(**mp_HeadLink->mp_PrevLink); }/* const ZCDataOpt GetTailDataOpt() const*/ ZCDataOpt GetDataOpt(TypeSize AI_Index) { if(mp_HeadLink==0) return ZCDataOpt(0); return ZCDataOpt( GetLinkPtr(AI_Index)->GetData() ); }/* ZCDataOpt GetDataOpt(TypeSize AI_Index)*/ const ZCDataOpt GetDataOpt(TypeSize AI_Index) const { if(mp_HeadLink==0) return ZCDataOpt(0); return ZCDataOpt( GetLinkPtr(AI_Index)->GetData() ); }/* const ZCDataOpt GetDataOpt(TypeSize AI_Index) const*/ Type& front(){return GetHeadData();} Type& back (){return GetTailData();} const Type& front() const{return GetHeadData();} const Type& back () const{return GetTailData();} ZtCObjList& Rotate(TypeSize AL_RotateNum) { if(ml_LinkSize>0) mp_HeadLink = mp_HeadLink->GetNextPrevPtr(AL_RotateNum); return *this; }/* ZtCObjList& Rotate(TypeSize AL_RotateNum)*/ ZtCObjList& Rotate () { if(ml_LinkSize>0) mp_HeadLink = mp_HeadLink->mp_NextLink ; return *this; } ZtCObjList& RotateBack() { if(ml_LinkSize>0) mp_HeadLink = mp_HeadLink->mp_PrevLink ; return *this; } template void IterElement(TFunctor AO_Functor) { ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData:: GetObjRef(AO_Functor)( **VP_LoopLink ); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElement(TFunctor AO_Functor) */ template void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) { typedef ZNsMain:: ZtCCheckRef ZCCheckRef; ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( **VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */ template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElement ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) /*#############################################################################*/ { typedef ZNsMain::ZtCCheckRef ZCCheckRef1; typedef ZNsMain::ZtCCheckRef ZCCheckRef2; ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( **VP_LoopLink , ZCCheckRef1::PassData(AO_TypeHelp1) , ZCCheckRef2::PassData(AO_TypeHelp2) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElement ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) ###############################################################################*/ template void IterElemRef(TFunctor AO_Functor, TTypeHelp& AR_TypeHelp) { /* TTypeHelp 을 참조로 받고 있음에 주의한다. -- 2015-09-07 02:55:00 */ ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef (AO_Functor)(**VP_LoopLink, AR_TypeHelp); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElemRef(TFunctor AO_Functor, TTypeHelp& AR_TypeHelp) */ template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElemRef ( TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2 ) /*#############################################################################*/ { /* TTypeHelp1 과 2 을 참조로 받고 있음에 주의한다. -- 2021-03-04 04:00:00 */ ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( **VP_LoopLink, AR_TypeHelp1, AR_TypeHelp2 ); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElemRef ( TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2 ) /*#############################################################################*/ template void IterElemRev(TFunctor AO_Functor) { // 끝에서부터 순회한다. if(size()<1) return; ZCLink* VP_LoopLink = mp_HeadLink->mp_PrevLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData:: GetObjRef(AO_Functor)( **VP_LoopLink ); VP_LoopLink = VP_LoopLink->mp_PrevLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElemRev(TFunctor AO_Functor) */ template void IterElemRev(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) { if(size()<1) return; ////////////////////////////// typedef ZNsMain::ZtCCheckRef ZCCheckRef; ZCLink* VP_LoopLink = mp_HeadLink->mp_PrevLink ; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( **VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_PrevLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElemRev(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */ template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElemRev ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) /*#############################################################################*/ { if(size()<1) return; typedef ZNsMain::ZtCCheckRef ZCCheckRef1; typedef ZNsMain::ZtCCheckRef ZCCheckRef2; ZCLink* VP_LoopLink = mp_HeadLink->mp_PrevLink ; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( VP_LoopLink->mo_DataObjt , ZCCheckRef1::PassData(AO_TypeHelp1) , ZCCheckRef2::PassData(AO_TypeHelp2) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_PrevLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElemRev ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) ###############################################################################*/ template void IterElemLink(TFunctor AO_Functor) { ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData:: GetObjRef(AO_Functor)( *VP_LoopLink ); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElemLink(TFunctor AO_Functor) */ template void IterElemLink(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) { typedef ZNsMain:: ZtCCheckRef ZCCheckRef; ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( *VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template void IterElemLink(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */ template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElemLink ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) /*#############################################################################*/ { typedef ZNsMain::ZtCCheckRef ZCCheckRef1; typedef ZNsMain::ZtCCheckRef ZCCheckRef2; ZCLink* VP_LoopLink=mp_HeadLink; __for0(TypeSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( *VP_LoopLink , ZCCheckRef1::PassData(AO_TypeHelp1) , ZCCheckRef2::PassData(AO_TypeHelp2) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TypeSize, i, ml_LinkSize)*/ }/* template < typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 > void IterElemLink ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) ###############################################################################*/ template void IterElemLink /////////////////////// ( ZCLink& AR_StdLink , TypeSize AL_WorkDistance, TFunctor AO_Functor ) /*#################################################################*/ { /* AP_StdLink 부터 AL_WorkDistance 만큼 이동하면서 * 각 ZCLink 에 대하여 AO_Functor() 함수를 수행한다. (총 수행 횟수는 (AL_WorkDistance)절대값+1) */ ZCLink* VP_StdLink = &AR_StdLink; if(AL_WorkDistance>=0) { for(TypeSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop) { ZtCTypeData:: GetObjRef(AO_Functor)(*VP_StdLink); VP_StdLink = VP_StdLink->mp_NextLink ; }/* for(TypeSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop)*/ } else // AL_WorkDistance<0 { AL_WorkDistance = -AL_WorkDistance; for(TypeSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop) { ZtCTypeData:: GetObjRef(AO_Functor)(*VP_StdLink); VP_StdLink = VP_StdLink->mp_PrevLink ; }/* for(TypeSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop)*/ }/* else // AL_WorkDistance<0*/ }/* void IterElemLink /////////////////////////////////////////////////// ( ZCLink& AR_StdLink , TypeSize AL_WorkDistance, TFunctor AO_Functor ) /*#################################################################*/ /*/////////////////////////////////////////////////////////////////////////// ■ IterElement() 예제. #include #include "ZCppMain/ZtCObjList.H" using namespace std; int main() { ZNsMain:: ZtCObjList myObjList; myObjList.AddTail(10); myObjList.AddTail(20); myObjList.AddTail(30); myObjList.AddTail(40); struct StFunctor { static void ShowElement(int ArgiValue){cout<<"# Value="< CArray ; typedef ZtCObjList CObjList ; typedef CArray ::IterEasy IterEasyA; typedef CObjList::IterEasy IterEasyL; CArray VO_CArray; CObjList VO_CObjList; VO_CArray.AddTail(10); VO_CArray.AddTail(20); VO_CArray.AddTail(30); VO_CArray.AddTail(40); VO_CObjList.AddTail(10); VO_CObjList.AddTail(20); VO_CObjList.AddTail(30); VO_CObjList.AddTail(40); IterEasyA VH_IterA = VO_CArray .ItHEasy(); IterEasyL VH_IterL = VO_CObjList.ItHEasy(); class CHelpObj { public: CHelpObj() { } CHelpObj(const CHelpObj& rhs) { cout<<"* CHelpObj(const CHelpObj& rhs)"<