#ifndef __ZCPPMAIN__ZCSIMLIST_H__ #define __ZCPPMAIN__ZCSIMLIST_H__ #include "ZCppMain/ZMainHead.H" namespace ZNsMain { template ////////////////////////////////////////////////////// < typename TType , typename TTypArgu , typename TTypCAlloc , typename TTypCInit , typename TTypSize , typename TMoveObj , typename TFeeeHeap > class ZtCSimList; ///////////////////////////////////////////// namespace ZNsIFaceEx { template<> class ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single > { public: template class ZtCBody { public : typedef typename TSimList::TypeSize TypeSize; typedef typename TSimList::TypeInit TypeInit; typedef typename TSimList::ZCLink ZCLink ; public : template ////////////////////////////////////////////////////// < typename TType , typename TTypArgu , typename TTypCAlloc , typename TTypCInit , typename TTypSize , typename TMoveObj , typename TFeeeHeap > friend class ZNsMain::ZtCSimList; ///////////////////////////// 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->GetNexPtr() ; }/* 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) { DeleteHeap(); // 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 ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single >*/ }/* namespace ZNsIFaceEx*/ template class ZtCSortObjList; template /*##################################################################*/ < typename TType , typename TTypArgu = const TType& , typename TTypCAlloc= ZCAllocator , typename TTypCInit = ZtCInit , typename TTypSize = ZTypLong , typename TMoveObj = ZNsMain:: ZtCMoveObj , typename TFeeeHeap = ZNsIFaceEx:: ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single > > class ZtCSimList /*##########################################################*/ { public: class ZCLink ; class ZCNodePoint ; class ZNodekPointN; /**************************************************/ typedef TType Type ; typedef TType TypeData ; typedef TTypArgu TypeArg ; typedef TTypCAlloc TypeAlloc ; typedef TTypCInit TypeInit ; typedef TTypSize TypeSize ; typedef TMoveObj TypeMoveObj ; typedef ZCLink TypeLink ; typedef ZCLink TypeNode ; typedef ZtCSimList TypeList ; typedef ZtCSimList TypeThis ; typedef ZCNodePoint TypeIter ; /**************************************************/ typedef const ZCLink ZCLinkC ; typedef const TypeThis TypeThisC ; typedef const TypeData TypeDataC ; typedef const TypeList TypeListC ; typedef const TypeLink TypeLinkC ; typedef const TypeNode TypeNodeC ; typedef const TypeIter TypeIterC ; /**************************************************/ typedef ZCNodePoint iterator ; typedef ZNodekPointN const_iterator ; typedef ZNodekPointN iteratorN ; /**************************************************/ typedef typename TFeeeHeap:: template ZtCBody ZCFreeHeap; /**************************************************/ public: class ZCLink : public TypeAlloc { public: template friend class ZtCSortObjList; ///////////// template friend class ZNsIFaceEx::ZtCFreeHeapSngl ; public: friend class ZtCSimList ; private: ZCLink* mp_NextLink; TType mo_DataObjt; private: inline static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink) { // 두 개의 링크를 연결 상태로 만든다. AP_PrevLink->mp_NextLink = AP_NextLink; }/* inline static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink)*/ inline static void MakeRing(ZCLink* AP_HeadLink, ZCLink* AP_TailLink) { // 처음과 끝 링크를 연결하여 원형상태로 만든다. // 이것은 ZtCSimList class template 과 멤버 함수를 맞추기 위한 것으로 // 실제적으로는 별 쓸모는 없는 것 같다. AP_TailLink->mp_NextLink = AP_HeadLink; }/* inline static void MakeRing(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)*/ //private: public : ZCLink():mp_NextLink(0) { }/* ZCLink()*/ ZCLink(const ZCLink& rhs):mp_NextLink(0) { // TType 의 대입연산자는 반드시 public 영역에 있어야 한다. mo_DataObjt=rhs.mo_DataObjt; }/* ZCLink(const ZCLink& rhs)*/ ZCLink(TypeArg AR_Type):mp_NextLink(0) { mo_DataObjt=AR_Type; }/* ZCLink(TypeArg AR_Type)*/ operator TType&() { return mo_DataObjt; }/* operator TType&()*/ operator TType() { return mo_DataObjt; }/* operator TType()*/ TType& GetData() { return mo_DataObjt; }/* TType& GetData()*/ const TType& GetData() const { return mo_DataObjt; }/* const TType& GetData() const*/ TType& GetData(TypeSize AL_FarNum) // must AL_FarNum >= 0 { return GetNextPtr(AL_FarNum)->mo_DataObjt; }/* TType& GetData(TypeSize AL_FarNum)*/ const TType& GetData(TypeSize AL_FarNum) const { return GetNextPtr(AL_FarNum)->mo_DataObjt; }/* const TType& GetData(TypeSize AL_FarNum) const*/ TType& operator* (){return mo_DataObjt;} TType& operator()(){return mo_DataObjt;} const TType& operator* () const{return mo_DataObjt;} const TType& operator()() const{return mo_DataObjt;} ZCLink* GetNextPtr(TypeSize AL_FarNum) // must AL_FarNum > 0 { // 이 멤버 함수는 TypeSize 가 용랑이 큰 object 라 할지라도 // 이 함수 내부에서 값이 변하고 있으므로 참조로 받지 않는다. ZCLink* VP_TmpLink=this; while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink; /*:::::::::::::::::*/ return VP_TmpLink; }/* ZCLink* GetNextPtr(TypeSize AL_FarNum)*/ ZCLinkC* const GetNextPtr(TypeSize AL_FarNum) const // or ZCLink const * const GetNextPtr(TypeSize AL_FarNum) const { // TypeSize 가 object 일 경우 AL_FarNum 의 값이 이 함수에서 변하고 있으므로 // TypeSize 을 참조로 받으면 안된다. ZCLink* VP_TmpLink = const_cast(this); // 이 함수는 뒤에 const keyword 가 붙어 있는데 이것 때문에 this pointer 는 상수 포인터로 간주된다. // 윗줄에서 이 this 포인터를 비상수 포인터로 먼저 형변환하였다. // ZCLink* VP_TmpLink=const_castthis; 라 하면 g++ 2.96 에서는 에러 while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink; /*:::::::::::::::::*/ return VP_TmpLink; }/* ZCLinkC* const GetNextPtr(TypeSize AL_FarNum) const*/ inline ZCLink * GetNextPtr() { return mp_NextLink; } inline ZCLinkC* const GetNextPtr() const{ return mp_NextLink; } ZCLink& operator=(TypeArg AR_Type) { mo_DataObjt=AR_Type; return *this; }/* ZCLink& operator=(TypeArg AR_Type)*/ ZCLink& operator+(TypeSize AL_Offset) { ZCLink* VP_CLinkLoop=this; __for0(TypeSize, i, AL_Offset) { VP_CLinkLoop = VP_CLinkLoop->mp_NextLink; }/* __for0(TypeSize, i, AL_Offset)*/ return *this; }/* ZCLink& operator+(TypeSize AL_Offset) public:*/ };/* class ZCLink*/ class ZCNodePoint { private: /*****/ TypeList& mr_CurrList; mutable TypeLink* mp_CurrLink; // 사실상 mp_CurrLink!=0 mutable TypeSize ml_CurrPos ; public: ZCNodePoint(TypeList& AR_TypeList) : mr_CurrList(AR_TypeList) { mp_CurrLink = AR_TypeList.HeadPtr(); ml_CurrPos = 1 ; } ZCNodePoint(const ZCNodePoint& rhs) : mr_CurrList(rhs.mr_CurrList), mp_CurrLink(rhs.mp_CurrLink), ml_CurrPos (rhs.ml_CurrPos ) {} public : static ZCNodePoint MakeTailPoint(TypeList& AR_TypeList) { ZCNodePoint VO_ZCLinkPoint(AR_TypeList); VO_ZCLinkPoint.mp_CurrLink = AR_TypeList.mp_TailLink; VO_ZCLinkPoint.ml_CurrPos = AR_TypeList.ml_LinkSize; return VO_ZCLinkPoint; /****************************/ }/* static ZCNodePoint MakeTailPoint(TypeList& AR_TypeList)*/ static ZCNodePoint MakeTailPoint(const TypeIter& AR_TypeIter) { ZCNodePoint VO_ZCLinkPoint(AR_TypeIter); VO_ZCLinkPoint.mp_CurrLink = VO_ZCLinkPoint.mr_TypeList.mp_TailLink; VO_ZCLinkPoint.ml_CurrPos = VO_ZCLinkPoint.mr_TypeList.ml_LinkSize; return VO_ZCLinkPoint; /****************************/ }/* static ZCNodePoint MakeTailPoint(const TypeIter& AR_TypeIter)*/ public : TypeThis & GetMain() {return mr_CurrList;} TypeNode & GetNode() {return *mp_CurrLink;} TypeThisC& GetMain() const{return mr_CurrList;} TypeNodeC& GetNode() const{return *mp_CurrLink;} /***************************************************/ TypeSize GetPos () const{return ml_CurrPos ;} /***************************************************/ bool IsValid() const{return mr_CurrList.size()>0;} bool IsEmpty() const{return mr_CurrList.size()<1;} ZCNodePoint& operator= (const ZCNodePoint& rhs){ return *this; } TypeData & operator*() {return **mp_CurrLink;} TypeDataC& operator*() const{return **mp_CurrLink;} operator TypeLink * () {return mp_CurrLink;} operator TypeLinkC* () const{return mp_CurrLink;} operator TypeLink & () {return *mp_CurrLink;} operator TypeLinkC& () const{return *mp_CurrLink;} bool operator == (const ZCNodePoint& rhs) const { return ml_CurrPos == rhs.ml_CurrPos; } bool operator != (const ZCNodePoint& rhs) const { return ml_CurrPos != rhs.ml_CurrPos; } bool operator > (const ZCNodePoint& rhs) const { return ml_CurrPos > rhs.ml_CurrPos; } bool operator >= (const ZCNodePoint& rhs) const { return ml_CurrPos >= rhs.ml_CurrPos; } bool operator < (const ZCNodePoint& rhs) const { return ml_CurrPos < rhs.ml_CurrPos; } bool operator <= (const ZCNodePoint& rhs) const { return ml_CurrPos <= rhs.ml_CurrPos; } bool operator == (TypeSize AL_Size) const { return ml_CurrPos == AL_Size; } bool operator != (TypeSize AL_Size) const { return ml_CurrPos != AL_Size; } bool operator > (TypeSize AL_Size) const { return ml_CurrPos > AL_Size; } bool operator >= (TypeSize AL_Size) const { return ml_CurrPos >= AL_Size; } bool operator < (TypeSize AL_Size) const { return ml_CurrPos < AL_Size; } bool operator <= (TypeSize AL_Size) const { return ml_CurrPos <= AL_Size; } const ZCNodePoint& operator++() const { mp_CurrLink = mp_CurrLink->mp_NextLink; ++ml_CurrPos; return *this ; }/* const ZCNodePoint& operator++() const*/ ZCNodePoint operator++(int) const { ZCNodePoint VO_NowPoint(*this); mp_CurrLink = mp_CurrLink->mp_NextLink; ++ml_CurrPos ; return VO_NowPoint ; }/* ZCNodePoint operator++(int) const*/ const ZCNodePoint& operator+=(TypeSize AL_Distance) const { if(IsEmpty()){return *this;} mp_CurrLink = &((*mp_CurrLink)+AL_Distance) ; ml_CurrPos += AL_Distance ; return *this; /*:::::::::::::::::::::::::::*/ }/* const ZCNodePoint& operator+=(TypeSize AL_Distance) const*/ public: };/* class ZCNodePoint*/ class ZNodekPointN { protected: const TypeList& mr_CurrList; mutable TypeLinkC* mp_CurrLink; // 사실상 mp_CurrLink!=0 mutable TypeSize ml_CurrPos ; public : ZNodekPointN(const TypeList& AR_TypeList) : mr_CurrList(AR_TypeList) { mp_CurrLink = AR_TypeList.HeadPtr(); ml_CurrPos = 1 ; } ZNodekPointN(const ZCNodePoint & rhs) : mr_CurrList( rhs.GetMain()), mp_CurrLink(&rhs.GetNode()), ml_CurrPos ( rhs.GetPos ()) {} ZNodekPointN(const ZNodekPointN& rhs) : mr_CurrList(rhs.mr_CurrList), mp_CurrLink(rhs.mp_CurrLink), ml_CurrPos (rhs.ml_CurrPos ) {} public : static ZNodekPointN MakeTailPoint(const TypeList& AR_TypeList) { ZNodekPointN VO_ZCLinkPoint(AR_TypeList); VO_ZCLinkPoint.mp_CurrLink = AR_TypeList.mp_TailLink; VO_ZCLinkPoint.ml_CurrPos = AR_TypeList.ml_LinkSize; return VO_ZCLinkPoint; /****************/ }/* static ZNodekPointN MakeTailPoint(const TypeList& AR_TypeList)*/ static ZNodekPointN MakeTailPoint(const ZCNodePoint& AR_TypeIter) { ZNodekPointN VO_ZCLinkPoint(AR_TypeIter); VO_ZCLinkPoint.mp_CurrLink = VO_ZCLinkPoint.mr_TypeList.mp_TailLink; VO_ZCLinkPoint.ml_CurrPos = VO_ZCLinkPoint.mr_TypeList.ml_LinkSize; return VO_ZCLinkPoint; /****************/ }/* static ZNodekPointN MakeTailPoint(const ZCNodePoint& AR_TypeIter)*/ static ZNodekPointN MakeTailPoint(const ZNodekPointN& AR_TypeIter) { ZNodekPointN VO_ZCLinkPoint(AR_TypeIter); VO_ZCLinkPoint.mp_CurrLink = VO_ZCLinkPoint.mr_TypeList.mp_TailLink; VO_ZCLinkPoint.ml_CurrPos = VO_ZCLinkPoint.mr_TypeList.ml_LinkSize; return VO_ZCLinkPoint; /****************/ }/* static ZNodekPointN MakeTailPoint(const ZNodekPointN& AR_TypeIter)*/ public : TypeListC& GetMain() const{return mr_CurrList;} TypeLinkC& GetNode() const{return *mp_CurrLink;} /***************************************************/ TypeSize GetPos () const{return ml_CurrPos ;} /***************************************************/ bool IsValid() const{return mr_CurrList.size()>0;} bool IsEmpty() const{return mr_CurrList.size()<1;} ZNodekPointN& operator= (const ZNodekPointN& rhs){ return *this; } TypeDataC& operator*() const{return **mp_CurrLink;} operator TypeLinkC* () const{return mp_CurrLink;} operator TypeLinkC& () const{return *mp_CurrLink;} bool operator == (const ZNodekPointN& rhs) const { return ml_CurrPos == rhs.ml_CurrPos; } bool operator != (const ZNodekPointN& rhs) const { return ml_CurrPos != rhs.ml_CurrPos; } bool operator > (const ZNodekPointN& rhs) const { return ml_CurrPos > rhs.ml_CurrPos; } bool operator >= (const ZNodekPointN& rhs) const { return ml_CurrPos >= rhs.ml_CurrPos; } bool operator < (const ZNodekPointN& rhs) const { return ml_CurrPos < rhs.ml_CurrPos; } bool operator <= (const ZNodekPointN& rhs) const { return ml_CurrPos <= rhs.ml_CurrPos; } bool operator == (TypeSize AL_Size) const { return ml_CurrPos == AL_Size; } bool operator != (TypeSize AL_Size) const { return ml_CurrPos != AL_Size; } bool operator > (TypeSize AL_Size) const { return ml_CurrPos > AL_Size; } bool operator >= (TypeSize AL_Size) const { return ml_CurrPos >= AL_Size; } bool operator < (TypeSize AL_Size) const { return ml_CurrPos < AL_Size; } bool operator <= (TypeSize AL_Size) const { return ml_CurrPos <= AL_Size; } const ZNodekPointN& operator++() const { mp_CurrLink = mp_CurrLink->mp_NextLink; ++ml_CurrPos; return *this ; }/* const ZNodekPointN& operator++() const*/ ZNodekPointN operator++(int) const { ZNodekPointN VO_NowPoint(*this); mp_CurrLink = mp_CurrLink->mp_NextLink; ++ml_CurrPos ; return VO_NowPoint ; }/* ZNodekPointN operator++(int) const*/ const ZNodekPointN& operator+=(TypeSize AL_Distance) const { if(IsEmpty()){return *this;} mp_CurrLink = &((*mp_CurrLink)+AL_Distance) ; ml_CurrPos += AL_Distance ; return *this; /*:::::::::::::::::::::::::::*/ }/* const ZNodekPointN& operator+=(TypeSize AL_Distance) const*/ public: };/* class ZNodekPointN*/ public : /*************************************************************/ protected: TypeSize ml_LinkSize ; ZCLink* mp_HeadLink ; ZCLink* mp_TailLink ; mutable ZCFreeHeap mo_FreeObjt ; /////////////////////////////////////////////////////////////// ZtCSimList& CopyLink /*######################################*/ ( ZCLinkC* const AP_CopyLink , TypeSize AL_FarNum , ZtCSimList& ARR_Rhs ) const /*###########################################################*/ { // AP_CopyLink 부터 AP_CopyLink->GetNextPrePtr(AL_FarNum) // 링크까지를 복사한다. 총 AL_FarNum + 1 개의 링크가 만들어진다. // // ARR_Rhs.size() 는 0 이어야 한다. ZCLink* VP_HeadLink=0; ZCLink* VP_TailLink=0; GetCFreeHeap().SendFreeOutCopy ( const_cast(AP_CopyLink), // g++ 에서는 반드시 AP_CopyLink 부분을 () 로 묶어 줄 것. AL_FarNum , VP_HeadLink , VP_TailLink ); ////////////////////////////// ZCLink::MakeRing(VP_HeadLink, VP_TailLink); ARR_Rhs.mp_HeadLink= VP_HeadLink ; ARR_Rhs.mp_TailLink= VP_TailLink ; ARR_Rhs.ml_LinkSize= AL_FarNum+1 ; return ARR_Rhs; }/* ZtCSimList& CopyLink ########################################## ( ZCLinkC* const AP_CopyLink , TypeSize AL_FarNum , ZtCSimList& ARR_Rhs ) const #############################################################*/ ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink) { // ZCLink* AP_PrevLink : 삭제하려는 링크의 이전 링크 // ZCLink* AP_CutLink : 삭제하려는 링크 if(AP_CutLink==mp_HeadLink) { if(mp_HeadLink==mp_TailLink) { mp_HeadLink=0; mp_TailLink=0; } else { mp_HeadLink = mp_HeadLink->mp_NextLink ; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); } //else } else if(AP_CutLink==mp_TailLink) { mp_TailLink= AP_PrevLink; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); } else { AP_PrevLink->mp_NextLink= AP_CutLink->mp_NextLink; } //else return (--ml_LinkSize, AP_CutLink); }/* ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)*/ ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TypeSize AL_CutPos) { if(AP_CutLink==mp_HeadLink) { if(mp_HeadLink==mp_TailLink) { mp_HeadLink=0; mp_TailLink=0; } else { mp_HeadLink = mp_HeadLink->mp_NextLink ; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); } //else } else if(AP_CutLink==mp_TailLink) { mp_TailLink= AP_PrevLink; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); } else { AP_PrevLink->mp_NextLink=AP_CutLink->mp_NextLink; }/* else*/ return (--ml_LinkSize, AP_CutLink); }/* ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TypeSize AL_CutPos)*/ ZtCSimList& CutLink /*###############################*/ ( ZCLink* AP_CutHeadPrev, ZCLink* AP_CutHead , TypeSize AL_CutHeadPos, ZCLink* AP_CutTail , TypeSize AL_CutTailPos, ZtCSimList& ARR_StoreList ) /*###################################################*/ { // AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크, AL_CutHeadPos 는 그 위치 ,AP_CutHeadPrev 는 그 이전 링크 // AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크, AL_CutTailPos 는 그 위치 // AP_CutTail 의 이전 링크도 대입받아야 짝아 맞을 것 같지만 안그래도 된다. if(AP_CutHead==mp_HeadLink) { if(AP_CutTail==mp_TailLink) { // 모든 링크를 삭제할 때. mp_HeadLink=0; mp_TailLink=0; } else { mp_HeadLink = AP_CutTail->mp_NextLink ; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); } } else if(AP_CutTail==mp_TailLink) // 잘라내려는 링크가 끝 링크를 포함할 때. { mp_TailLink= AP_CutHeadPrev ; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); } else // 잘라내려는 링크가 처음과 끝 링크를 포함하지 않을 때. { AP_CutHeadPrev->mp_NextLink = AP_CutTail->mp_NextLink; } //else TypeSize VL_CutSize = AL_CutTailPos-AL_CutHeadPos+1 ; /*++++*/ ml_LinkSize-= VL_CutSize ; #ifdef _DEBUG if(ARR_StoreList.IsEmpty()!=true) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mo_DataObjt; }/* TType& operator[](TypeSize AL_Index)*/ const TType& operator[](TypeSize AL_Index) const { return GetLinkPtr(AL_Index)->mo_DataObjt; }/* const TType& operator[](TypeSize AL_Index) const*/ operator TType&(){return AddTailDef()->mo_DataObjt;} TType& operator()() { return AddTailDef()->mo_DataObjt; }/* TType& operator()()*/ void AddHead(TypeArg AR_Type) { ZCLink* VP_AddLink = GetCFreeHeap().SendFreeOut() ; if(TypeMoveObj::ZEUseMoveObj>0) //////////////////// { TypeMoveObj::Exec(VP_AddLink->mo_DataObjt, AR_Type); } /*::::::::::::::::::::::::::::::::::::::::::::::::*/ if(++ml_LinkSize==1) // ml_LinkSize==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { ZCLink::JoinLink(VP_AddLink, mp_HeadLink); mp_HeadLink = VP_AddLink ; }/* else*/ ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void AddHead(TypeArg AR_Type)*/ ZCLink& AddHeadDef() { ZCLink* VP_AddLink=GetCFreeHeap().SendFreeOut(); if(++ml_LinkSize==1) // ml_LinkSize==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { ZCLink::JoinLink (VP_AddLink, mp_HeadLink); mp_HeadLink = VP_AddLink ; } ZCLink::MakeRing (mp_HeadLink, mp_TailLink); return *VP_AddLink; }/* ZCLink& AddHeadDef()*/ void AddTail(TypeArg AR_Type) { ZCLink* VP_AddLink = GetCFreeHeap().SendFreeOut(); if(TypeMoveObj::ZEUseMoveObj>0) //:::::::::::::::: { TypeMoveObj::Exec(VP_AddLink->mo_DataObjt, AR_Type); } /*::::::::::::::::::::::::::::::::::::::::::::::*/ if(++ml_LinkSize==1) // ml_LinkSize==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { ZCLink::JoinLink(mp_TailLink, VP_AddLink); mp_TailLink = VP_AddLink; }/* else*/ ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void AddTail(TypeArg AR_Type)*/ ZCLink* AddTailDef() { ZCLink* VP_AddLink = GetCFreeHeap().SendFreeOut(); if(++ml_LinkSize==1) // ml_LinkSize==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { ZCLink::JoinLink (mp_TailLink, VP_AddLink); mp_TailLink = VP_AddLink ; } ZCLink::MakeRing (mp_HeadLink, mp_TailLink); return *VP_AddLink; }/* ZCLink* AddTailDef()*/ void AddHeadDef(TypeSize AL_DefaultSize) { if(AL_DefaultSize<1) return; ZtCSimList VO_StoreList; JoinHead ( MakeDefault(AL_DefaultSize ,VO_StoreList) ); ////////////////////////////////// }/* void AddHeadDef(TypeSize AL_DefaultSize)*/ void AddTailDef(TypeSize AL_DefaultSize) { if(AL_DefaultSize<1) return; ZtCSimList VO_StoreList; JoinTail ( MakeDefault(AL_DefaultSize ,VO_StoreList) ); ////////////////////////////////// }/* void AddTailDef(TypeSize AL_DefaultSize)*/ TypeData & front() {return mp_HeadLink->mo_DataObjt;} TypeData & back () {return mp_TailLink->mo_DataObjt;} TypeDataC& front() const{return mp_HeadLink->mo_DataObjt;} TypeDataC& back () const{return mp_TailLink->mo_DataObjt;} ZCLink * GetHeadLinkPtr () {return mp_HeadLink;} ZCLink * GetHeadIterEasy () {return mp_HeadLink;} IterEasyID GetHeadIterEasyID () {return (IterEasyID)mp_HeadLink;} ZCLink * GetTailLinkPtr () {return mp_TailLink;} ZCLink * GetTailIterEasy () {return mp_TailLink;} IterEasyID GetTailIterEasyID () {return (IterEasyID)mp_TailLink;} ZCLinkC* GetHeadLinkPtr () const{return mp_HeadLink;} ZCLinkC* GetHeadIterEasy () const{return mp_HeadLink;} IterEasyIDc GetHeadIterEasyID () const{return (IterEasyID)mp_HeadLink;} ZCLinkC* GetTailLinkPtr () const{return mp_TailLink;} ZCLinkC* GetTailIterEasy () const{return mp_TailLink;} IterEasyIDc GetTailIterEasyID () const{return (IterEasyID)mp_TailLink;} void pop_back (TypeArg AR_Type){ return AddHead(AR_Type); } void push_back(TypeArg AR_Type){ return AddTail(AR_Type); } TypeData & GetHeadData() { return mp_HeadLink->mo_DataObjt; } TypeDataC& GetHeadData() const{ return mp_HeadLink->mo_DataObjt; } TypeData & GetTailData() { return mp_TailLink->mo_DataObjt ; } TypeDataC& GetTailData() const{ return mp_TailLink->mo_DataObjt ; } TypeData & GetData(TypeSize AL_Index) { return GetLinkPtr(AL_Index)->mo_DataObjt; } TypeDataC& GetData(TypeSize AL_Index) const{ return GetLinkPtr(AL_Index)->mo_DataObjt; } void JoinHead(ZCLink* AP_Link) { if(mp_HeadLink==0) { mp_HeadLink = mp_TailLink = AP_Link ; } else { AP_Link->mp_NextLink= mp_HeadLink ; mp_HeadLink = AP_Link ; } ++ml_LinkSize; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void JoinHead(ZCLink* AP_Link)*/ void JoinTail(ZCLink* AP_Link) { if(mp_HeadLink==0) { mp_HeadLink = mp_TailLink = AP_Link ; } else { mp_TailLink->mp_NextLink=AP_Link; mp_TailLink =AP_Link; }/* else*/ ++ml_LinkSize; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void JoinTail(ZCLink* AP_Link)*/ void JoinHead(ZtCSimList& rhs) { if(this==&rhs || rhs.mp_HeadLink==0) {return;} /*++++++++++++++++++++++++++++++++*/ if(mp_HeadLink==0) { mp_HeadLink= rhs.mp_HeadLink; mp_TailLink= rhs.mp_TailLink; ml_LinkSize= rhs.ml_LinkSize; } else { rhs.mp_TailLink->mp_NextLink = mp_HeadLink; mp_HeadLink = rhs.mp_HeadLink ; ml_LinkSize += rhs.ml_LinkSize ; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* else*/ rhs.mp_HeadLink=0; rhs.mp_TailLink=0; rhs.ml_LinkSize=0; }/* void JoinHead(ZtCSimList& rhs)*/ void JoinTail(ZtCSimList& rhs) { if(this==&rhs || rhs.mp_HeadLink==0) { return; } /*++++++++++++++++++++++++++++++++*/ if(mp_HeadLink==0) { mp_HeadLink = rhs.mp_HeadLink ; mp_TailLink = rhs.mp_TailLink ; ml_LinkSize = rhs.ml_LinkSize ; } else { mp_TailLink->mp_NextLink=rhs.mp_HeadLink; mp_TailLink =rhs.mp_TailLink; ml_LinkSize += rhs.ml_LinkSize; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* else*/ rhs.mp_HeadLink =0 ; rhs.mp_TailLink =0 ; rhs.ml_LinkSize =0 ; }/* void JoinTail(ZtCSimList& rhs)*/ void DeleteHead() { if(ml_LinkSize==0) return; ZCLink* VP_DelLink = mp_HeadLink ; /*+++*/ mp_HeadLink = mp_HeadLink->mp_NextLink; GetCFreeHeap().RecvFreeIn(VP_DelLink); if(--ml_LinkSize==0) { mp_HeadLink = mp_TailLink = 0 ; return; }/* if(--ml_LinkSize==0)*/ ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void DeleteHead()*/ void DeleteHead(TypeSize AL_DelSize) { // 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_TailLink); mp_HeadLink=0 ; mp_TailLink=0 ; ml_LinkSize=0 ; return; }/* if(AL_DelSize==ml_LinkSize)*/ ZCLink* VP_NewHead= mp_HeadLink-> GetNextPtr( AL_DelSize ); GetCFreeHeap().RecvFreeIn //////////// ( AL_DelSize , mp_HeadLink , VP_NewHead->mp_PrevLink ); ////////////////////////////////////// mp_HeadLink = VP_NewHead ; ml_LinkSize -= AL_DelSize ; ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void DeleteHead(TypeSize AL_DelSize)*/ void DeleteTail() { if(ml_LinkSize==0){return;} ZCLink* VP_CutLink = mp_TailLink; if(--ml_LinkSize==0) { mp_HeadLink = mp_TailLink = 0 ; return; }/* if(--ml_LinkSize==0)*/ mp_TailLink = mp_HeadLink->GetNextPtr(ml_LinkSize-1); mp_TailLink->mp_NextLink=0 ; GetCFreeHeap().RecvFreeIn(VP_CutLink); ZCLink::MakeRing(mp_HeadLink, mp_TailLink); }/* void DeleteTail()*/ void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink) { GetCFreeHeap().RecvFreeIn ( CutLink(AP_PrevLink, AP_CutLink) ); }/* void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)*/ void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TypeSize AL_CutPos) { GetCFreeHeap().RecvFreeIn ( CutLink(AP_PrevLink, AP_CutLink, AL_CutPos) ); }/* void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TypeSize AL_CutPos)*/ void Delete /*###################################*/ ( ZCLink* AP_CutHeadPrev, ZCLink* AP_CutHead, TypeSize AL_CutHeadPos, ZCLink* AP_CutTail, TypeSize AL_CutTailPos ) /*###############################################*/ { ZtCSimList VO_StoreList; CutLink /*==========================================*/ ( AP_CutHeadPrev, AP_CutHead , AL_CutHeadPos, AP_CutTail , AL_CutTailPos , VO_StoreList ). DeleteAll() ; /*==================================================*/ }/* void Delete /////////////////////////////////////// ( ZCLink* AP_CutHeadPrev, ZCLink* AP_CutHead, TypeSize AL_CutHeadPos, ZCLink* AP_CutTail, TypeSize AL_CutTailPos ) /////////////////////////////////////////////////*/ void DeleteAll() { if(ml_LinkSize==0) {return;} GetCFreeHeap().RecvFreeIn (ml_LinkSize, mp_HeadLink, mp_TailLink); mp_HeadLink = mp_TailLink =0 ; ml_LinkSize =0 ; }/* void DeleteAll()*/ void DeleteHeap() { GetCFreeHeap().DeleteHeap(); }/* void DeleteHeap()*/ void clear(){DeleteAll();} TypeSize Find(ZCLinkC* AP_pSearchLink, TypeSize AL_FirstFindIndex=1) const { const bool CB_DoStop = ////////////////////// ( mp_HeadLink ==0 || AL_FirstFindIndex < 1 || AL_FirstFindIndex > ml_LinkSize ); if(CB_DoStop) {return 0;} /////////////////// TypeSize VL_FindIndex = AL_FirstFindIndex ; ZCLink* VP_TempLink = const_cast (GetLinkPtr(AL_FirstFindIndex)); do ////// { if(VP_TempLink==AP_pSearchLink) { return VL_FindIndex; } /*+++++++++++++++++++++++++++*/ if(VL_FindIndex==ml_LinkSize){return 0;} VP_TempLink = VP_TempLink->mp_NextLink; VL_FindIndex= VL_FindIndex + 1 ; } while(true); }/* TypeSize Find(ZCLink* AP_pSearchLink, TypeSize AL_FirstFindIndex=1) const*/ TypeSize Find(TypeArg AR_TypeArg, TypeSize AL_FirstFindIndex=1) { const bool CB_DoStop = ////////////////////// ( mp_HeadLink ==0 || AL_FirstFindIndex< 1 || AL_FirstFindIndex> ml_LinkSize ); if(CB_DoStop) return 0; ///////////////////// TypeSize VL_FindIndex = AL_FirstFindIndex ; ZCLink* VP_TempLink = const_cast (GetLinkPtr(AL_FirstFindIndex)); do ////// { if(**VP_TempLink==AR_TypeArg) {return VL_FindIndex;} /*+++++++++++++++++++++++++*/ if(VL_FindIndex==ml_LinkSize){return 0; } VP_TempLink = VP_TempLink->mp_NextLink; VL_FindIndex= VL_FindIndex + 1 ; } while(true); }/* TypeSize Find(TypeArg AR_TypeArg, TypeSize AL_FirstFindIndex=1)*/ /*//////////////////////////////////////////////////////////////////////////////////////// ■ FindData(TTypeArg, ~) 함수가 없다면, TypeCArg 이 const TType& 으로 정의되어 있는 경우, const TType& 에 대해서만 찾기를 수행할 수 있고, TType& 에 대해서는 찾기를 수행할 수 없다. -- 2010-05-29 21:31:00 ////////////////////////////////////////////////////////////////////////////////////////*/ TypeSize FindData(TypeArg AR_TypeArg, TypeSize AL_FirstFindIndex=1) const { return Find(AR_TypeArg, AL_FirstFindIndex); }/* TypeSize FindData(TypeArg AR_TypeArg, TypeSize AL_FirstFindIndex=1) const*/ ZCLink * GetLinkPtr(TypeSize AL_Index) { return mp_HeadLink->GetNextPtr(AL_Index-1); } ZCLinkC* GetLinkPtr(TypeSize AL_Index) const { return mp_HeadLink->GetNextPtr(AL_Index-1); } ZCFreeHeap& GetCFreeHeap() const{return mo_FreeObjt;} inline TypeSize GetSize() const { return ml_LinkSize; } inline TypeSize size () const { return ml_LinkSize; } inline TypeSize capacity() const { return size()+mo_FreeObjt.size(); } inline TypeSize GetFreeSize() const { return mo_FreeObjt.size(); } inline TypeSize size_free () const { return mo_FreeObjt.size(); } inline bool IsEmpty() const{ return mp_HeadLink==0; } inline bool empty () const{ return mp_HeadLink==0; } // ***************************************************************** // // *********************** Functor 부분 시작 *********************** // // ***************************************************************** // template void IterElement(TFunctor AO_Functor) { ZCLink* VP_LoopLink = mp_HeadLink; __for1(TTypSize, VL_Index, ml_LinkSize) { ZtCTypeData:: GetObjRef(AO_Functor)(VP_LoopLink->mo_DataObjt); VP_LoopLink = VP_LoopLink->mp_NextLink; }/* __for1(TTypSize, VL_Index, 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(TTypSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( **VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TTypSize, i, ml_LinkSize)*/ }/* template void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */ template 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(TTypSize, i, ml_LinkSize) { ZtCTypeData::GetObjRef(AO_Functor) ( VP_LoopLink->mo_DataObjt , ZCCheckRef1::PassData(AO_TypeHelp1), ZCCheckRef2::PassData(AO_TypeHelp2) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TTypSize, i, ml_LinkSize)*/ }/* template void IterElement (TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2) */ template void IterElemDel(TFunctor AO_Functor) { // 각 링크에 대하여 AO_Functor(ZCLink*) 함수를 실행한다. // 각 링크를 순회하면서 삭제할 수 있게 한 것이다. ZCLink* VP_TempPrev = 0 ; ZCLink* VP_TempLink = mp_HeadLink ; ZCLink* VP_TempBefore = VP_TempLink ; // 순회 도중에 링크가 삭제되면, 링크 갯수가 변할 수 // 있으므로, ml_LinkSize 를 다른 변수에 담아 놓는다. TTypSize VL_Count = ml_LinkSize ; TTypSize VL_Index = 1 ; __for1(TTypSize, VL_Loop, VL_Count) { VP_TempLink = VP_TempLink->mp_NextLink; const bool CB_IsTrue = ZtCTypeData:: GetObjRef(AO_Functor)(**VP_TempBefore); if(CB_IsTrue) { Delete(VP_TempPrev, VP_TempBefore, VL_Index); } else { ++VL_Index; if(VP_TempPrev==0) VP_TempPrev=VP_TempBefore; else VP_TempPrev=VP_TempPrev->mp_NextLink; }/* else*/ VP_TempBefore = VP_TempLink; }/* __for1(TTypSize, VL_Loop, VL_Count)*/ }/* template void IterElemDel(TFunctor AO_Functor) */ 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 , TTypSize AL_WorkDistance, TFunctor AO_Functor ) /*#################################################################*/ { /* AR_StdLink 부터 AL_WorkDistance 만큼 이동하면서 * 각 ZCLink 에 대하여 AO_Functor() 함수를 수행한다. (총 수행 횟수는 (AL_WorkDistance)절대값+1) */ ZCLink* VP_StdLink = &AR_StdLink; for(TTypSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop) { ZtCTypeData:: GetObjRef(AO_Functor)(*VP_StdLink); VP_StdLink = VP_StdLink->mp_NextLink ; }/* for(TTypSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop)*/ }/* void IterElemLink /////////////////////////////////////////////////// ( ZCLink& AR_StdLink , TTypSize AL_WorkDistance, TFunctor AO_Functor ) ###################################################################*/ // ****************************************************************** // ************************* Functor 부분 끝 ************************ // ****************************************************************** /*/////////////////////////////////////////////////////////////////////////// ■ 순차적으로 각 원소를 순회할 수 있는 자료 구조, 즉 리스트나 배열 클래스는 MoveNextIter(), MovePrevIter() 멤버를 갖는 것으로 정했다. stl 의 반복자는 너무 일반화하다보니, 성능 상의 제약이 발생한 것 같다. -- 2011-06-07 20:25:00 GetDataInIter() 를 추가했다. -- 2011-06-12 17:12:00 ///////////////////////////////////////////////////////////////////////////*/ void MoveNextIter(ZCLink*& APR_CLink) { APR_CLink=APR_CLink->GetNextPtr() ; } void MoveNextIter(IterEasyID& APPI_IterEasyID) { MoveNextIter((ZCLink*&)APPI_IterEasyID) ; } void MoveNextIter(ZCLinkC*& APR_CLink) const { APR_CLink=APR_CLink->GetNextPtr() ; } void MoveNextIter(IterEasyIDc& APPI_IterEasyID) const { MoveNextIter((ZCLinkC*&)APPI_IterEasyID) ; } void MoveNextIter(iterator & ARR_iterator) { ++ARR_iterator ; } void MoveNextIter(iteratorN& ARR_iterator) const { ++ARR_iterator ; } TypeData & GetDataInIter(ZCLink* AP_CLink) { return **AP_CLink ; } TypeData & GetDataInIter(IterEasyID APPI_IterEasyID) { return GetDataInIter((ZCLink*)APPI_IterEasyID) ; } TypeData & GetDataInIter(iterator & ARR_iterator) { return *ARR_iterator ; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ TypeDataC& GetDataInIter(ZCLinkC* AP_CLink) const { return **AP_CLink ; } TypeDataC& GetDataInIter(IterEasyIDc APPI_IterEasyID) const { return GetDataInIter((ZCLinkC*)APPI_IterEasyID) ; } TypeDataC& GetDataInIter(iteratorN& ARR_iterator) const { return *ARR_iterator ; } ZCLink * ItHEasy() {return mp_HeadLink;} IterEasyID ItHID () {return (IterEasyID)mp_HeadLink;} ZCLink * ItTEasy() {return mp_TailLink;} IterEasyID ItTID () {return (IterEasyID)mp_TailLink;} /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ZCLinkC* ItHEasy() const{return mp_HeadLink;} IterEasyIDc ItHID () const{return (IterEasyIDc)mp_HeadLink;} ZCLinkC* ItTEasy() const{return mp_TailLink;} IterEasyIDc ItTID () const{return (IterEasyIDc)mp_TailLink;} void ItNext(ZCLink* & APR_CLink ) { MoveNextIter(APR_CLink) ; } void ItNext(IterEasyID & APPI_IterEasyID) { MoveNextIter(APPI_IterEasyID) ; } void ItNext(iterator & ARR_Iterator ) { ++ARR_Iterator ; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void ItNext(ZCLinkC* & APR_CLink ) const{ MoveNextIter(APR_CLink) ; } void ItNext(IterEasyIDc& APPI_IterEasyID) const{ MoveNextIter(APPI_IterEasyID) ; } void ItNext(iteratorN & ARR_Iterator ) const{ ++ARR_Iterator ; } TypeData & ItD(ZCLink* AP_CLink ) { return **AP_CLink; } TypeData & ItD(IterEasyID & APPI_IterEasyID ) { return ItD((ZCLink*)APPI_IterEasyID); } TypeData & ItD(iterator & ARR_Iterator ) { return *ARR_Iterator; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ TypeDataC& ItD(ZCLinkC* AP_CLink ) const{ return **AP_CLink; } TypeDataC& ItD(IterEasyIDc& APPI_IterEasyID ) const{ return ItD((ZCLinkC*)APPI_IterEasyID); } TypeDataC& ItD(iteratorN & ARR_Iterator ) const{ return *ARR_Iterator; } iterator begin () { return ZCNodePoint (*this); } iteratorN begin () const{ return ZNodekPointN(*this); } iterator end () { return ZCNodePoint ::MakeTailPoint(*this); } iteratorN end () const{ return ZNodekPointN::MakeTailPoint(*this); } iteratorN cbegin() const{ return ZNodekPointN(*this); } iteratorN cend () const{ return ZNodekPointN::MakeTailPoint(*this); } ZCLink * HeadPtr() {return mp_HeadLink;} ZCLink * TailPtr() {return mp_TailLink;} ZCLinkC* HeadPtr() const{return mp_HeadLink;} ZCLinkC* TailPtr() const{return mp_TailLink;} ZCLink * HeadPtr(TypeSize AI_Distance) {return &((*mp_HeadLink)+AI_Distance);} ZCLinkC* HeadPtr(TypeSize AI_Distance) const{return &((*mp_HeadLink)+AI_Distance);} ZCLink & HeadRef() {return *mp_HeadLink;} ZCLinkC& HeadRef() const{return *mp_HeadLink;} ZCLink & HeadRef(TypeSize AI_Distance) {return (*mp_HeadLink)+AI_Distance;} ZCLinkC& HeadRef(TypeSize AI_Distance) const{return (*mp_HeadLink)+AI_Distance;} public: };/* template ###################################################################### < typename TType , typename TTypArgu = const TType& , typename TTypCAlloc= ZCAllocator , typename TTypCInit = ZtCInit , typename TTypSize = ZTypLong , typename TMoveObj = ZNsMain:: ZtCMoveObj , typename TFeeeHeap = ZNsIFaceEx:: ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single > > class ZtCSimList ##########################################################*/ }/* namespace ZNsMain*/ #endif //__ZCPPMAIN__ZCSIMLIST_H__