Files
RepoMain/ZCppMain/ZtCObjList.H

3496 lines
122 KiB
C++

#ifndef __ZCPPMAIIN__ZTCOBJLIST_H__
#define __ZCPPMAIIN__ZTCOBJLIST_H__
#include "ZCppMain/ZMainHead.H"
namespace ZNsMain
{
/*/////////////////////////////////////////////////////////////////
■ typename TTypCInit 는 별다른 역할을 하지 않고 있다. 다른 리스트
클래스와 템플릿 인수를 비슷하게 맞추기 위해, 그리고 차후의 설계
를 위해 일단 이대로 두자.
■ typename ZCInit 가 필요한지 모르겠다. 일단 주석으로 막는다.
-- 2025-08-11 14:47
ZtCTreeData.H 에서 ZtCObjList<> 에서 TTypCInit 자리에 형을 지정
하고 있다. 쓰긴 쓰니까 주석을 해제하자. -- 2025-08-14 13:43
/////////////////////////////////////////////////////////////////*/
template<typename TypeObjList> class ZtCSortObjList;
template< typename TType ,
typename TTypCArg =const TType&,
typename TTypCAlloc=ZCAllocator ,
typename TTypCInit =ZCInit ,
typename TTypSize =ZTypLong
>
class ZtCObjList ////////////////////////////
{
public:
template<typename TypeObjList> friend class ZtCSortObjList;
public:
typedef TType Type ;
typedef TType TypeData ;
typedef TTypCArg TypeArg ;
typedef TTypCAlloc TypeAlloc;
//typedef TTypCInit TypeInit ;
typedef TTypSize TypeSize ;
public:
class ZCIterator;
class ZCLink ;
public:
typedef ZCLink* IterEasy; // 가장 대표적으로 쓰일 수 있는 반복자.
typedef ZCIterator iterator;
typedef const ZCIterator const_iterator;
public:
class ZCLink : public TypeAlloc
{
public :
template<typename TypeObjList> friend class ZtCSortObjList;
/*##########################*/ friend class ZtCObjList ;
private:
TypeData mo_Type ;
ZCLink* mp_NextLink;
ZCLink* mp_PrevLink;
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 MakeCircle(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)
{
AP_HeadLink->mp_PrevLink=AP_TailLink;
AP_TailLink->mp_NextLink=AP_HeadLink;
}/*
static void MakeCircle(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)*/
/*private:*/
public :
ZCLink()
{
mp_NextLink=0;
mp_PrevLink=0;
}/*
ZCLink()*/
ZCLink(TypeArg AR_Type):mo_Type(AR_Type)
{
mp_NextLink=0;
mp_PrevLink=0;
}/*
ZCLink(TypeArg AR_Type)*/
ZCLink(const ZCLink& rhs):mo_Type(rhs.mo_Type)
{
mp_NextLink=0;
mp_PrevLink=0;
}/*
ZCLink(const ZCLink& rhs)*/
operator Type& (){return mo_Type;}
operator Type (){return mo_Type;}
Type& GetData (){return mo_Type;}
Type& operator*(){return mo_Type;}
operator const Type& () const{return mo_Type;}
const Type& GetData () const{return mo_Type;}
const Type& operator*() const{return mo_Type;}
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)*/
const ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) const // or ZCLink const * const GetNextPrevPtr(TypeSize AL_FarNum) const
{
ZCLink* VP_TmpLink=const_cast<ZCLink*>(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;
}/*
const ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) const*/
ZCLink* GetNextPtr(){return mp_NextLink;}
ZCLink* GetPrevPtr(){return mp_PrevLink;}
const ZCLink* GetNextPtr() const{return mp_NextLink;}
const ZCLink* 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_PrevtLink;
return VP_TmpLink;
}/*
ZCLink* GetPrevPtr(TypeSize AL_Distance)*/
const ZCLink* GetNextPtr(TypeSize AL_Distance) const
{
TypeSize VL_LoopIndex=0 ;
ZCLink* VP_TmpLink =const_cast<ZCLink*>(this);
while(VL_LoopIndex++<AL_Distance)
VP_TmpLink=VP_TmpLink->mp_NextLink;
return VP_TmpLink;
}/*
const ZCLink* GetNextPtr(TypeSize AL_Distance) const*/
const ZCLink* GetPrevPtr(TypeSize AL_Distance) const
{
TypeSize VL_LoopIndex=0 ;
ZCLink* VP_TmpLink = const_cast<ZCLink*>(this) ;
while(VL_LoopIndex++<AL_Distance)
VP_TmpLink=VP_TmpLink->mp_PrevtLink;
return VP_TmpLink;
}/*
const ZCLink* GetPrevPtr(TypeSize AL_Distance) const*/
public:
};/*
class ZCLink*/
/*public :*/
protected:
ZCLink* mp_HeadLink;
TypeSize ml_Size ;
protected:
virtual void OnDelete(
ZCLink* AP_CutHead, TypeSize AI_CutHeadPos,
ZCLink* AP_CutTail, TypeSize AI_CutTailPos
/*//////////*/ )
{
// 상속클래스에서 추가된 멤버 데이타가 링크의 삭제시 변해야 하는 값이라면
// 이 함수를 overload 하여 값을 조종한다.
}/*
virtual void OnDelete(
ZCLink* AP_CutHead, TypeSize AI_CutHeadPos,
ZCLink* AP_CutTail, TypeSize AI_CutTailPos
////////////// ) */
virtual void OnInsert(
TypeSize AI_InsertPos , // 삽입되는 위치
TypeSize AI_InsertSize, // 삽입되는 링크의 갯수
ZCLink* AP_HeadInsert // 삽입되는 첫번째 링크의 포인터
/*//////////*/ )
{
// 상속클래스에서 추가된 멤버 데이타가 링크의 삽입시 변해야 하는 값이라면
// 이 함수를 overload 하여 값을 조종한다.
}/*
virtual void OnInsert(
TypeSize AI_InsertPos ,
TypeSize AI_InsertSize,
ZCLink* AP_HeadInsert
////////////// ) */
void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypeSize AL_PosStd)
{
// AP_LinkInsert 를 AL_PosStd 번째 링크인 AP_LinkStd 뒤에 삽입한다.
// AL_PosStd==0 이면 맨 앞에 삽입한다.
if(AP_LinkStd==0)
{
OnInsert(1,1,AP_LinkInsert);
if(++ml_Size==1)
{
mp_HeadLink =AP_LinkInsert ;
mp_HeadLink->mp_NextLink=mp_HeadLink ;
mp_HeadLink->mp_PrevLink=mp_HeadLink ;
}
else
{
AP_LinkInsert->mp_NextLink =mp_HeadLink ;
mp_HeadLink->mp_PrevLink->mp_NextLink=AP_LinkInsert ;
AP_LinkInsert->mp_PrevLink =mp_HeadLink->mp_PrevLink ;
mp_HeadLink->mp_PrevLink =AP_LinkInsert ;
mp_HeadLink=AP_LinkInsert;
}/*
else*/
}
else
{
OnInsert(AL_PosStd+1, 1, AP_LinkInsert); ++ml_Size;
AP_LinkInsert->mp_NextLink = AP_LinkStd->mp_NextLink ;
AP_LinkStd ->mp_NextLink = AP_LinkInsert ;
AP_LinkInsert->mp_PrevLink =AP_LinkStd ;
AP_LinkInsert->mp_NextLink->mp_PrevLink=AP_LinkInsert;
}/*
else*/
}/*
void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypeSize AL_PosStd)*/
public : void JoinAfter(ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd)
{
#ifdef _DEBUG
if(AP_LinkStd!=0 && Find(AP_LinkStd)!=AL_PosStd)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : " <<__LINE__<<std::endl;
fileout<<"Error In 'ZtCObjList& JoinAfter( ZtCObjList& rhs," <<std::endl;
fileout<<" ZCLink* AP_LinkStd," <<std::endl;
fileout<<" TypeSize AL_PosStd" <<std::endl;
fileout<<" ): Parameter is bad index"<<std::endl;
fileout.close();
::exit(1); return;
}/*
if(AP_LinkStd!=0 && Find(AP_LinkStd)!=AL_PosStd)*/
#endif //_DEBUG
if(AO_CObjList.ml_Size<1) return;
if(AP_LinkStd==0)
{
if(ml_Size==0)
{
mp_HeadLink=AO_CObjList.mp_HeadLink ;
ml_Size =AO_CObjList.ml_Size ;
}
else
{
ZCLink* VP_TailLink=AO_CObjList.mp_HeadLink->mp_PrevLink;
ZCLink::MakeCircle(AO_CObjList.mp_HeadLink, mp_HeadLink->mp_PrevLink);
ZCLink::JoinLink (VP_TailLink,mp_HeadLink );
mp_HeadLink = AO_CObjList.mp_HeadLink;
ml_Size += AO_CObjList.ml_Size ;
}/*
else*/
}
else // AP_LinkStd!=0
{
ZCLink* VP_TailLink=AO_CObjList.mp_HeadLink->mp_PrevLink;
ZCLink::JoinLink(VP_TailLink, AP_LinkStd->mp_NextLink);
ZCLink::JoinLink(AP_LinkStd , AO_CObjList.mp_HeadLink);
ml_Size += AO_CObjList.ml_Size ;
}/*
else // AP_LinkStd!=0*/
AO_CObjList.mp_HeadLink=0;
AO_CObjList.ml_Size =0;
}/*
void JoinAfter(ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd)*/
protected: ZCLink* CutLink(ZCLink* AP_CutLink)
{
// 삭제하려는 링크의 위치값을 알 수 없으므로 모든 링크를 삭제한다는 신호를 보낸다.
OnDelete(mp_HeadLink, 1, mp_HeadLink->mp_PrevLink, ml_Size);
if(AP_CutLink==mp_HeadLink)
{
if(mp_HeadLink==mp_HeadLink->mp_PrevLink)
mp_HeadLink=0;
else
{
ZCLink::MakeCircle( mp_HeadLink=mp_HeadLink->mp_NextLink,
AP_CutLink->mp_PrevLink
/*/////////////*/ );
}/*
else*/
}
else if(AP_CutLink==mp_HeadLink->mp_PrevLink)
ZCLink::MakeCircle(mp_HeadLink , AP_CutLink->mp_PrevLink);
else ZCLink::JoinLink (AP_CutLink->mp_PrevLink, AP_CutLink->mp_NextLink);
return (--ml_Size, AP_CutLink);
}/*
protected: ZCLink* CutLink(ZCLink* AP_CutLink)*/
ZCLink* CutLink(ZCLink* AP_CutLink, TypeSize AL_CutPos)
{
OnDelete(AP_CutLink, AL_CutPos, AP_CutLink, AL_CutPos);
if(AL_CutPos==1) // 첫째 링크를 삭제.
{
if(ml_Size==1)
mp_HeadLink=0;
else
{
ZCLink::MakeCircle
(
mp_HeadLink=mp_HeadLink->mp_NextLink,
AP_CutLink->mp_PrevLink
);
//////////////////
}/*
else*/
}
else if(AL_CutPos==ml_Size) // 끝 링크를 삭제할 때
ZCLink::MakeCircle(mp_HeadLink , AP_CutLink->mp_PrevLink);
else ZCLink::JoinLink (AP_CutLink->mp_PrevLink, AP_CutLink->mp_NextLink);
return (--ml_Size, AP_CutLink);
}/*
ZCLink* CutLink(ZCLink* AP_CutLink, TypeSize AL_CutPos)*/
ZtCObjList& CutLink /*########################################################*/
(
ZCLink* AP_CutHead, TypeSize AL_CutHeadPos,
ZCLink* AP_CutTail, TypeSize AL_CutTailPos,
ZtCObjList& ARR_StoreList
)
/*#############################################################################*/
{
// AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크, AL_CutHeadPos 는 그 위치
// AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크, AL_CutTailPos 는 그 위치
// 따라서 AL_CutHeadPos <= AL_CutTailPos
#ifdef _DEBUG
if(AL_CutHeadPos>AL_CutTailPos)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"ZtCObjList& CutLink( ZCLink* AP_CutHead, TypeSize AL_CutHeadPos,"<<std::endl;
fileout<<" ZCLink* AP_CutTail, TypeSize AL_CutTailPos, ZtCObjList& ARR_StoreList"<<std::endl;
fileout<<"/****************/ ) : AL_CutHeadPos>AL_CutTailPos"<<std::endl;
fileout.close();
::exit(1); return ARR_StoreList;
}/*
if(AL_CutHeadPos>AL_CutTailPos)*/
#endif // _DEBUG
OnDelete(AP_CutHead, AL_CutHeadPos, AP_CutTail, AL_CutTailPos);
if(AL_CutHeadPos==1 && AL_CutTailPos==ml_Size) // 모든 링크를 삭제할 때.
{
mp_HeadLink=0;
}
else if(AL_CutHeadPos==1) // 잘라내려는 링크가 처음 링크를 포함할 때.
{
ZCLink::MakeCircle(mp_HeadLink=AP_CutTail->mp_NextLink, AP_CutHead->mp_PrevLink);
}
else if(AL_CutTailPos==ml_Size) // 잘라내려는 링크가 끝 링크를 포함할 때.
{
ZCLink::MakeCircle(mp_HeadLink, AP_CutHead->mp_PrevLink);
}
else // 잘라내려는 링크가 처음과 끝 링크를 포함하지 않을 때.
{
ZCLink::JoinLink(AP_CutHead ->mp_PrevLink, AP_CutTail->mp_NextLink);
}/*
else*/
ml_Size -= AL_CutTailPos-AL_CutHeadPos+1 ;
// AP_CutHead 과 AP_CutTail 을 연결하여
// 이중 원형 연결리스트가 되도록 한다.
ZCLink::MakeCircle(AP_CutHead, AP_CutTail);
#ifdef _DEBUG
if(ARR_StoreList.IsEmpty()!=true)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZtCObjList& CutLink( ZCLink* AP_CutHead, TypeSize AL_CutHeadPos," <<std::endl;
fileout<<" ZCLink* AP_CutTail, TypeSize AL_CutTailPos, ZtCObjList& ARR_StoreList" <<std::endl;
fileout<<" /****************/ )" <<std::endl;
fileout<<"Object ARR_StoreList is not EMPTY !"<<std::endl;
fileout.close();
::exit(1); return ARR_StoreList;
}/*
if(ARR_StoreList.IsEmpty()!=true)*/
#endif //_DEBUG
ARR_StoreList.mp_HeadLink=AP_CutHead ;
ARR_StoreList.ml_Size =AL_CutTailPos-AL_CutHeadPos+1;
return ARR_StoreList;
}/*
ZtCObjList& CutLink ############################################################
(
ZCLink* AP_CutHead, TypeSize AL_CutHeadPos,
ZCLink* AP_CutTail, TypeSize AL_CutTailPos,
ZtCObjList& ARR_StoreList
)
###############################################################################*/
ZtCObjList& CopyLink /*########################################################*/
(
const ZCLink* AP_CopyLink ,
TypeSize AL_FarNum ,
ZtCObjList& ARR_StoreList
) const
/*#############################################################################*/
{
// AP_CopyLink 부터 AP_CopyLink->GetNextPrevPtr(AL_FarNum) 링크까지를 복사한다.
// AL_FarNum 은 0 이거나 음수일 수 있다.
// 총 (FarNum의 절대값) + 1 개의 링크가 만들어 진다.
#ifdef _DEBUG
if(ARR_StoreList.IsEmpty()!=true)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : " <<__LINE__<<std::endl;
fileout<<"Error In 'ZtCObjList& CopyLink( const ZCLink* AP_CopyLink,"<<std::endl;
fileout<<" TypeSize AL_FarNum, ZtCObjList& ARR_StoreList" <<std::endl;
fileout<<" /*///////////////*/ )" <<std::endl;
fileout<<"Static Object ARR_StoreList is not EMPTY !" <<std::endl;
fileout.close();
::exit(1); return ARR_StoreList;
}/*
if(ARR_StoreList.IsEmpty()!=true)*/
#endif //_DEBUG
ZCLink* VP_HeadLink=0;
ZCLink* VP_TailLink=0;
GetManyLinkCopy /////////////////////////////
(
const_cast<ZCLink*>(AP_CopyLink),
AL_FarNum ,
VP_HeadLink ,
VP_TailLink
);
/////////////////////////////////////////////
ZCLink::MakeCircle(VP_HeadLink, VP_TailLink);
ARR_StoreList.mp_HeadLink=VP_HeadLink;
ARR_StoreList.ml_Size =(AL_FarNum<0 ? -AL_FarNum : AL_FarNum)+1 ;
return ARR_StoreList;
}/*
ZtCObjList& CopyLink ###########################################################
(
const ZCLink* AP_CopyLink ,
TypeSize AL_FarNum ,
ZtCObjList& ARR_StoreList
) const
###############################################################################*/
ZtCObjList& CopyThis(ZtCObjList& ARR_StoreList) const
{
return CopyLink(mp_HeadLink, ml_Size-1, RR(ARR_StoreList));
}/*
ZtCObjList& CopyThis(ZtCObjList& ARR_StoreList) const*/
ZtCObjList& MakeDefault(TypeSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const
{
// must AL_DefaultSize > 0
ZCLink* VP_HeadLink=0;
ZCLink* VP_TailLink=0;
GetManyLink(AL_DefaultSize, VP_HeadLink, VP_TailLink);
ZCLink::MakeCircle(VP_HeadLink, VP_TailLink);
ARR_StoreList.mp_HeadLink=VP_HeadLink ;
ARR_StoreList.ml_Size =AL_DefaultSize;
return ARR_StoreList;
}/*
ZtCObjList& MakeDefault(TypeSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const*/
void GetManyLink(
TypeSize AL_LinkSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink) const
{
#ifdef _DEBUG
ZNsMain::ZCCheckAlloc::ZCAllowAlloc VO_CAllowAllocObj;
#endif //_DEBUG
APR_HeadLink=new ZCLink; ZCLink* VP_TempLink=APR_HeadLink;
for(TypeSize i=2; i<=AL_LinkSize; ++i)
{
ZCLink::JoinLink(VP_TempLink, new ZCLink);
VP_TempLink=VP_TempLink->mp_NextLink;
}/*
for(TypeSize i=2; i<=AL_LinkSize; ++i)*/
APR_TailLink=VP_TempLink;
}/*
void GetManyLink(
TypeSize AL_LinkSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink) const */
void GetManyLinkCopy /*#######################################################*/
(
ZCLink* AP_CopyLink , TypeSize AL_FarNum ,
ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink
) const
/*#############################################################################*/
{
// AL_FarNum 의 절대값 + 1 개의 링크가 생성된다.
#ifdef _DEBUG
ZNsMain::ZCCheckAlloc::ZCAllowAlloc VO_CAllowAllocObj;
#endif //_DEBUG
if(AL_FarNum>0)
{
APR_HeadLink=
new ZCLink(AP_CopyLink->GetData());
ZCLink* VP_TempLink=APR_HeadLink;
for(TypeSize i=1; i<=AL_FarNum; ++i)
{
AP_CopyLink=AP_CopyLink->mp_NextLink;
ZCLink::JoinLink(
VP_TempLink, new ZCLink(AP_CopyLink->GetData()));
VP_TempLink=VP_TempLink->mp_NextLink;
}/*
for(TypeSize i=1; i<=AL_FarNum; ++i)*/
APR_TailLink=VP_TempLink;
}
else //AL_FarNum<=0
{
APR_TailLink=
new ZCLink( AP_CopyLink->GetData() );
ZCLink* VP_TempLink=APR_TailLink;
for(TypeSize i=AL_FarNum; i<0; ++i)
{
AP_CopyLink=AP_CopyLink->mp_PrevLink;
ZCLink::JoinLink(
VP_TempLink, new ZCLink(AP_CopyLink->GetData()));
VP_TempLink=VP_TempLink->mp_PrevLink;
}/*
for(TypeSize i=AL_FarNum; i<0; ++i)*/
APR_HeadLink=VP_TempLink;
}/*
else //AL_FarNum<=0*/
}/*
void GetManyLinkCopy ###########################################################
(
ZCLink* AP_CopyLink , TypeSize AL_FarNum ,
ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink
) const
###############################################################################*/
/*protected:*/
public :
ZtCObjList()
{
mp_HeadLink=0;
ml_Size =0;
}/*
ZtCObjList()*/
ZtCObjList(const ZtCObjList& rhs):mp_HeadLink(0),ml_Size(0)
{
*this=rhs;
}/*
ZtCObjList(const ZtCObjList& rhs)*/
virtual ~ZtCObjList()
{
DeleteAll();
}/*
virtual ~ZtCObjList()*/
ZtCObjList& operator=(const ZtCObjList& rhs)
{
if(rhs.ml_Size<1)
{
return DeleteAll();
}
else if(ml_Size<=rhs.ml_Size)
{
AddDefault(rhs.ml_Size-ml_Size,ml_Size+1);
ZCLink* pRhsLink=rhs.mp_HeadLink;
ZCLink* pLhsLink= mp_HeadLink;
__for1(TypeSize, i, ml_Size)
{
pLhsLink->GetData()=pRhsLink->GetData();
pLhsLink=pLhsLink->mp_NextLink;
pRhsLink=pRhsLink->mp_NextLink;
}/*
__for1(TypeSize, i, ml_Size)*/
}
else
{
ZtCObjList VO_StoreList;
CutLink ///////////////////////////////////////
(
GetLinkPtr(rhs.ml_Size+1),rhs.ml_Size+1,
GetLinkPtr( ml_Size ), ml_Size ,
RR(VO_StoreList)
). DeleteAll();
////////////////////////////////////////////////
}/*
else*/
return *this;
}/*
ZtCObjList& operator=(const ZtCObjList& rhs)*/
bool IsEmpty() const
{
return mp_HeadLink==0 ;
}/*
bool IsEmpty() const*/
TypeSize GetSize() const{return ml_Size;}
TypeSize size () const{return ml_Size;}
ZCLink* GetHeadLinkPtr(){return mp_HeadLink;}
ZCLink* GetTailLinkPtr()
{
return mp_HeadLink==0 ? 0 : mp_HeadLink->mp_PrevLink ;
}/*
ZCLink* GetTailLinkPtr()*/
const ZCLink* GetHeadLinkPtr() const{return mp_HeadLink;}
const ZCLink* GetTailLinkPtr() const
{
return mp_HeadLink==0 ? 0 : mp_HeadLink->mp_PrevLink ;
}/*
const ZCLink* GetTailLinkPtr() const*/
Type& operator[](TypeSize AL_Index)
{
// [] 에 들어가는 AL_Index 은 1 부터 시작하는 첨자이다.
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'Type& ZtCObjList::operator[](TypeSize AL_Index)' : Parameter is bad index("<<AL_Index<<")"<<std::endl;
fileout.close();
::exit(1); return *(new Type);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AL_Index)->GetData();
}/*
Type& operator[](TypeSize AL_Index)*/
const Type& operator[](TypeSize AL_Index) const
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'const Type& ZtCObjList::operator[](TypeSize AL_Index) const' : Parameter is bad index("<<AL_Index<<")"<<std::endl;
fileout.close();
::exit(1); return *(new Type);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AL_Index)->GetData();
}/*
Type& operator[](TypeSize AL_Index) const*/
TypeSize Find /*###############################################################*/
(
TypeArg AR_SearchType ,
TypeSize AL_FirstFindIndex =1 ,
bool AB_DoFindFromFront=true
) const
/*#############################################################################*/
{
// AB_DoFindFromFront==true 이면 AL_FirstFindIndex 번째 링크부터
// 다음 링크로 순회하면서 GetData() == AR_SearchType 이 되는
// 최초의 위치를 반환한다.
const bool CB_IsTrue = //////////////////
(
mp_HeadLink == 0 ||
AL_FirstFindIndex < 1 ||
AL_FirstFindIndex > ml_Size
) ;
if(CB_IsTrue) return 0; ////////////////
TypeSize VL_FindIndex=AL_FirstFindIndex; const
ZCLink* VP_TempLink =GetLinkPtr(AL_FirstFindIndex);
if(AB_DoFindFromFront==true)
{
do /////////
{
if(VP_TempLink->GetData()==AR_SearchType) return VL_FindIndex;
if(VL_FindIndex ==ml_Size ) return 0 ;
VP_TempLink=VP_TempLink->mp_NextLink; ++VL_FindIndex;
}
while(true);
}
else // AB_DoFindFromFront!=true
{
do /////////
{
if(VP_TempLink->GetData()==AR_SearchType) return VL_FindIndex;
if(VL_FindIndex ==1 ) return 0 ;
VP_TempLink=VP_TempLink->mp_PrevLink; --VL_FindIndex;
}
while(true);
}/*
else // AB_DoFindFromFront!=true*/
return 0;
}/*
TypeSize Find ###################################################################
(
TypeArg AR_SearchType ,
TypeSize AL_FirstFindIndex =1 ,
bool AB_DoFindFromFront=true
) const
###############################################################################*/
TypeSize Find /*##############################################################*/
(
const ZCLink* AP_SearchLink ,
TypeSize AL_FirstFindIndex =1,
bool AB_DoFindFromFront=true
) const
/*#############################################################################*/
{
if(mp_HeadLink==0 || AL_FirstFindIndex<1 || AL_FirstFindIndex>ml_Size)
return 0;
//////////////////////////////////////////////////////////////////////
TypeSize VL_FindIndex= AL_FirstFindIndex;
ZCLink* VP_TempLink = const_cast<ZCLink*>
( GetLinkPtr(AL_FirstFindIndex) );
if(AB_DoFindFromFront==true)
{
do /**/
{
if(VP_TempLink ==AP_SearchLink) return VL_FindIndex;
if(VL_FindIndex==ml_Size ) return 0 ;
VP_TempLink=VP_TempLink->mp_NextLink; ++VL_FindIndex;
}
while(true);
}
else // AB_DoFindFromFront!=true
{
do /**/
{
if(VP_TempLink ==AP_SearchLink) return VL_FindIndex;
if(VL_FindIndex==1 ) return 0 ;
VP_TempLink=VP_TempLink->mp_PrevLink; --VL_FindIndex;
}
while(true);
}/*
else // AB_DoFindFromFront!=true*/
return 0;
}/*
TypeSize Find ##################################################################
(
ZCLink* AP_SearchLink ,
TypeSize AL_FirstFindIndex =1 ,
bool AB_DoFindFromFront=true
) const
/*#############################################################################*/
/*////////////////////////////////////////////////////////////////////////////////////////
■ FindData(TypeArg, ~) 함수가 없다면, TypeArg 이 const Type& 으로 정의되어 있는 경우,
const Type& 에 대해서만 찾기를 수행할 수 있고, Type& 에 대해서는 찾기를 수행할 수 없다.
-- 2010-05-29 21:31:00
////////////////////////////////////////////////////////////////////////////////////////*/
TypeSize FindData(
TypeArg AR_SearchType, TypeSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const
{
return Find(AR_SearchType, AL_FirstFindIndex, AB_DoFindFromFront);
}/*
TypeSize FindData(
TypeArg AR_SearchType, TypeSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const*/
ZCLink* GetLinkPtr(TypeSize AL_Index)
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZCLink* GetLinkPtr(TypeSize AL_Index)' : Parameter is bad index("<<AL_Index<<")"<<std::endl;
fileout.close();
::exit(1); return 0;
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif // _DEBUG
TypeSize VI_LeftDistance =AL_Index-1 ;
TypeSize VI_RightDistance=ml_Size-AL_Index+1;
TypeSize VI_ShortDistance=
(VI_LeftDistance<=VI_RightDistance ? VI_LeftDistance : -VI_RightDistance);
return mp_HeadLink->GetNextPrevPtr(VI_ShortDistance);
}/*
ZCLink* GetLinkPtr(TypeSize AL_Index)*/
const ZCLink* GetLinkPtr(TypeSize AL_Index) const // or 'ZCLink const * const GetLinkPtr(TypeSize AL_Index) const'
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'const ZCLink* GetLinkPtr(TypeSize AL_Index) const' : Parameter is bad index("<<AL_Index<<")"<<std::endl;
fileout.close();
::exit(1); return 0;
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif // _DEBUG
TypeSize VI_LeftDistance = AL_Index-1 ;
TypeSize VI_RightDistance= ml_Size-AL_Index+1;
TypeSize VI_ShortDistance=
(VI_LeftDistance<=VI_RightDistance ? VI_LeftDistance : -VI_RightDistance);
return mp_HeadLink->GetNextPrevPtr(VI_ShortDistance);
}/*
const ZCLink* GetLinkPtr(TypeSize AL_Index) const*/
ZtCObjList& DeleteAll()
{
if(mp_HeadLink!=0)
{
OnDelete(
mp_HeadLink, 1, mp_HeadLink->mp_PrevLink, ml_Size);
ZCLink* VP_DelLink=0;
do ////
{
VP_DelLink =mp_HeadLink;
mp_HeadLink=mp_HeadLink->mp_NextLink;
delete VP_DelLink;
}
while(--ml_Size>0);
mp_HeadLink =0;
}/*
if(mp_HeadLink!=0)*/
return *this;
}/*
ZtCObjList& DeleteAll()*/
ZtCObjList& clear()
{
return this->DeleteAll();
}/*
ZtCObjList& clear()*/
ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink)
{
#ifdef _DEBUG
if(Find(AP_DeleteLink)<1)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink)"<<std::endl;
fileout<<"Parameter ZCLink* type AP_DeleteLink Is Not Valid !"<<std::endl;
fileout.close();
::exit(1); return *this;
}/*
if(Find(AP_DeleteLink)<1)*/
#endif //_DEBUG
delete this->CutLink(AP_DeleteLink); return *this;
}/*
ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink)*/
ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos)
{
#ifdef _DEBUG
if(AL_DeletePos<1 || Find(AP_DeleteLink)!=AL_DeletePos)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink,TypeSize AL_DeletePos)"<<std::endl;
fileout<<"Parameter ZCLink* type AP_DeleteLink Is Not Valid !"<<std::endl;
fileout.close();
::exit(1); return *this;
}/*
if(AL_DeletePos<1 || Find(AP_DeleteLink)!=AL_DeletePos)*/
#endif //_DEBUG
delete this->CutLink(AP_DeleteLink, AL_DeletePos); return *this;
}/*
ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos)*/
ZtCObjList& Delete(ZCLink* AP_DeleteLink)
{
return DeleteLink(AP_DeleteLink);
}/*
ZtCObjList& Delete(ZCLink* AP_DeleteLink)*/
ZtCObjList& Delete(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos)
{
return DeleteLink(AP_DeleteLink, AL_DeletePos);
}/*
ZtCObjList& Delete(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos)*/
ZtCObjList& DeleteLink(TypeSize AL_DeletePos)
{
if(AL_DeletePos<1 || this->ml_Size>AL_DeletePos) return *this;
Delete(this->GetLinkPtr(AL_DeletePos), AL_DeletePos); return *this;
}/*
ZtCObjList& DeleteLink(TypeSize AL_DeletePos)*/
ZtCObjList& DeleteHead()
{
if(ml_Size>0)
delete this->CutLink(mp_HeadLink);
return *this;
}/*
ZtCObjList& DeleteHead()*/
ZtCObjList& DeleteHead(TypeSize AI_DeleteCnt)
{
__for1(TypeSize, i, AI_DeleteCnt)
{
if(ml_Size<1) return *this;
delete this->CutLink(mp_HeadLink);
}/*
__for1(TypeSize, i, AI_DeleteCnt)*/
return *this;
}/*
ZtCObjList& DeleteHead(TypeSize AI_DeleteCnt)*/
ZtCObjList& DeleteTail()
{
if(ml_Size>0)
delete this->CutLink(mp_HeadLink->mp_PrevLink);
return *this;
}/*
ZtCObjList& DeleteTail()*/
ZCLink* AddDefault(TypeSize AL_DefaultSize, TypeSize AL_AddPos)
{
if(AL_DefaultSize<1 || AL_AddPos<1 || AL_AddPos>ml_Size+1)
return 0;
//////////////////////////////////////////////////////////
ZtCObjList VO_StoreList; MakeDefault(
AL_DefaultSize, VO_StoreList);
ZCLink* VP_HeadLink=VO_StoreList.mp_HeadLink;
if(AL_AddPos==1)
JoinAfter(VO_StoreList, 0 , 1 );
else JoinAfter(VO_StoreList, GetLinkPtr(AL_AddPos-1), AL_AddPos-1);
return VP_HeadLink;
}/*
ZCLink* AddDefault(TypeSize AL_DefaultSize, TypeSize AL_AddPos)*/
ZtCObjList& AddHead(TypeArg AR_Type)
{
JoinAfter(new ZCLink(AR_Type), 0, 0); return *this;
}/*
ZtCObjList& AddHead(TypeArg AR_Type)*/
ZtCObjList& AddHead(const ZtCObjList& rhs)
{
if(this==&rhs) return *this;
ZtCObjList VO_StoreList(rhs);
JoinAfter(VO_StoreList, 0, 0); return *this;
}/*
ZtCObjList& AddHead(const ZtCObjList& rhs)*/
ZtCObjList& AddTail(TypeArg AR_Type)
{
JoinAfter(new ZCLink(AR_Type), GetTailLinkPtr(), ml_Size); return *this;
}/*
ZtCObjList& AddTail(TypeArg AR_Type)*/
ZtCObjList& AddTail(const ZtCObjList& rhs)
{
ZtCObjList VO_StoreList(rhs); return JoinTail(VO_StoreList);
}/*
ZtCObjList& AddTail(const ZtCObjList& rhs)*/
/*///////////////////////////////////////////////////////////////////
■ ZCLink* AddHeadDefault() 함수의 코드 중 return 문이 return *this
라고 되어 있었다. 10 여년간 이를 모른 것이다. 자그마치 10 여년간!
-- 2015-02-21- 21:36:00
///////////////////////////////////////////////////////////////////*/
ZCLink* AddHeadDefault()
{ ZCLink* VP_NewLink = new ZCLink ;
JoinAfter(VP_NewLink, 0 /*/////////*/ , 0 ); return VP_NewLink; }
ZCLink* AddTailDefault()
{ ZCLink* VP_NewLink = new ZCLink ;
JoinAfter(VP_NewLink, GetTailLinkPtr(), ml_Size); return VP_NewLink; }
ZCLink* AddHeadDef(){ return AddHeadDefault(); }
ZCLink* AddTailDef(){ return AddTailDefault(); }
ZtCObjList& pop_back (TypeArg AR_Type){return AddHead(AR_Type);}
ZtCObjList& push_back(TypeArg AR_Type){return AddTail(AR_Type);}
ZtCObjList& JoinHead(ZtCObjList& rhs)
{
JoinAfter(rhs, 0, 0); return *this;
}/*
ZtCObjList& JoinHead(ZtCObjList& rhs)*/
ZtCObjList& JoinHead(ZtCObjList& rhs, ZCLink* AP_CLink)
{
// rhs 의 AP_CLink 를 앞으로 연결한다.
// 일단 뒤로 연결한 다음 mp_HeadLink 을 뒤로 움직인다.
JoinAfter(rhs.CutLink(AP_CLink), GetTailLinkPtr(), ml_Size);
mp_HeadLink=mp_HeadLink->GetPrevPtr(); return *this;
}/*
ZtCObjList& JoinHead(ZtCObjList& rhs, ZCLink* AP_CLink)*/
ZtCObjList& JoinTail(ZtCObjList& rhs)
{
JoinAfter(rhs, GetTailLinkPtr(), ml_Size); return *this;
}/*
ZtCObjList& JoinTail(ZtCObjList& rhs)*/
ZtCObjList& JoinTail(ZtCObjList& rhs, ZCLink* AP_CLink)
{
// rhs 의 AP_CLink 를 뒤로 연결한다.
JoinAfter(rhs.CutLink(AP_CLink), GetTailLinkPtr(), ml_Size); return *this;
}/*
ZtCObjList& JoinTail(ZtCObjList& rhs, ZCLink* AP_CLink)*/
ZtCObjList& JoinAfter /*######################################################*/
(
ZtCObjList& rhs ,
ZCLink* AP_LinkOfRhs, TypeSize AL_AddPosOfRhs ,
ZCLink* AP_LinkStd , TypeSize AL_PosStd
)
/*#############################################################################*/
{
// rhs 의 AP_LinkOfRhs 링크를 잘라서 AP_LinkStd 앞에 붙인다.
#ifdef _DEBUG
if(rhs.Find(AP_LinkOfRhs)!=AL_AddPosOfRhs || (AP_LinkStd!=0 && Find(AP_LinkStd)!=AL_PosStd) )
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZtCObjList& JoinAfter(ZtCObjList& rhs,"<<std::endl;
fileout<<" (ZtCObjList& rhs ,"<<std::endl;
fileout<<" ZCLink* AP_LinkOfRhs ,"<<std::endl;
fileout<<" TypeSize AL_AddPosOfRhs ,"<<std::endl;
fileout<<" ZCLink* AP_LinkStd ,"<<std::endl;
fileout<<" TypeSize AL_PosStd" <<std::endl;
fileout<<"/*//////////////////////////*/ ): Parameter is bad index"<<std::endl;
fileout.close();
::exit(1); return *this;
}/*
if(rhs.Find(AP_LinkOfRhs)!=AL_AddPosOfRhs || (AP_LinkStd!=0 && Find(AP_LinkStd)!=AL_PosStd) )*/
#endif //_DEBUG
JoinAfter(
rhs.CutLink(AP_LinkOfRhs, AL_AddPosOfRhs), AP_LinkStd, AL_PosStd);
return *this;
}/*
ZtCObjList& JoinAfter ##########################################################
(
ZtCObjList& rhs ,
ZCLink* AP_LinkOfRhs, TypeSize AL_AddPosOfRhs ,
ZCLink* AP_LinkStd , TypeSize AL_PosStd
)
###############################################################################*/
ZtCObjList& CutLinkOut /*#####################################################*/
(
ZCLink* AP_CutHead, TypeSize AL_CutHeadPos,
ZCLink* AP_CutTail, TypeSize AL_CutTailPos,
ZtCObjList& ARR_StoreList
)
/*#############################################################################*/
{
// AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크, AL_CutHeadPos 는 그 위치
// AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크, AL_CutTailPos 는 그 위치
// 따라서 AL_CutHeadPos <= AL_CutTailPos
#ifdef _DEBUG
if(AL_CutHeadPos>AL_CutTailPos)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"ZtCObjList& CutLinkOut( ZCLink* AP_CutHead, TypeSize AL_CutHeadPos,"<<std::endl;
fileout<<" ZCLink* AP_CutTail, TypeSize AL_CutTailPos, ZtCObjList& ARR_StoreList"<<std::endl;
fileout<<"/*******************/ ) : AL_CutHeadPos>AL_CutTailPos"<<std::endl;
fileout.close();
::exit(1); return *this;
}/*
if(AL_CutHeadPos>AL_CutTailPos)*/
#endif // _DEBUG
OnDelete(AP_CutHead, AL_CutHeadPos, AP_CutTail, AL_CutTailPos);
if(AL_CutHeadPos==1 && AL_CutTailPos==ml_Size) // 모든 링크를 삭제할 때.
{
mp_HeadLink=0;
}
else if(AL_CutHeadPos==1) // 잘라내려는 링크가 처음 링크를 포함할 때.
{
ZCLink::MakeCircle(mp_HeadLink=AP_CutTail->mp_NextLink, AP_CutHead->mp_PrevLink);
}
else if(AL_CutTailPos==ml_Size) // 잘라내려는 링크가 끝 링크를 포함할 때.
{
ZCLink::MakeCircle(mp_HeadLink, AP_CutHead->mp_PrevLink);
}
else // 잘라내려는 링크가 처음과 끝 링크를 포함하지 않을 때.
{
ZCLink::JoinLink(AP_CutHead ->mp_PrevLink, AP_CutTail->mp_NextLink);
}/*
else*/
ml_Size -= AL_CutTailPos-AL_CutHeadPos+1 ;
// 여기까지는 CutLink(ZCLink*,TypeSize,ZCLink*,TypeSize,ZtCObjList&) 와 같다. 이후에 CutLink() 에서는
// ARR_StoreList 가 비어 있는 것으로 간주하지만, CutLinkOut() 는 ARR_StoreList 이 비어 있지
// 않은 경우에도 대비한다.
if(ARR_StoreList.ml_Size<1)
{
// AP_CutHead 과 AP_CutTail 을 연결하여 이중 원형 연결리스트가 되도록 한다.
ZCLink::MakeCircle(AP_CutHead, AP_CutTail);
ARR_StoreList.mp_HeadLink=AP_CutHead ;
ARR_StoreList.ml_Size =AL_CutTailPos-AL_CutHeadPos+1;
}
else
{
ZCLink::JoinLink (ARR_StoreList.mp_HeadLink->mp_PrevLink, AP_CutHead);
ZCLink::MakeCircle(ARR_StoreList.mp_HeadLink , AP_CutTail);
ARR_StoreList.ml_Size += AL_CutTailPos-AL_CutHeadPos+1 ;
}/*
else*/
return ARR_StoreList;
}/*
ZtCObjList& CutLinkOut #########################################################
(
ZCLink* AP_CutHead, TypeSize AL_CutHeadPos,
ZCLink* AP_CutTail, TypeSize AL_CutTailPos,
ZtCObjList& ARR_StoreList
)
###############################################################################*/
operator Type&()
{
return AddDefault(1, ml_Size+1)->GetData();
}/*
operator Type&()*/
Type& GetData(TypeSize AI_Index)
{
#ifdef _DEBUG
if(AI_Index<1 || AI_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'Type& GetData(TypeSize AI_Index)' : Parameter is bad index("<<AI_Index<<")"<<std::endl;
fileout.close();
::exit(1);
}/*
if(AI_Index<1 || AI_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AI_Index)->GetData();
}/*
Type& GetData(TypeSize AI_Index)*/
const Type& GetData(TypeSize AI_Index) const
{
#ifdef _DEBUG
if(AI_Index<1 || AI_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'const Type& GetData(TypeSize AI_Index) const' : Parameter is bad index("<<AI_Index<<")"<<std::endl;
fileout.close();
::exit(1);
}/*
if(AI_Index<1 || AI_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AI_Index)->GetData();
}/*
const Type& GetData(TypeSize AI_Index) const*/
Type& GetHeadData()
{
#ifdef _DEBUG
if(mp_HeadLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'Type& ZNsMain::ZtCObjList::GetHeadData()' : Type Instance is nothing"<<std::endl;
fileout.close();
::exit(1);
}/*
if(mp_HeadLink==0)*/
#endif //#_DEBUG
return mp_HeadLink->GetData();
}/*
Type& GetHeadData()*/
const Type& GetHeadData() const
{
#ifdef _DEBUG
if(mp_HeadLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'const Type& ZNsMain::ZtCObjList::GetHeadData() const' : Type Instance is nothing"<<std::endl;
fileout.close();
::exit(1);
}/*
if(mp_HeadLink==0)*/
#endif //_DEBUG
return mp_HeadLink->GetData();
}/*
const Type& GetHeadData() const*/
Type& GetTailData()
{
#ifdef _DEBUG
if(mp_HeadLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'Type& ZNsMain::ZtCObjList::GetTailData()' : Type Instance is nothing"<<std::endl;
fileout.close();
::exit(1);
}/*
if(mp_HeadLink==0)*/
#endif //_DEBUG
return mp_HeadLink->mp_PrevLink->GetData();
}/*
Type& GetTailData()*/
const Type& GetTailData() const
{
#ifdef _DEBUG
if(mp_HeadLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'const Type& ZNsMain::ZtCObjList::GetTailData() const' : Type Instance is nothing"<<std::endl;
fileout.close();
::exit(1);
}/*
if(mp_HeadLink==0)*/
#endif //_DEBUG
return mp_HeadLink->mp_PrevLink->GetData();
}/*
const Type& GetTailData() const*/
Type& front(){return GetHeadData();}
Type& back (){return GetTailData();}
const Type& front() const{return GetHeadData();}
const Type& back () const{return GetTailData();}
ZtCObjList& Rotate(TypeSize AL_RotateNum)
{
if(ml_Size>0) mp_HeadLink =
mp_HeadLink->GetNextPrevPtr(AL_RotateNum);
return *this;
}/*
ZtCObjList& Rotate(TypeSize AL_RotateNum)*/
ZtCObjList& Rotate ()
{ if(ml_Size>0) mp_HeadLink = mp_HeadLink->mp_NextLink ; return *this; }
ZtCObjList& RotateBack()
{ if(ml_Size>0) mp_HeadLink = mp_HeadLink->mp_PrevLink ; return *this; }
template<typename TFunctor> void IterElement(TFunctor AO_Functor)
{
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(int, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)(VP_LoopLink->mo_Type);
/* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator()
연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. */
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(int, i, ml_Size)*/
}/*
template<typename TFunctor> void IterElement(TFunctor AO_Functor) */
template<typename TFunctor, typename TTypeHelp>
void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp)
{
/*/////////////////////////////////////////////////////////////////////////////
■ TTypeHelp 가 class 일 경우, 크기가 커서 참조로 넘어가야 한다면,
IterElement<myFunctor, myClass&>(myFunctor_obj, myClass_Obj);
의 형태로 호출할 게 아니라, ZtCObjectPtr<> 을 사용하여,
myClass myClass_Obj; ZtCObjectPtr<myClass> myCObjPtr(myClass_Obj);
IterElement(myFunctor_obj, ZtCObjectPtr<myClass>(myClass_Obj));
형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00
이제는 ZtCRef 과 ZCCheckRef 클래스 템플릿을 사용하면 된다. -- 2021-03-11 11:00
/////////////////////////////////////////////////////////////////////////////*/
typedef ZNsMain::
ZtCCheckRef<TTypeHelp> ZCCheckRef;
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(int, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
VP_LoopLink->mo_Type, ZCCheckRef::PassData(AO_TypeHelp)
);
////////////////////////////////////////////
/* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator()
연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. */
/* ZCCheckRef::PassData() 으로 인해, 인수를 ZtCRef 클래스를 이용해
인수를 참조로 넘길 수 있게 되었다. -- 2021-03-10 16:56 */
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(int, 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
)
/*#############################################################################*/
{
/*/////////////////////////////////////////////////////////////////////////////
■ TTypeHelp 가 class 일 경우, 크기가 커서 참조로 넘어가야 한다면,
IterElement<myFunctor, myClass&>(myFunctor_obj, myClass_Obj);
의 형태로 호출할 게 아니라, ZtCObjectPtr<> 을 사용하여,
myClass myClass_Obj; ZtCObjectPtr<myClass> myCObjPtr(myClass_Obj);
IterElement(myFunctor_obj, ZtCObjectPtr<myClass>(myClass_Obj));
형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00
이제는 ZtCRef 과 ZCCheckRef 클래스 템플릿을 사용하면 된다. -- 2021-03-11 11:00
/////////////////////////////////////////////////////////////////////////////*/
typedef ZNsMain::ZtCCheckRef<TTypeHelp1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<TTypeHelp2> ZCCheckRef2;
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(int, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
VP_LoopLink->mo_Type
, ZCCheckRef1::PassData(AO_TypeHelp1)
, ZCCheckRef2::PassData(AO_TypeHelp2)
);
////////////////////////////////////////////
/* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator()
연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. */
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(int, i, ml_Size)*/
}/*
template
<typename TFunctor, typename TTypeHelp1, typename TTypeHelp2> ###############
void IterElement
(
TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2
)
###############################################################################*/
template<typename TFunctor, typename TTypeHelp>
void IterElemRef(TFunctor AO_Functor, TTypeHelp& AR_TypeHelp)
{
/* TTypeHelp 을 참조로 받고 있음에 주의한다. -- 2015-09-07 02:55:00 */
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(int, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef
(AO_Functor)(VP_LoopLink->mo_Type, AR_TypeHelp);
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(int, i, ml_Size)*/
}/*
template<typename TFunctor, typename TTypeHelp>
void IterElemRef(TFunctor AO_Functor, TTypeHelp& AR_TypeHelp) */
template
<typename TFunctor, typename TTypeHelp1, typename TTypeHelp2> /*###########*/
void IterElemRef
(
TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2
)
/*#############################################################################*/
{
/* TTypeHelp1 과 2 을 참조로 받고 있음에 주의한다. -- 2021-03-04 04:00:00 */
ZCLink* VP_LoopLink=mp_HeadLink;
__for0(int, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
( VP_LoopLink->mo_Type, AR_TypeHelp1, AR_TypeHelp2 );
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(int, i, ml_Size)*/
}/*
template
<typename TFunctor, typename TTypeHelp1, typename TTypeHelp2> ###############
void IterElemRef
(
TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2
)
/*#############################################################################*/
/*///////////////////////////////////////////////////////////////////////////
■ 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
///////////////////////////////////////////////////////////////////////////*/
class ZCIterator
{
protected:
mutable ZCLink* mp_Link;
mutable TypeSize ml_Pos ;
public :
ZCIterator(ZCLink* AP_CLink=0, TypeSize AL_Pos=0)
{
mp_Link=AP_CLink;
ml_Pos =AL_Pos ;
}/*
ZCIterator(ZCLink* AP_CLink=0, TypeSize AL_Pos=0)*/
ZCLink* GetLink()
{
return mp_Link;
}/*
ZCLink* GetLink()*/
const ZCLink* GetLink() const
{
return mp_Link;
}/*
const ZCLink* GetLink() const*/
TypeSize GetPos() const
{
return ml_Pos;
}/*
TypeSize GetPos() const*/
Type& operator *()
{
return mp_Link->GetData();
}/*
Type& operator *()*/
const Type& operator *() const
{
return mp_Link->GetData();
}/*
const Type& operator *() const*/
ZCIterator& operator++()
{
mp_Link=mp_Link->GetNextPtr(); ++ml_Pos; return *this;
}/*
ZCIterator& operator++()*/
const ZCIterator& operator++() const
{
mp_Link=mp_Link->GetNextPtr(); ++ml_Pos; return *this;
}/*
const ZCIterator& operator++() const*/
ZCIterator operator++(int)
{
ZCIterator VO_CIterator(*this);
mp_Link=mp_Link->GetNextPtr();
++ml_Pos; return VO_CIterator;
}/*
ZCIterator operator++(int)*/
const ZCIterator operator++(int) const
{
ZCIterator VO_CIterator(*this);
mp_Link=mp_Link->GetNextPtr();
++ml_Pos; return VO_CIterator;
}/*
const ZCIterator operator++(int) const*/
ZCIterator& operator--()
{
mp_Link=mp_Link->GetPrevPtr(); --ml_Pos; return *this;
}/*
ZCIterator& operator--()*/
const ZCIterator& operator--() const
{
mp_Link=mp_Link->GetPrevPtr(); --ml_Pos; return *this;
}/*
const ZCIterator& operator--() const*/
ZCIterator operator--(int)
{
ZCIterator VO_CIterator(*this);
mp_Link=mp_Link->GetPrevPtr();
--ml_Pos; return VO_CIterator;
}/*
ZCIterator operator--(int)*/
const ZCIterator operator--(int) const
{
ZCIterator VO_CIterator(*this);
mp_Link=mp_Link->GetPrevPtr();
--ml_Pos; return VO_CIterator;
}/*
ZCIterator operator--(int) const*/
ZCIterator operator+(TypeSize AI_FarNum) const
{
ZCIterator VO_CIterator(*this);
VO_CIterator.mp_Link =mp_Link->GetNextPtr(AI_FarNum);
VO_CIterator.ml_Pos +=AI_FarNum ;
return VO_CIterator;
}/*
ZCIterator operator+(TypeSize AI_FarNum) const*/
ZCIterator operator-(TypeSize AI_FarNum) const
{
ZCIterator VO_CIterator(*this);
VO_CIterator.mp_Link =mp_Link->GetNextPtr(-AI_FarNum);
VO_CIterator.ml_Pos -=AI_FarNum ;
return VO_CIterator;
}/*
ZCIterator operator-(TypeSize AI_FarNum) const*/
bool operator==(const ZCIterator& rhs) const
{
return mp_Link==rhs.mp_Link && ml_Pos==rhs.ml_Pos ;
}/*
bool operator==(const ZCIterator& rhs) const*/
bool operator!=(const ZCIterator& rhs) const
{
return mp_Link!=rhs.mp_Link || ml_Pos!=rhs.mp_Pos ;
}/*
bool operator!=(const ZCIterator& rhs) const*/
public:
};/*
class ZCIterator*/
ZCIterator begin()
{
return ZCIterator(mp_HeadLink, (ml_Size>0 ? 1 : 0) );
}/*
ZCIterator begin()*/
ZCIterator end()
{
return ZCIterator(mp_HeadLink, (ml_Size>0 ? ml_Size+1 : 0) );
}/*
ZCIterator end()*/
const ZCIterator begin() const
{
return ZCIterator(mp_HeadLink, (ml_Size>0 ? 1 : 0) );
}/*
const ZCIterator begin() const*/
const ZCIterator end() const
{
return ZCIterator(mp_HeadLink, (ml_Size>0 ? ml_Size+1 : 0) );
}/*
const ZCIterator end() const*/
void erase(ZCIterator& AR_CIterator)
{
return DeleteLink(AR_CIterator.GetLink(), AR_CIterator.GetPos());
}/*
void erase(ZCIterator& AR_CIterator)*/
void erase(ZCIterator& AR_CIterator1, ZCIterator& AR_CIterator2)
{
ZtCObjList VO_CObjList;
CutLink( AR_CIterator1.GetLink(), AR_CIterator1.GetPos(),
AR_CIterator2.GetLink(), AR_CIterator2.GetPos(), RR(VO_CObjList)
/****/ );
VO_CObjList.DeleteAll();
}/*
void erase(ZCIterator& AR_CIterator1, ZCIterator& AR_CIterator2)*/
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();}
IterEasyID GetHeadIterEasyID() const{return (IterEasyID)GetHeadLinkPtr();}
IterEasyID GetTailIterEasyID() const{return (IterEasyID)GetTailLinkPtr();}
/*///////////////////////////////////////////////////////////////////////////
■ 순차적으로 각 원소를 순회할 수 있는 자료 구조, 즉 리스트나 배열 클래스는
MoveNextIter(), MovePrevIter()
멤버를 갖는 것으로 정했다. stl 의 반복자는 너무 일반화하다보니, 성능 상의
제약이 발생한 것 같다.
-- 2011-06-07 20:25:00
GetDataInIter() 를 추가했다.
-- 2011-06-12 16:35:00
■ --
///////////////////////////////////////////////////////////////////////////*/
void MoveNextIter(ZCLink*& APR_CLink) const
{
APR_CLink=APR_CLink->GetNextPtr();
}/*
void MoveNextIter(ZCLink*& APR_CLink) const*/
void MoveNextIter(iterator& ARR_CIterator)
{
++ARR_CIterator;
}/*
void MoveNextIter(iterator& ARR_CIterator)*/
void MoveNextIter(IterEasyID& ARRI_IterEasyID) const
{
MoveNextIter((ZCLink*&)(ARRI_IterEasyID));
}/*
void MoveNextIter(IterEasyID& ARRI_IterEasyID) const*/
void MoveNextIter(const ZCLink*& APR_CLink) const
{
APR_CLink=APR_CLink->GetNextPtr();
}/*
void MoveNextIter(const ZCLink*& APR_CLink) const*/
void MoveNextIter(const iterator& ARR_CIterator) const
{
++ARR_CIterator;
}/*
void MoveNextIter(const iterator& ARR_CIterator) const*/
void MoveNextIter(IterEasyIDc& ARRI_IterEasyID) const
{
MoveNextIter((const ZCLink*&)(ARRI_IterEasyID));
}/*
void MoveNextIter(IterEasyIDc& ARRI_IterEasyID) const*/
void MovePrevIter(ZCLink*& APR_CLink)
{
APR_CLink=APR_CLink->GetPrevPtr();
}/*
void MovePrevIter(ZCLink*& APR_CLink)*/
void MovePrevIter(iterator& ARR_CIterator)
{
--ARR_CIterator;
}/*
void MovePrevIter(iterator& ARR_CIterator)*/
void MovePrevIter(IterEasyID& ARRI_IterEasyID)
{
MovePrevIter((ZCLink*&)(ARRI_IterEasyID));
}/*
void MovePrevIter(IterEasyID& ARRI_IterEasyID)*/
void MovePrevIter(const ZCLink*& APR_CLink) const
{
APR_CLink=APR_CLink->GetPrevPtr();
}/*
void MovePrevIter(const ZCLink*& APR_CLink) const*/
void MovePrevIter(const iterator& ARR_CIterator) const
{
--ARR_CIterator;
}/*
void MovePrevIter(const iterator& ARR_CIterator) const*/
void MovePrevIter(IterEasyIDc& ARRI_IterEasyID) const
{
MovePrevIter((const ZCLink*&)(ARRI_IterEasyID));
}/*
void MovePrevIter(IterEasyIDc& ARRI_IterEasyID) const*/
Type& GetDataInIter(ZCLink* AP_CLink)
{
return **AP_CLink;
}/*
Type& GetDataInIter(ZCLink* AP_CLink)*/
Type& GetDataInIter(iterator& ARR_CIterator)
{
return *ARR_CIterator;
}/*
Type& GetDataInIter(iterator& ARR_CIterator)*/
Type& GetDataInIter(IterEasyID ARRI_IterEasyID)
{
return GetDataInIter((ZCLink*)ARRI_IterEasyID);
}/*
Type& GetDataInIter(IterEasyID ARRI_IterEasyID)*/
Type& GetDataInIter(ZCLink* AP_CLink, TypeSize AI_FarNum)
{
return **AP_CLink->GetNextPrevPtr(AI_FarNum);
}/*
Type& GetDataInIter(ZCLink* AP_CLink, TypeSize AI_FarNum)*/
Type& GetDataInIter(iterator& ARR_CIterator, TypeSize AI_FarNum)
{
return *(ARR_CIterator+AI_FarNum);
}/*
Type& GetDataInIter(iterator& ARR_CIterator, TypeSize AI_FarNum)*/
Type& GetDataInIter(IterEasyID ARRI_IterEasyID, TypeSize AI_FarNum)
{
return GetDataInIter((ZCLink*)ARRI_IterEasyID, AI_FarNum);
}/*
Type& GetDataInIter(IterEasyID ARRI_IterEasyID, TypeSize AI_FarNum)*/
const Type& GetDataInIter(const ZCLink* AP_CLink) const
{
return **AP_CLink;
}/*
const Type& GetDataInIter(const ZCLink* AP_CLink) const*/
const Type& GetDataInIter(const iterator& ARR_CIterator) const
{
return *ARR_CIterator;
}/*
const Type& GetDataInIter(const iterator& ARR_CIterator) const*/
const Type& GetDataInIter(IterEasyIDc ARRI_IterEasyID) const
{
return GetDataInIter((const ZCLink*)ARRI_IterEasyID);
}/*
const Type& GetDataInIter(IterEasyIDc ARRI_IterEasyID) const*/
const Type& GetDataInIter(const ZCLink* AP_CLink, TypeSize AI_FarNum) const
{
return **AP_CLink->GetNextPrevPtr(AI_FarNum);
}/*
const Type& GetDataInIter(const ZCLink* AP_CLink, TypeSize AI_FarNum) const*/
const Type& GetDataInIter(const iterator& ARR_CIterator, TypeSize AI_FarNum) const
{
return *(ARR_CIterator+AI_FarNum);
}/*
const Type& GetDataInIter(const iterator& ARR_CIterator, TypeSize AI_FarNum) const*/
const Type& GetDataInIter(IterEasyIDc ARRI_IterEasyID, TypeSize AI_FarNum) const
{
return GetDataInIter((ZCLink*)ARRI_IterEasyID, AI_FarNum);
}/*
const Type& GetDataInIter(IterEasyIDc ARRI_IterEasyID, TypeSize AI_FarNum) const*/
// cf typedef ZCLink* IterEasy;
IterEasy ItHEasy(){return mp_HeadLink ;}
IterEasy ItTEasy(){return mp_HeadLink->mp_PrevLink ;}
IterEasyID ItHID (){return (IterEasyID) mp_HeadLink ;}
IterEasyID ItTID (){return (IterEasyID)(mp_HeadLink->mp_PrevLink);}
const IterEasy ItHEasy() const{return mp_HeadLink ;}
const IterEasy ItTEasy() const{return mp_HeadLink->mp_PrevLink ;}
const IterEasyID ItHID () const{return (IterEasyID) mp_HeadLink ;}
const IterEasyID ItTID () const{return (IterEasyID)(mp_HeadLink->mp_PrevLink);}
void ItNext(IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_NextLink;}
void ItNext(iterator& ARR_CIterator) const{++ARR_CIterator;}
void ItNext(IterEasyID& AI_IterEasyID) const
{ ItNext((IterEasy&)AI_IterEasyID); }
void ItNext(const IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_NextLink;}
void ItNext(const iterator& ARR_CIterator) const{++ARR_CIterator;}
void ItNext(const IterEasyID& AI_IterEasyID)
const{ ItNext((const IterEasy&)AI_IterEasyID); }
void ItPrev(IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_PrevLink;}
void ItPrev(iterator& ARR_CIterator) const{--ARR_CIterator;}
void ItPrev(IterEasyID& AI_IterEasyID) const
{ ItPrev((IterEasy&)AI_IterEasyID); }
void ItPrev(const IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_PrevLink;}
void ItPrev(const iterator& ARR_CIterator) const{--ARR_CIterator;}
void ItPrev(const IterEasyID& AI_IterEasyID)
const{ ItPrev((const Type*&)AI_IterEasyID); }
Type& ItD(IterEasy AP_CLink ){return GetDataInIter(AP_CLink );}
Type& ItD(iterator& ARR_CIterator ){return GetDataInIter(ARR_CIterator );}
Type& ItD(IterEasyID ARRI_IterEasyID ){return GetDataInIter(ARRI_IterEasyID );}
Type& ItD(ZCLink* AP_CLink , TypeSize AI_FarNum){return GetDataInIter(AP_CLink , AI_FarNum);}
Type& ItD(iterator& ARR_CIterator , TypeSize AI_FarNum){return GetDataInIter(ARR_CIterator , AI_FarNum);}
Type& ItD(IterEasyID ARRI_IterEasyID, TypeSize AI_FarNum){return GetDataInIter(ARRI_IterEasyID, AI_FarNum);}
const Type& ItD(const IterEasy AP_CLink ) const{return GetDataInIter(AP_CLink );}
const Type& ItD(const iterator& ARR_CIterator ) const{return GetDataInIter(ARR_CIterator );}
const Type& ItD(IterEasyIDc ARRI_IterEasyID ) const{return GetDataInIter(ARRI_IterEasyID );}
const Type& ItD(const ZCLink* AP_CLink , TypeSize AI_FarNum) const{return GetDataInIter(AP_CLink );}
const Type& ItD(const iterator& ARR_CIterator , TypeSize AI_FarNum) const{return GetDataInIter(ARR_CIterator , AI_FarNum);}
const Type& ItD(IterEasyIDc ARRI_IterEasyID, TypeSize AI_FarNum) const{return GetDataInIter(ARRI_IterEasyID, AI_FarNum);}
public:
};/*
template< typename TType ,
typename TTypCArg =const TType&,
typename TTypCAlloc=ZCAllocator ,
typename TTypCInit =ZCInit ,
typename TTypSize =ZTypLong
>
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 :
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];
typedef TypeData ZCLink ; // 이 typedef 에 주의.
public :
class ZCLinkUnit : public TypeAlloc
{
public :
friend class ZtCObjUnitList;
private:
TypeArr mo_TypeArr ;
TypeSize ml_UseSize ;
ZCLinkUnit* mp_NextUnit;
ZCLinkUnit* mp_PrevUnit;
private:
static void JoinLink(ZCLinkUnit* lhs, ZCLinkUnit* rhs)
{
lhs->mp_NextUnit=rhs;
rhs->mp_PrevUnit=lhs;
}/*
static void JoinLink(ZCLinkUnit* lhs, ZCLinkUnit* rhs)*/
static void MakeCircle(ZCLinkUnit* AP_HeadUnit, ZCLinkUnit* AP_TailUnit)
{
AP_HeadUnit->mp_PrevUnit=AP_TailUnit;
AP_TailUnit->mp_NextUnit=AP_HeadUnit;
}/*
static void MakeCircle(ZCLinkUnit* AP_HeadUnit, ZCLinkUnit* AP_TailUnit)*/
TypeData& AddEmptyObj_E() // E 는 Error 가 발생할 수 있다는 뜻.
{
return mo_TypeArr[ml_UseSize++]; // error 체크 즉, ml_UseSize>=ZEArrSize 인지를 체크하지 않는다.
}/*
TypeData& AddEmptyObj_E()*/
/*private:*/
public :
ZCLinkUnit()
{
ml_UseSize =0;
mp_NextUnit=0;
mp_PrevUnit=0;
}/*
ZCLinkUnit()*/
ZCLinkUnit(const ZCLinkUnit& rhs)
{
ml_UseSize =rhs.ml_UseSize;
mp_NextUnit=0 ;
mp_PrevUnit=0 ;
::memcpy( mo_TypeArr,
rhs.mo_TypeArr, ml_UseSize*sizeof(TypeData));
}/*
ZCLinkUnit(const ZCLinkUnit& rhs)*/
ZCLinkUnit& operator=(const ZCLinkUnit& rhs)
{
if(this==&rhs) return *this;
ml_UseSize=rhs.ml_UseSize;
::memcpy( mo_TypeArr,
rhs.mo_TypeArr, ml_UseSize*sizeof(TypeData));
return *this;
}/*
ZCLinkUnit& operator=(const ZCLinkUnit& rhs)*/
TypeData* GetHeadObjPtr (){return mo_TypeArr ;}
ZCLinkUnit* GetNextUnitPtr(){return mp_NextUnit;}
ZCLinkUnit* GetPrevUniPtr (){return mp_PrevUnit;}
TypeSize size () const{return ml_UseSize ;}
TypeSize GetUseSize () const{return ml_UseSize ;}
const TypeData* GetHeadObjPtr () const{return mo_TypeArr ;}
const ZCLinkUnit* GetNextUnitPtr() const{return mp_NextUnit;}
const ZCLinkUnit* GetPrevUniPtr () const{return mp_PrevUnit;}
TypeData& GetData(TypeSize AI_Index) // AI_Index start from 1
{
return mo_TypeArr[AI_Index-1];
}/*
TypeData& GetData(TypeSize AI_Index) // AI_Index start from 1*/
TypeArg GetData(TypeSize AI_Index) const // AI_Index start from 1
{
return mo_TypeArr[AI_Index-1];
}/*
TypeArg GetData(TypeSize AI_Index) const // AI_Index start from 1*/
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* GetObjtPtr(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* GetObjtPtr(TypeSize AI_Distance)*/
const ZCLinkUnit* GetObjtPtr(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* GetObjtPtr(TypeSize AI_Distance) const*/
ZCLinkUnit* GetObjtPtr(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* GetObjtPtr(TypeSize AI_Distance, TypeSize& ARRI_ObjCnt)*/
const ZCLinkUnit* GetObjtPtr(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* GetObjtPtr(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 ; // mp_NowHeadUnit 이 시작인 리스트의 원소 수.
/*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_NewCLinkUnit=CreateUnit();
VP_NewCLinkUnit->ml_UseSize=0; return VP_NewCLinkUnit;
}/*
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::MakeCircle(mp_CutHeadUnit, VP_CutTailUnit);
//else
VP_CutHeadUnit->ml_UseSize=0; return VP_CutHeadUnit;
}/*
ZCLinkUnit* AllocUnit()*/
ZCLinkUnit* AllocUnitAtHead()
{
// AllocUnit() 을 통해 가져온 ZCLinkUnit* 을 '내부 사용 리스트'의 앞에 삽입한다.
ZCLinkUnit* VP_NewCLinkUnit=AllocUnit();
if(++ml_NowUnitCnt<=1)
{
mp_NowHeadUnit=VP_NewCLinkUnit;
mp_NowHeadUnit->mp_NextUnit=mp_NowHeadUnit;
mp_NowHeadUnit->mp_PrevUnit=mp_NowHeadUnit;
}
else
{
ZCLinkUnit* VP_TailCLinkUnit=mp_NowHeadUnit->mp_PrevUnit;
ZCLinkUnit::JoinLink (VP_NewCLinkUnit, mp_NowHeadUnit );
ZCLinkUnit::MakeCircle(VP_NewCLinkUnit, VP_TailCLinkUnit);
mp_NowHeadUnit=VP_NewCLinkUnit;
}/*
else*/
return VP_NewCLinkUnit;
}/*
ZCLinkUnit* AllocUnitAtHead()*/
ZCLinkUnit* AllocUnitAtTail()
{
// AllocUnit() 을 통해 가져온 ZCLinkUnit* 을 '내부 사용 리스트'의 뒤에 삽입한다.
ZCLinkUnit* VP_NewCLinkUnit=AllocUnit();
if(++ml_NowUnitCnt<=1)
{
mp_NowHeadUnit=VP_NewCLinkUnit;
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_NewCLinkUnit);
ZCLinkUnit::MakeCircle(mp_NowHeadUnit ,VP_NewCLinkUnit);
}/*
else*/
return VP_NewCLinkUnit;
}/*
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->GetObjtPtr(AI_Distance); }
ZCLinkUnit* GetCutUnitPtr(TypeSize AI_Distance){
if(mp_CutHeadUnit==0) return 0; return mp_CutHeadUnit->GetObjtPtr(AI_Distance); }
const ZCLinkUnit* GetNowUnitPtr(TypeSize AI_Distance) const{
if(mp_NowHeadUnit==0) return 0; return mp_NowHeadUnit->GetObjtPtr(AI_Distance); }
const ZCLinkUnit* GetCutUnitPtr(TypeSize AI_Distance) const{
if(mp_CutHeadUnit==0) return 0; return mp_CutHeadUnit->GetObjtPtr(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 는 '임시 작업 큐'다.
typedef typename TAllocWork::CSyncExec CSyncExec;
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)
{
// CAllocWork_BASE2_T<> 를 참고하면, *this 는 '임시 작업 큐'다.
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 연산자가 지원되어야 한다.
typedef typename TAllocWork::CSyncExec CSyncExec;
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::MakeCircle(VP_UnitHead, VP_UnitTail);
mp_CutHeadUnit = VP_UnitHead; ///////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_CutHeadUnit->mp_PrevUnit, VP_UnitHead);
ZCLinkUnit::MakeCircle(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::MakeCircle(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::MakeCircle(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::MakeCircle(mp_NowHeadUnit , VP_TailLink);
ZCLinkUnit::JoinLink (mp_CutHeadUnit->mp_PrevUnit, VP_HeadLink);
ZCLinkUnit::MakeCircle(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::JoinLink (mp_NowHeadUnit->mp_PrevUnit, rhs.mp_NowHeadUnit);
ZCLinkUnit::MakeCircle(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::MakeCircle(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->
GetObjtPtr( -(AI_FetchSize-1), RR(VI_RhsObjCnt) ) ;
ZCLinkUnit::MakeCircle(
rhs.mp_NowHeadUnit, VP_RhsNowHead->mp_PrevUnit);
rhs.ml_NowUnitCnt -= AI_FetchSize;
rhs.ml_NowObjtCnt -= VI_RhsObjCnt;
if(ml_NowUnitCnt<1)
{
ZCLinkUnit::MakeCircle(VP_RhsNowHead, VP_RhsNowTail); mp_NowHeadUnit=VP_RhsNowHead;
}
else
{
ZCLinkUnit::JoinLink (mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeCircle(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->
GetObjtPtr( AI_FetchSize-1, RR(VI_RhsObjCnt) );
rhs.mp_NowHeadUnit=VP_RhsNowTail->mp_NextUnit;
ZCLinkUnit::MakeCircle(
rhs.mp_NowHeadUnit, VP_RhsNowHead->mp_PrevUnit);
rhs.ml_NowUnitCnt -= AI_FetchSize;
rhs.ml_NowObjtCnt -= VI_RhsObjCnt;
if(ml_NowUnitCnt<1)
{
ZCLinkUnit::MakeCircle(VP_RhsNowHead, VP_RhsNowTail);
mp_NowHeadUnit=VP_RhsNowHead; ///////////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeCircle(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::MakeCircle(
rhs.mp_NowHeadUnit, VP_RhsNowTail->mp_PrevUnit);
}
rhs.ml_NowObjtCnt -= VP_RhsNowTail->ml_UseSize ;
if(++ml_NowUnitCnt<=1)
{
ZCLinkUnit::MakeCircle(VP_RhsNowTail, VP_RhsNowTail);
mp_NowHeadUnit=VP_RhsNowTail; ///////////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowTail);
ZCLinkUnit::MakeCircle(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::MakeCircle(
rhs.mp_NowHeadUnit, VP_RhsNowHead->mp_PrevUnit);
}
rhs.ml_NowObjtCnt -= VP_RhsNowHead->ml_UseSize ;
if(++ml_NowUnitCnt<=1)
{
ZCLinkUnit::MakeCircle(VP_RhsNowHead, VP_RhsNowHead);
mp_NowHeadUnit=VP_RhsNowHead; ///////////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_NowHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeCircle(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::MakeCircle(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->GetObjtPtr(-(AI_FetchSize-1));
ZCLinkUnit::MakeCircle(
rhs.mp_CutHeadUnit, VP_RhsCutHead->mp_PrevUnit);
rhs.ml_CutUnitCnt -= AI_FetchSize;
if(ml_CutUnitCnt<1)
{
ZCLinkUnit::MakeCircle(VP_RhsCutHead, VP_RhsCutTail);
mp_CutHeadUnit=VP_RhsCutHead; ///////////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_CutHeadUnit->mp_PrevUnit, VP_RhsCutHead);
ZCLinkUnit::MakeCircle(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->GetObjtPtr(AI_FetchSize-1);
rhs.mp_CutHeadUnit=VP_RhsCutTail->mp_NextUnit;
ZCLinkUnit::MakeCircle(
rhs.mp_CutHeadUnit, VP_RhsCutHead->mp_PrevUnit);
rhs.ml_CutUnitCnt -= AI_FetchSize;
if(ml_CutUnitCnt<1)
{
ZCLinkUnit::MakeCircle(VP_RhsCutHead, VP_RhsCutTail);
mp_CutHeadUnit=VP_RhsCutHead; ///////////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_CutHeadUnit->mp_PrevUnit, VP_RhsCutHead);
ZCLinkUnit::MakeCircle(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::MakeCircle(
rhs.mp_CutHeadUnit, VP_RhsNowTail->mp_PrevUnit);
}/*
else*/
if(++ml_CutUnitCnt<=1)
{
ZCLinkUnit::MakeCircle(VP_RhsNowTail, VP_RhsNowTail);
mp_CutHeadUnit=VP_RhsNowTail; ///////////////////////
}
else
{
ZCLinkUnit::JoinLink (mp_CutHeadUnit->mp_PrevUnit, VP_RhsNowTail);
ZCLinkUnit::MakeCircle(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::MakeCircle(
rhs.mp_CutHeadUnit, VP_RhsNowHead->mp_PrevUnit);
}/*
////////////////////////////////////////////////////*/
if(++ml_CutUnitCnt<=1)
{
ZCLinkUnit::
MakeCircle(VP_RhsNowHead, VP_RhsNowHead);
mp_CutHeadUnit = VP_RhsNowHead;
}
else
{
ZCLinkUnit::JoinLink (mp_CutHeadUnit->mp_PrevUnit, VP_RhsNowHead);
ZCLinkUnit::MakeCircle(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;}
TypeData& ItD(TypeData* AP_Object ){return *AP_Object;}
TypeArr & ItD(ZCLinkUnit* AP_CLinkUnit)
{
return AP_CLinkUnit->mo_TypeArr;
}/*
TypeArr & ItD(ZCLinkUnit* AP_CLinkUnit)*/
public :
};/*
template< typename TType,
typename TTypeObjUnitList=ZNsType::ZtCTypeObjUnitList<TType>
>
class ZtCObjUnitList /////////////////////////////////////////////////*/
}/*
namespace ZNsMain*/
#endif //__ZCPPMAIIN__ZTCOBJLIST_H__