commit 2025-09-14 00:42 edit a bit ZCppMain/ZtCObjList.H

This commit is contained in:
2025-09-14 00:42:27 +09:00
parent 86e1668591
commit 82761030c8

View File

@ -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<typename TSimList> 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_NeedCnt<ml_UseSize)
{
APR_HeadLink = mp_NoUseHead;
if(TypeInit::ZEUseInit>0)
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<typename TSimList> class ZtCBody*/
public:
};/*
template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >*/
}/*
namespace ZNsIFaceEx*/
/*/////////////////////////////////////////////////////////////////
■ typename TTypeInit 는 별다른 역할을 하지 않고 있다. 다른 리스트
@ -68,6 +682,8 @@ namespace ZNsMain
public :
template<typename TypeObjList> friend class ZtCSortObjList;
/*++++++++++++++++++++++++++*/ friend class ZtCObjList ;
public :
template<int> 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)