Files
RepoMain/ZCppMain/ZtCObjList.H

4656 lines
163 KiB
C++

#ifndef __ZCPPMAIN__ZTCOBJLIST_H__
#define __ZCPPMAIN__ZTCOBJLIST_H__
#include "ZCppMain/ZMainHead.H"
namespace ZNsMain
{
template //////////////////////////////////////////////////////
<
typename TType , typename TTypArgu
, typename TTypCAlloc , typename TTypeInit
, typename TTypSize , typename TMoveObj
, typename TFeeeHeap
>
class ZtCObjList; /////////////////////////////////////////////
namespace ZNsIFaceEx
{
template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >
{
public:
template<typename TObjList> class ZtCBody
{
public :
typedef typename TObjList::TypeSize TypeSize;
typedef typename TObjList::TypeInit TypeInit;
typedef typename TObjList::ZCLink ZCLink ;
public :
template //////////////////////////////////////////////////////
<
typename TType , typename TTypArgu
, typename TTypCAlloc , typename TTypeInit
, typename TTypSize , typename TMoveObj
, typename TFeeeHeap
>
friend class ZNsMain::ZtCObjList; /////////////////////////////
private:
TypeSize ml_UseSize ;
ZCLink* mp_NoUseHead ;
ZCLink* mp_NoUseTail ;
private:
ZCLink* SendFreeOut()
{
if(ml_UseSize==0)
{
ZCLink* VP_TempLink = new ZCLink ;
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(*VP_TempLink, *this);
return VP_TempLink;
}/*
if(ml_UseSize==0)*/
ZCLink* VP_TempLink=mp_NoUseHead;
if(VP_TempLink==mp_NoUseTail)
{
mp_NoUseHead=0;
mp_NoUseTail=0;
}
else
{
mp_NoUseHead = mp_NoUseHead->GetNextPtr();
}
//else
--ml_UseSize; return VP_TempLink;
}/*
ZCLink* SendFreeOut()*/
void SendFreeOut /*#####################################################*/
(
TypeSize AL_NeedCnt, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink
)
/*######################################################################*/
{
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->GetNextPtr() ;
}/*
while(true)*/
APR_HeadLink = mp_NoUseHead;
// MakeLink() 에서 TypeInit::OnInit() 가 호출됨.
MakeLink ///////////////////////////////////////
(
AL_NeedCnt - ml_UseSize ,
RR(mp_NoUseTail->mp_NextLink) ,
RR(APR_TailLink)
);
////////////////////////////////////////////////
mp_NoUseHead= 0 ;
mp_NoUseTail= 0 ;
ml_UseSize = 0 ;
}/*
else // AL_NeedCnt > ml_UseSize*/
}/*
void SendFreeOut ########################################################
(
TypeSize AL_NeedCnt, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink
)
########################################################################*/
void SendFreeOutCopy /*////////////////////////////*/
(
ZCLink* AP_LinkOrgin, TypeSize AL_FarNum ,
ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy
)
/*/////////////////////////////////////////////////*/
{
/*//////////////////////////////////////////////////////////////////////
■ AL_FarNum > 0
AP_LinkOrgin 링크부터, AP_LinkOrgin 에서 AL_FarNum 만큼 떨어진 링크까
지를 복사하여 복사 생성된
처음 링크 포인터를 APR_HeadCopy 에,
마지막 링크 포인터를 APR_TailCopy 에
대입한다. AP_LinkOrgin 링크에서 그 다음 링크로 접근하면서 링크를 복사
할 것이다. 따라서 총 AL_FarNum + 1 개의 링크가 만들어진다.
이 함수는 각 링크를 새로 생성하는 MakeLinkCopy() 함수와는 달리, 기존
에 있는 ml_UseSize 개의 링크를 먼저 사용한다.
//////////////////////////////////////////////////////////////////////*/
if(mp_NoUseHead==0)
{
MakeLinkCopy /////////////////////////////
(
AP_LinkOrgin , AL_FarNum ,
RR(APR_HeadCopy), RR(APR_TailCopy)
);
//////////////////////////////////////////
}
else if( AL_FarNum < ml_UseSize) // ( (AL_FarNum<0 ? -AL_FarNum : AL_FarNum)+1 <= ml_UseSize)
{
ml_UseSize -= AL_FarNum+1 ;
**mp_NoUseHead = **AP_LinkOrgin ;
APR_HeadCopy = mp_NoUseHead ;
while(--AL_FarNum>=0)
{
mp_NoUseHead = mp_NoUseHead->GetNextPtr() ;
AP_LinkOrgin = AP_LinkOrgin->GetNextPtr() ;
**mp_NoUseHead = **AP_LinkOrgin ;
}
//while(--AL_FarNum>=0)
APR_TailCopy = mp_NoUseHead ;
// 이 부분에서 mp_NoUseHead 는 잘려나가는 마지막 링크가 된다.
// 그러므로 다시 다음 링크로 초기화한다.
mp_NoUseHead = mp_NoUseHead->GetNextPtr();
if(mp_NoUseHead==0)
{
mp_NoUseTail=0;
// mp_NoUseHead == 0 인데 mp_NoUseTail !=0 이라면
// 나중에 자칫 무한루프에 빠질 수 있다.
// 따라서 위 코드를 두었다.
}/*
if(mp_NoUseHead==0)*/
}
else // AL_FarNum > ml_UseSize
{
**mp_NoUseHead = **AP_LinkOrgin ;
APR_HeadCopy = mp_NoUseHead ;
while(mp_NoUseHead!=mp_NoUseTail)
{
mp_NoUseHead = mp_NoUseHead->GetNextPtr() ;
AP_LinkOrgin = AP_LinkOrgin->GetNextPtr() ;
**mp_NoUseHead = **AP_LinkOrgin ;
}/*
while(mp_NoUseHead!=mp_NoUseTail)*/
MakeLinkCopy /*++++++++++++++++++++++++++++++++++++++++++++*/
(
AP_LinkOrgin->GetNextPtr() , AL_FarNum-ml_UseSize,
RR(mp_NoUseTail->mp_NextLink), RR(APR_TailCopy)
);
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
mp_NoUseHead =
mp_NoUseTail = 0;
ml_UseSize = 0;
}
//else // AL_FarNum > ml_UseSize
}/*
void SendFreeOutCopy ////////////////////////////////
(
ZCLink* AP_LinkOrgin, TypeSize AL_FarNum ,
ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy
)
///////////////////////////////////////////////////*/
void MakeLink ///////////////////////////////////////
(
TypeSize AL_MakeSize ,
ZCLink*& APR_HeadLink,
ZCLink*& APR_TailLink
) const
///////////////////////////////////////////////////*/
{
APR_HeadLink = new ZCLink;
if(APR_HeadLink==0)
{
// add codes for memory over
return;
}/*
if(APR_HeadLink==0)*/
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**APR_HeadLink, *this);
ZCLink* VP_MakeLink = 0 ;
ZCLink* VP_TempLink = APR_HeadLink;
bool VB_IsHeapOver= false ;
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
■ bool VB_IsHeapOver 은 new 연산자가 NULL 포인터를 반환했을 때
true 를 대입받는다. 이 값을 조사함으로써 heap overflow 를 처리한다.
bool VB_IsHeapOver 변수를 두지 않고 아래 for 문에서 직접 메모리 처리
를 하는 코드를 둘 수 있으나, for 문 안에 if 문 속에서 또 for 문을 써
야 함으로 가독성이 떨어질 수가 있다. 그래서 heap over 에 대한 예외처
리 코드를 for 문 바깥으로 빼려는 것이다.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
while(--AL_MakeSize>0) // AL_MakeSize - 1 번 순환
{
// AL_MakeSize - 1 번 순환
VP_MakeLink = new ZCLink;
if(VP_MakeLink==0)
{
VB_IsHeapOver = true; break;
}/*
if(VP_MakeLink==0)*/
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**VP_MakeLink, *this);
ZCLink::JoinLink
(VP_TempLink, VP_MakeLink);
VP_TempLink = VP_MakeLink ;
}/*
while(--AL_MakeSize>0)*/
APR_TailLink = VP_TempLink;
// 메모리를 더 이상 할당할 수 없었다면
// 이미 만들어진 VL_Count 개의 비원형 이중 링크를 지운다.
if(VB_IsHeapOver==true)
{
VP_TempLink=APR_HeadLink;
// 이 시점에서 최소한 APR_HeadLink 하나는
// heap 에 생성되어 있다.
do //////
{
delete VP_TempLink;
if(VP_TempLink==APR_TailLink)
{
// Add extra codes for memory over
return;
}/*
if(VP_TempLink==APR_TailLink)*/
APR_HeadLink=APR_HeadLink->GetNextPtr();
}
while(true);
}/*
if(VB_IsHeapOver==true)*/
}/*
void MakeLink ///////////////////////////////////////
(
TypeSize AL_MakeSize ,
ZCLink*& APR_HeadLink,
ZCLink*& APR_TailLink
) const
///////////////////////////////////////////////////*/
void MakeLinkCopy ///////////////////////////////////
(
ZCLink* AP_LinkOrgin, TypeSize AL_FarNum ,
ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy
) const
///////////////////////////////////////////////////*/
{
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
■ 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
) const
///////////////////////////////////////////////////*/
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<typename TObjList> class ZtCBody*/
public:
};/*
template<> class ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >*/
}/*
namespace ZNsIFaceEx*/
/*/////////////////////////////////////////////////////////////////
■ typename TTypeInit 는 별다른 역할을 하지 않고 있다. 다른 리스트
클래스와 템플릿 인수를 비슷하게 맞추기 위해, 그리고 차후의 설계
를 위해 일단 이대로 두자.
■ typename ZtCInit 가 필요한지 모르겠다. 일단 주석으로 막는다.
-- 2025-08-11 14:47
ZtCTreeData.H 에서 ZtCObjList<> 에서 TTypeInit 자리에 형을 지정
하고 있다. 쓰긴 쓰니까 주석을 해제하자. -- 2025-08-14 13:43
아, 일종의 TType 생성자의 다형성을 위해서 필요하겠네. 생성자에는
가상 함수가 없으니까. -- 2025-10-03 19:15
/////////////////////////////////////////////////////////////////*/
template<typename TypeObjList> class ZtCSortObjList;
template< typename TType ///////////////////////////////////////////////////
, typename TTypArgu = const TType&
, typename TTypCAlloc = ZCAllocator
, typename TTypeInit = ZtCInit<TType>
, typename TTypSize = ZTypLong
, typename TMoveObj = ZtCMoveObj<TType, TTypArgu, true>
, typename TFeeeHeap = ZNsIFaceEx::
ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >
>
class ZtCObjList //////////////////////////////////////////////////////////////
{
public:
class ZCLink ;
class ZCNodePoint ;
class ZCNodePointN ;
public:
template<typename TypeObjList> friend class ZtCSortObjList;
/*********************************************************************/
typedef ZtCObjOpt<ZCLink> ZCLinkOpt ;
typedef ZtCObjOpt<TType > ZCDataOpt ;
/*********************************************************************/
typedef TType Type ;
typedef TType TypeData ;
typedef TTypArgu TypeArg ;
typedef TTypCAlloc TypeAlloc ;
typedef TTypeInit TypeInit ;
typedef TTypSize TypeSize ;
typedef TMoveObj TypeMoveObj ;
typedef ZtCObjList TypeThis ;
typedef ZCLink TypeLink ;
typedef ZCLink TypeNode ; // ZCNodePoint::GetNode() 의 반환형.
typedef TypeThis TypeList ;
typedef ZCLink* IterEasy ; // 가장 간단하게 쓰일 수 있는 반복자.
typedef ZCNodePoint TypeIter ;
typedef ZCNodePointN TypeIterN ;
/*********************************************************************/
typedef ZCNodePoint iterator ; // 다양한 기능을 가진 반복자.
typedef ZCNodePointN const_iterator;
/*********************************************************************/
typedef const TypeThis TypeThisC ;
typedef const TypeList TypeListC ;
typedef const TypeData TypeDataC ;
typedef const TypeLink TypeLinkC ;
typedef const TypeNode TypeNodeC ; // ZCNodePoint::GetNode() const 의 반환형.
typedef const ZCLink ZCLinkC ;
typedef const ZCLinkOpt ZCLinkOptC ;
typedef const ZCDataOpt ZCDataOptC ;
typedef const ZCLink* IterEasyC ;
typedef ZCNodePointN iteratorN ;
/*********************************************************************/
typedef typename TFeeeHeap::
template ZtCBody<ZtCObjList> ZCFreeHeap;
/*********************************************************************/
public:
class ZCLink : public TypeAlloc
{
public :
template<typename TypeObjList> friend class ZtCSortObjList;
/*++++++++++++++++++++++++++*/ friend class ZtCObjList ;
public :
template<int> friend class ZNsIFaceEx::ZtCFreeHeapCDL ;
private:
ZCLink* mp_NextLink;
ZCLink* mp_PrevLink;
TypeData mo_DataObjt;
private:
static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink)
{
AP_PrevLink->mp_NextLink=AP_NextLink;
AP_NextLink->mp_PrevLink=AP_PrevLink;
}/*
static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink)*/
static void MakeRing(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)
{
AP_HeadLink->mp_PrevLink=AP_TailLink;
AP_TailLink->mp_NextLink=AP_HeadLink;
}/*
static void MakeRing(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)*/
private:
/******************************************************************/
public :
ZCLink()
{
mp_NextLink =0 ;
mp_PrevLink =0 ;
}/*
ZCLink()*/
ZCLink(TypeArg AR_Type)
{
mp_NextLink = 0 ;
mp_PrevLink = 0 ;
mo_DataObjt = AR_Type ;
}/*
ZCLink(TypeArg AR_Type)*/
ZCLink(const ZCLink& rhs)
{
mp_NextLink =0 ;
mp_PrevLink =0 ;
mo_DataObjt = rhs.mo_DataObjt ;
}/*
ZCLink(const ZCLink& rhs)*/
ZCLink& operator=(const ZCLink& rhs)
{
mo_DataObjt = rhs.mo_DataObjt; return *this;
}/*
ZCLink& operator=(const ZCLink& rhs)*/
operator TypeData & () {return mo_DataObjt;}
operator TypeData () {return mo_DataObjt;}
operator TypeDataC& () const{return mo_DataObjt;}
TypeData & GetData () {return mo_DataObjt;}
TypeData & operator* () {return mo_DataObjt;}
TypeData & operator()() {return mo_DataObjt;}
TypeDataC& GetData () const{return mo_DataObjt;}
TypeDataC& operator* () const{return mo_DataObjt;}
TypeDataC& operator()() const{return mo_DataObjt;}
ZCLink * GetNextPrevPtr(TypeSize AL_FarNum) // AL_FarNum 은 0 이거나 음수일 수 있다.
{
ZCLink* VP_TmpLink = this;
if(AL_FarNum>=0)
{
while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink;
}
else // AL_FarNum<0 인 경우.
{
while(++AL_FarNum<=0) VP_TmpLink=VP_TmpLink->mp_PrevLink;
}/*
else*/
return VP_TmpLink;
}/*
ZCLink * GetNextPrevPtr(TypeSize AL_FarNum)*/
ZCLinkC* GetNextPrevPtr(TypeSize AL_FarNum) const // or ZCLink const * const GetNextPrevPtr(TypeSize AL_FarNum) const
{
ZCLinkC* VP_TmpLink = this;
if(AL_FarNum>=0)
{
while(--AL_FarNum>=0) VP_TmpLink=VP_TmpLink->mp_NextLink;
}
else // AL_FarNum<0 인 경우.
{
while(++AL_FarNum<=0) VP_TmpLink=VP_TmpLink->mp_PrevLink;
}/*
else*/
return VP_TmpLink;
}/*
ZCLinkC* GetNextPrevPtr(TypeSize AL_FarNum) const*/
ZCLink * GetNextPtr() {return mp_NextLink;}
ZCLink * GetPrevPtr() {return mp_PrevLink;}
ZCLinkC* GetNextPtr() const{return mp_NextLink;}
ZCLinkC* GetPrevPtr() const{return mp_PrevLink;}
ZCLink* GetNextPtr(TypeSize AL_Distance)
{
TypeSize VL_LoopIndex=0 ;
ZCLink* VP_TmpLink =this;
while(VL_LoopIndex++ < AL_Distance)
VP_TmpLink = VP_TmpLink->mp_NextLink ;
return VP_TmpLink;
}/*
ZCLink* GetNextPtr(TypeSize AL_Distance)*/
ZCLink* GetPrevPtr(TypeSize AL_Distance)
{
TypeSize VL_LoopIndex=0 ;
ZCLink* VP_TmpLink =this;
while(VL_LoopIndex++ < AL_Distance)
VP_TmpLink = VP_TmpLink->mp_PrevLink ;
return VP_TmpLink;
}/*
ZCLink* GetPrevPtr(TypeSize AL_Distance)*/
ZCLinkC* GetNextPtr(TypeSize AL_Distance) const
{
TypeSize VL_LoopIndex= 0 ;
ZCLinkC* VP_TmpLink = this ;
while(VL_LoopIndex++ < AL_Distance)
VP_TmpLink = VP_TmpLink->mp_NextLink ;
return VP_TmpLink;
}/*
ZCLinkC* GetNextPtr(TypeSize AL_Distance) const*/
ZCLinkC* GetPrevPtr(TypeSize AL_Distance) const
{
TypeSize VL_LoopIndex= 0 ;
ZCLinkC* VP_TmpLink = this ;
while(VL_LoopIndex++ < AL_Distance)
VP_TmpLink = VP_TmpLink->mp_PrevLink ;
return VP_TmpLink;
}/*
ZCLinkC* GetPrevPtr(TypeSize AL_Distance) const*/
ZCLink & operator+(TypeSize AL_Distance)
{
if(AL_Distance>=0)
return *GetNextPtr(AL_Distance);
else return *GetPrevPtr(AL_Distance);
}/*
ZCLink & operator+(TypeSize AL_Distance)*/
ZCLink & operator-(TypeSize AL_Distance)
{
if(AL_Distance>=0)
return *GetPrevPtr(AL_Distance);
else return *GetNextPtr(AL_Distance);
}/*
ZCLink & operator-(TypeSize AL_Distance)*/
ZCLinkC& operator+(TypeSize AL_Distance) const
{
if(AL_Distance>=0)
return *GetNextPtr(AL_Distance);
else return *GetPrevPtr(AL_Distance);
}/*
ZCLinkC& operator+(TypeSize AL_Distance) const*/
ZCLinkC& operator-(TypeSize AL_Distance) const
{
if(AL_Distance>=0)
return *GetPrevPtr(AL_Distance);
else return *GetNextPtr(AL_Distance);
}/*
ZCLinkC& operator-(TypeSize AL_Distance) const*/
public:
};/*
class ZCLink*/
class ZCNodePoint
{
protected:
/*****/ 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*/
const ZCNodePoint& operator--() const
{
mp_CurrLink = mp_CurrLink->mp_PrevLink;
--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*/
ZCNodePoint operator--(int) const
{
ZCNodePoint VO_NowPoint(*this);
mp_CurrLink = mp_CurrLink->mp_PrevLink;
--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*/
const ZCNodePoint& operator-=(TypeSize AL_Distance) const
{
mp_CurrLink = &((*mp_CurrLink)-AL_Distance);
ml_CurrPos -= AL_Distance ;
return *this; /*::::::::::::::::::::::::::*/
}/*
const ZCNodePoint& operator-=(TypeSize AL_Distance) const*/
public:
};/*
class ZCNodePoint*/
class ZCNodePointN
{
protected:
const TypeList& mr_CurrList;
mutable TypeLinkC* mp_CurrLink; // 사실상 mp_CurrLink!=0
mutable TypeSize ml_CurrPos ;
public :
ZCNodePointN(const TypeList& AR_TypeList) :
mr_CurrList(AR_TypeList)
{
mp_CurrLink = AR_TypeList.HeadPtr();
ml_CurrPos = 1 ;
}
ZCNodePointN(const ZCNodePoint & rhs) :
mr_CurrList( rhs.GetMain()),
mp_CurrLink(&rhs.GetNode()),
ml_CurrPos ( rhs.GetPos ())
{}
ZCNodePointN(const ZCNodePointN& rhs) :
mr_CurrList(rhs.mr_CurrList),
mp_CurrLink(rhs.mp_CurrLink),
ml_CurrPos (rhs.ml_CurrPos )
{}
public :
static ZCNodePointN MakeTailPoint(const TypeList& AR_TypeList)
{
ZCNodePointN VO_ZCLinkPoint(AR_TypeList);
VO_ZCLinkPoint.mp_CurrLink = AR_TypeList.mp_TailLink;
VO_ZCLinkPoint.ml_CurrPos = AR_TypeList.ml_LinkSize;
return VO_ZCLinkPoint; /****************/
}/*
static ZCNodePointN MakeTailPoint(const TypeList& AR_TypeList)*/
static ZCNodePointN MakeTailPoint(const ZCNodePoint& AR_TypeIter)
{
ZCNodePointN 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 ZCNodePointN MakeTailPoint(const ZCNodePoint& AR_TypeIter)*/
static ZCNodePointN MakeTailPoint(const ZCNodePointN& AR_TypeIter)
{
ZCNodePointN 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 ZCNodePointN MakeTailPoint(const ZCNodePointN& AR_TypeIter)*/
public :
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;}
ZCNodePointN& operator= (const ZCNodePointN& rhs){ return *this; }
TypeDataC& operator*() const{return **mp_CurrLink;}
operator TypeNodeC* () const{return mp_CurrLink;}
operator TypeNodeC& () const{return *mp_CurrLink;}
operator TypeNode * () const{return 0 ;}
bool operator == (const ZCNodePointN& rhs) const
{ return ml_CurrPos == rhs.ml_CurrPos; }
bool operator != (const ZCNodePointN& rhs) const
{ return ml_CurrPos != rhs.ml_CurrPos; }
bool operator > (const ZCNodePointN& rhs) const
{ return ml_CurrPos > rhs.ml_CurrPos; }
bool operator >= (const ZCNodePointN& rhs) const
{ return ml_CurrPos >= rhs.ml_CurrPos; }
bool operator < (const ZCNodePointN& rhs) const
{ return ml_CurrPos < rhs.ml_CurrPos; }
bool operator <= (const ZCNodePointN& 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 ZCNodePointN& operator++() const
{
mp_CurrLink = mp_CurrLink->mp_NextLink;
++ml_CurrPos; return *this ;
}/*
const ZCNodePointN& operator++() const*/
const ZCNodePointN& operator--() const
{
mp_CurrLink = mp_CurrLink->mp_PrevLink;
--ml_CurrPos; return *this ;
}/*
const ZCNodePointN& operator--() const*/
ZCNodePointN operator++(int) const
{
ZCNodePointN VO_NowPoint(*this);
mp_CurrLink = mp_CurrLink->mp_NextLink;
++ml_CurrPos ; return VO_NowPoint ;
}/*
ZCNodePointN operator++(int) const*/
ZCNodePointN operator--(int) const
{
ZCNodePointN VO_NowPoint(*this);
mp_CurrLink = mp_CurrLink->mp_PrevLink;
--ml_CurrPos; return VO_NowPoint ;
}/*
ZCNodePointN operator--(int) const*/
const ZCNodePointN& operator+=(TypeSize AL_Distance) const
{
if(IsEmpty()){return *this;}
mp_CurrLink = &((*mp_CurrLink)+AL_Distance) ;
ml_CurrPos += AL_Distance ;
return *this; /*:::::::::::::::::::::::::::*/
}/*
const ZCNodePointN& operator+=(TypeSize AL_Distance) const*/
const ZCNodePointN& operator-=(TypeSize AL_Distance) const
{
mp_CurrLink = &((*mp_CurrLink)-AL_Distance);
ml_CurrPos -= AL_Distance ;
return *this; /*::::::::::::::::::::::::::*/
}/*
const ZCNodePointN& operator-=(TypeSize AL_Distance) const*/
public:
};/*
class ZCNodePointN*/
class ZCLinkPointEx : public ZCNodePoint
{
public:
ZCLinkPointEx(TypeList& AR_TypeList): ZCNodePoint(AR_TypeList){}
ZCLinkPointEx(const ZCNodePoint & rhs): ZCNodePoint(rhs ){}
ZCLinkPointEx(const ZCLinkPointEx& rhs): ZCNodePoint(rhs ){}
public:
static ZCLinkPointEx MakeTailPoint(const ZCLinkPointEx& AR_TypeIter)
{
ZCLinkPointEx VO_ZCLinkPoint(AR_TypeIter);
if(!AR_TypeIter.IsEmpty()) /****************************/
{
VO_ZCLinkPoint.mp_CurrLink = VO_ZCLinkPoint.mr_TypeList.mp_TailLink;
VO_ZCLinkPoint.ml_CurrPos = VO_ZCLinkPoint.mr_TypeList.ml_LinkSize;
}
return VO_ZCLinkPoint; /********************************/
}/*
static ZCLinkPointEx MakeTailPoint(const ZCLinkPointEx& AR_TypeIter)*/
public:
ZCLinkPointEx& operator= (const ZCLinkPointEx& rhs){ return *this; }
const ZCLinkPointEx& operator++() const
{
if(this->IsEmpty()){return *this;}
this->mp_CurrLink = this->mp_CurrLink->mp_NextLink ;
if(++this->ml_CurrPos>this->mr_CurrList.size())
{ this->ml_CurrPos -= this->mr_CurrList.size(); }
return *this; /*******************************/
}/*
const ZCLinkPointEx& operator++() const*/
const ZCLinkPointEx& operator--() const
{
if(this->IsEmpty()){return *this;}
this->mp_CurrLink = this->mp_CurrLink->mp_PrevLink ;
if(--this->ml_CurrPos<1)
{ this->ml_CurrPos += this->mr_CurrList.size(); }
return *this; /********/
}/*
const ZCLinkPointEx& operator--() const*/
ZCLinkPointEx operator++(int) const
{
ZCLinkPointEx VO_NowPoint(*this);
if(this->IsEmpty()){return VO_NowPoint;}
this->mp_CurrLink = this->mp_CurrLink->mp_NextLink ;
if(++this->ml_CurrPos>this->mr_CurrList.size())
{ this->ml_CurrPos -= this->mr_CurrList.size(); }
return VO_NowPoint; /*************************/
}/*
ZCLinkPointEx operator++(int) const*/
ZCLinkPointEx operator--(int) const
{
ZCLinkPointEx VO_NowPoint(*this);
if(this->IsEmpty()){return VO_NowPoint;}
this->mp_CurrLink = this->mp_CurrLink->mp_PrevLink ;
if(--this->ml_CurrPos<1)
{ this->ml_CurrPos += this->mr_CurrList.size(); }
return VO_NowPoint;
}/*
ZCLinkPointEx operator--(int) const*/
const ZCLinkPointEx& operator+=(TypeSize AL_Distance) const
{
if(this->IsEmpty()){return *this;}
this->mp_CurrLink = &((*this->mp_CurrLink)+AL_Distance) ;
if(this->ml_CurrPos+=AL_Distance > this->mr_CurrList.size())
{ this->ml_CurrPos %= this->mr_CurrList.size(); }
else if(this->ml_CurrPos<1) // AL_Distance<0
{ while(this->ml_CurrPos+= this->mr_CurrList.size()<1){} }
return *this; /****************************/
}/*
const ZCLinkPointEx& operator+=(TypeSize AL_Distance) const*/
const ZCLinkPointEx& operator-=(TypeSize AL_Distance) const
{
if(this->IsEmpty()){return *this;}
this->mp_CurrLink = &((*this->mp_CurrLink)-AL_Distance);
if(this->ml_CurrPos-=AL_Distance > this->mr_CurrList.size())
{ this->ml_CurrPos %= this->mr_CurrList.size(); }
else if(this->ml_CurrPos<1) // AL_Distance>=0
{ while(this->ml_CurrPos+= this->mr_CurrList.size()<1){} }
return *this; /*****************************/
}/*
const ZCLinkPointEx& operator-=(TypeSize AL_Distance) const*/
public:
};/*
class ZCLinkPointEx*/
public :
/******************************************************************/
protected:
ZCLink* mp_HeadLink;
ZCLink* mp_TailLink;
TypeSize ml_LinkSize; mutable
ZCFreeHeap mo_FreeObjt;
protected:
ZCLink* AddTailLink(ZCLink* AP_NewLink)
{
if(ml_LinkSize<1)
{
mp_HeadLink = AP_NewLink;
mp_TailLink = AP_NewLink;
ZCLink::MakeRing
( mp_HeadLink, mp_TailLink ) ;
ml_LinkSize= 1; return AP_NewLink;
}/*
if(ml_LinkSize<1)*/
ZCLink::JoinLink(mp_TailLink, AP_NewLink) ;
ZCLink::MakeRing(mp_HeadLink, AP_NewLink) ;
mp_TailLink = AP_NewLink; ++ml_LinkSize ;
return AP_NewLink; /*::::::::::::::::::::*/
}/*
ZCLink* AddTailLink(ZCLink* AP_NewLink)*/
ZCLink* AddHeadLink(ZCLink* AP_NewLink)
{
if(ml_LinkSize<1)
{
mp_HeadLink = AP_NewLink;
mp_TailLink = AP_NewLink;
ZCLink::MakeRing
( mp_HeadLink, mp_TailLink ) ;
ml_LinkSize= 1; return AP_NewLink;
}/*
if(ml_LinkSize<1)*/
ZCLink::JoinLink(AP_NewLink, mp_HeadLink) ;
ZCLink::MakeRing(AP_NewLink, mp_TailLink) ;
mp_HeadLink = AP_NewLink; ++ml_LinkSize ;
return AP_NewLink; /*::::::::::::::::::::*/
}/*
ZCLink* AddHeadLink(ZCLink* AP_NewLink)*/
ZCLink* AddLinkAfter(ZCLink* AP_StdLink, ZCLink* AP_NewLink)
{
// *this 에 속한 AP_StdLink 의 뒤에, AP_NewLink 를 삽입한다.
// AP_StdLink 이 0 이면, 맨 앞에 삽입한다.
if(AP_StdLink==0) // 맨 앞에 삽입
{
if(ml_LinkSize<1)
{
mp_HeadLink = AP_NewLink;
mp_TailLink = AP_NewLink;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}
else
{
ZCLink::JoinLink(AP_NewLink, mp_HeadLink) ;
ZCLink::MakeRing(AP_NewLink, mp_TailLink) ;
mp_HeadLink = AP_NewLink;
}
}
else if(AP_StdLink==mp_TailLink)
{
ZCLink::JoinLink(mp_TailLink, AP_NewLink) ;
ZCLink::MakeRing(mp_HeadLink, AP_NewLink) ;
mp_TailLink = AP_NewLink;
}
else
{
ZCLink* VP_StdNext = AP_StdLink->mp_NextLink ;
ZCLink::JoinLink(AP_StdLink, AP_NewLink) ;
ZCLink::JoinLink(AP_NewLink, VP_StdNext) ;
}
++ml_LinkSize; return AP_NewLink;
}/*
ZCLink* AddLinkAfter(ZCLink* AP_StdLink, ZCLink* AP_NewLink)*/
ZCLink* AddLinkBefore(ZCLink* AP_StdLink, ZCLink* AP_NewLink)
{
// *this 에 속한 AP_StdLink 의 앞에, AP_NewLink 를 삽입한다.
// AP_StdLink 이 0 이면, 맨 뒤에 삽입한다.
if(AP_StdLink==0) // 맨 뒤에 삽입
{
if(ml_LinkSize<1)
{
mp_HeadLink = AP_NewLink;
mp_TailLink = AP_NewLink;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}
else
{
ZCLink::JoinLink(mp_TailLink, AP_NewLink) ;
ZCLink::MakeRing(mp_HeadLink, AP_NewLink) ;
mp_TailLink = AP_NewLink;
}
}
else if(AP_StdLink==mp_HeadLink)
{
ZCLink::JoinLink(AP_NewLink, mp_HeadLink) ;
ZCLink::MakeRing(AP_NewLink, mp_TailLink) ;
mp_HeadLink = AP_NewLink;
}
else
{
ZCLink* VP_StdPrev = AP_StdLink->mp_PrevLink ;
ZCLink::JoinLink(VP_StdPrev, AP_NewLink) ;
ZCLink::JoinLink(AP_NewLink, AP_StdLink) ;
}
++ml_LinkSize; return AP_NewLink;
}/*
ZCLink* AddLinkBefore(ZCLink* AP_StdLink, ZCLink* AP_NewLink)*/
ZCLink* CutLink(ZCLink* AP_StdLink)
{
if(mp_HeadLink==AP_StdLink)
{
if(ml_LinkSize==1)
{
mp_HeadLink = 0;
mp_TailLink = 0;
}
else // ml_LinkSize>1
{
mp_HeadLink = mp_HeadLink->mp_NextLink ;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}/*
else*/
}
else if(mp_TailLink==AP_StdLink)
{
mp_TailLink = mp_TailLink->mp_PrevLink ;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}
else
{
ZCLink::JoinLink
(
AP_StdLink->mp_PrevLink, AP_StdLink->mp_NextLink
) ;
////////////////
}/*
else*/
--ml_LinkSize ; return AP_StdLink;
}/*
ZCLink* CutLink(ZCLink* AP_StdLink)*/
ZtCObjList& CutLinkRangeOut /*////////////////////////////////////////*/
(
ZCLink& AR_CutHead ,
ZCLink& AR_CutTail ,
TypeSize AL_CutSize ,
ZtCObjList& rhs ,
ZCLink* AP_RhsStd ,
bool AB_After=true
)
/*#####################################################################*/
{
/*///////////////////////////////////////////////////////////
■ AR_CutHead 는 삭제하려는 링크의 범위의 앞의 링크.
AR_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크.
AR_CutHead 의 앞과 AR_CutTail 의 뒤에서 연결 상태를 끊고,
rhs 의 AP_RhsStd 의 뒤에 삽입한다.
AP_RhsStd==0 이면 맨 앞에 삽입한다. -- 2025-10-06 09:16
■ bool AB_After=true 추가. AB_After==false 이면, rhs 의
AP_RhsStd 의 앞에 삽입한다.
AP_RhsStd==0 이면 맨 뒤에 삽입한다. -- 2025-10-07 08:36
///////////////////////////////////////////////////////////*/
if(this==&rhs ) return rhs;
if(ml_LinkSize<1) return rhs;
if(AL_CutSize>=ml_LinkSize) // 모든 링크를 삭제할 때.
{
mp_HeadLink=0;
}
else if(&AR_CutHead==mp_HeadLink)
{
ZCLink::MakeRing
( mp_HeadLink=AR_CutTail.mp_NextLink, mp_TailLink );
}
else if(&AR_CutTail==mp_TailLink)
{
ZCLink::MakeRing
( mp_HeadLink, mp_TailLink=AR_CutHead.mp_PrevLink );
}
else
{
ZCLink::JoinLink
( AR_CutHead.mp_PrevLink, AR_CutTail.mp_NextLink );
}/*
else*/
ml_LinkSize -= AL_CutSize;
if(rhs.size()<1)
{
// AP_CutHead 과 AP_CutTail 을 연결하여 이중 원형 연결리스트가 되도록 한다.
ZCLink::MakeRing(&AR_CutHead, &AR_CutTail);
rhs.mp_HeadLink = &AR_CutHead ;
rhs.mp_TailLink = &AR_CutTail ;
}
else if(AB_After)
{
if(AP_RhsStd==0) // 맨 앞에 삽입.
{
ZCLink::JoinLink(&AR_CutTail, rhs.mp_HeadLink);
ZCLink::MakeRing(&AR_CutHead, rhs.mp_TailLink);
rhs.mp_HeadLink = &AR_CutHead;
}
else // AP_RhsStd 의 뒤에 삽입.
{
ZCLink* VP_RhsStdNext = AP_RhsStd->mp_NextLink ;
ZCLink::JoinLink(AP_RhsStd , &AR_CutHead );
ZCLink::JoinLink(&AR_CutTail, VP_RhsStdNext);
if(AP_RhsStd==rhs.mp_TailLink)
{ rhs.mp_TailLink = &AR_CutTail; }
}
}
else // !AB_After
{
if(AP_RhsStd==0) // 맨 뒤에 삽입.
{
ZCLink::JoinLink(rhs.mp_TailLink, &AR_CutHead);
ZCLink::MakeRing(rhs.mp_HeadLink, &AR_CutTail);
rhs.mp_TailLink = &AR_CutTail;
}
else // AP_RhsStd 의 앞에 삽입.
{
ZCLink* VP_RhsStdPrev = AP_RhsStd->mp_PrevLink ;
ZCLink::JoinLink(VP_RhsStdPrev, &AR_CutHead);
ZCLink::JoinLink(&AR_CutTail , AP_RhsStd );
if(AP_RhsStd==rhs.mp_HeadLink)
{ rhs.mp_HeadLink = &AR_CutHead; }
}
}/*
else // !AB_After*/
rhs.ml_LinkSize += AL_CutSize; return rhs;
}/*
ZtCObjList& CutLinkRangeOut ////////////////////////////////////////////
(
ZCLink& AR_CutHead ,
ZCLink& AR_CutTail ,
TypeSize AL_CutSize ,
ZtCObjList& rhs ,
ZCLink* AP_RhsStd ,
bool AB_After=true
)
#######################################################################*/
/*private :*/
public :
ZtCObjList()
{
mp_HeadLink = 0 ;
mp_TailLink = 0 ;
ml_LinkSize = 0 ;
}/*
ZtCObjList()*/
ZtCObjList(const ZtCObjList& rhs)
{
mp_HeadLink = 0 ;
mp_TailLink = 0 ;
ml_LinkSize = 0 ;
*this = (rhs);
}/*
ZtCObjList(const ZtCObjList& rhs)*/
~ZtCObjList()
{
DeleteAll();
}/*
~ZtCObjList()*/
ZtCObjList& operator=(const ZtCObjList& rhs)
{
if(this==&rhs) return *this;
if(rhs.size()<1)
{ this->DeleteAll(); return *this; }
TypeSize VL_MinusSize = this->size() - rhs.size() ;
if (VL_MinusSize>0)
{
ZCLink* VP_CutTail =
mp_HeadLink->GetNextPrevPtr(VL_MinusSize-1);
ZCLink* VP_CutTailNext = VP_CutTail->mp_NextLink ;
mo_FreeObjt.RecvFreeIn ///////////////////////////
(
VL_MinusSize, mp_HeadLink, VP_CutTail
);
//////////////////////////////////////////////////
mp_HeadLink = VP_CutTailNext;
ml_LinkSize -= VL_MinusSize ;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}
else if(VL_MinusSize<0)
{
ZCLink* VP_HeadLink=0;
ZCLink* VP_TailLink=0;
mo_FreeObjt.SendFreeOut ///////////////////////////
(
-VL_MinusSize ,
RR(VP_HeadLink) ,
RR(VP_TailLink)
);
///////////////////////////////////////////////////
if(ml_LinkSize>0)
{
ZCLink::JoinLink(mp_TailLink, VP_HeadLink);
ZCLink::MakeRing(mp_HeadLink, VP_TailLink);
mp_TailLink = VP_TailLink ;
}
else
{
mp_HeadLink = VP_HeadLink ;
mp_TailLink = VP_TailLink ;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}/*
else*/
ml_LinkSize += (-VL_MinusSize);
}/*
else if(VL_MinusSize<0)*/
ZCLink* VP_RhsLink = rhs.mp_HeadLink ;
ZCLink* VP_LhsLink = mp_HeadLink ;
__for0(TypeSize, i, rhs.size())
{
**VP_LhsLink = **VP_RhsLink ;
VP_RhsLink = VP_RhsLink->mp_NextLink;
VP_LhsLink = VP_LhsLink->mp_NextLink;
}/*
__for0(TypeSize, i, rhs.size())*/
return *this;
}/*
ZtCObjList& operator=(const ZtCObjList& rhs)*/
void DeleteAll()
{
if(ml_LinkSize<1) return;
mo_FreeObjt.RecvFreeIn
(ml_LinkSize, mp_HeadLink, mp_TailLink);
mp_HeadLink =0 ;
mp_TailLink =0 ;
ml_LinkSize =0 ;
}/*
void DeleteAll()*/
TypeData& AddHead()
{ return **AddHeadLink(mo_FreeObjt.SendFreeOut()); }
TypeData& AddTail()
{ return **AddTailLink(mo_FreeObjt.SendFreeOut()); }
ZCLink& AddHeadDef()
{ return *AddHeadLink(mo_FreeObjt.SendFreeOut()); }
ZCLink& AddTailDef()
{ return *AddTailLink(mo_FreeObjt.SendFreeOut()); }
TypeData& AddHead(TypeArg AO_ArgData) /*########################*/
{
if(TypeMoveObj::ZEUseMoveObj>0) ////////////////////
{
ZCLink* VP_NewNode = mo_FreeObjt.SendFreeOut();
TypeMoveObj::Exec(**VP_NewNode, AO_ArgData);
return AddHeadLink(VP_NewNode)->mo_DataObjt;
}
////////////////////////////////////////////////////
return AddHeadLink(new ZCLink(AO_ArgData))->mo_DataObjt;
}/*
TypeData& AddHead(TypeArg AO_ArgData) ##########################*/
TypeData& AddTail(TypeArg AO_ArgData) /*########################*/
{
if(TypeMoveObj::ZEUseMoveObj>0) ////////////////////
{
ZCLink* VP_NewNode = mo_FreeObjt.SendFreeOut();
TypeMoveObj::Exec(*VP_NewNode, AO_ArgData);
return AddTailLink(VP_NewNode)->mo_DataObjt;
}
////////////////////////////////////////////////////
return AddTailLink(new ZCLink(AO_ArgData))->mo_DataObjt;
}/*
TypeData& AddTail(TypeArg AO_ArgData) ##########################*/
ZtCObjList& AddHead(ZtCObjList& rhs)
{
if(this == &rhs ) return *this;
if(rhs.size()<1 ) return *this;
ZtCObjList VO_TempList(rhs);
return JoinHead(VO_TempList);
}/*
ZtCObjList& AddHead(ZtCObjList& rhs)*/
ZtCObjList& AddTail(ZtCObjList& rhs)
{
if(this == &rhs ) return *this;
if(rhs.size()<1 ) return *this;
ZtCObjList VO_TempList(rhs);
return JoinTail(VO_TempList);
}/*
ZtCObjList& AddTail(ZtCObjList& rhs)*/
void DeleteHead()
{
if(ml_LinkSize<1) return;
ZCLink* VP_TempLink = mp_HeadLink ;
mp_HeadLink = mp_HeadLink->mp_NextLink ;
mo_FreeObjt.RecvFreeIn(VP_TempLink);
if(--ml_LinkSize<1)
{
mp_HeadLink = mp_TailLink =0; return;
}/*
if(--ml_LinkSize<1)*/
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}/*
void DeleteHead()*/
void DeleteTail()
{
if(ml_LinkSize<1) return;
ZCLink* VP_TempLink = mp_TailLink ;
mp_TailLink = mp_TailLink->mp_PrevLink ;
mo_FreeObjt.RecvFreeIn(VP_TempLink);
if(--ml_LinkSize<1)
{
mp_HeadLink = mp_TailLink =0; return;
}/*
if(--ml_LinkSize<1)*/
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}/*
void DeleteTail()*/
void DeleteHead(TTypSize AL_DelSize)
{
// AL_DelSize 개의 링크를 앞 부분에서 삭제
if(ml_LinkSize<1 || AL_DelSize<1){ return; }
if(AL_DelSize > ml_LinkSize)
{ AL_DelSize = ml_LinkSize; }
if(AL_DelSize== ml_LinkSize)
{
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->GetNextPrevPtr( AL_DelSize ) ;
mo_FreeObjt.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(TTypSize AL_DelSize)*/
void DeleteTail(TTypSize AL_DelSize)
{
if(ml_LinkSize==0 || AL_DelSize<1){ return; }
if(AL_DelSize> ml_LinkSize){ AL_DelSize=ml_LinkSize; }
if(AL_DelSize==ml_LinkSize)
{
mo_FreeObjt.RecvFreeIn
(ml_LinkSize, mp_HeadLink, mp_TailLink);
mp_HeadLink=0 ;
mp_TailLink=0 ;
ml_LinkSize=0 ;
return;
}/*
if(AL_DelSize==ml_LinkSize)*/
ZCLink* VP_NewTail =
mp_TailLink->GetNextPrevPtr( -AL_DelSize ) ;
mo_FreeObjt.RecvFreeIn
(AL_DelSize, VP_NewTail->mp_NextLink, mp_TailLink);
mp_TailLink = VP_NewTail ;
ml_LinkSize -= AL_DelSize ;
ZCLink::MakeRing(mp_HeadLink, mp_TailLink);
}/*
void DeleteTail(TTypSize AL_DelSize)*/
ZtCObjList& JoinAfter(TypeThis& rhs, ZCLinkOpt AO_StdOpt)
{
// AP_StdLink 의 뒤에 rhs 를 삽입.
if(rhs.ml_LinkSize<1) return *this;
ZCLink* VP_StdLink = AO_StdOpt.Raw();
if(VP_StdLink==0) // 맨 앞에 삽입
{
if(ml_LinkSize<1)
{
mp_HeadLink = rhs.mp_HeadLink ;
mp_TailLink = rhs.mp_TailLink ;
}
else // ml_LinkSize>=1
{
ZCLink::JoinLink( rhs.mp_TailLink, mp_HeadLink );
ZCLink::MakeRing( rhs.mp_HeadLink, mp_TailLink );
mp_HeadLink = rhs.mp_HeadLink ;
}/*
else // ml_LinkSize>=1*/
ml_LinkSize += rhs.ml_LinkSize;
rhs.mp_HeadLink = 0 ;
rhs.mp_TailLink = 0 ;
rhs.ml_LinkSize = 0 ;
return *this; /////////////////
}/*
if(VP_StdLink==0)*/
ZCLink* VP_StdNext=VP_StdLink->mp_NextLink;
ZCLink::JoinLink(VP_StdLink , rhs.mp_HeadLink );
ZCLink::JoinLink(rhs.mp_TailLink, VP_StdNext );
if(VP_StdLink==mp_TailLink)
{ mp_TailLink=rhs.mp_TailLink; }
ml_LinkSize += rhs.ml_LinkSize;
rhs.mp_HeadLink =0 ;
rhs.mp_TailLink =0 ;
rhs.ml_LinkSize =0 ;
return *this; /*:::::::::::::*/
}/*
ZtCObjList& JoinAfter(TypeThis& rhs, ZCLinkOpt AO_StdOpt)*/
ZtCObjList& JoinBefore(TypeThis& rhs, ZCLinkOpt AO_StdOpt)
{
// AO_StdOpt 의 앞에 rhs 를 삽입.
if(rhs.size()<1) return *this;
ZCLink* VP_StdLink = AO_StdOpt.Raw();
if(VP_StdLink==0) // 맨 뒤에 삽입
{
if(ml_LinkSize<1)
{
mp_HeadLink = rhs.mp_HeadLink ;
mp_TailLink = rhs.mp_TailLink ;
}
else // ml_LinkSize>=1
{
ZCLink::JoinLink(mp_TailLink, rhs.mp_HeadLink );
ZCLink::MakeRing(mp_HeadLink, rhs.mp_TailLink );
mp_TailLink = rhs.mp_TailLink ;
}/*
else // ml_LinkSize>=1*/
ml_LinkSize += rhs.ml_LinkSize;
rhs.mp_HeadLink = 0 ;
rhs.mp_TailLink = 0 ;
rhs.ml_LinkSize = 0 ;
return *this; /////////////////
}/*
if(VP_StdLink==0)*/
ZCLink* VP_StdPrev = VP_StdLink->mp_PrevLink;
ZCLink::JoinLink( VP_StdPrev , rhs.mp_HeadLink );
ZCLink::JoinLink(rhs.mp_TailLink, VP_StdLink );
if(VP_StdLink==mp_HeadLink)
{ mp_HeadLink = rhs.mp_HeadLink; }
ml_LinkSize += rhs.ml_LinkSize;
rhs.mp_HeadLink =0 ;
rhs.mp_TailLink =0 ;
rhs.ml_LinkSize =0 ;
return *this; /*:::::::::::::*/
}/*
ZtCObjList& JoinBefore(TypeThis& rhs, ZCLinkOpt AO_StdOpt)*/
ZtCObjList& JoinHead(TypeThis& rhs)
{ if(this==&rhs) return *this; return JoinAfter (rhs, ZCLinkOpt(0)); }
ZtCObjList& JoinTail(TypeThis& rhs)
{ if(this==&rhs) return *this; return JoinBefore(rhs, ZCLinkOpt(0)); }
void SendOutAfter (ZCLink& AR_CutLink, TypeThis& rhs, ZCLinkOpt AO_StdOpt)
{
// AP_CutLink 를 잘라서 rhs 의 AP_StdLink 뒤에 연결한다.
CutLink(&AR_CutLink); rhs.AddLinkAfter(AO_StdOpt.Raw(), &AR_CutLink);
}/*
void SendOutAfter (ZCLink& AR_CutLink, TypeThis& rhs, ZCLinkOpt AO_StdOpt)*/
void SendOutBefore(ZCLink& AR_CutLink, TypeThis& rhs, ZCLinkOpt AO_StdOpt)
{
// AP_CutLink 를 잘라서 rhs 의 AP_StdLink 앞에 연결한다.
CutLink(&AR_CutLink); rhs.AddLinkBefore(AO_StdOpt.Raw(), &AR_CutLink);
}/*
void SendOutBefore(ZCLink& AR_CutLink, TypeThis& rhs, ZCLinkOpt AO_StdOpt)*/
ZtCObjList& SwapLinkNext(ZCLink& AR_LinkPrev)
{
// 다음 링크와 위치를 맞바꾼다.
if(size()<=1){return *this;}
ZCLink* VP_LinkNext = AR_LinkPrev.mp_NextLink;
if(&AR_LinkPrev == VP_LinkNext){ return *this; }
if(size()==2)
{
if(&AR_LinkPrev==mp_HeadLink) /*************************/
{
// VP_LinkNext==mp_TailLink
mp_HeadLink = VP_LinkNext ;
mp_TailLink = &AR_LinkPrev;
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::*/
else // VP_LinkNext==mp_HeadLink
{
mp_HeadLink = &AR_LinkPrev ;
mp_TailLink = VP_LinkNext ;
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}
else if(&AR_LinkPrev==mp_HeadLink)
{
// VP_LinkNext == mp_HeadLink.mp_NextLink;
ZCLink* VP_HeadNext2 =
VP_LinkNext->mp_NextLink ;
ZCLink::JoinLink(VP_LinkNext , &AR_LinkPrev);
ZCLink::JoinLink(&AR_LinkPrev, VP_HeadNext2);
ZCLink::MakeRing(VP_LinkNext , mp_TailLink );
mp_HeadLink = VP_LinkNext ;
}
else if(&AR_LinkPrev==mp_TailLink)
{
// VP_LinkNext==mp_HeadLink
ZCLink* VP_HeadNext =
mp_HeadLink->mp_NextLink ;
ZCLink* VP_TailPrev =
mp_TailLink->mp_PrevLink ;
ZCLink::JoinLink(mp_TailLink, VP_HeadNext);
ZCLink::JoinLink(VP_TailPrev, mp_HeadLink);
ZCLink::MakeRing(mp_TailLink, mp_HeadLink);
mp_HeadLink = &AR_LinkPrev ;
mp_TailLink = VP_LinkNext ;
}
else if(VP_LinkNext==mp_TailLink)
{
ZCLink* VP_TailPrev2 =
AR_LinkPrev.mp_PrevLink ;
ZCLink::JoinLink(VP_TailPrev2, VP_LinkNext );
ZCLink::JoinLink(VP_LinkNext , &AR_LinkPrev );
ZCLink::MakeRing(mp_HeadLink , &AR_LinkPrev );
mp_TailLink = &AR_LinkPrev ;
}
else
{
ZCLink* VP_SwapPrev = AR_LinkPrev. mp_PrevLink;
ZCLink* VP_SwapNext = VP_LinkNext->mp_NextLink;
ZCLink::JoinLink(VP_SwapPrev , VP_LinkNext ) ;
ZCLink::JoinLink(VP_LinkNext , &AR_LinkPrev ) ;
ZCLink::JoinLink(&AR_LinkPrev, VP_SwapNext ) ;
}
return *this; /***********************************/
}/*
ZtCObjList& SwapLinkNext(ZCLink& AR_LinkPrev)*/
ZtCObjList& SwapLinkPrev(ZCLink& AR_LinkNext)
{
// 이전 링크와 위치를 맞바꾼다.
return SwapLinkNext(*AR_LinkNext.mp_PrevLink);
}/*
ZtCObjList& SwapLinkPrev(ZCLink& AR_LinkNext)*/
ZtCObjList& SwapLink(ZCLink& AR_LinkOne, ZCLink& AR_LinkTwo)
{
// AR_LinkOne 와 AR_LinkTwo 의 위치를 바꾼다.
if(size()<=1){return *this;}
if(&AR_LinkOne==&AR_LinkTwo){return *this;}
if(&AR_LinkOne==mp_HeadLink && &AR_LinkTwo==mp_TailLink)
{ return SwapLinkNext(AR_LinkTwo); }
if(&AR_LinkOne==mp_TailLink && &AR_LinkTwo==mp_HeadLink)
{ return SwapLinkNext(AR_LinkOne); }
/******************************************************/
if(&AR_LinkTwo==AR_LinkOne.mp_NextLink)
{ return SwapLinkNext(AR_LinkOne); }
if(&AR_LinkOne==AR_LinkTwo.mp_NextLink)
{ return SwapLinkNext(AR_LinkTwo); }
/******************************************************/
if(&AR_LinkOne==mp_HeadLink)
{
ZCLink* VP_HeadNext=mp_HeadLink->mp_NextLink;
ZCLink* VP_TwoNext =AR_LinkTwo. mp_NextLink;
ZCLink* VP_TwoPrev =AR_LinkTwo. mp_PrevLink;
ZCLink::JoinLink(&AR_LinkTwo, VP_HeadNext) ;
ZCLink::JoinLink( VP_TwoPrev, &AR_LinkOne ) ;
ZCLink::JoinLink(&AR_LinkOne, VP_TwoNext ) ;
ZCLink::MakeRing(&AR_LinkTwo, mp_TailLink) ;
mp_HeadLink = &AR_LinkTwo ; return *this;
}
if(&AR_LinkOne==mp_TailLink)
{
ZCLink* VP_TailPrev= mp_TailLink->mp_PrevLink;
ZCLink* VP_TwoNext = AR_LinkTwo. mp_NextLink;
ZCLink* VP_TwoPrev = AR_LinkTwo. mp_PrevLink;
ZCLink::JoinLink( VP_TwoPrev , &AR_LinkOne ) ;
ZCLink::JoinLink(&AR_LinkOne , VP_TwoNext ) ;
ZCLink::JoinLink( VP_TailPrev, &AR_LinkTwo ) ;
ZCLink::MakeRing( mp_HeadLink, &AR_LinkTwo ) ;
mp_TailLink = &AR_LinkTwo ; return *this;
}
/******************************************************/
if(&AR_LinkTwo==mp_HeadLink)
{
ZCLink* VP_HeadNext=mp_HeadLink->mp_NextLink;
ZCLink* VP_OneNext =AR_LinkOne. mp_NextLink;
ZCLink* VP_OnePrev =AR_LinkOne. mp_PrevLink;
ZCLink::JoinLink(&AR_LinkTwo, VP_HeadNext) ;
ZCLink::JoinLink( VP_OnePrev, &AR_LinkOne ) ;
ZCLink::JoinLink(&AR_LinkOne, VP_OneNext ) ;
ZCLink::MakeRing(&AR_LinkTwo, mp_TailLink) ;
mp_HeadLink = &AR_LinkTwo ; return *this;
}
if(&AR_LinkTwo==mp_TailLink)
{
ZCLink* VP_TailPrev=mp_TailLink->mp_PrevLink;
ZCLink* VP_OneNext =AR_LinkOne. mp_NextLink;
ZCLink* VP_OnePrev =AR_LinkOne. mp_PrevLink;
ZCLink::JoinLink( VP_OnePrev , &AR_LinkTwo ) ;
ZCLink::JoinLink(&AR_LinkTwo, VP_OneNext ) ;
ZCLink::JoinLink( VP_TailPrev, &AR_LinkTwo ) ;
ZCLink::MakeRing( mp_HeadLink, &AR_LinkTwo ) ;
mp_TailLink = &AR_LinkTwo ; return *this;
}
/********************************************************/
ZCLink* VP_OnePrev= AR_LinkOne.mp_PrevLink ;
ZCLink* VP_OneNext= AR_LinkOne.mp_NextLink ;
ZCLink* VP_TwoPrev= AR_LinkTwo.mp_PrevLink ;
ZCLink* VP_TwoNext= AR_LinkTwo.mp_NextLink ;
ZCLink::JoinLink( VP_OnePrev, &AR_LinkTwo) ;
ZCLink::JoinLink(&AR_LinkTwo, VP_OneNext) ;
ZCLink::JoinLink( VP_TwoPrev, &AR_LinkOne) ;
ZCLink::JoinLink(&AR_LinkOne, VP_TwoNext) ; return *this;
}/*
ZtCObjList& SwapLink(ZCLink& AR_LinkOne, ZCLink& AR_LinkTwo)*/
ZtCObjList& MoveLinkAfter (ZCLink& AR_MoveLink, ZCLinkOpt AO_StdOpt)
{
if(&AR_MoveLink==AO_StdOpt.Raw()){return *this;}
if(size()<=1){return *this;} AddLinkAfter
( AO_StdOpt.Raw(), CutLink(&AR_MoveLink) ) ;
return *this; /**************************/
}/*
ZtCObjList& MoveLinkAfter (ZCLink& AR_MoveLink, ZCLinkOpt AO_StdOpt)*/
ZtCObjList& MoveLinkBefore(ZCLink& AR_MoveLink, ZCLinkOpt AO_StdOpt)
{
if(&AR_MoveLink==AO_StdOpt.Raw()){return *this;}
if(size()<=1){return *this;} AddLinkBefore
( AO_StdOpt.Raw(), CutLink(&AR_MoveLink) ) ;
return *this; /**************************/
}/*
ZtCObjList& MoveLinkBefore(ZCLink& AR_MoveLink, ZCLinkOpt AO_StdOpt)*/
ZtCObjList& MoveLinkHead(ZCLink& AR_MoveLink) /*::::::::::::::::::::*/
{
if(&AR_MoveLink==mp_HeadLink){return *this;}
if(size()<=1){return *this;} AddLinkAfter
( 0, CutLink(&AR_MoveLink) ) ;
return *this; /**************************/
}/*
ZtCObjList& MoveLinkHead(ZCLink& AR_MoveLink) ::::::::::::::::::::::*/
ZtCObjList& MoveLinkTail(ZCLink& AR_MoveLink) /*::::::::::::::::::::*/
{
if(&AR_MoveLink==mp_TailLink){return *this;}
if(size()<=1){return *this;} AddLinkBefore
( 0, CutLink(&AR_MoveLink) ) ;
return *this; /**************************/
}/*
ZtCObjList& MoveLinkTail(ZCLink& AR_MoveLink) ::::::::::::::::::::::*/
void SendOutHead(ZCLink& AR_CutLink, TypeThis& rhs) // AP_CutLink 를 잘라서 rhs 의 앞에 연결한다.
{ SendOutAfter (AR_CutLink, rhs, ZCLinkOpt(0)); }
void SendOutTail(ZCLink& AR_CutLink, TypeThis& rhs) // AP_CutLink 를 잘라서 rhs 의 뒤에 연결한다.
{ SendOutBefore(AR_CutLink, rhs, ZCLinkOpt(0)); }
ZtCObjList& SendRangeOut ///////////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, TypeThis& rhs ,
ZCLinkOpt AO_LinkOpt, bool AB_After
)
/*#####################################################################*/
{
// AR_CutHead 부터 AR_CutTail 까지를 잘라서 rhs 의 AR_StdLink 뒤에 연결한다.
return CutLinkRangeOut /************************/
(
AR_CutHead, AR_CutTail , AI_CutSize,
rhs , AO_LinkOpt.Raw(), AB_After
);
/***********************************************/
}
/*#####################################################################*/
ZtCObjList& SendRangeOutAfter //////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt
)
/*#####################################################################*/
{
// AR_CutHead 부터 AR_CutTail 까지를 잘라서 rhs 의 AR_StdLink 뒤에 연결한다.
return CutLinkRangeOut /////////////
(
AR_CutHead, AR_CutTail, AI_CutSize, rhs, AO_LinkOpt.Raw(), true
);
////////////////////////////////////
}
ZtCObjList& SendRangeOutBefore /////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, TypeThis& rhs , ZCLinkOpt AO_LinkOpt
)
/*#####################################################################*/
{
// AR_CutHead 부터 AR_CutTail 까지를 잘라서 rhs 의 AR_StdLink 뒤에 연결한다.
return CutLinkRangeOut
(
AR_CutHead, AR_CutTail, AI_CutSize, rhs, AO_LinkOpt.Raw(), false
);
//////////////////////
}
/*#####################################################################*/
ZtCObjList& SendRangeIn /////////////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, ZCLinkOpt AO_LinkOpt, bool AB_After
)
/*#####################################################################*/
{
// AR_CutHead 부터 AR_CutTail 까지를 잘라서 AR_StdLink 뒤에 연결한다.
if(AI_CutSize < 1 ){return *this;}
if(AI_CutSize >= size()){return *this;}
ZtCObjList VO_Saver; CutLinkRangeOut /***********/
(
AR_CutHead , AR_CutTail , AI_CutSize,
RR(VO_Saver), AO_LinkOpt.Raw(), AB_After
);
/*************************************************/
if(AB_After)
return JoinAfter (VO_Saver, AO_LinkOpt);
else return JoinBefore(VO_Saver, AO_LinkOpt);
}
/*#####################################################################*/
ZtCObjList& SendRangeInAfter ////////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, ZCLinkOpt AO_LinkOpt
)
/*#####################################################################*/
{
return SendRangeIn
( AR_CutHead, AR_CutTail, AI_CutSize, AO_LinkOpt, true );
}
/*#####################################################################*/
ZtCObjList& SendRangeInBefore ///////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, ZCLinkOpt AO_LinkOpt
)
/*#####################################################################*/
{
return SendRangeIn
( AR_CutHead, AR_CutTail, AI_CutSize, AO_LinkOpt, false);
}
/*#####################################################################*/
ZtCObjList& SendRangeInHead /////////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, ZCLinkOpt AO_LinkOpt
)
/*#####################################################################*/
{
return SendRangeIn
( AR_CutHead, AR_CutTail, AI_CutSize, ZCLinkOpt(0), true );
}
/*#####################################################################*/
ZtCObjList& SendRangeInTail ////////////////////////////////////////////
(
ZCLink& AR_CutHead, ZCLink& AR_CutTail,
TypeSize AI_CutSize, ZCLinkOpt AO_LinkOpt
)
/*#####################################################################*/
{
return SendRangeIn
( AR_CutHead, AR_CutTail, AI_CutSize, ZCLinkOpt(0), false);
}
/*#####################################################################*/
TypeThis& CopyThis(TypeThis& ARR_Rhs) const
{
// *this 를 복사해서, ARR_Rhs 의 끝에 연결한다.
if(size()<1) return ARR_Rhs;
ZCLink* VP_HeadCopy=0;
ZCLink* VP_TailCopy=0;
mo_FreeObjt.SendFreeOutCopy ////////////
(
mp_HeadLink , size()-1,
RR(VP_HeadCopy), RR(VP_TailCopy)
);
////////////////////////////////////////
TypeThis VO_TempList;
VO_TempList.mp_HeadLink=VP_HeadCopy ;
VO_TempList.mp_TailLink=VP_TailCopy ;
VO_TempList.ml_LinkSize=size() ;
return ARR_Rhs.JoinTail(VO_TempList);
}/*
TypeThis& CopyThis(TypeThis& ARR_Rhs) const*/
ZCFreeHeap& GetCFreeHeap() const{return mo_FreeObjt;}
TypeData & GetHeadData() {return mp_HeadLink->mo_DataObjt;}
TypeData & GetTailData() {return mp_TailLink->mo_DataObjt;}
TypeDataC& GetHeadData() const{return mp_HeadLink->mo_DataObjt;}
TypeDataC& GetTailData() const{return mp_TailLink->mo_DataObjt;}
operator TypeData&() { return AddTail() ; }
ZCDataOpt GetHeadDataOpt()
{ if(mp_HeadLink==0) return ZCDataOpt(0);
return ZCDataOpt(mp_HeadLink->mo_DataObjt);
}
ZCDataOpt GetTailDataOpt()
{ if(mp_TailLink==0) return ZCDataOpt(0);
return ZCDataOpt(mp_TailLink->mo_DataObjt);
}
ZCDataOptC GetHeadDataOpt() const
{
if(mp_HeadLink==0) return ZCDataOpt(0);
return ZCDataOpt(mp_HeadLink->mo_DataObjt);
}
ZCDataOptC GetTailDataOpt() const
{
if(mp_TailLink==0) return ZCDataOpt(0);
return ZCDataOpt(mp_TailLink->mo_DataObjt);
}/*
ZCDataOptC GetTailDataOpt()*/
TypeSize size() const{ return ml_LinkSize; }
TypeSize GetSize() const{ return ml_LinkSize; }
TypeSize capacity () const
{ return mo_FreeObjt.size()+size(); }
TypeSize size_free() const
{ return mo_FreeObjt.size() ; }
TypeSize GetFreeSize() const{ return size_free(); }
bool IsEmpty() const{return ml_LinkSize<1;}
bool empty () const{return ml_LinkSize<1;}
void clear (){DeleteAll();}
void push_front(TypeArg AO_ArgData){AddHead(AO_ArgData);}
void push_back (TypeArg AO_ArgData){AddTail(AO_ArgData);}
void pop_front(){DeleteHead();}
void pop_back (){DeleteTail();}
TypeData & front() {return GetHeadData();}
TypeData & back () {return GetTailData();}
TypeDataC& front() const{return GetHeadData();}
TypeDataC& back () const{return GetTailData();}
template<typename TFunctor> void IterElement(TFunctor AO_Functor)
{
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)(**VP_LoopLink);
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TypeSize, i, ml_Size)*/
}/*
template<typename TFunctor> void IterElement(TFunctor AO_Functor) */
template<typename TFunctor, typename TTypeHelp>
void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp)
{
typedef ZNsMain::
ZtCCheckRef<TTypeHelp> ZCCheckRef;
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
**VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TypeSize, i, ml_Size)*/
}/*
template<typename TFunctor, typename TTypeHelp>
void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */
template
< typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElement
( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 )
/*#############################################################################*/
{
typedef ZNsMain::ZtCCheckRef<TTypeHelp1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<TTypeHelp2> ZCCheckRef2;
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
VP_LoopLink->mo_DataObjt
, ZCCheckRef1::PassData(AO_TypeHelp1)
, ZCCheckRef2::PassData(AO_TypeHelp2)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TypeSize, i, ml_Size)*/
}/*
template
< typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElement
( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 )
###############################################################################*/
template<typename TFunctor> void IterElemRev(TFunctor AO_Functor)
{
ZCLink* VP_LoopLink=mp_TailLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)(**VP_LoopLink);
VP_LoopLink = VP_LoopLink->mp_PrevLink ;
}/*
__for0(TypeSize, i, ml_Size)*/
}/*
template<typename TFunctor> void IterElemRev(TFunctor AO_Functor) */
template<typename TFunctor, typename TTypeHelp>
void IterElemRev(TFunctor AO_Functor, TTypeHelp AO_TypeHelp)
{
typedef ZNsMain::
ZtCCheckRef<TTypeHelp> ZCCheckRef;
ZCLink* VP_LoopLink = mp_TailLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
**VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp)
);
VP_LoopLink = VP_LoopLink->mp_PrevLink ;
}/*
__for0(TypeSize, i, ml_Size)*/
}/*
template<typename TFunctor, typename TTypeHelp>
void IterElemRev(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */
template
< typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElemRev
( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 )
/*#############################################################################*/
{
typedef ZNsMain::ZtCCheckRef<TTypeHelp1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<TTypeHelp2> ZCCheckRef2;
ZCLink* VP_LoopLink = mp_TailLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
VP_LoopLink->mo_DataObjt
, ZCCheckRef1::PassData(AO_TypeHelp1)
, ZCCheckRef2::PassData(AO_TypeHelp2)
);
VP_LoopLink = VP_LoopLink->mp_PrevLink ;
}/*
__for0(TypeSize, i, ml_Size)*/
}/*
template
< typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElemRev
( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 )
###############################################################################*/
template<typename TFunctor> void IterElemLink(TFunctor AO_Functor)
{
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)( *VP_LoopLink );
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TypeSize, i, ml_LinkSize)*/
}/*
template<typename TFunctor> void IterElemLink(TFunctor AO_Functor) */
template<typename TFunctor, typename TTypeHelp>
void IterElemLink(TFunctor AO_Functor, TTypeHelp AO_TypeHelp)
{
typedef ZNsMain::
ZtCCheckRef<TTypeHelp> ZCCheckRef;
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
*VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TypeSize, i, ml_LinkSize)*/
}/*
template<typename TFunctor, typename TTypeHelp>
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<TTypeHelp1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<TTypeHelp2> ZCCheckRef2;
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::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<typename TFunctor> void IterElemLinkRev(TFunctor AO_Functor)
{
ZCLink* VP_LoopLink = mp_TailLink ;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)( *VP_LoopLink );
VP_LoopLink = VP_LoopLink->mp_PrevLink ;
}/*
__for0(TypeSize, i, ml_LinkSize)*/
}/*
template<typename TFunctor> void IterElemLinkRev(TFunctor AO_Functor) */
template<typename TFunctor, typename TTypeHelp>
void IterElemLinkRev(TFunctor AO_Functor, TTypeHelp AO_TypeHelp)
{
typedef ZNsMain::
ZtCCheckRef<TTypeHelp> ZCCheckRef;
ZCLink* VP_LoopLink=mp_TailLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
*VP_LoopLink, ZCCheckRef::PassData(AO_TypeHelp)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_PrevLink ;
}/*
__for0(TypeSize, i, ml_LinkSize)*/
}/*
template<typename TFunctor, typename TTypeHelp>
void IterElemLinkRev(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */
template
< typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElemLinkRev
( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 )
/*#############################################################################*/
{
typedef ZNsMain::ZtCCheckRef<TTypeHelp1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<TTypeHelp2> ZCCheckRef2;
ZCLink* VP_LoopLink=mp_TailLink;
__for0(TypeSize, i, ml_LinkSize)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
*VP_LoopLink
, ZCCheckRef1::PassData(AO_TypeHelp1)
, ZCCheckRef2::PassData(AO_TypeHelp2)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_PrevLink ;
}/*
__for0(TypeSize, i, ml_LinkSize)*/
}/*
template
< typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElemLinkRev
( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 )
###############################################################################*/
ZCLink * GetHeadLinkPtr() {return mp_HeadLink;}
ZCLink * GetTailLinkPtr() {return mp_TailLink;}
ZCLinkC* GetHeadLinkPtr() const{return mp_HeadLink;}
ZCLinkC* GetTailLinkPtr() const{return mp_TailLink;}
ZCLink * GetLinkPtr(TypeSize AI_Index) {return mp_HeadLink->GetNextPrevPtr(AI_Index-1);}
ZCLinkC* GetLinkPtr(TypeSize AI_Index) const{return mp_HeadLink->GetNextPrevPtr(AI_Index-1);}
ZCLink & GetHeadLink(TypeSize AI_Distance) {return (*mp_HeadLink)+AI_Distance;}
ZCLink & GetTailLink(TypeSize AI_Distance) {return (*mp_TailLink)-AI_Distance;}
ZCLinkC& GetHeadLink(TypeSize AI_Distance) const{return (*mp_HeadLink)+AI_Distance;}
ZCLinkC& GetTailLink(TypeSize AI_Distance) const{return (*mp_TailLink)-AI_Distance;}
ZCLink & GetNode(TypeSize AI_Index) {return (*mp_HeadLink)+(AI_Index-1);}
ZCLinkC& GetNode(TypeSize AI_Index) const{return (*mp_HeadLink)+(AI_Index-1);}
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);}
ZCLink * TailPtr(TypeSize AI_Distance) {return &((*mp_TailLink)-AI_Distance);}
ZCLinkC* HeadPtr(TypeSize AI_Distance) const{return &((*mp_HeadLink)+AI_Distance);}
ZCLinkC* TailPtr(TypeSize AI_Distance) const{return &((*mp_TailLink)-AI_Distance);}
ZCLink & HeadRef() {return *mp_HeadLink;}
ZCLink & TailRef() {return *mp_TailLink;}
ZCLinkC& HeadRef() const{return *mp_HeadLink;}
ZCLinkC& TailRef() const{return *mp_TailLink;}
ZCLink & HeadRef(TypeSize AI_Distance) {return (*mp_HeadLink)+AI_Distance;}
ZCLink & TailRef(TypeSize AI_Distance) {return (*mp_TailLink)-AI_Distance;}
ZCLinkC& HeadRef(TypeSize AI_Distance) const{return (*mp_HeadLink)+AI_Distance;}
ZCLinkC& TailRef(TypeSize AI_Distance) const{return (*mp_TailLink)-AI_Distance;}
ZCDataOpt GetDataOpt(TypeSize AI_Index) // 1부터 시작.
{ return DataOpt(AI_Index-1); }
ZCDataOptC GetDataOpt(TypeSize AI_Index) const
{ return DataOpt(AI_Index-1); }
ZCDataOpt DataOpt(TypeSize AI_Index) // 1부터
{ if(mp_HeadLink==0){return ZCDataOpt(0);}
return ZCDataOpt(**HeadPtr(AI_Index-1));
}
ZCDataOptC DataOpt(TypeSize AI_Index) const
{ if(mp_HeadLink==0){return ZCDataOpt(0) ;}
return ZCDataOpt(**HeadPtr(AI_Index-1));
}
ZCDataOpt HeadOptD(TypeSize AI_Distance=0)
{ if(mp_HeadLink==0){return ZCDataOpt(0);}
return ZCDataOpt(**HeadPtr(AI_Distance));
}
ZCDataOpt TailOptD(TypeSize AI_Distance=0)
{ if(mp_HeadLink==0){return ZCDataOpt(0);}
return ZCDataOpt(**TailPtr(AI_Distance));
}
ZCDataOptC HeadOptD(TypeSize AI_Distance=0) const
{ if(mp_HeadLink==0){return ZCDataOpt(0);}
return ZCDataOpt(**HeadPtr(AI_Distance));
}
ZCDataOptC TailOptD(TypeSize AI_Distance=0) const
{ if(mp_HeadLink==0){return ZCDataOpt(0);}
return ZCDataOpt(**TailPtr(AI_Distance));
}
ZCLinkOpt HeadOpt() {return ZCLinkOpt(mp_HeadLink);}
ZCLinkOpt TailOpt() {return ZCLinkOpt(mp_TailLink);}
ZCLinkOptC HeadOpt() const{return ZCLinkOpt(mp_HeadLink);}
ZCLinkOptC TailOpt() const{return ZCLinkOpt(mp_TailLink);}
ZCLinkOpt HeadOpt(TypeSize AI_Distance)
{if(mp_HeadLink==0){return ZCLinkOpt(0);} return ZCLinkOpt((*mp_HeadLink)+AI_Distance);}
ZCLinkOpt TailOpt(TypeSize AI_Distance)
{if(mp_TailLink==0){return ZCLinkOpt(0);} return ZCLinkOpt((*mp_TailLink)-AI_Distance);}
ZCLinkOptC HeadOpt(TypeSize AI_Distance) const
{if(mp_HeadLink==0){return ZCLinkOpt(0);} return ZCLinkOpt((*mp_HeadLink)+AI_Distance);}
ZCLinkOptC TailOpt(TypeSize AI_Distance) const
{if(mp_TailLink==0){return ZCLinkOpt(0);} return ZCLinkOpt((*mp_TailLink)-AI_Distance);}
ZCLink & _1() {return HeadRef();}
ZCLink & _0() {return TailRef();}
ZCLinkC& _1() const{return HeadRef();}
ZCLinkC& _0() const{return TailRef();}
ZCLink & _1(TypeSize AI_Distance) {return HeadRef(AI_Distance);}
ZCLink & _0(TypeSize AI_Distance) {return TailRef(AI_Distance);}
ZCLinkC& _1(TypeSize AI_Distance) const{return HeadRef(AI_Distance);}
ZCLinkC& _0(TypeSize AI_Distance) const{return TailRef(AI_Distance);}
ZCLinkOpt GetLinkOpt(TypeSize AI_Index)
{ if(mp_HeadLink==0) return ZCLinkOpt(0); return ZCLinkOpt(GetLinkPtr(AI_Index)); }
ZCLinkOptC GetLinkOpt(TypeSize AI_Index) const
{ if(mp_HeadLink==0) return ZCLinkOpt(0); return ZCLinkOpt(GetLinkPtr(AI_Index)); }
IterEasy GetHeadIterEasy () {return GetHeadLinkPtr();}
IterEasy GetTailIterEasy () {return GetTailLinkPtr();}
IterEasyID GetHeadIterEasyID () {return (IterEasyID) GetHeadLinkPtr();}
IterEasyID GetTailIterEasyID () {return (IterEasyID) GetTailLinkPtr();}
IterEasy GetHeadIterEasy () const{return GetHeadLinkPtr();}
IterEasy GetTailIterEasy () const{return GetTailLinkPtr();}
IterEasyIDc GetHeadIterEasyID () const{return (IterEasyIDc)GetHeadLinkPtr();}
IterEasyIDc GetTailIterEasyID () const{return (IterEasyIDc)GetTailLinkPtr();}
IterEasyIDc GetHeadIterEasyIDc() const{return (IterEasyIDc)GetHeadLinkPtr();}
IterEasyIDc GetTailIterEasyIDc() const{return (IterEasyIDc)GetTailLinkPtr();}
void MoveNextIter(ZCLink* & APR_CLink ) const
{ APR_CLink=APR_CLink->GetNextPtr();
}
void MoveNextIter(IterEasyID & ARRI_IterEasyID ) const
{ MoveNextIter((ZCLink*&)(ARRI_IterEasyID));
}
void MoveNextIter(TypeLinkC* & APR_CLink ) const
{ APR_CLink=APR_CLink->GetNextPtr();
}
void MoveNextIter(IterEasyIDc& ARRI_IterEasyID ) const
{ MoveNextIter((TypeLinkC*&)(ARRI_IterEasyID));
}
void MoveNextIter(iterator & ARR_Iterator ) const{++ARR_Iterator;}
void MoveNextIter(iteratorN & ARR_Iterator ) const{++ARR_Iterator;}
void MovePrevIter(ZCLink* & APR_CLink ) const
{ APR_CLink=APR_CLink->GetPrevPtr();
}
void MovePrevIter(IterEasyID & ARRI_IterEasyID ) const
{ MovePrevIter((ZCLink*&)(ARRI_IterEasyID));
}
void MovePrevIter(TypeLinkC* & APR_CLink ) const
{ APR_CLink=APR_CLink->GetPrevPtr();
}
void MovePrevIter(IterEasyIDc& ARRI_IterEasyID ) const
{ MovePrevIter((TypeLinkC*&)(ARRI_IterEasyID));
}
void MovePrevIter(iterator & ARR_Iterator ) const{--ARR_Iterator;}
void MovePrevIter(iteratorN & ARR_Iterator ) const{--ARR_Iterator;}
iterator begin () { return ZCNodePoint (*this); }
iteratorN begin () const{ return ZCNodePointN(*this); }
iterator end () { return ZCNodePoint ::MakeTailPoint(*this); }
iteratorN end () const{ return ZCNodePointN::MakeTailPoint(*this); }
iteratorN cbegin () const{ return ZCNodePointN(*this); }
iteratorN cend () const{ return ZCNodePointN::MakeTailPoint(*this); }
IterEasy ItHEasy() {return GetHeadIterEasy ();}
IterEasy ItTEasy() {return GetTailIterEasy ();}
IterEasyID ItHID () {return GetHeadIterEasyID ();}
IterEasyID ItTID () {return GetTailIterEasyID ();}
IterEasyC ItHEasy() const{return GetHeadIterEasy ();}
IterEasyC ItTEasy() const{return GetTailIterEasy ();}
IterEasyIDc ItHID () const{return GetHeadIterEasyIDc();}
IterEasyIDc ItTID () const{return GetTailIterEasyIDc();}
IterEasyIDc ItHIDc () const{return GetHeadIterEasyIDc();}
IterEasyIDc ItTIDc () const{return GetTailIterEasyIDc();}
void ItNext(TypeLink* & APR_CLink ) const{ APR_CLink=APR_CLink->GetNextPtr() ;}
void ItNext(iterator & ARR_Iterator ) const{++ARR_Iterator;}
void ItNext(IterEasyID & ARRI_IterEasyID) const{ItNext((ZCLink*&)(ARRI_IterEasyID));}
void ItNext(TypeLinkC* & APR_CLink ) const{ APR_CLink=APR_CLink->GetNextPtr() ;}
void ItNext(iteratorN & ARR_Iterator ) const{++ARR_Iterator;}
void ItNext(IterEasyIDc & ARRI_IterEasyID) const
{ ItNext((TypeLinkC*&)(ARRI_IterEasyID)); }
void ItPrev(ZCLink* & APR_CLink ) const{ APR_CLink=APR_CLink->GetPrevPtr() ;}
void ItPrev(iterator & ARR_Iterator ) const{--ARR_Iterator;}
void ItPrev(IterEasyID & ARRI_IterEasyID) const{ItPrev((ZCLink*&)(ARRI_IterEasyID));}
void ItPrev(TypeLinkC* & APR_CLink ) const{ APR_CLink=APR_CLink->GetPrevPtr() ;}
void ItPrev(iteratorN & ARR_Iterator ) const{--ARR_Iterator;}
void ItPrev(IterEasyIDc & ARRI_IterEasyID) const
{ ItPrev((TypeLinkC*&)(ARRI_IterEasyID)); }
TypeData & ItD(TypeLink * AP_CLink ){return **AP_CLink ;}
TypeData & ItD(iterator & AR_Iterator ){return *AR_Iterator;}
TypeData & ItD(IterEasyID AH_IterEasyID)
{ return ItD((TypeLink *)AH_IterEasyID); }
TypeDataC& ItD(TypeLinkC * AP_CLink ) const{return **AP_CLink ;}
TypeDataC& ItD(iteratorN & AR_Iterator ) const{return *AR_Iterator;}
TypeDataC& ItD(IterEasyIDc AH_IterEasyID ) const
{ return ItD((TypeLinkC*)AH_IterEasyID); }
TypeData & ItD(TypeLink * AP_CLink , TypeSize AI_FarNum)
{return **(AP_CLink->GetNextPrevPtr(AI_FarNum)) ; }
TypeData & ItD(IterEasyID AH_IterEasyID, TypeSize AI_FarNum)
{ return ItD((ZCLink*)AH_IterEasyID , AI_FarNum); }
TypeData & ItD(iterator & ARR_Iterator , TypeSize AI_FarNum)
{ return ItD((ZCLink* )ARR_Iterator , AI_FarNum); }
TypeDataC& ItD(TypeLinkC * AP_CLink , TypeSize AI_FarNum) const
{return **(AP_CLink->GetNextPrePtr(AI_FarNum)) ; }
TypeDataC& ItD(IterEasyIDc AH_IterEasyID, TypeSize AI_FarNum) const
{ return ItD((ZCLinkC*)AH_IterEasyID , AI_FarNum); }
TypeDataC& ItD(iteratorN & ARR_Iterator , TypeSize AI_FarNum) const
{ return ItD((ZCLinkC*)ARR_Iterator , AI_FarNum); }
ZtCObjList& Rotate(TypeSize AL_RotateNum)
{
if(ml_LinkSize>0) /***********************/
{
mp_HeadLink = mp_HeadLink->
GetNextPrevPtr(AL_RotateNum);
mp_TailLink = mp_HeadLink->mp_PrevLink;
}
return *this; /***************************/
}/*
ZtCObjList& Rotate(TypeSize AL_RotateNum)*/
ZtCObjList& Rotate()
{
if(ml_LinkSize>0) /************************/
{
mp_HeadLink = mp_HeadLink->mp_NextLink ;
mp_TailLink = mp_HeadLink->mp_PrevLink ;
}
return *this; /****************************/
}/*
ZtCObjList& Rotate()*/
ZtCObjList& RotateBack()
{
if(ml_LinkSize>0) /************************/
{
mp_HeadLink = mp_HeadLink->mp_PrevLink ;
mp_TailLink = mp_HeadLink->mp_PrevLink ;
}
return *this; /****************************/
}/*
ZtCObjList& RotateBack()*/
/*///////////////////////////////////////////////////////////////////////////
■ IterElement() 예제.
#include <iostream>
#include "ZCppMain/ZtCObjList.H"
using namespace std;
int main()
{
ZNsMain:: ZtCObjList<int> myObjList;
myObjList.AddTail(10);
myObjList.AddTail(20);
myObjList.AddTail(30);
myObjList.AddTail(40);
struct StFunctor
{
static void ShowElement(int ArgiValue){cout<<"# Value="<<ArgiValue<<endl;}
};
struct StFunctor2
{
int MI_Index;
StFunctor2(){MI_Index=0;}
void operator()(int ArgiValue){cout<<"# index="<<++MI_Index<<", Value="<<ArgiValue<<endl;}
};
StFunctor2 VO_StFunctor2;
myObjList.IterElement(StFunctor::ShowElement);
myObjList.IterElement(&VO_StFunctor2); // linux g++ 4.4.7 에서 컴파일 에러다.
// struct StFunctor2 정의를 main() 함수 바깥으로 빼면 컴파일된다.
return 0;
}
■ -- 2014-06-16 23:34:00
///////////////////////////////////////////////////////////////////////////*/
public:
};/*
template< typename TType ///////////////////////////////////////////////////
, typename TTypArgu = const TType&
, typename TTypCAlloc = ZCAllocator
, typename TTypeInit = ZtCInit<TType>
, typename TTypSize = ZTypLong
, typename TMoveObj = ZtCMoveObj<TType, TTypArgu, true>
, typename TFeeeHeap = ZNsIFaceEx::
ZtCFreeHeapCDL< ZNsConst::CI_ListKind_Double >
>
class ZtCObjList ////////////////////////////////////////////////////////////*/
/*/////////////////////////////////////////////////////////////////////////////
■ 주로 IterElement() 을 사용하는 ZtCObjList<> 예제 --2025-08-10 11:41
#include <iostream>
#include "ZCppMain/ZtCArray.H"
#include "ZCppMain/ZtCObjList.H"
using namespace std ;
using namespace ZNsMain;
int main()
{
typedef ZtCArray<int> CArray ;
typedef ZtCObjList<int> CObjList ;
typedef CArray ::IterEasy IterEasyA;
typedef CObjList::IterEasy IterEasyL;
CArray VO_CArray; CObjList VO_CObjList;
VO_CArray.AddTail(10);
VO_CArray.AddTail(20);
VO_CArray.AddTail(30);
VO_CArray.AddTail(40);
VO_CObjList.AddTail(10);
VO_CObjList.AddTail(20);
VO_CObjList.AddTail(30);
VO_CObjList.AddTail(40);
IterEasyA VH_IterA = VO_CArray .ItHEasy();
IterEasyL VH_IterL = VO_CObjList.ItHEasy();
class CHelpObj
{
public:
CHelpObj()
{
}
CHelpObj(const CHelpObj& rhs)
{
cout<<"* CHelpObj(const CHelpObj& rhs)"<<endl;
}
public:
}; CHelpObj VO_CHelpObj; cout<<"VO_CHelpObj Ptr : "<<&VO_CHelpObj<<endl;
struct StFunctor
{
static void ShowElement(int ArgiValue){cout<<"#1 Value="<<ArgiValue<<endl;}
};
struct StFunctor2
{
static void ShowElement(int ArgiValue, CHelpObj)
{cout<<"#2 Value="<<ArgiValue<<", CHelpObj Addr=None"<<" With CHelpObj"<<endl;}
};
struct StFunctor3
{
static void ShowElement(int ArgiValue, CHelpObj& AR_CHelpObj)
{cout<<"#3 Value="<<ArgiValue<<", HelpObj Ptr="<<&AR_CHelpObj<<" With CHelpObj Ref"<<endl;}
};
struct StFunctor4
{
static void ShowElement(int ArgiValue, CHelpObj& AR_CHelpObj)
{cout<<"#4 Value="<<ArgiValue<<", HelpObj Ptr="<<&AR_CHelpObj<<" With CHelpObj in Ptr"<<endl;}
};
struct StFunctor5
{
static void ShowElement(int ArgiValue, CHelpObj& AR_CHelpObj, CHelpObj& AR_CHelpObj2)
{cout<<"#5 Value="<<ArgiValue<<", HelpObj Ptr="<<&AR_CHelpObj<<" With CHelpObj Ref 2"<<endl;}
};
struct StFunctor6
{
static void ShowElement(int ArgiValue, CHelpObj& AR_CHelpObj, CHelpObj AO_CHelpObj2)
{cout<<"#6 Value="<<ArgiValue<<", HelpObj Ptr="<<&AR_CHelpObj<<" With CHelpObj Half Ref"<<endl;}
};
VO_CArray.IterElement(StFunctor ::ShowElement);
VO_CArray.IterElement(StFunctor2::ShowElement, VO_CHelpObj );
VO_CArray.IterElement(StFunctor3::ShowElement, ZftMCR(VO_CHelpObj) );
VO_CArray.IterElement(StFunctor4::ShowElement, ZftMCP(VO_CHelpObj) );
VO_CArray.IterElement(StFunctor5::ShowElement, ZftMCP(VO_CHelpObj), ZftMCP(VO_CHelpObj) );
VO_CArray.IterElement(StFunctor6::ShowElement, ZftMCP(VO_CHelpObj), VO_CHelpObj );
__for1(int, i, VO_CArray.size())
{
cout<<i<<"th value="<<VO_CArray.ItD(VH_IterA)<<endl; VO_CArray.ItNext(VH_IterA);
}
cout<<endl<<"#### Show CObjList Element ####"<<endl<<endl;
VO_CObjList.IterElement(StFunctor ::ShowElement);
VO_CObjList.IterElement(StFunctor2::ShowElement, VO_CHelpObj );
VO_CObjList.IterElement(StFunctor3::ShowElement, ZftMCR(VO_CHelpObj) );
VO_CObjList.IterElement(StFunctor4::ShowElement, ZftMCP(VO_CHelpObj) );
VO_CObjList.IterElement(StFunctor5::ShowElement, ZftMCP(VO_CHelpObj), ZftMCP(VO_CHelpObj) );
VO_CObjList.IterElement(StFunctor6::ShowElement, ZftMCP(VO_CHelpObj), VO_CHelpObj );
__for1(int, i, VO_CObjList.size())
{
cout<<i<<"th value="<<VO_CObjList.ItD(VH_IterL)<<endl; VO_CObjList.ItNext(VH_IterL);
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////*/
namespace ZNsType
{
/*////////////////////////////////////////////////////////////////////////////////////
■ class ZtCTypeObjUnitList<> 은 ZNsMain::ZtCObjUnitList<> 의 2번 템플릿 인자로 들어가
서, 자칫 지저분하게 보일 수 있는 ZtCObjUnitList<> 선언을 단순하게 한다.
ZtCObjUnitList<> 는 IOCP 형 쓰레드 풀의 작업 큐로 사용하는데에 최적화되었다.
■ int TInMaxUnitCnt
동기화 영역에서 '작업 큐'에 한 번에 등록할 수 있는 ZCLinkUnit 의 최대 갯수. 무슨 얘
기냐면, epoll_wait() 등의 이벤트 수신 함수에서처럼 작업을 배열로 받는 경우, 임시로
'작업 큐'를 만들어서 여기에 등록한 다음, 이 임시 '작업 큐'('임시 작업 큐')의 모든
원소를 한 번에 실제 '작업 큐'에 동기화 영역에서 고정 시간에 등록하게 된다. '임시 작
업 큐'를 설계하지 않고 실제 '작업 큐'에 바로 배열을 각 원소마다 등록한다면, 배열의
크기에 따른 선형 시간이 걸리게 되고, 동기화 영역의 수행 시간이 길어질 수 있다.
그렇다고 배열로 받은 작업을 '임시 작업 큐'에 한꺼번에 등록해 버리면, 그 만큼의 메
모리를, 즉 그 만큼의 '내부 삭제 리스트'를 동기화 영역에서 실제 '작업 큐'로부터 가
지고 올 때, 선형 시간이 걸리게 된다. 그래서 '임시 작업 큐'에 등록하는 ZCLinkUnit 의
최대 갯수를
int TInMaxUnitCnt
개로 제한하려는 것이다.
////////////////////////////////////////////////////////////////////////////////////*/
template< typename TType ,
typename TTypArg =const TType& ,
typename TTypCAlloc =ZCAllocator ,
typename TTypSize =ZTypLong ,
ZTypInt TInArrSize =4 ,
ZTypInt TInMaxUnitCnt =5
>
class ZtCTypeObjUnitList //////////////////////////
{
public :
enum{ZEArrSize =TInArrSize };
enum{ZEMaxUnitCnt =TInMaxUnitCnt};
public :
typedef TType TypeData ;
typedef TTypArg TypeArg ;
typedef TTypSize TypeSize ;
typedef TTypCAlloc TypeAlloc;
public:
};/*
template< typename TType ,
typename TTypArg =const TType& ,
typename TTypCAlloc =ZCAllocator ,
typename TTypSize =ZTypLong ,
ZTypInt TInArrSize =4 ,
ZTypInt TInMaxUnitCnt =5
>
class ZtCTypeObjUnitList ////////////////////////*/
}/*
namespace ZNsType*/
/*////////////////////////////////////////////////////////////////////////////////////////////////////////
■ class ZtCObjUnitList<> 는 IOCP 형 쓰레드 풀의 작업 큐로 사용하는데에 최적화되었다.
■ class ZtCObjUnitList<> 는 내부적으로 '내부 사용 리스트'와 '내부 삭제 리스트'를 갖는다. '내부 사용 리스트'
에서 ZCLinkUnit 이 삭제가 되면 실제로 삭제되는 것이 아니고, '내부 삭제 리스트'로 옮겨 가는 것이다.
-- 2013-02-14 10:42:00
////////////////////////////////////////////////////////////////////////////////////////////////////////*/
template< typename TType , ///////////////////////////////////////////
typename TTypeObjUnitList =
ZNsType::ZtCTypeObjUnitList<TType>
>
class ZtCObjUnitList ///////////////////////////////////////////////////
{
public :
class ZCLinkUnit; typedef ZCLinkUnit TypeUnit;
public :
typedef TTypeObjUnitList TypeObjUnitList;
public :
enum{ZEArrSize =TypeObjUnitList::ZEArrSize };
enum{ZEMaxUnitCnt =TypeObjUnitList::ZEMaxUnitCnt};
public :
typedef typename TypeObjUnitList::TypeData TypeData ;
typedef typename TypeObjUnitList::TypeArg TypeArg ;
typedef typename TypeObjUnitList::TypeSize TypeSize ;
typedef typename TypeObjUnitList::TypeAlloc TypeAlloc;
public :
typedef TypeData TypeArr[ZEArrSize] ;
public :
typedef const TypeUnit TypeUnitC ;
typedef const TypeData TypeDataC ;
typedef const TypeArr TypeArrC ;
public :
class ZCLinkUnit : public TypeAlloc
{
public :
friend class ZtCObjUnitList;
private:
TypeArr mo_TypeArr ;
TypeSize ml_UseSize ;
TypeUnit* mp_NextUnit;
TypeUnit* mp_PrevUnit;
private:
static void JoinLink(ZCLinkUnit* AP_UnitLhs , ZCLinkUnit* AP_UnitRhs )
{
AP_UnitLhs ->mp_NextUnit= AP_UnitRhs;
AP_UnitRhs ->mp_PrevUnit= AP_UnitLhs;
}/*
static void JoinLink(ZCLinkUnit* AP_UnitLhs , ZCLinkUnit* AP_UnitRhs )*/
static void MakeRing(ZCLinkUnit* AP_HeadUnit, ZCLinkUnit* AP_TailUnit)
{
AP_HeadUnit->mp_PrevUnit= AP_TailUnit;
AP_TailUnit->mp_NextUnit= AP_HeadUnit;
}/*
static void MakeRing(ZCLinkUnit* AP_HeadUnit, ZCLinkUnit* AP_TailUnit)*/
/********************************************************************/
TypeData& AddEmptyObj()
{
return mo_TypeArr[ml_UseSize++]; // must ml_UseSize>=ZEArrSize
}/*
TypeData& AddEmptyObj()*/
private:
/********************************************************************/
public :
ZCLinkUnit()
{
ml_UseSize =0 ;
mp_NextUnit=0 ;
mp_PrevUnit=0 ;
}/*
ZCLinkUnit()*/
ZCLinkUnit(const ZCLinkUnit& rhs)
{
ml_UseSize =0 ;
mp_NextUnit=0 ;
mp_PrevUnit=0 ;
*this = (rhs) ;
}/*
ZCLinkUnit(const ZCLinkUnit& rhs)*/
ZCLinkUnit& operator=(const ZCLinkUnit& rhs)
{
if(this==&rhs) return *this;
ml_UseSize = rhs.ml_UseSize;
__for0(TypeSize, i, rhs.ml_UseSize)
{
mo_TypeArr[i] = rhs.mo_TypeArr[i] ;
}/*
__for0(TypeSize, i, rhs.ml_UseSize)*/
return *this;
}/*
ZCLinkUnit& operator=(const ZCLinkUnit& rhs)*/
TypeSize size () const{return ml_UseSize ;}
TypeSize GetUseSize () const{return ml_UseSize ;}
TypeData * GetHeadObjPtr () {return mo_TypeArr ;}
TypeUnit * GetNextUnitPtr() {return mp_NextUnit;}
TypeUnit * GetPrevUniPtr () {return mp_PrevUnit;}
TypeDataC* GetHeadObjPtr () const{return mo_TypeArr ;}
TypeUnitC* GetNextUnitPtr() const{return mp_NextUnit;}
TypeUnitC* GetPrevUniPtr () const{return mp_PrevUnit;}
TypeData & GetData (TypeSize AI_Index)
{ return mo_TypeArr[AI_Index-1]; } // AI_Index start from 1
TypeDataC& GetData (TypeSize AI_Index) const
{ return mo_TypeArr[AI_Index-1]; }
TypeData & operator[](TypeSize AI_Index)
{ return mo_TypeArr[AI_Index ]; }
TypeDataC& operator[](TypeSize AI_Index) const
{ return mo_TypeArr[AI_Index ]; }
TypeArr & operator*() { return mo_TypeArr; }
TypeArrC & operator*() const{ return mo_TypeArr; }
bool AddObj(TypeArg AR_Object)
{
if(ml_UseSize>=ZEArrSize) return false;
mo_TypeArr[ml_UseSize++]=AR_Object; return true;
}/*
bool AddObj(TypeArg AR_Object)*/
void AddObjArr(TypeData* AP_ObjArr, TypeSize AI_ArrSize)
{
if(ml_UseSize>=ZEArrSize) return;
while(--AI_ArrSize>=0)
{
mo_TypeArr[ml_UseSize++] = *AP_ObjArr++;
if(ml_UseSize>=ZEArrSize) return;
}/*
while(--AI_ArrSize>=0)*/
}/*
void AddObjArr(TypeData* AP_ObjArr, TypeSize AI_ArrSize)*/
bool AddEmptyObj(TypeData*& APR_Object)
{
if(ml_UseSize>=ZEArrSize) return false;
APR_Object=mo_TypeArr+(ml_UseSize++); return true;
}/*
bool AddEmptyObj(TypeData*& APR_Object)*/
ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance)
{
if(AI_Distance==0) return this;
ZCLinkUnit* VP_NowUnit=this;
if(AI_Distance<0)
{
for(; AI_Distance!=0; ++AI_Distance)
VP_NowUnit = VP_NowUnit->mp_PrevUnit ;
return VP_NowUnit;
}/*
if(AI_Distance<0)*/
for(; AI_Distance!=0; --AI_Distance)
{ VP_NowUnit = VP_NowUnit->mp_NextUnit; }
return VP_NowUnit;
}/*
ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance)*/
const ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance) const
{
if(AI_Distance==0) return this;
ZCLinkUnit* VP_NowUnit=this;
if(AI_Distance<0)
{
for(; AI_Distance!=0; ++AI_Distance)
VP_NowUnit = VP_NowUnit->mp_PrevUnit ;
return VP_NowUnit;
}/*
if(AI_Distance<0)*/
for(; AI_Distance!=0; --AI_Distance)
{ VP_NowUnit=VP_NowUnit->mp_NextUnit; }
return VP_NowUnit;
}/*
const ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance) const*/
ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance, TypeSize& ARRI_ObjCnt)
{
if(AI_Distance==0) return this;
ARRI_ObjCnt=ml_UseSize; ZCLinkUnit* VP_NowUnit=this;
if(AI_Distance<0)
{
for(; AI_Distance!=0; ++AI_Distance)
{
VP_NowUnit = VP_NowUnit->mp_PrevUnit;
ARRI_ObjCnt+= VP_NowUnit->ml_UseSize ;
}/*
for(; AI_Distance!=0; ++AI_Distance)*/
return VP_NowUnit;
}/*
if(AI_Distance<0)*/
for(; AI_Distance!=0; --AI_Distance)
{
VP_NowUnit = VP_NowUnit->mp_NextUnit;
ARRI_ObjCnt+= VP_NowUnit->ml_UseSize ;
}/*
for(; AI_Distance!=0; --AI_Distance)*/
return VP_NowUnit;
}/*
ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance, TypeSize& ARRI_ObjCnt)*/
const ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance, TypeSize& ARRI_ObjCnt) const
{
if(AI_Distance==0) return this;
ARRI_ObjCnt=ml_UseSize; ZCLinkUnit* VP_NowUnit=this;
if(AI_Distance<0)
{
for(; AI_Distance!=0; ++AI_Distance)
{
VP_NowUnit = VP_NowUnit->mp_PrevUnit;
ARRI_ObjCnt+= VP_NowUnit->ml_UseSize ;
}/*
for(; AI_Distance!=0; ++AI_Distance)*/
return VP_NowUnit;
}/*
if(AI_Distance<0)*/
for(; AI_Distance!=0; --AI_Distance)
{
VP_NowUnit = VP_NowUnit->mp_NextUnit;
ARRI_ObjCnt+= VP_NowUnit->ml_UseSize ;
}/*
for(; AI_Distance!=0; --AI_Distance)*/
return VP_NowUnit;
}/*
const ZCLinkUnit* GetUnitPtr(TypeSize AI_Distance, TypeSize& ARRI_ObjCnt) const*/
public :
};/*
class ZCLinkUnit*/
/*public :*/
private:
ZCLinkUnit* mp_NowHeadUnit; // '내부 사용 리스트'의 첫 ZCLinkUnit 포인터.
ZCLinkUnit* mp_CutHeadUnit; // '내부 삭제 리스트'의 첫 ZCLinkUnit 포인터. 일종의 삭제 버퍼다.
TypeSize ml_NowUnitCnt ; // '내부 사용 리스트'의 ZCLinkUnit 의 갯수.
TypeSize ml_CutUnitCnt ; // '내부 삭제 리스트'의 ZCLinkUnit 의 갯수 , 즉 삭제 버퍼에 있는 ZCLinkUnit 의 갯수.
TypeSize ml_NowObjtCnt ; // '내부 사용 리스트'의 모든 ZCLinkUnit 의 원소 수.
/*private:*/
private:
ZCLinkUnit* CreateUnit()
{
return new ZCLinkUnit;
}/*
ZCLinkUnit* CreateUnit()*/
void DeleteUnit(ZCLinkUnit* AP_CLinkUnit)
{
delete AP_CLinkUnit;
}/*
void DeleteUnit(ZCLinkUnit* AP_CLinkUnit)*/
ZCLinkUnit& AllocUnit()
{
// '내부 삭제 리스트'에 ZCLinkUnit 가 있다면 그것을 반환한다.
if(ml_CutUnitCnt<1)
{
ZCLinkUnit* VP_NewLinkUnit=CreateUnit();
VP_NewLinkUnit->ml_UseSize=0; return *VP_NewLinkUnit;
}/*
if(ml_CutUnitCnt<1)*/
ZCLinkUnit* VP_CutHeadUnit=mp_CutHeadUnit ;
ZCLinkUnit* VP_CutTailUnit=mp_CutHeadUnit->mp_PrevUnit;
mp_CutHeadUnit=mp_CutHeadUnit->mp_NextUnit;
if(--ml_CutUnitCnt<1)
mp_CutHeadUnit=0;
else
ZCLinkUnit::MakeRing(mp_CutHeadUnit, VP_CutTailUnit);
//else
VP_CutHeadUnit->ml_UseSize=0; return *VP_CutHeadUnit;
}/*
ZCLinkUnit& AllocUnit()*/
ZCLinkUnit& AllocUnitAtHead()
{
// AllocUnit() 을 통해 가져온 ZCLinkUnit* 을
// '내부 사용 리스트'의 앞에 삽입한다.
ZCLinkUnit* VP_NewLinkUnit= &AllocUnit();
if(++ml_NowUnitCnt<=1)
{
mp_NowHeadUnit = VP_NewLinkUnit;
mp_NowHeadUnit->mp_NextUnit = mp_NowHeadUnit ;
mp_NowHeadUnit->mp_PrevUnit = mp_NowHeadUnit ;
}
else
{
ZCLinkUnit* VP_TailCLinkUnit= mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink(VP_NewLinkUnit, mp_NowHeadUnit );
ZCLinkUnit::MakeRing(VP_NewLinkUnit, VP_TailCLinkUnit);
mp_NowHeadUnit=VP_NewLinkUnit;
}/*
else*/
return *VP_NewLinkUnit;
}/*
ZCLinkUnit& AllocUnitAtHead()*/
ZCLinkUnit& AllocUnitAtTail()
{
// AllocUnit() 을 통해 가져온 ZCLinkUnit* 을
// '내부 사용 리스트'의 뒤에 삽입한다.
ZCLinkUnit* VP_NewLinkUnit= &AllocUnit();
if(++ml_NowUnitCnt<=1)
{
mp_NowHeadUnit = VP_NewLinkUnit;
mp_NowHeadUnit->mp_NextUnit= mp_NowHeadUnit;
mp_NowHeadUnit->mp_PrevUnit= mp_NowHeadUnit;
}
else
{
ZCLinkUnit* VP_TailCLinkUnit= mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink(VP_TailCLinkUnit, VP_NewLinkUnit);
ZCLinkUnit::MakeRing(mp_NowHeadUnit , VP_NewLinkUnit);
}/*
else*/
return *VP_NewLinkUnit;
}/*
ZCLinkUnit& AllocUnitAtTail()*/
/*private:*/
public :
ZtCObjUnitList()
{
mp_NowHeadUnit=0;
mp_CutHeadUnit=0;
ml_NowUnitCnt =0;
ml_CutUnitCnt =0;
ml_NowObjtCnt =0;
}/*
ZtCObjUnitList()*/
ZtCObjUnitList(const ZtCObjUnitList& rhs)
{
mp_NowHeadUnit=0;
mp_CutHeadUnit=0;
ml_NowUnitCnt =0;
ml_CutUnitCnt =0;
ml_NowObjtCnt =0;
AddTail(rhs);
}/*
ZtCObjUnitList(const ZtCObjUnitList& rhs)*/
~ZtCObjUnitList()
{
ClearEx();
}/*
~ZtCObjUnitList()*/
ZtCObjUnitList& operator=(const ZtCObjUnitList& rhs)
{
if(this!=&rhs)
{
DeleteAll(); AddTail(rhs);
}/*
if(this!=&rhs)*/
return *this;
}/*
ZtCObjUnitList& operator=(const ZtCObjUnitList& rhs)*/
TypeSize size () const{return ml_NowObjtCnt;}
TypeSize GetNowUnitCnt() const{return ml_NowUnitCnt;}
TypeSize GetNowObjtCnt() const{return ml_NowObjtCnt;}
TypeSize GetCutUnitCnt() const{return ml_CutUnitCnt;}
ZCLinkUnit* GetNowHeadUnitPtr() {return mp_NowHeadUnit;}
ZCLinkUnit* GetCutHeadUnitPtr() {return mp_CutHeadUnit;}
TypeData& GetHeadData () {return mp_NowHeadUnit->mo_TypeArr[0];}
const ZCLinkUnit* GetNowHeadUnitPtr() const{return mp_NowHeadUnit;}
const ZCLinkUnit* GetCutHeadUnitPtr() const{return mp_CutHeadUnit;}
const TypeData& GetHeadData () const{return mp_NowHeadUnit->mo_TypeArr[0];}
ZCLinkUnit* GetNowUnitPtr(TypeSize AI_Distance){
if(mp_NowHeadUnit==0) return 0; return mp_NowHeadUnit->GetUnitPtr(AI_Distance); }
ZCLinkUnit* GetCutUnitPtr(TypeSize AI_Distance){
if(mp_CutHeadUnit==0) return 0; return mp_CutHeadUnit->GetUnitPtr(AI_Distance); }
const ZCLinkUnit* GetNowUnitPtr(TypeSize AI_Distance) const{
if(mp_NowHeadUnit==0) return 0; return mp_NowHeadUnit->GetUnitPtr(AI_Distance); }
const ZCLinkUnit* GetCutUnitPtr(TypeSize AI_Distance) const{
if(mp_CutHeadUnit==0) return 0; return mp_CutHeadUnit->GetUnitPtr(AI_Distance); }
void AddTail(TypeArg AR_Object)
{
if(ml_NowUnitCnt>0 && mp_NowHeadUnit->mp_PrevUnit->size() < this->ZEArrSize)
{
mp_NowHeadUnit->mp_PrevUnit->AddObj(AR_Object); ++ml_NowObjtCnt; return;
}/*
if(ml_NowUnitCnt>0 && mp_NowHeadUnit->mp_PrevUnit->size() < this->ZEArrSize)*/
AllocUnitAtTail().AddObj(AR_Object); ++ml_NowObjtCnt;
}/*
void AddTail(TypeArg AR_Object)*/
void AddTail(const ZCLinkUnit& AR_CLinkUnit)
{
if(AR_CLinkUnit.size()>0)
{
AllocUnitAtTail()=AR_CLinkUnit; ml_NowObjtCnt+=AR_CLinkUnit.size();
}/*
if(AR_CLinkUnit.size()>0)*/
}/*
void AddTail(const ZCLinkUnit& AR_CLinkUnit)*/
void AddTail(const ZtCObjUnitList& AR_ZtCObjUnitList)
{
TypeSize VL_RhsNowUnitCnt = AR_ZtCObjUnitList.GetNowUnitCnt ();
const ZCLinkUnit* VP_RhsNowHeadUnit = AR_ZtCObjUnitList.GetNowHeadUnitPtr();
while(--VL_RhsNowUnitCnt>=0)
{
AddTail(*VP_RhsNowHeadUnit); VP_RhsNowHeadUnit=VP_RhsNowHeadUnit->GetNextUnitPtr();
}/*
while(--VL_RhsNowUnitCnt>=0)*/
}/*
void AddTail(const ZtCObjUnitList& AR_ZtCObjUnitList)*/
TypeData& AddTail()
{
if(ml_NowUnitCnt>0 && mp_NowHeadUnit->mp_PrevUnit->size() < this->ZEArrSize)
{
++ml_NowObjtCnt; return mp_NowHeadUnit->mp_PrevUnit->AddEmptyObj_E();
}/*
if(ml_NowUnitCnt>0 && mp_NowHeadUnit->mp_PrevUnit->size() < this->ZEArrSize)*/
++ml_NowObjtCnt; return AllocUnitAtTail().AddEmptyObj_E();
}/*
TypeData& AddTail()*/
void AddTail(TypeData* AP_ObjArr, TypeSize AI_ArrSize)
{
// 마지막 ZCLinkUnit 이 채워져 있지 않아도, 건너
// 뛰고 새 ZCLinkUnit 부터 채워 나가기 시작한다.
if(AI_ArrSize<1) return;
TypeSize VI_AddUnitCnt =AI_ArrSize/ZEArrSize;
TypeSize VI_AddExtraCnt=AI_ArrSize%ZEArrSize;
while(--VI_AddUnitCnt>=0)
{
AllocUnitAtTail().AddObjArr
( AP_ObjArr, ZEArrSize ) ;
AP_ObjArr += ZEArrSize ;
}/*
while(--VI_AddUnitCnt>=0)*/
if(VI_AddExtraCnt<1) return;
AllocUnitAtTail().
AddObjArr(AP_ObjArr, VI_AddExtraCnt);
ml_NowObjtCnt += AI_ArrSize ;
}/*
void AddTail(TypeData* AP_ObjArr, TypeSize AI_ArrSize)*/
// 무조건 새로운 ZCLinkUnit 에 AR_Object 를 추가.
void AddTailInNewUnit(TypeArg AR_Object)
{
AllocUnitAtTail().AddObj(AR_Object); ++ml_NowObjtCnt;
}/*
void AddTailInNewUnit(TypeArg AR_Object)*/
template<typename TAllocWork> void AddTailInPool(
TAllocWork& AR_CAllocWork, TypeData* AP_ObjArr, TypeSize AI_ArrSize)
{
/*//////////////////////////////////////////////////////////////////////
■ ZEMaxUnitCnt 개 단위로 등록한다.
CAllocWork_BASE2_T<> 를 참고하면, *this 는 '임시 작업 큐'다.
■ AR_CAllocWork.AddList() 는 작업 AP_ObjArr 을
1) '임시 작업 큐'에 등록하고,
2) 대기 작업 쓰레드가 있으면 하나를 깨우고,
3) 해당 쓰레드의 작업 큐의 '내부 삭제 리스트'를 적당한 크기로
*this 의 '내부 삭제 리스트'에 돌려준다.
-- 2025-10-04 08:31
TAllocWork 은 일종의 thread pool 이고,
*this 는 그 pool 의 '임시 작업 큐'다. -- 2025-10-04 08:36
//////////////////////////////////////////////////////////////////////*/
if(AI_ArrSize<1) return;
TypeSize VI_AddUnitCnt = AI_ArrSize/ZEArrSize;
TypeSize VI_AddExtraCnt= AI_ArrSize%ZEArrSize;
TypeSize VI_MaxUnitCnt = ZEMaxUnitCnt ;
while(--VI_AddUnitCnt>=0)
{
AllocUnitAtTail().
AddObjArr(AP_ObjArr, ZEArrSize);
AP_ObjArr += ZEArrSize ;
ml_NowObjtCnt += ZEArrSize ;
if(--VI_MaxUnitCnt<=0)
{
AR_CAllocWork.AddList(RR(*this)); VI_MaxUnitCnt=ZEMaxUnitCnt;
}/*
if(--VI_MaxUnitCnt<=0)*/
}/*
while(--VI_AddUnitCnt>=0)*/
if(VI_MaxUnitCnt>0)
{
if(VI_AddExtraCnt>0)
{
AllocUnitAtTail().
AddObjArr(AP_ObjArr, VI_AddExtraCnt);
ml_NowObjtCnt += VI_AddExtraCnt ;
AR_CAllocWork.AddList(RR(*this)); return;
}/*
if(VI_AddExtraCnt>0)*/
}/*
if(VI_MaxUnitCnt>0)*/
if(VI_AddExtraCnt<1)
{
AR_CAllocWork.AddList(RR(*this)); return;
}/*
if(VI_AddExtraCnt<1)*/
AllocUnitAtTail().
AddObjArr(AP_ObjArr, VI_AddExtraCnt);
ml_NowObjtCnt += VI_AddExtraCnt ;
AR_CAllocWork.AddList(RR(*this));
}/*
template<typename TAllocWork> void AddTailInPool(
TAllocWork& AR_CAllocWork, TypeData* AP_ObjArr, TypeSize AI_ArrSize) */
template<typename TAllocWork, typename TypeData2> void AddTailInPool2
( TAllocWork& AR_CAllocWork, TypeData2* AP_ObjArr, TypeSize AI_ArrSize )
{
// TypeData = TypeData2 연산자가 지원되어야 한다.
if(AI_ArrSize<1) return;
TypeSize VI_AddUnitCnt = AI_ArrSize/ZEArrSize;
TypeSize VI_AddExtraCnt= AI_ArrSize%ZEArrSize;
TypeSize VI_MaxUnitCnt = ZEMaxUnitCnt ;
while(--VI_AddUnitCnt>=0)
{
__for0(TypeSize, i, ZEArrSize)
push_back() = *(AP_ObjArr++) ;
if(--VI_MaxUnitCnt<=0)
{
AR_CAllocWork.AddList(RR(*this)); VI_MaxUnitCnt=ZEMaxUnitCnt;
}/*
if(--VI_MaxUnitCnt<=0)*/
}/*
while(--VI_AddUnitCnt>=0)*/
if(VI_MaxUnitCnt>0)
{
if(VI_AddExtraCnt>0)
{
__for0(TypeSize, i, VI_AddExtraCnt)
{ push_back() = *(AP_ObjArr++); }
AR_CAllocWork.AddList(RR(*this)); return;
}/*
if(VI_AddExtraCnt>0)*/
}/*
if(VI_MaxUnitCnt>0)*/
if(VI_AddExtraCnt<1)
{
AR_CAllocWork.AddList(RR(*this)); return;
}/*
if(VI_AddExtraCnt<1)*/
__for0(TypeSize, i, VI_AddExtraCnt)
{ push_back() = *(AP_ObjArr++); }
AR_CAllocWork.AddList(RR(*this));
}/*
template<typename TAllocWork, typename TypeData2> void AddTailInPool2
( TAllocWork& AR_CAllocWork, TypeData2* AP_ObjArr, TypeSize AI_ArrSize ) */
void AddUnitInCutList(TypeSize AI_AddUnitCnt)
{
// 초기에 이 함수로 미리 ZCLinkUnit 을 할당해 놓으면 좋다.
if(AI_AddUnitCnt<1) return;
ZCLinkUnit* VP_UnitHead =CreateUnit() ;
ZCLinkUnit* VP_UnitTail =VP_UnitHead ;
TypeSize VI_AddUnitCnt=AI_AddUnitCnt;
while(--VI_AddUnitCnt>0) // AI_AddUnitCnt-1 번 순환.
{
ZCLinkUnit* VP_UnitTail2 = CreateUnit();
ZCLinkUnit::JoinLink(VP_UnitTail, VP_UnitTail2);
VP_UnitTail=VP_UnitTail2;
}/*
while(--VI_AddUnitCnt>0)*/
if(ml_CutUnitCnt<1)
{
ZCLinkUnit::MakeRing(VP_UnitHead, VP_UnitTail);
mp_CutHeadUnit = VP_UnitHead; /////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, VP_UnitHead);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_UnitTail);
}/*
else*/
ml_CutUnitCnt += AI_AddUnitCnt;
}/*
void AddUnitInCutList(TypeSize AI_AddUnitCnt)*/
operator TypeData& (){return AddTail();}
void push_back(TypeArg AR_Object){return AddTail(AR_Object);}
TypeData& push_back() {return AddTail() ;}
void DeleteAll()
{
// '내부 사용 리스트'를 '내부 삭제 리스트'의 끝으로 옮긴다.
if(ml_NowUnitCnt<1) return;
if(ml_CutUnitCnt>0)
{
ZCLinkUnit* VP_TailLink=mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, mp_NowHeadUnit);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_TailLink );
}
else
mp_CutHeadUnit=mp_NowHeadUnit;
//else
mp_NowHeadUnit =0 ;
ml_CutUnitCnt +=ml_NowUnitCnt ;
ml_NowUnitCnt =0 ;
ml_NowObjtCnt =0 ;
}/*
void DeleteAll()*/
void DeleteHead()
{
// '내부 사용 리스트'의 앞 링크 하나를 '내부 삭제 리스트'로 옮긴다.
if(ml_NowUnitCnt<1) return;
if(--ml_NowUnitCnt<1)
{
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, mp_NowHeadUnit);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , mp_NowHeadUnit);
mp_NowHeadUnit=0;
ml_NowObjtCnt =0;
}
else
{
ZCLinkUnit* VP_HeadLink = mp_NowHeadUnit ;
ZCLinkUnit* VP_TailLink = mp_NowHeadUnit->mp_PrevUnit;
mp_NowHeadUnit = mp_NowHeadUnit->mp_NextUnit;
ml_NowObjtCnt -= VP_HeadLink->size() ;
ZCLinkUnit::MakeRing(mp_NowHeadUnit , VP_TailLink);
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, VP_HeadLink);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_HeadLink);
}/*
else*/
++ml_CutUnitCnt;
}/*
void DeleteHead()*/
void DeleteAllCutList()
{
// '내부 삭제 리스트'를 지운다.
ZCLinkUnit* VP_CutHead=mp_CutHeadUnit;
for(; ml_CutUnitCnt>0; --ml_CutUnitCnt)
{
mp_CutHeadUnit=mp_CutHeadUnit->mp_NextUnit;
DeleteUnit(VP_CutHead); VP_CutHead=mp_CutHeadUnit;
}/*
for(; ml_CutUnitCnt>0; --ml_CutUnitCnt)*/
mp_CutHeadUnit=0;
}/*
void DeleteAllCutList()*/
void Clear (){DeleteAll();}
void clear (){DeleteAll();}
void ClearEx(){DeleteAll(); DeleteAllCutList();}
void JoinTail (ZtCObjUnitList& rhs){JoinAtTail(rhs);} // for compatiblity with ZNsMain::ZtCObjList<>
void JoinHead (ZtCObjUnitList& rhs){JoinAtHead(rhs);} // for compatiblity with ZNsMain::ZtCObjList<>
void JoinHeadEx(ZtCObjUnitList& rhs){JoinAtHead(rhs); JoinCutListAtTail(rhs);}
void JoinTailEx(ZtCObjUnitList& rhs){JoinAtTail(rhs); JoinCutListAtTail(rhs);}
void JoinAtTail(ZtCObjUnitList& rhs)
{
if(this==&rhs) return;
if(rhs.ml_NowUnitCnt<1) return;
if(ml_NowUnitCnt<1)
{
mp_NowHeadUnit=rhs.mp_NowHeadUnit;
}
else
{
ZCLinkUnit* VP_RhsTailUnit=rhs.mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit* VP_LhsTailUnit= mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink( VP_LhsTailUnit, rhs.mp_NowHeadUnit );
ZCLinkUnit::MakeRing( mp_NowHeadUnit, VP_RhsTailUnit );
}/*
else*/
ml_NowUnitCnt+=rhs.ml_NowUnitCnt; rhs.ml_NowUnitCnt =0;
ml_NowObjtCnt+=rhs.ml_NowObjtCnt; rhs.ml_NowObjtCnt =0;
rhs.mp_NowHeadUnit=0;
}/*
void JoinAtTail(ZtCObjUnitList& rhs)*/
void JoinAtHead(ZtCObjUnitList& rhs)
{
if(this==&rhs) return;
if(rhs.ml_NowUnitCnt<1) return;
if(ml_NowUnitCnt>=1)
{
ZCLinkUnit* VP_RhsTailUnit=rhs.mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit* VP_LhsTailUnit= mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink(VP_RhsTailUnit , mp_NowHeadUnit);
ZCLinkUnit::MakeRing(rhs.mp_NowHeadUnit, VP_LhsTailUnit);
}/*
if(ml_NowUnitCnt>=1)*/
ml_NowUnitCnt += rhs.ml_NowUnitCnt ; rhs.ml_NowUnitCnt =0;
ml_NowObjtCnt += rhs.ml_NowObjtCnt ; rhs.ml_NowObjtCnt =0;
mp_NowHeadUnit = rhs.mp_NowHeadUnit; rhs.mp_NowHeadUnit=0;
}/*
void JoinAtHead(ZtCObjUnitList& rhs)*/
void JoinRhsTailAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)
{
// rhs 의 '내부 사용 리스트'의 마지막 AI_FetchSize 개의 링크를
// 자신의 '내부 사용 리스트'로 가져온다.
if(AI_FetchSize<1) return ;
if(rhs.ml_NowUnitCnt<=AI_FetchSize)
{
JoinAtTail(RR(rhs)); return;
}/*
if(rhs.ml_CutUnitCnt<=AI_FetchSize)*/
// rhs.ml_NowUnitCnt>AI_FetchSize 이고 rhs.ml_NowUnitCnt>0
TypeSize VI_RhsObjCnt = 0 ;
ZCLinkUnit* VP_RhsNowTail = rhs.mp_NowHeadUnit->mp_PrevUnit ;
ZCLinkUnit* VP_RhsNowHead = VP_RhsNowTail->
GetUnitPtr( -(AI_FetchSize-1), RR(VI_RhsObjCnt) ) ;
ZCLinkUnit::MakeRing(
rhs.mp_NowHeadUnit, VP_RhsNowHead->mp_PrevUnit);
rhs.ml_NowUnitCnt -= AI_FetchSize;
rhs.ml_NowObjtCnt -= VI_RhsObjCnt;
if(ml_NowUnitCnt<1)
{
ZCLinkUnit::MakeRing
(VP_RhsNowHead, VP_RhsNowTail);
mp_NowHeadUnit=VP_RhsNowHead;
}
else
{
ZCLinkUnit::JoinLink(mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeRing(mp_NowHeadUnit , VP_RhsNowTail);
}
ml_NowUnitCnt += AI_FetchSize;
ml_NowObjtCnt += VI_RhsObjCnt;
}/*
void JoinRhsTailAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)*/
void JoinRhsHeadAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)
{
// rhs 의 '내부 사용 리스트'의 처음 AI_FetchSize 개의 링크를
// 자신의 '내부 사용 리스트'로 가져온다.
if(AI_FetchSize<1) return ;
if(rhs.ml_NowUnitCnt<=AI_FetchSize)
{
JoinAtTail(RR(rhs)); return;
}/*
if(rhs.ml_CutUnitCnt<=AI_FetchSize)*/
// rhs.ml_NowUnitCnt>AI_FetchSize 이고 rhs.ml_NowUnitCnt>0
TypeSize VI_RhsObjCnt = 0 ;
ZCLinkUnit* VP_RhsNowHead= rhs.mp_NowHeadUnit ;
ZCLinkUnit* VP_RhsNowTail= VP_RhsNowHead->
GetUnitPtr( AI_FetchSize-1, RR(VI_RhsObjCnt) ) ;
rhs.mp_NowHeadUnit = VP_RhsNowTail->mp_NextUnit ;
ZCLinkUnit::MakeRing(
rhs.mp_NowHeadUnit, VP_RhsNowHead->mp_PrevUnit);
rhs.ml_NowUnitCnt -= AI_FetchSize;
rhs.ml_NowObjtCnt -= VI_RhsObjCnt;
if(ml_NowUnitCnt<1)
{
ZCLinkUnit::MakeRing(VP_RhsNowHead, VP_RhsNowTail);
mp_NowHeadUnit = VP_RhsNowHead; ///////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeRing(mp_NowHeadUnit , VP_RhsNowTail);
}
ml_NowUnitCnt += AI_FetchSize;
ml_NowObjtCnt += VI_RhsObjCnt;
}/*
void JoinRhsHeadAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)*/
void JoinRhsTailOneAtTail(ZtCObjUnitList& rhs)
{
// rhs 의 '내부 사용 리스트'의 마지막 1 개의 링크를
// 자신의 '내부 사용 리스트'로 가져온다.
if(rhs.ml_NowUnitCnt<1) return;
ZCLinkUnit* VP_RhsNowTail=rhs.mp_NowHeadUnit->mp_PrevUnit;
if(--rhs.ml_NowUnitCnt<1)
{
rhs.mp_NowHeadUnit=0;
}
else
{
ZCLinkUnit::MakeRing(
rhs.mp_NowHeadUnit, VP_RhsNowTail->mp_PrevUnit);
}
rhs.ml_NowObjtCnt -= VP_RhsNowTail->ml_UseSize ;
if(++ml_NowUnitCnt<=1)
{
ZCLinkUnit::MakeRing(VP_RhsNowTail, VP_RhsNowTail);
mp_NowHeadUnit=VP_RhsNowTail; /////////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowTail);
ZCLinkUnit::MakeRing(mp_NowHeadUnit , VP_RhsNowTail);
}
ml_NowObjtCnt += VP_RhsNowTail->ml_UseSize ;
}/*
void JoinRhsTailOneAtTail(ZtCObjUnitList& rhs)*/
void JoinRhsHeadOneAtTail(ZtCObjUnitList& rhs)
{
// rhs 의 '내부 사용 리스트'의 처음 1 개의 링크를
// 자신의 '내부 사용 리스트'로 가져온다.
if(rhs.ml_NowUnitCnt<1) return;
ZCLinkUnit* VP_RhsNowHead = rhs.mp_NowHeadUnit;
rhs. mp_NowHeadUnit= rhs.mp_NowHeadUnit->mp_NextUnit;
if(--rhs.ml_NowUnitCnt<1)
{
rhs.mp_NowHeadUnit=0;
}
else
{
ZCLinkUnit::MakeRing(
rhs.mp_NowHeadUnit, VP_RhsNowHead->mp_PrevUnit);
}
rhs.ml_NowObjtCnt -= VP_RhsNowHead->ml_UseSize ;
if(++ml_NowUnitCnt<=1)
{
ZCLinkUnit::MakeRing(VP_RhsNowHead, VP_RhsNowHead);
mp_NowHeadUnit=VP_RhsNowHead; /////////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeRing(mp_NowHeadUnit , VP_RhsNowHead);
}
ml_NowObjtCnt += VP_RhsNowHead->ml_UseSize ;
}/*
void JoinRhsHeadOneAtTail(ZtCObjUnitList& rhs)*/
void JoinCutListAtTail(ZtCObjUnitList& rhs)
{
if(rhs.ml_CutUnitCnt<1) return;
if(ml_CutUnitCnt<1)
{
mp_CutHeadUnit=rhs.mp_CutHeadUnit;
}
else
{
ZCLinkUnit* VP_RhsTailUnit = rhs.mp_CutHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, rhs.mp_CutHeadUnit);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_RhsTailUnit);
}/*
else*/
ml_CutUnitCnt += rhs.ml_CutUnitCnt;
rhs.ml_CutUnitCnt = 0 ;
rhs.mp_CutHeadUnit = 0 ;
}/*
void JoinCutListAtTail(ZtCObjUnitList& rhs)*/
void JoinRhsCutListTailAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)
{
// rhs 의 '내부 삭제 리스트'의 마지막 AI_FetchSize 개의 링크를
// 자신의 '내부 삭제 리스트'로 가져온다.
if(AI_FetchSize<1) return ;
if(rhs.ml_CutUnitCnt<=AI_FetchSize)
{
JoinCutListAtTail(RR(rhs)); return;
}/*
if(rhs.ml_CutUnitCnt<=AI_FetchSize)*/
// rhs.ml_CutUnitCnt>AI_FetchSize 이고 rhs.ml_CutUnitCnt>0
ZCLinkUnit* VP_RhsCutTail = rhs.mp_CutHeadUnit->mp_PrevUnit;
ZCLinkUnit* VP_RhsCutHead =
VP_RhsCutTail->GetUnitPtr( -(AI_FetchSize-1) );
ZCLinkUnit::MakeRing(
rhs.mp_CutHeadUnit, VP_RhsCutHead->mp_PrevUnit);
rhs.ml_CutUnitCnt -= AI_FetchSize;
if(ml_CutUnitCnt<1)
{
ZCLinkUnit::MakeRing(VP_RhsCutHead, VP_RhsCutTail);
mp_CutHeadUnit = VP_RhsCutHead; ///////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, VP_RhsCutHead);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_RhsCutTail);
}
ml_CutUnitCnt += AI_FetchSize;
}/*
void JoinRhsCutListTailAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)*/
void JoinRhsCutListHeadAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)
{
// rhs 의 '내부 삭제 리스트'의 처음 AI_FetchSize 개의 링크를
// 자신의 '내부 삭제 리스트'로 가져온다.
if(AI_FetchSize<1) return ;
if(rhs.ml_CutUnitCnt<=AI_FetchSize)
{
JoinCutListAtTail(RR(rhs)); return;
}/*
if(rhs.ml_CutUnitCnt<=AI_FetchSize)*/
// rhs.ml_CutUnitCnt>AI_FetchSize 이고 rhs.ml_CutUnitCnt>0
ZCLinkUnit* VP_RhsCutHead = rhs.mp_CutHeadUnit ;
ZCLinkUnit* VP_RhsCutTail =
VP_RhsCutHead->GetUnitPtr(AI_FetchSize-1) ;
rhs.mp_CutHeadUnit = VP_RhsCutTail->mp_NextUnit;
ZCLinkUnit::MakeRing(
rhs.mp_CutHeadUnit, VP_RhsCutHead->mp_PrevUnit);
rhs.ml_CutUnitCnt -= AI_FetchSize;
if(ml_CutUnitCnt<1)
{
ZCLinkUnit::MakeRing(VP_RhsCutHead, VP_RhsCutTail);
mp_CutHeadUnit=VP_RhsCutHead; /////////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, VP_RhsCutHead);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_RhsCutTail);
}
ml_CutUnitCnt += AI_FetchSize;
}/*
void JoinRhsCutListHeadAtTail(ZtCObjUnitList& rhs, TypeSize AI_FetchSize)*/
void JoinRhsCutTailOneAtTail(ZtCObjUnitList& rhs)
{
// rhs 의 '내부 삭제 리스트'의 마지막 1 개의 링크를
// 자신의 '내부 삭제 리스트'로 가져온다.
if(rhs.ml_CutUnitCnt<1) return;
ZCLinkUnit* VP_RhsNowTail=rhs.mp_CutHeadUnit->mp_PrevUnit;
if(--rhs.ml_CutUnitCnt<1)
rhs.mp_CutHeadUnit=0;
else
{
ZCLinkUnit::MakeRing(
rhs.mp_CutHeadUnit, VP_RhsNowTail->mp_PrevUnit);
}/*
else*/
if(++ml_CutUnitCnt<=1)
{
ZCLinkUnit::MakeRing(VP_RhsNowTail, VP_RhsNowTail);
mp_CutHeadUnit=VP_RhsNowTail; /////////////////////
}
else
{
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, VP_RhsNowTail);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_RhsNowTail);
}/*
else*/
}/*
void JoinRhsCutTailOneAtTail(ZtCObjUnitList& rhs)*/
void JoinRhsCutHeadOneAtTail(ZtCObjUnitList& rhs)
{
// rhs 의 '내부 삭제 리스트'의 처음 1 개의 링크를
// 자신의 '내부 삭제 리스트'로 가져온다.
if(rhs.ml_CutUnitCnt<1) return;
ZCLinkUnit* VP_RhsNowHead=rhs.mp_CutHeadUnit;
rhs.mp_CutHeadUnit=rhs.mp_CutHeadUnit->mp_NextUnit;
if(--rhs.ml_CutUnitCnt<1) {rhs.mp_CutHeadUnit=0;} else
{
ZCLinkUnit::MakeRing(
rhs.mp_CutHeadUnit, VP_RhsNowHead->mp_PrevUnit);
}/*
////////////////////////////////////////////////////*/
if(++ml_CutUnitCnt<=1)
{
ZCLinkUnit::
MakeRing(VP_RhsNowHead, VP_RhsNowHead);
mp_CutHeadUnit = VP_RhsNowHead;
}
else
{
ZCLinkUnit::JoinLink(mp_CutHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeRing(mp_CutHeadUnit , VP_RhsNowHead);
}/*
else*/
}/*
void JoinRhsCutHeadOneAtTail(ZtCObjUnitList& rhs)*/
TypeData& GetDataInIter(TypeData* AP_Object )
{ return *AP_Object ; }
TypeArr & GetDataInIter(ZCLinkUnit* AP_CLinkUnit)
{ return AP_CLinkUnit->mo_TypeArr; }
void MoveNextIter(TypeData*& APR_Object){++APR_Object;}
void MovePrevIter(TypeData*& APR_Object){--APR_Object;}
void MoveNextIter(ZCLinkUnit*& APR_CLinkUnit)
{ APR_CLinkUnit=APR_CLinkUnit->mp_NextUnit; }
void MovePrevIter(ZCLinkUnit*& APR_CLinkUnit)
{ APR_CLinkUnit=APR_CLinkUnit->mp_PrevUnit; }
void ItNext(TypeData*& APR_Object){++APR_Object;}
void ItPrev(TypeData*& APR_Object){--APR_Object;}
void ItNext(ZCLinkUnit*& APR_CLinkUnit)
{ APR_CLinkUnit=APR_CLinkUnit->mp_NextUnit; }
void ItPrev(ZCLinkUnit*& APR_CLinkUnit)
{ APR_CLinkUnit=APR_CLinkUnit->mp_PrevUnit; }
TypeData& ItD(TypeData* AP_Object )
{ return *AP_Object ; }
TypeArr & ItD(ZCLinkUnit* AP_CLinkUnit)
{ return **AP_CLinkUnit; }
public :
};/*
template< typename TType , ///////////////////////////////////////////
typename TTypeObjUnitList =
ZNsType::ZtCTypeObjUnitList<TType>
>
class ZtCObjUnitList /////////////////////////////////////////////////*/
}/*
namespace ZNsMain*/
#endif //__ZCPPMAIN__ZTCOBJLIST_H__