From 82761030c87176c8b6b3ec62cfb8a0c85bc2bb72 Mon Sep 17 00:00:00 2001 From: sauron Date: Sun, 14 Sep 2025 00:42:27 +0900 Subject: [PATCH] commit 2025-09-14 00:42 edit a bit ZCppMain/ZtCObjList.H --- ZCppMain/ZtCObjList.H | 632 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 625 insertions(+), 7 deletions(-) diff --git a/ZCppMain/ZtCObjList.H b/ZCppMain/ZtCObjList.H index 0295c7c..28b0f24 100644 --- a/ZCppMain/ZtCObjList.H +++ b/ZCppMain/ZtCObjList.H @@ -10,6 +10,620 @@ namespace ZNsMain { + + template ////////////////////////////////////////////////////// + < + typename TType , typename TTypArgu + , typename TTypCAlloc , typename TTypeInit + , typename TTypSize , typename TMoveObj + , typename TFeeeHeap + > + class ZtCObjList; ///////////////////////////////////////////// + + + + namespace ZNsIFaceEx + { + + template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double > + { + public: + + template class ZtCBody + { + public : + typedef typename TSimList::TypeData TypeData; + typedef typename TSimList::TypeSize TypeSize; + typedef typename TSimList::TypeInit TypeInit; + typedef typename TSimList::ZCLink ZCLink ; + public : + + template ////////////////////////////////////////////////////// + < + typename TType , typename TTypArgu + , typename TTypCAlloc , typename TTypeInit + , typename TTypSize , typename TMoveObj + , typename TFeeeHeap + > + friend class ZNsMain::ZtCObjList; ///////////////////////////// + + private: + TypeSize ml_AllSize ; + 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 (++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->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); + + 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, *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) ; + + 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->GetNextPtr() ; + VP_MakeLink = new ZCLink(**AP_LinkOrgin) ; + + if(VP_MakeLink==0) + { + ml_AllSize -= AL_FarNum+1 ; + 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_AllSize = + ml_UseSize = 0 ; + + mp_NoUseHead = + mp_NoUseTail = 0 ; + }/* + ZtCBody()*/ + + ~ZtCBody() + { + DeleteHeap(); + }/* + ~ZtCBody()*/ + + + void DeleteHeap() + { + if(ml_UseSize<1) return ; + + ZCLink* VP_DelLink = mp_NoUseHead; + + do /*+++++++++++++++++++++++++++*/ + { + mp_NoUseHead = + mp_NoUseHead->GetNextPtr() ; + + delete VP_DelLink; + + VP_DelLink = mp_NoUseHead ; + } + while(--ml_UseSize>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*/ + + + public: + };/* + template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >*/ + + + }/* + namespace ZNsIFaceEx*/ + + + /*///////////////////////////////////////////////////////////////// ■ typename TTypeInit 는 별다른 역할을 하지 않고 있다. 다른 리스트 @@ -68,6 +682,8 @@ namespace ZNsMain public : template friend class ZtCSortObjList; /*++++++++++++++++++++++++++*/ friend class ZtCObjList ; + public : + template friend class ZNsIFaceEx::ZtCFreeHeapCDL ; private: TypeData mo_Data ; ZCLink* mp_NextLink; @@ -308,10 +924,10 @@ namespace ZNsMain } else { - AP_LinkInsert->mp_NextLink =mp_HeadLink ; - mp_HeadLink->mp_PrevLink->mp_NextLink=AP_LinkInsert ; - AP_LinkInsert->mp_PrevLink =mp_HeadLink->mp_PrevLink ; - mp_HeadLink->mp_PrevLink =AP_LinkInsert ; + AP_LinkInsert->mp_NextLink =mp_HeadLink ; + mp_HeadLink ->mp_PrevLink->mp_NextLink=AP_LinkInsert ; + AP_LinkInsert->mp_PrevLink =mp_HeadLink->mp_PrevLink ; + mp_HeadLink ->mp_PrevLink =AP_LinkInsert ; mp_HeadLink=AP_LinkInsert; }/* @@ -332,7 +948,8 @@ namespace ZNsMain void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypeSize AL_PosStd)*/ - public : void JoinAfter(ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd) + public : void JoinAfter + (ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd) { #ifdef _DEBUG @@ -380,7 +997,7 @@ namespace ZNsMain ZCLink* VP_TailLink=AO_CObjList.mp_HeadLink->mp_PrevLink; ZCLink::MakeCircle(AO_CObjList.mp_HeadLink, mp_HeadLink->mp_PrevLink); - ZCLink::JoinLink (VP_TailLink,mp_HeadLink ); + ZCLink::JoinLink (VP_TailLink , mp_HeadLink ); mp_HeadLink = AO_CObjList.mp_HeadLink; ml_Size += AO_CObjList.ml_Size ; @@ -401,7 +1018,8 @@ namespace ZNsMain AO_CObjList.mp_HeadLink=0; AO_CObjList.ml_Size =0; }/* - void JoinAfter(ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd)*/ + void JoinAfter + (ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd)*/ protected: ZCLink* CutLink(ZCLink* AP_CutLink)