#ifndef __ZCPPMAIN__ZCSIMLIST_H__ #define __ZCPPMAIN__ZCSIMLIST_H__ #include "ZCppMain/ZMainHead.H" namespace ZNsMain { namespace ZNsIFaceEx { class ZCFreeHeapSngl { template class ZtCBody { public: typedef typename ZtCBody::TypeData TypeData; typedef typename ZtCBody::TypeSize TypeSize; typedef typename ZtCBody::TypeInit TypeInit; typedef typename ZtCBody::ZCLink ZCLink ; public: #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallInit mo_Mutex ; #endif //_REENTRANT_MUTEX private: TypeSize ml_AllSize ; TypeSize ml_UseSize ; ZCLink* mp_NoUseHead ; ZCLink* mp_NoUseTail ; private: ZCLink* SendFreeOut() { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(ml_UseSize==0) { ZCLink* VP_TempLink = new ZCLink ; if(TypeInit::ZEUseInit>0) TypeInit::OnInit(VP_TempLink->mo_Data, *this); return (++ml_AllSize, 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->mp_NextLink; } //else --ml_UseSize; return VP_TempLink; }/* ZCLink* SendFreeOut()*/ void SendFreeOut /*#####################################################*/ ( TypeSize AL_LinkSize, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) /*######################################################################*/ { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(mp_NoUseHead==0) { MakeLink(AL_LinkSize, APR_HeadLink, APR_TailLink); } else if(AL_LinkSize==ml_UseSize) { ZCLink* VP_Temp = mp_NoUseHead; while(true) { if(TypeInit::ZEUseInit>0) TypeInit::OnInit(VP_Temp->mo_Data, *this); if(VP_Temp==mp_NoUseTail) { break; } VP_Temp = VP_Temp->mp_NextLink; }/* while(true)*/ APR_HeadLink = mp_NoUseHead ; APR_TailLink = mp_NoUseTail ; mp_NoUseHead =0 ; mp_NoUseTail =0 ; ml_UseSize =0 ; } else if(AL_LinkSize0) TypeInit::OnInit(mp_NoUseHead->mo_Data, *this); for(TypeSize VL_Count=2; VL_Count<=AL_LinkSize; ++VL_Count) { // VL_Count 가 2 부터 시작함으로 AL_LinkSize-1 번 순환한다. // 그래야지 AL_LinkSize 개의 링크를 자를 수 있다. mp_NoUseHead = mp_NoUseHead->mp_NextLink; if(TypeInit::ZEUseInit>0) TypeInit::OnInit(mp_NoUseHead->mo_Data, *this); }/* for(TypeSize VL_Count=2; VL_Count<=AL_LinkSize; ++VL_Count)*/ APR_TailLink = mp_NoUseHead ; mp_NoUseHead= mp_NoUseHead->mp_NextLink; ml_UseSize -= AL_LinkSize ; } else // AL_LinkSize > ml_UseSize { ZCLink* VP_Temp=mp_NoUseHead; while(true) { if(VP_Temp==mp_NoUseTail) { break; } VP_Temp=VP_Temp->mp_NextLink ; } //while(true) APR_HeadLink = mp_NoUseHead; // MakeLink() 에서 TypeInit::OnInit() 가 호출됨. MakeLink( AL_LinkSize - ml_UseSize , mp_NoUseTail->mp_NextLink, APR_TailLink /*****/ ); mp_NoUseHead= 0 ; mp_NoUseTail= 0 ; ml_UseSize = 0 ; } //else // AL_LinkSize > ml_UseSize }/* void SendFreeOut ( TypeSize AL_LinkSize, 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 개의 링크를 먼저 사용한다. #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(mp_NoUseHead==0) { MakeLinkCopy(AP_LinkOrgin, AL_FarNum, APR_HeadCopy, 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->mo_Data = AP_LinkOrgin->mo_Data ; APR_HeadCopy = mp_NoUseHead ; while(--AL_FarNum>=0) { mp_NoUseHead = mp_NoUseHead->mp_NextLink ; AP_LinkOrgin = AP_LinkOrgin->mp_NextLink ; mp_NoUseHead->mo_Data = AP_LinkOrgin->mo_Data; } //while(--AL_FarNum>=0) APR_TailCopy=mp_NoUseHead; // 이 부분에서 mp_NoUseHead 는 잘려나가는 마지막 링크가 된다. // 그러므로 다시 다음 링크로 초기화한다. mp_NoUseHead=mp_NoUseHead->mp_NextLink; if(mp_NoUseHead==0) { mp_NoUseTail=0; // mp_NoUseHead == 0 인데 mp_NoUseTail !=0 이라면 // 나중에 자칫 무한루프에 빠질 수 있다. // 따라서 위 코드를 두었다. } //if(mp_NoUseHead==0) } else // AL_FarNum > ml_UseSize { mp_NoUseHead->mo_Data = AP_LinkOrgin->mo_Data ; APR_HeadCopy = mp_NoUseHead ; while(mp_NoUseHead!=mp_NoUseTail) { mp_NoUseHead= mp_NoUseHead->mp_NextLink; AP_LinkOrgin= AP_LinkOrgin->mp_NextLink; mp_NoUseHead->mo_Data = AP_LinkOrgin->mo_Data; } //while(mp_NoUseHead!=mp_NoUseTail) MakeLinkCopy /*++++++++++++++++++++++++++++++++++++++++++++*/ ( AP_LinkOrgin->mp_NextLink, AL_FarNum-ml_UseSize , mp_NoUseTail->mp_NextLink, 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 ) ///////////////////////////////////////////////////*/ { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG 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->mo_Data, *this); ml_AllSize += AL_MakeSize; 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) { ml_AllSize -= AL_MakeSize+1 ; VB_IsHeapOver = true ; break; }/* if(VP_MakeLink==0)*/ if(TypeInit::ZEUseInit>0) TypeInit::OnInit(VP_MakeLink->mo_Data, *this); VP_TempLink->mp_NextLink=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->mp_NextLink; } 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 개의 링크가 만들어진다. #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG ZCLink* VP_MakeLink = 0 ; ZCLink* VP_TempLink = 0 ; bool VB_IsHeapOver= false; VP_TempLink = \ VP_MakeLink = new ZCLink(AP_LinkOrgin->mo_Data); ml_AllSize += AL_FarNum+1 ; if(VP_MakeLink==0) { //add codes for memory over ml_AllSize -= AL_FarNum+1; DeleteHeap(); return; ///////////////////////////////// }/* if(VP_MakeLink==0)*/ APR_HeadCopy=VP_MakeLink; while(--AL_FarNum >= 0) { AP_LinkOrgin= AP_LinkOrgin->mp_NextLink ; VP_MakeLink = new ZCLink(AP_LinkOrgin->mo_Data); if(VP_MakeLink==0) { ml_AllSize -= AL_FarNum+1 ; APR_TailCopy = VP_TempLink ; VB_IsHeapOver= true ; break; }/* if(VP_MakeLink==0)*/ VP_TempLink->mp_NextLink= VP_MakeLink; VP_TempLink = VP_MakeLink; }/* while(--AL_FarNum >= 0)*/ APR_TailCopy=VP_TempLink; // 메모리를 더 이상 할당할 수 없었다면 // 이미 만들어진 비원형 이중 링크를 지운다. 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_Link) { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX AP_Link->mp_NextLink=0; if(++ml_UseSize==1) // ml_UseSize 이 0 일때 { mp_NoUseHead = mp_NoUseTail = AP_Link ; } else { // 새로운 링크는 mp_NoUseTail 다음에 붙인다. mp_NoUseTail->mp_NextLink= AP_Link; mp_NoUseTail = AP_Link; } //else if(TypeInit::ZEUseFini>0) TypeInit::OnFini(AP_Link->mo_Data, *this); }/* void RecvFreeIn(ZCLink* AP_Link)*/ void RecvFreeIn(ZCLink* AP_HeadLink, ZCLink* AP_TailLink, TypeSize AL_Count) { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX if(TypeInit::ZEUseFini>0) { ZCLink* VP_NowLink = AP_HeadLink; __for1(TypeSize, i, AL_Count) { TypeInit::OnFini(VP_NowLink->mo_Data, *this) ; VP_NowLink = VP_NowLink->mp_NextLink; }/* __for1(TypeSize, i, AL_Count)*/ }/* if(TypeInit::ZEUseFini>0)*/ if(ml_UseSize==0) { mp_NoUseHead = AP_HeadLink ; mp_NoUseTail = AP_TailLink ; } else { // 새로운 링크는 mp_NoUseTail 다음에 붙인다. mp_NoUseTail->mp_NextLink = AP_HeadLink; mp_NoUseTail = AP_TailLink; } //else mp_NoUseTail->mp_NextLink=0; ml_UseSize += AL_Count ; }/* void RecvFreeIn(ZCLink* AP_HeadLink, ZCLink* AP_TailLink, TypeSize AL_Count)*/ //private: public : ZtCBody() { ml_AllSize = ml_UseSize = 0 ; mp_NoUseHead = mp_NoUseTail = 0 ; ZNsMain::GetCHeapAllocList().AddFreeAllocBase(*this); }/* ZtCBody()*/ ~ZtCBody() { #ifndef _SIMLIST_FREE_STORE_CHECK_ #ifdef _SIMLIST_FREE_STORE_LOG_ if( ml_UseSize>0 ) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<0 )*/ #endif //_SIMLIST_FREE_STORE_LOG_ return ; #endif //!_SIMLIST_FREE_STORE_CHECK_ if(ml_UseSize==0) return ; ZCLink* VP_DelLink=mp_NoUseHead; do ////// { mp_NoUseHead = mp_NoUseHead->mp_NextLink; delete VP_DelLink; VP_DelLink = mp_NoUseHead ; } while(VP_DelLink!=0); ml_AllSize -= ml_UseSize ; ml_UseSize = 0 ; mp_NoUseHead = mp_NoUseTail = 0 ; }/* ~ZtCBody()*/ void DeleteHeap() { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX if(ml_UseSize==0) return ; ZCLink* VP_DelLink = mp_NoUseHead; do ////// { mp_NoUseHead = mp_NoUseHead->mp_NextLink ; delete VP_DelLink; VP_DelLink = mp_NoUseHead ; } while(VP_DelLink!=0); ml_AllSize -= ml_UseSize; ml_UseSize = 0 ; mp_NoUseHead = mp_NoUseTail = 0 ; }/* void DeleteHeap()*/ TypeSize GetUseHeapSize() const { return ml_UseSize; }/* TypeSize GetUseHeapSize() const*/ TypeSize GetAllHeapSize() const { return ml_AllSize; }/* TypeSize GetAllHeapSize() const*/ TypeSize size() const { return ml_UseSize; }/* TypeSize size() const*/ TypeSize capacity() const { return ml_AllSize; }/* TypeSize capacity() const*/ //public: }; //template class ZtCBody };/* class ZCFreeHeapSngl*/ }/* 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 > class ZtCSimList /*###############################*/ { public: typedef TType Type ; typedef TType TypeData ; typedef TTypArgu TypeArg ; typedef TTypCAlloc TypeAlloc ; typedef TTypCInit TypeInit ; typedef TTypSize TypeSize ; typedef TMoveObj TypeMoveObj; public: class ZCFreeHeap; class ZCLink : public TypeAlloc { public: template friend class ZtCSortObjList ; friend class ZtCSimList ; /*##########################*/ friend class ZCFreeHeap ; public: #ifdef _DEBUG ZCCheckAlloc mo_CheckStack; #endif //_DEBUG private: ZCLink* mp_NextLink; TType mo_Data ; 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 MakeCircle(ZCLink* AP_HeadLink, ZCLink* AP_TailLink) { // 처음과 끝 링크를 연결하여 원형상태로 만든다. // 이것은 ZtCSimList class template 과 멤버 함수를 맞추기 위한 것으로 // 실제적으로는 별 쓸모는 없는 것 같다. AP_TailLink->mp_NextLink=AP_HeadLink; }/* inline static void MakeCircle(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)*/ //private: public : ZCLink():mp_NextLink(0) { }/* ZCLink()*/ ZCLink(const ZCLink& rhs):mp_NextLink(0) { // TType 의 대입연산자는 반드시 public 영역에 있어야 한다. mo_Data=rhs.mo_Data; }/* ZCLink(const ZCLink& rhs)*/ ZCLink(TypeArg AR_Type):mp_NextLink(0) { mo_Data=AR_Type; }/* ZCLink(TypeArg AR_Type)*/ operator TType&() { return mo_Data; }/* operator TType&()*/ operator TType() { return mo_Data; }/* operator TType()*/ TType& GetData() { return mo_Data; }/* TType& GetData()*/ const TType& GetData() const { return mo_Data; }/* const TType& GetData() const*/ TType& GetData(TTypSize AL_FarNum) // must AL_FarNum >= 0 { return GetNextPtr(AL_FarNum)->mo_Data; }/* TType& GetData(TTypSize AL_FarNum)*/ const TType& GetData(TTypSize AL_FarNum) const { return GetNextPtr(AL_FarNum)->mo_Data; }/* const TType& GetData(TTypSize AL_FarNum) const*/ TType& operator*() { return mo_Data; }/* TType& operator*()*/ const TType& operator*() const { return mo_Data; }/* const TType& operator*() const*/ ZCLink* GetNextPtr(TTypSize AL_FarNum) // must AL_FarNum > 0 { // 이 멤버 함수는 TTypSize 가 용랑이 큰 object 라 할지라도 // 이 함수 내부에서 값이 변하고 있으므로 참조로 받지 않는다. ZCLink* VP_TmpLink=this; while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink; //end while return VP_TmpLink; }/* ZCLink* GetNextPtr(TTypSize AL_FarNum)*/ const ZCLink* const GetNextPtr(TTypSize AL_FarNum) const // or ZCLink const * const GetNextPtr(TTypSize AL_FarNum) const { // TTypSize 가 object 일 경우 AL_FarNum 의 값이 이 함수에서 변하고 있으므로 // TTypSize 을 참조로 받으면 안된다. 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; //end while return VP_TmpLink; }/* const ZCLink* const GetNextPtr(TTypSize AL_FarNum) const*/ inline ZCLink* GetNextPtr() { return mp_NextLink; }/* inline ZCLink* GetNextPtr()*/ inline const ZCLink* const GetNextPtr() const { return mp_NextLink; }/* inline const ZCLink* const GetNextPtr() const*/ ZCLink& operator=(TypeArg AR_Type) { mo_Data=AR_Type; return *this; }/* ZCLink& operator=(TypeArg AR_Type)*/ ZCLink* operator+(TypeSize AL_Offset) { ZCLink* VP_CLinkLoop=this; __for0(TTypSize, i, AL_Offset) { VP_CLinkLoop = VP_CLinkLoop->mp_NextLink; }/* __for0(TTypSize, i, AL_Offset)*/ return *this; }/* ZCLink* operator+(TypeSize AL_Offset) public:*/ };/* class ZCLink*/ ////////////////////////////////////////////////// /*************** end class ZCLink ***************/ ////////////////////////////////////////////////// class ZCFreeHeap : public ZCFreeAllocBase { public: friend class ZtCSimList ; friend class ZCLink ; public: #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallInit mo_Mutex ; #endif //_REENTRANT_MUTEX private: TTypSize ml_AllSize ; TTypSize ml_UseSize ; ZCLink* mp_NoUseHeadLink; ZCLink* mp_NoUseTailLink; //private: private: ZCLink* GetOneLink() { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(ml_UseSize==0) { ZCLink* VP_TempLink = new ZCLink ; if(TypeInit::ZEUseInit>0) TypeInit::OnInit(VP_TempLink->mo_Data, *this); return (++ml_AllSize, VP_TempLink); }/* if(ml_UseSize==0)*/ ZCLink* VP_TempLink=mp_NoUseHeadLink; if(VP_TempLink==mp_NoUseTailLink) { mp_NoUseHeadLink=0; mp_NoUseTailLink=0; } else { mp_NoUseHeadLink=mp_NoUseHeadLink->mp_NextLink; } //else --ml_UseSize; return VP_TempLink; }/* ZCLink* GetOneLink()*/ void GetManyLink /*#####################################################*/ ( TTypSize AL_LinkSize, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) /*######################################################################*/ { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(mp_NoUseHeadLink==0) { MakeLink(AL_LinkSize, APR_HeadLink, APR_TailLink); } else if(AL_LinkSize==ml_UseSize) { ZCLink* VP_Temp = mp_NoUseHeadLink; while(true) { if(TypeInit::ZEUseInit>0) TypeInit::OnInit(VP_Temp->mo_Data, *this); if(VP_Temp==mp_NoUseTailLink) { break; } VP_Temp = VP_Temp->mp_NextLink; } //while(true) APR_HeadLink = mp_NoUseHeadLink ; APR_TailLink = mp_NoUseTailLink ; mp_NoUseHeadLink =0; mp_NoUseTailLink =0; ml_UseSize=0; } else if(AL_LinkSize0) TypeInit::OnInit(mp_NoUseHeadLink->mo_Data, *this); for(TTypSize VL_Count=2; VL_Count<=AL_LinkSize; ++VL_Count) { // VL_Count 가 2 부터 시작함으로 AL_LinkSize-1 번 순환한다. // 그래야지 AL_LinkSize 개의 링크를 자를 수 있다. mp_NoUseHeadLink = mp_NoUseHeadLink->mp_NextLink; if(TypeInit::ZEUseInit>0) TypeInit::OnInit(mp_NoUseHeadLink->mo_Data, *this); } //for(TTypSize VL_Count=2; VL_Count<=AL_LinkSize; ++VL_Count) APR_TailLink = mp_NoUseHeadLink; mp_NoUseHeadLink= mp_NoUseHeadLink->mp_NextLink; ml_UseSize -= AL_LinkSize; } else // AL_LinkSize > ml_UseSize { ZCLink* VP_Temp=mp_NoUseHeadLink; while(true) { if(VP_Temp==mp_NoUseTailLink) { break; } VP_Temp=VP_Temp->mp_NextLink ; } //while(true) APR_HeadLink = mp_NoUseHeadLink; // MakeLink() 에서 TypeInit::OnInit() 가 호출됨. MakeLink( AL_LinkSize - ml_UseSize , mp_NoUseTailLink->mp_NextLink, APR_TailLink /*****/ ); mp_NoUseHeadLink=0; mp_NoUseTailLink=0; ml_UseSize =0; } //else // AL_LinkSize > ml_UseSize }/* void GetManyLink ( TTypSize AL_LinkSize, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) ########################################################################*/ void GetManyLinkCopy /*////////////////////////////*/ ( ZCLink* AP_LinkOrgin, TTypSize 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 개의 링크를 먼저 사용한다. #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG if(mp_NoUseHeadLink==0) { MakeLinkCopy(AP_LinkOrgin, AL_FarNum, APR_HeadCopy, APR_TailCopy); } else if( AL_FarNum < ml_UseSize) // ( (AL_FarNum<0 ? -AL_FarNum : AL_FarNum)+1 <= ml_UseSize) { ml_UseSize -= AL_FarNum+1 ; mp_NoUseHeadLink->mo_Data = AP_LinkOrgin->mo_Data; APR_HeadCopy = mp_NoUseHeadLink ; while(--AL_FarNum>=0) { mp_NoUseHeadLink= mp_NoUseHeadLink->mp_NextLink ; AP_LinkOrgin = AP_LinkOrgin->mp_NextLink ; mp_NoUseHeadLink->mo_Data = AP_LinkOrgin->mo_Data; } //while(--AL_FarNum>=0) APR_TailCopy=mp_NoUseHeadLink; // 이 부분에서 mp_NoUseHeadLink 는 잘려나가는 마지막 링크가 된다. // 그러므로 다시 다음 링크로 초기화한다. mp_NoUseHeadLink=mp_NoUseHeadLink->mp_NextLink; if(mp_NoUseHeadLink==0) { mp_NoUseTailLink=0; // mp_NoUseHeadLink == 0 인데 mp_NoUseTailLink !=0 이라면 // 나중에 자칫 무한루프에 빠질 수 있다. // 따라서 위 코드를 두었다. } //if(mp_NoUseHeadLink==0) } else // AL_FarNum > ml_UseSize { mp_NoUseHeadLink->mo_Data = AP_LinkOrgin->mo_Data ; APR_HeadCopy = mp_NoUseHeadLink ; while(mp_NoUseHeadLink!=mp_NoUseTailLink) { mp_NoUseHeadLink=mp_NoUseHeadLink->mp_NextLink; AP_LinkOrgin =AP_LinkOrgin ->mp_NextLink; mp_NoUseHeadLink->mo_Data = AP_LinkOrgin->mo_Data; } //while(mp_NoUseHeadLink!=mp_NoUseTailLink) MakeLinkCopy /*++++++++++++++++++++++++++++++++++++++++++++*/ ( AP_LinkOrgin ->mp_NextLink, AL_FarNum-ml_UseSize , mp_NoUseTailLink->mp_NextLink, APR_TailCopy ); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ mp_NoUseHeadLink = mp_NoUseTailLink = 0; ml_UseSize = 0; } //else // AL_FarNum > ml_UseSize }/* void GetManyLinkCopy //////////////////////////////// ( ZCLink* AP_LinkOrgin, TTypSize AL_FarNum , ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) ///////////////////////////////////////////////////*/ void MakeLink /////////////////////////////////////// ( TTypSize AL_MakeSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) ///////////////////////////////////////////////////*/ { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG APR_HeadLink = new ZCLink; if(APR_HeadLink==0) { //add codes for memory over DeleteAllInHeap(); return; } //if(APR_HeadLink==0) if(TypeInit::ZEUseInit>0) TypeInit::OnInit(APR_HeadLink->mo_Data, *this); ml_AllSize += AL_MakeSize; 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) { ml_AllSize -= AL_MakeSize+1 ; VB_IsHeapOver = true ; break; } //if(VP_MakeLink==0) if(TypeInit::ZEUseInit>0) TypeInit::OnInit(VP_MakeLink->mo_Data, *this); VP_TempLink->mp_NextLink=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) { DeleteAllInHeap(); // Add extra codes for memory over return; } //if(VP_TempLink==APR_TailLink) APR_HeadLink=APR_HeadLink->mp_NextLink; } while(true); } //if(VB_IsHeapOver==true) }/* void MakeLink /////////////////////////////////////// ( TTypSize AL_MakeSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink ) ///////////////////////////////////////////////////*/ void MakeLinkCopy /////////////////////////////////// ( ZCLink* AP_LinkOrgin, TTypSize AL_FarNum , ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) ///////////////////////////////////////////////////*/ { // AP_LinkOrgin 링크부터, // AP_LinkOrgin 에서 AL_FarNum 만큼 떨어진 링크까지를 복사하여 // 복사생성된 처음 링크 포인터를 APR_HeadCopy 에, // 마지막 링크를 APR_TailCopy 에 대입한다. // AL_FarNum > 0 , 총 AL_FarNum + 1 개의 링크가 만들어진다. #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj; #endif //_DEBUG ZCLink* VP_MakeLink = 0 ; ZCLink* VP_TempLink = 0 ; bool VB_IsHeapOver= false; VP_TempLink = \ VP_MakeLink = new ZCLink(AP_LinkOrgin->mo_Data); ml_AllSize += AL_FarNum+1 ; if(VP_MakeLink==0) { //add codes for memory over ml_AllSize -= AL_FarNum+1 ; DeleteAllInHeap() ; return; } //if(VP_MakeLink==0) APR_HeadCopy=VP_MakeLink; while(--AL_FarNum >= 0) { AP_LinkOrgin= AP_LinkOrgin->mp_NextLink; VP_MakeLink = new ZCLink(AP_LinkOrgin->mo_Data); if(VP_MakeLink==0) { ml_AllSize -= AL_FarNum+1 ; APR_TailCopy = VP_TempLink ; VB_IsHeapOver= true ; break; } //if(VP_MakeLink==0) VP_TempLink->mp_NextLink= VP_MakeLink; VP_TempLink = VP_MakeLink; } //while(--AL_FarNum >= 0) APR_TailCopy=VP_TempLink; // 메모리를 더 이상 할당할 수 없었다면 // 이미 만들어진 비원형 이중 링크를 지운다. if(VB_IsHeapOver==true) { do ////// { delete APR_HeadCopy; if(APR_HeadCopy==APR_TailCopy) { DeleteAllInHeap(); return; } //if(APR_HeadCopy==APR_TailCopy) APR_HeadCopy=APR_HeadCopy->mp_NextLink; } while(true); } //if(VB_IsHeapOver==true) }/* void MakeLinkCopy /////////////////////////////////// ( ZCLink* AP_LinkOrgin, TTypSize AL_FarNum, ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy ) ///////////////////////////////////////////////////*/ void ReceiveLink(ZCLink* AP_Link) { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX AP_Link->mp_NextLink=0; if(++ml_UseSize==1) // ml_UseSize 이 0 일때 { mp_NoUseHeadLink = mp_NoUseTailLink = AP_Link ; } else { // 새로운 링크는 mp_NoUseTailLink 다음에 붙인다. mp_NoUseTailLink->mp_NextLink= AP_Link; mp_NoUseTailLink = AP_Link; } //else if(TypeInit::ZEUseFini>0) TypeInit::OnFini(AP_Link->mo_Data, *this); } //void ReceiveLink(ZCLink* AP_Link) void ReceiveLink(TTypSize AL_Count, ZCLink* AP_HeadLink, ZCLink* AP_TailLink) { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX if(TypeInit::ZEUseFini>0) { ZCLink* VP_NowLink = AP_HeadLink; __for1(TypeSize, i, AL_Count) { TypeInit::OnFini(VP_NowLink->mo_Data, *this) ; VP_NowLink = VP_NowLink->mp_NextLink; }/* __for1(TypeSize, i, AL_Count)*/ }/* if(TypeInit::ZEUseFini>0)*/ if(ml_UseSize==0) { mp_NoUseHeadLink = AP_HeadLink ; mp_NoUseTailLink = AP_TailLink ; } else { // 새로운 링크는 mp_NoUseTailLink 다음에 붙인다. mp_NoUseTailLink->mp_NextLink = AP_HeadLink; mp_NoUseTailLink = AP_TailLink; } //else mp_NoUseTailLink->mp_NextLink=0; ml_UseSize += AL_Count ; } //void ReceiveLink(TTypSize AL_Count, ZCLink* AP_HeadLink, ZCLink* AP_TailLink) //private: public : ZCFreeHeap() { ml_AllSize = ml_UseSize = 0 ; mp_NoUseHeadLink = mp_NoUseTailLink = 0 ; ZNsMain::GetCHeapAllocList().AddFreeAllocBase(*this); } //ZCFreeHeap() ~ZCFreeHeap() { #ifndef _SIMLIST_FREE_STORE_CHECK_ #ifdef _SIMLIST_FREE_STORE_LOG_ if( ml_UseSize>0 ) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<0 ) #endif //_SIMLIST_FREE_STORE_LOG_ return ; #endif //!_SIMLIST_FREE_STORE_CHECK_ if(ml_UseSize==0) return ; ZCLink* VP_DelLink=mp_NoUseHeadLink; do ////// { mp_NoUseHeadLink = mp_NoUseHeadLink->mp_NextLink; delete VP_DelLink; VP_DelLink = mp_NoUseHeadLink ; } while(VP_DelLink!=0); ml_AllSize -= ml_UseSize ; ml_UseSize = 0 ; mp_NoUseHeadLink = mp_NoUseTailLink = 0 ; } //~ZCFreeHeap() void DeleteAllInHeap() { #ifdef _REENTRANT_MUTEX ZNsMain::ZCMutexSmallLock VO_ZCMutexSmallLock(mo_Mutex); #endif //_REENTRANT_MUTEX if(ml_UseSize==0) return ; ZCLink* VP_DelLink=mp_NoUseHeadLink; do ////// { mp_NoUseHeadLink = mp_NoUseHeadLink->mp_NextLink; delete VP_DelLink; VP_DelLink = mp_NoUseHeadLink ; } while(VP_DelLink!=0); ml_AllSize -= ml_UseSize; ml_UseSize = 0 ; mp_NoUseHeadLink = mp_NoUseTailLink = 0 ; } //void DeleteAllInHeap() TTypSize GetUseHeapSize() const { return ml_UseSize; } //TTypSize GetUseHeapSize() const TTypSize GetAllHeapSize() const { return ml_AllSize; } //TTypSize GetAllHeapSize() const long size() const { return ml_UseSize; } //long size() const long GetMemSize() const { return ml_UseSize*sizeof(ZCLink); } //long GetMemSize() const //public: }; //class ZCFreeHeap //////////////////////////////////////////////// /************ end class ZCFreeHeap ************/ //////////////////////////////////////////////// //public : protected: TTypSize ml_Size ; ZCLink* mp_HeadLink; ZCLink* mp_TailLink; /////////////////////////////////////////////////////////////// ZtCSimList& CopyLink /*######################################*/ ( const ZCLink* const AP_CopyLink , TTypSize AL_FarNum , ZtCSimList& ARR_StoreList ) const /*###########################################################*/ { // AP_CopyLink 부터 AP_CopyLink->GetNextPrePtr(AL_FarNum) // 링크까지를 복사한다. 총 AL_FarNum + 1 개의 링크가 만들어 진다. ZCLink* VP_HeadLink=0; ZCLink* VP_TailLink=0; GetCFreeHeap().GetManyLinkCopy ( const_cast(AP_CopyLink), // g++ 에서는 반드시 AP_CopyLink 부분을 () 로 묶어 줄 것. AL_FarNum , VP_HeadLink , VP_TailLink ); ////////////////////////////// VP_TailLink->mp_NextLink=0; ARR_StoreList.mp_HeadLink= VP_HeadLink ; ARR_StoreList.mp_TailLink= VP_TailLink ; ARR_StoreList.ml_Size = AL_FarNum+1 ; return ARR_StoreList; }/* ZtCSimList& CopyLink ########################################## ( const ZCLink* const AP_CopyLink , TTypSize AL_FarNum , ZtCSimList& ARR_StoreList ) 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; } //else } else if(AP_CutLink==mp_TailLink) { AP_PrevLink->mp_NextLink=0; } else { AP_PrevLink->mp_NextLink=AP_CutLink->mp_NextLink; } //else return (--ml_Size, AP_CutLink); }/* ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)*/ ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize 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; } //else } else if(AP_CutLink==mp_TailLink) { AP_PrevLink->mp_NextLink=0; } else { AP_PrevLink->mp_NextLink=AP_CutLink->mp_NextLink; } //else return (--ml_Size, AP_CutLink); } //ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize AL_CutPos) ZtCSimList& CutLink /*###############################*/ ( ZCLink* AP_CutHeadPrev, ZCLink* AP_CutHead , TTypSize AL_CutHeadPos, ZCLink* AP_CutTail , TTypSize 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; } } else if(AP_CutTail==mp_TailLink) // 잘라내려는 링크가 끝 링크를 포함할 때. { mp_TailLink= AP_CutHeadPrev ; mp_TailLink->mp_NextLink= 0 ; } else // 잘라내려는 링크가 처음과 끝 링크를 포함하지 않을 때. { AP_CutHeadPrev->mp_NextLink=AP_CutTail->mp_NextLink; } //else ml_Size -= AL_CutTailPos-AL_CutHeadPos+1 ; #ifdef _DEBUG if(ARR_StoreList.IsEmpty()!=true) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout< 0 ZCLink* VP_HeadLink=0; ZCLink* VP_TailLink=0; GetCFreeHeap().GetManyLink (AL_DefaultSize, VP_HeadLink, VP_TailLink); ZCLink::MakeCircle( VP_HeadLink, VP_TailLink ); ARR_StoreList.mp_HeadLink= VP_HeadLink ; ARR_StoreList.mp_TailLink= VP_TailLink ; ARR_StoreList.ml_Size = AL_DefaultSize ; return ARR_StoreList; }/* ZtCSimList& MakeDefault(TTypSize AL_DefaultSize, ZtCSimList& ARR_StoreList) const protected: */ public : ZtCSimList() { ml_Size =0; mp_HeadLink=0; mp_TailLink=0; }/* ZtCSimList()*/ ZtCSimList(TypeArg AR_Type) { ml_Size =0; mp_HeadLink=0; mp_TailLink=0; AddTail(AR_Type); }/* ZtCSimList(TypeArg AR_Type)*/ ZtCSimList(const ZtCSimList& rhs) { ml_Size =0; mp_HeadLink=0; mp_TailLink=0; ZtCSimList VO_StoreList; JoinHead( CopyLink(rhs.mp_HeadLink, rhs.ml_Size-1 ,VO_StoreList) ); }/* ZtCSimList(const ZtCSimList& rhs)*/ ZtCSimList& operator=(const ZtCSimList& rhs) { if(&rhs ==this){return *this;} { DeleteAll(); } if(rhs.ml_Size==0 ){return *this;} ZtCSimList VO_StoreList; JoinHead /////////////////////////// ( CopyLink(rhs.mp_HeadLink, rhs.ml_Size-1 ,VO_StoreList) ); return *this; ////////////////////// }/* ZtCSimList& operator=(const ZtCSimList& rhs)*/ virtual ~ZtCSimList() { DeleteAll(); }/* virtual ~ZtCSimList()*/ ZtCSimList& operator()(TypeArg AR_Type) { AddTail(AR_Type); return *this; }/* ZtCSimList& operator()(TypeArg AR_Type)*/ TType& operator[](TTypSize AL_Index) { #ifdef _DEBUG if(AL_Index<1 || AL_Index>ml_Size) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ml_Size)*/ #endif //_DEBUG return GetLinkPtr(AL_Index)->mo_Data; }/* TType& operator[](TTypSize AL_Index)*/ const TType& operator[](TTypSize AL_Index) const { #ifdef _DEBUG if(AL_Index<1 || AL_Index>ml_Size) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ml_Size)*/ #endif //_DEBUG return GetLinkPtr(AL_Index)->mo_Data; } //const TType& operator[](TTypSize AL_Index) const operator TType&(){return AddTailDefault()->mo_Data;} TType& operator()() { return AddTailDefault()->mo_Data; }/* TType& operator()()*/ void AddHead(TypeArg AR_Type) { ZCLink* VP_AddLink = GetCFreeHeap().GetOneLink() ; #if(_CODE_NEW_) if(TypeMoveObj::ZEUseMoveObj>0) //////////////////// { TypeMoveObj::Exec(VP_AddLink->mo_Data, AR_Type); } else /////////////////////////////////////////////// #endif VP_AddLink->mo_Data= AR_Type ; if(++ml_Size==1) // ml_Size==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { VP_AddLink->mp_NextLink =mp_HeadLink; mp_HeadLink=VP_AddLink; }/* else*/ }/* void AddHead(TypeArg AR_Type)*/ ZCLink* AddHeadDefault() { ZCLink* VP_AddLink=GetCFreeHeap().GetOneLink(); if(++ml_Size==1) // ml_Size==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { VP_AddLink->mp_NextLink =mp_HeadLink; mp_HeadLink=VP_AddLink; } //else }/* ZCLink* AddHeadDefault()*/ void AddTail(TypeArg AR_Type) { ZCLink* VP_AddLink = GetCFreeHeap().GetOneLink(); #if(_CODE_NEW_) if(TypeMoveObj::ZEUseMoveObj>0) //////////////////// { TypeMoveObj::Exec(VP_AddLink->mo_Data, AR_Type); } else /////////////////////////////////////////////// #endif VP_AddLink->mo_Data= AR_Type ; if(++ml_Size==1) // ml_Size==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { mp_TailLink->mp_NextLink=VP_AddLink ; mp_TailLink=mp_TailLink->mp_NextLink; }/* else*/ }/* void AddTail(TypeArg AR_Type)*/ ZCLink* AddTailDefault() { ZCLink* VP_AddLink = GetCFreeHeap().GetOneLink(); if(++ml_Size==1) // ml_Size==0 { mp_HeadLink = mp_TailLink = VP_AddLink ; } else { mp_TailLink->mp_NextLink = VP_AddLink ; mp_TailLink=mp_TailLink->mp_NextLink; }/* else*/ }/* ZCLink* AddTailDefault()*/ void AddHeadDefault(TTypSize AL_DefaultSize) { if(AL_DefaultSize<1) return; ZtCSimList VO_StoreList; JoinHead ( MakeDefault(AL_DefaultSize ,VO_StoreList) ); ////////////////////////////////// }/* void AddHeadDefault(TTypSize AL_DefaultSize)*/ void AddTailDefault(TTypSize AL_DefaultSize) { if(AL_DefaultSize<1) return; ZtCSimList VO_StoreList; JoinTail ( MakeDefault(AL_DefaultSize ,VO_StoreList) ); ////////////////////////////////// }/* void AddTailDefault(TTypSize AL_DefaultSize)*/ 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;} TType& front(){return mp_HeadLink->mo_Data;} TType& back (){return mp_TailLink->mo_Data;} const ZCLink* GetHeadLinkPtr () const{return mp_HeadLink;} const ZCLink* GetHeadIterEasy () const{return mp_HeadLink;} const IterEasyID GetHeadIterEasyID() const{return (IterEasyID)mp_HeadLink;} const ZCLink* GetTailLinkPtr () const{return mp_TailLink;} const ZCLink* GetTailIterEasy () const{return mp_TailLink;} const IterEasyID GetTailIterEasyID() const{return (IterEasyID)mp_TailLink;} const TType& front() const{return mp_HeadLink->mo_Data;} const TType& back () const{return mp_TailLink->mo_Data;} void pop_back(TypeArg AR_Type) { return AddHead(AR_Type); }/* void pop_back(TypeArg AR_Type)*/ void push_back(TypeArg AR_Type) { return AddTail(AR_Type); }/* void push_back(TypeArg AR_Type)*/ TType& GetHeadData() { #ifdef _DEBUG if(mp_HeadLink==0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mo_Data; }/* TType& GetHeadData()*/ const TType& GetHeadData() const { #ifdef _DEBUG if(mp_HeadLink==0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mo_Data; }/* const TType& GetHeadData() const*/ TType& GetTailData() { #ifdef _DEBUG if(mp_TailLink==0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mo_Data ; }/* TType& GetTailData()*/ const TType& GetTailData() const { #ifdef _DEBUG if(mp_TailLink==0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mo_Data ; }/* const TType& GetTailData() const*/ TType& GetData(TTypSize AL_Index) { #ifdef _DEBUG if(AL_Index<1 || AL_Index>ml_Size) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ml_Size)*/ #endif //_DEBUG return GetLinkPtr(AL_Index)->mo_Data; }/* TType& GetData(TTypSize AL_Index)*/ TType GetData(TTypSize AL_Index) const { #ifdef _DEBUG if(AL_Index<1 || AL_Index>ml_Size) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ml_Size)*/ #endif //_DEBUG return GetLinkPtr(AL_Index)->mo_Data; }/* TType GetData(TTypSize AL_Index) const*/ void JoinHead(ZCLink* AP_Link) { #ifdef _DEBUG if(AP_Link==0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mp_NextLink=0; return; }/* if(mp_HeadLink==0)*/ AP_Link->mp_NextLink= mp_HeadLink ; mp_HeadLink = AP_Link ; ++ml_Size; }/* void JoinHead(ZCLink* AP_Link)*/ void JoinTail(ZCLink* AP_Link) { #ifdef _DEBUG if(AP_Link==0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<mp_NextLink=0; if(mp_HeadLink==0) { mp_HeadLink = mp_TailLink = AP_Link ; } else { mp_TailLink->mp_NextLink=AP_Link; mp_TailLink =AP_Link; }/* else*/ ++ml_Size; }/* 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_Size =rhs.ml_Size ; } else { rhs.mp_TailLink->mp_NextLink=mp_HeadLink; mp_HeadLink= rhs.mp_HeadLink ; ml_Size += rhs.ml_Size ; }/* else*/ rhs.mp_HeadLink=0; rhs.mp_TailLink=0; rhs.ml_Size =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_Size =rhs.ml_Size ; } else { mp_TailLink->mp_NextLink=rhs.mp_HeadLink; mp_TailLink =rhs.mp_TailLink; ml_Size += rhs.ml_Size; }/* else*/ rhs.mp_HeadLink=0; rhs.mp_TailLink=0; rhs.ml_Size =0; }/* void JoinTail(ZtCSimList& rhs)*/ void DeleteHead() { if(ml_Size==0) return; ZCLink* VP_DelLink= mp_HeadLink ; mp_HeadLink = mp_HeadLink->mp_NextLink; GetCFreeHeap().ReceiveLink(VP_DelLink); if(--ml_Size==0) { mp_HeadLink = mp_TailLink = 0 ; }/* if(--ml_Size==0)*/ }/* void DeleteHead()*/ void DeleteHead(TTypSize AL_DelSize) { // AL_DelSize 개의 링크를 앞 부분에서 삭제 if(AL_DelSize < 1 ) AL_DelSize= 1 ; if(AL_DelSize > ml_Size) AL_DelSize= ml_Size; ZCLink* VP_CutTail = mp_HeadLink->GetNextPtr(AL_DelSize-1); ZtCSimList VO_StoreList; CutLink ///////////// ( 0, mp_HeadLink , 1, VP_CutTail , AL_DelSize , VO_StoreList ) .DeleteAll(); //////////////////////////////////////////////// }/* void DeleteHead(TTypSize AL_DelSize)*/ void DeleteTail() { if(ml_Size==0){return;} ZCLink* VP_CutLink = mp_TailLink; if(--ml_Size==0) { mp_HeadLink = mp_TailLink = 0 ; return; }/* if(--ml_Size==0)*/ mp_TailLink = mp_HeadLink->GetNextPtr(ml_Size-1); mp_TailLink->mp_NextLink=0 ; GetCFreeHeap().ReceiveLink(VP_CutLink); }/* void DeleteTail()*/ void DeleteTail(TTypSize AL_DelSize) { if(ml_Size==0){return;} if(AL_DelSize> ml_Size){ AL_DelSize=ml_Size; } if(AL_DelSize< 1 ){ AL_DelSize=1 ; } if(AL_DelSize==ml_Size) { GetCFreeHeap().ReceiveLink (ml_Size, mp_HeadLink, mp_TailLink); mp_HeadLink=0 ; mp_TailLink=0 ; ml_Size =0 ; return; }/* if(AL_DelSize==ml_Size)*/ ZCLink* VP_NewTail= mp_HeadLink-> GetNextPtr( ml_Size-AL_DelSize-1 ); GetCFreeHeap().ReceiveLink (AL_DelSize, VP_NewTail->mp_NextLink, mp_TailLink); mp_TailLink = VP_NewTail ; mp_TailLink-> mp_NextLink=0 ; ml_Size -= AL_DelSize ; }/* void DeleteTail(TTypSize AL_DelSize)*/ void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink) { #ifdef _DEBUG if ( Find(AP_CutLink)==0 || Find(AP_CutLink)!=Find(AP_PrevLink)+1 ) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<AL_CutTailPos || Find(AP_CutHead)!=AL_CutHeadPos || Find(AP_CutTail)!=AL_CutTailPos || (AL_CutHeadPos!=1 && AP_CutHeadPrev->mp_NextLink!=AP_CutHead) ) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout< ml_Size ); if(CB_DoStop) {return 0;} ///////// TTypSize 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_Size){return 0; } VP_TempLink = VP_TempLink->mp_NextLink; VL_FindIndex= VL_FindIndex + 1 ; } while(true); }/* TTypSize Find(ZCLink* AP_pSearchLink, TTypSize AL_FirstFindIndex=1) const*/ TTypSize Find(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1) { const bool CB_DoStop = ( mp_HeadLink==0 || AL_FirstFindIndex<1 || AL_FirstFindIndex>ml_Size ); if(CB_DoStop) return 0; TTypSize 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_Size){return 0; } VP_TempLink = VP_TempLink->mp_NextLink; VL_FindIndex= VL_FindIndex + 1 ; } while(true); }/* TTypSize Find(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1)*/ /*//////////////////////////////////////////////////////////////////////////////////////// ■ FindData(TTypeArg, ~) 함수가 없다면, TypeCArg 이 const TType& 으로 정의되어 있는 경우, const TType& 에 대해서만 찾기를 수행할 수 있고, TType& 에 대해서는 찾기를 수행할 수 없다. -- 2010-05-29 21:31:00 ////////////////////////////////////////////////////////////////////////////////////////*/ TTypSize FindData(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1) const { return Find(AR_TypeArg, AL_FirstFindIndex); }/* TTypSize FindData(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1) const*/ ZCLink* GetLinkPtr(TTypSize AL_Index) { #ifdef _DEBUG if(AL_Index<1 || AL_Index>ml_Size) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ml_Size)*/ #endif //_DEBUG return mp_HeadLink->GetNextPtr(AL_Index-1); }/* ZCLink* GetLinkPtr(TTypSize AL_Index)*/ const ZCLink* GetLinkPtr(TTypSize AL_Index) const { #ifdef _DEBUG if(AL_Index<1 || AL_Index>ml_Size) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ml_Size)*/ #endif //_DEBUG return mp_HeadLink->GetNextPtr(AL_Index-1); }/* const ZCLink* GetLinkPtr(TTypSize AL_Index) const*/ static ZCFreeHeap& GetCFreeHeap() { static ZCFreeHeap SO_CLinkHeap; return SO_CLinkHeap; }/* static ZCFreeHeap& GetCFreeHeap()*/ inline TTypSize GetSize() const { return ml_Size; }/* inline TTypSize GetSize() const*/ inline TTypSize size() const { return ml_Size; }/* inline TTypSize size() const*/ inline bool IsEmpty() const { return mp_HeadLink==0; }/* inline bool IsEmpty() const*/ // ***************************************************************** // // *********************** Functor 부분 시작 *********************** // // ***************************************************************** // template void IterElement(TFunctor AO_Functor) { ZCLink* VP_LoopLink = mp_HeadLink; __for1(TTypSize, VL_Index, ml_Size) { ZtCTypeData:: GetObjRef(AO_Functor)(VP_LoopLink->mo_Data); VP_LoopLink = VP_LoopLink->mp_NextLink; }/* __for1(TTypSize, VL_Index, ml_Size)*/ }/* 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_Size) { ZtCTypeData::GetObjRef(AO_Functor) ( VP_LoopLink->mo_Data, ZCCheckRef::PassData(AO_TypeHelp) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TTypSize, i, ml_Size)*/ }/* 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_Size) { ZtCTypeData::GetObjRef(AO_Functor) ( VP_LoopLink->mo_Data , ZCCheckRef1::PassData(AO_TypeHelp1), ZCCheckRef2::PassData(AO_TypeHelp2) ); //////////////////////////////////////////// VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(TTypSize, i, ml_Size)*/ }/* template void IterElement (TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2) */ template void IterEleCutIf(TFunctor AO_Functor) { // 각 링크에 대하여 AO_Functor(ZCLink*) 함수를 실행한다. // 이 함수를 설계한 이유는 각 링크를 순회하면서 삭제할 수 있도록 하기 위해서다. ZCLink* VP_TempLink =mp_HeadLink ; ZCLink* VP_TempPrev =0 ; ZCLink* VP_TempBefore=VP_TempLink ; // 순회 도중에 링크가 삭제되면 노드갯수가 변할 수 있으므로 // ml_Size 를 다른 변수에 담아 놓는다. TTypSize VL_Count=ml_Size ; 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->mo_Data ); 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 IterEleCutIf(TFunctor AO_Functor) */ template void IterEleLink ( ZCLink* AP_StdLink , TTypSize AL_WorkDistance, TFunctor AO_Functor ) /*########################################*/ { /* AP_StdLink 부터 AL_WorkDistance 만큼 이동하면서 * 각 ZCLink 에 대하여 AO_Functor() 함수를 수행한다.(총 수행 횟수는 (AL_WorkDistance)절대값+1) * AL_WorkDistance>=0 이면 다음으로 이동하고 * AL_WorkDistance <0 이면 이전으로 이동한다. */ #ifdef _DEBUG if(ml_Size==0 || Find(AP_StdLink)==0 || AL_WorkDistance>=ml_Size || AL_WorkDistance<0) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_Size || AL_WorkDistance<0)*/ #endif //_DEBUG for(TTypSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop) { ZtCTypeData:: GetObjRef(AO_Functor)(AP_StdLink); AP_StdLink = AP_StdLink->mp_NextLink ; }/* for(TTypSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop)*/ }/* void IterEleLink ///////////////// ( ZCLink* AP_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(ZCLink*& APR_CLink)*/ void MoveNextIter(IterEasyID& APPI_IterEasyID) { MoveNextIter((ZCLink*&)APPI_IterEasyID); }/* void MoveNextIter(IterEasyID& APPI_IterEasyID)*/ void MoveNextIter(const ZCLink*& APR_CLink) const { APR_CLink=APR_CLink->GetNextPtr(); }/* void MoveNextIter(const ZCLink*& APR_CLink) const*/ void MoveNextIter(const IterEasyID& APPI_IterEasyID) const { MoveNextIter((const ZCLink*&)APPI_IterEasyID); }/* void MoveNextIter(const IterEasyID& APPI_IterEasyID) const*/ TType& GetDataInIter(ZCLink* AP_CLink) { return **AP_CLink; }/* TType& GetDataInIter(ZCLink* AP_CLink)*/ TType& GetDataInIter(IterEasyID APPI_IterEasyID) { return GetDataInIter((ZCLink*)APPI_IterEasyID); }/* TType& GetDataInIter(IterEasyID APPI_IterEasyID)*/ const TType& GetDataInIter(const ZCLink* AP_CLink) const { return **AP_CLink; }/* const TType& GetDataInIter(const ZCLink* AP_CLink) const*/ const TType& GetDataInIter(const IterEasyID APPI_IterEasyID) const { return GetDataInIter((const ZCLink*)APPI_IterEasyID); }/* const TType& GetDataInIter(const IterEasyID APPI_IterEasyID) const*/ ZCLink* ItHEasy(){return mp_HeadLink;} IterEasyID ItHID (){return (IterEasyID)mp_HeadLink;} ZCLink* ItTEasy(){return mp_TailLink;} IterEasyID ItTID (){return (IterEasyID)mp_TailLink;} const ZCLink* ItHEasy() const{return mp_HeadLink;} const IterEasyID ItHID () const{return (IterEasyIDc)mp_HeadLink;} const ZCLink* ItTEasy() const{return mp_TailLink;} const IterEasyID ItTID () const{return (IterEasyIDc)mp_TailLink;} void ItNext(ZCLink*& APR_CLink) { MoveNextIter(APR_CLink); }/* void ItNext(ZCLink*& APR_CLink)*/ void ItNext(IterEasyID& APPI_IterEasyID) { MoveNextIter(APPI_IterEasyID); }/* void ItNext(IterEasyID& APPI_IterEasyID)*/ void ItNext(const ZCLink*& APR_CLink) const { MoveNextIter(APR_CLink); }/* void ItNext(const ZCLink*& APR_CLink) const*/ void ItNext(const IterEasyID& APPI_IterEasyID) const { MoveNextIter(APPI_IterEasyID); }/* void ItNext(const IterEasyID& APPI_IterEasyID) const*/ TType& ItD(ZCLink* AP_CLink) { return **AP_CLink; }/* TType& ItD(ZCLink* AP_CLink)*/ TType& ItD(IterEasyID APPI_IterEasyID) { return ItD((ZCLink*)APPI_IterEasyID); }/* TType& ItD(IterEasyID APPI_IterEasyID)*/ const TType& ItD(const ZCLink* AP_CLink) const { return **AP_CLink; }/* const TType& ItD(const ZCLink* AP_CLink) const*/ const TType& ItD(const IterEasyID APPI_IterEasyID) const { return ItD((const ZCLink*)APPI_IterEasyID); }/* const TType& ItD(const IterEasyID APPI_IterEasyID) const*/ public: };/* template ########################################### < typename TType , typename TTypArgu = const TType& , typename TTypCAlloc= ZCAllocator , typename TTypCInit = ZtCInit , typename TTypSize = ZTypLong , typename TMoveObj = ZNsMain:: ZtCMoveObj > class ZtCSimList #################################*/ }/* namespace ZNsMain*/ #endif //__ZCPPMAIN__ZCSIMLIST_H__