Files
RepoMain/ZCppMain/ZtCSimList.H

2273 lines
74 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef __ZCPPMAIN__ZCSIMLIST_H__
#define __ZCPPMAIN__ZCSIMLIST_H__
#include "ZCppMain/ZMainHead.H"
namespace ZNsMain
{
namespace ZNsIFaceEx
{
template<> class ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single >
{
public:
template<typename TSimList> class ZtCBody
{
public :
typedef typename TSimList::TypeData TypeData;
typedef typename TSimList::TypeSize TypeSize;
typedef typename TSimList::TypeInit TypeInit;
typedef typename TSimList::ZCLink ZCLink ;
public :
#if(0)
/* 아래는 g++ 이 지원하지 않는다.
In file included from ZtCSimList_000.cpp:4:
../ZCppMain/ZtCSimList.H:35:39: error: ZtCSimList in namespace ZNsMain does not name a type; did you mean ZtCList?
35 | friend class ZNsMain::ZtCSimList; /////////////////////////////
| ^~~~~~~~~~
| ZtCList
-- Visual C++ 2022 는 지원한다. -- 2025-09-13 22:06
-- ZNsMain::ZtCSimList 을 전방 선언하면 되기는 할 것이다. -- 2025-09-13 22:44
*/
template //////////////////////////////////////////////////////
<
typename TType , typename TTypArgu
, typename TTypCAlloc , typename TTypCInit
, typename TTypSize , typename TMoveObj
, typename TFeeeHeap
>
friend class ZNsMain::ZtCSimList; /////////////////////////////
#endif //(0)
private:
TypeSize ml_AllSize ;
TypeSize ml_UseSize ;
ZCLink* mp_NoUseHead ;
ZCLink* mp_NoUseTail ;
public :
_NP_ ZCLink* SendFreeOut()
{
if(ml_UseSize==0)
{
ZCLink* VP_TempLink = new ZCLink ;
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(*VP_TempLink, *this);
return (++ml_AllSize, VP_TempLink);
}/*
if(ml_UseSize==0)*/
ZCLink* VP_TempLink=mp_NoUseHead;
if(VP_TempLink==mp_NoUseTail)
{
mp_NoUseHead=0;
mp_NoUseTail=0;
}
else
{
mp_NoUseHead = mp_NoUseHead->GetNextPtr();
}
//else
--ml_UseSize; return VP_TempLink;
}/*
_NP_ ZCLink* SendFreeOut()*/
_NP_ void SendFreeOut /*################################################*/
(
TypeSize AL_NeedCnt, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink
)
/*######################################################################*/
{
#ifdef _DEBUG
ZNsMain::ZCCheckAlloc::ZCAllowAlloc CAllowAllocObj;
#endif //_DEBUG
if(mp_NoUseHead==0)
{
MakeLink(AL_NeedCnt, RR(APR_HeadLink), RR(APR_TailLink));
}
else if(AL_NeedCnt==ml_UseSize)
{
ZCLink* VP_Temp = mp_NoUseHead;
while(true)
{
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**VP_Temp, *this);
if(VP_Temp==mp_NoUseTail)
{ break; }
VP_Temp = VP_Temp->GetNextPtr();
}/*
while(true)*/
APR_HeadLink = mp_NoUseHead ;
APR_TailLink = mp_NoUseTail ;
mp_NoUseHead =0 ;
mp_NoUseTail =0 ;
ml_UseSize =0 ;
}
else if(AL_NeedCnt<ml_UseSize)
{
APR_HeadLink = mp_NoUseHead;
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**mp_NoUseHead, *this);
for(TypeSize VL_Count=2; VL_Count<=AL_NeedCnt; ++VL_Count)
{
// VL_Count 가 2 부터 시작함으로 AL_NeedCnt-1 번 순환한다.
// 그래야지 AL_NeedCnt 개의 링크를 자를 수 있다.
mp_NoUseHead = mp_NoUseHead->GetNextPtr();
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**mp_NoUseHead, *this);
}/*
for(TypeSize VL_Count=2; VL_Count<=AL_NeedCnt; ++VL_Count)*/
APR_TailLink = mp_NoUseHead ;
mp_NoUseHead = mp_NoUseHead->GetNextPtr();
ml_UseSize -= AL_NeedCnt ;
}
else // AL_NeedCnt > ml_UseSize
{
ZCLink* VP_Temp=mp_NoUseHead;
while(true)
{
if(VP_Temp==mp_NoUseTail)
{ break; }
VP_Temp=VP_Temp->GetNexPtr() ;
}/*
while(true)*/
APR_HeadLink = mp_NoUseHead;
// MakeLink() 에서 TypeInit::OnInit() 가 호출됨.
MakeLink ///////////////////////////////////////
(
AL_NeedCnt - ml_UseSize ,
RR(mp_NoUseTail->mp_NextLink) ,
RR(APR_TailLink)
);
////////////////////////////////////////////////
mp_NoUseHead= 0 ;
mp_NoUseTail= 0 ;
ml_UseSize = 0 ;
}/*
else // AL_NeedCnt > ml_UseSize*/
}/*
_NP_ void SendFreeOut ###################################################
(
TypeSize AL_NeedCnt, ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink
)
########################################################################*/
_NP_ 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
)
///////////////////////////////////////////////////*/
_NP_ void MakeLink /////////////////////////////////
(
TypeSize AL_MakeSize ,
ZCLink*& APR_HeadLink,
ZCLink*& APR_TailLink
)
///////////////////////////////////////////////////*/
{
APR_HeadLink = new ZCLink;
if(APR_HeadLink==0)
{
//add codes for memory over
DeleteHeap(); return;
}/*
if(APR_HeadLink==0)*/
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**APR_HeadLink, *this);
ml_AllSize += AL_MakeSize;
ZCLink* VP_MakeLink = 0 ;
ZCLink* VP_TempLink = APR_HeadLink;
bool VB_IsHeapOver= false ;
// bool VB_IsHeapOver 은 new 연산자가 NULL 포인터를 반환했을 때
// true 를 대입받는다. 이 값을 조사함으로써 heap overflow 를 처리한다.
// bool VB_IsHeapOver 변수를 두지 않고
// 아래 for 문에서 직접 메모리 처리를 하는 코드를 둘 수 있으나
// for 문 안에 if 문 속에서 또 for 문을 써야 함으로
// 가독성이 떨어질 수가 있다.
// 그래서 heap over 에 대한 예외처리 코드를
// for 문 바깥으로 빼려는 것이다.
while(--AL_MakeSize>0) // AL_MakeSize - 1 번 순환
{
// AL_MakeSize - 1 번 순환
VP_MakeLink = new ZCLink;
if(VP_MakeLink==0)
{
ml_AllSize -= AL_MakeSize+1 ;
VB_IsHeapOver = true ;
break;
}/*
if(VP_MakeLink==0)*/
if(TypeInit::ZEUseInit>0)
TypeInit::OnInit(**VP_MakeLink, *this);
ZCLink::JoinLink
(VP_TempLink, VP_MakeLink);
VP_TempLink = VP_MakeLink ;
}/*
while(--AL_MakeSize>0)*/
APR_TailLink = VP_TempLink;
// 메모리를 더 이상 할당할 수 없었다면
// 이미 만들어진 VL_Count 개의 비원형 이중 링크를 지운다.
if(VB_IsHeapOver==true)
{
VP_TempLink=APR_HeadLink;
// 이 시점에서 최소한 APR_HeadLink 하나는
// heap 에 생성되어 있다.
do //////
{
delete VP_TempLink;
if(VP_TempLink==APR_TailLink)
{
DeleteHeap();
// Add extra codes for memory over
return;
}/*
if(VP_TempLink==APR_TailLink)*/
APR_HeadLink=APR_HeadLink->GetNextPtr();
}
while(true);
}/*
if(VB_IsHeapOver==true)*/
}/*
_NP_ void MakeLink //////////////////////////////////
(
TypeSize AL_MakeSize ,
ZCLink*& APR_HeadLink,
ZCLink*& APR_TailLink
)
///////////////////////////////////////////////////*/
_NP_ void MakeLinkCopy //////////////////////////////
(
ZCLink* AP_LinkOrgin, TypeSize AL_FarNum ,
ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy
)
///////////////////////////////////////////////////*/
{
// AP_LinkOrgin 링크부터,
// AP_LinkOrgin 에서 AL_FarNum 만큼 떨어진 링크까지를 복사하여
// 복사생성된 처음 링크 포인터를 APR_HeadCopy 에,
// 마지막 링크를 APR_TailCopy 에 대입한다.
// AL_FarNum > 0 , 총 AL_FarNum + 1 개의 링크가 만들어진다.
ZCLink* VP_MakeLink = 0 ;
ZCLink* VP_TailLink = 0 ;
bool VB_IsHeapOver= false;
VP_TailLink = VP_MakeLink =
new ZCLink(**AP_LinkOrgin) ;
ml_AllSize += AL_FarNum+1 ;
if(VP_MakeLink==0)
{
//add codes for memory over
ml_AllSize -= AL_FarNum+1;
DeleteHeap(); return ;
}/*
if(VP_MakeLink==0)*/
APR_HeadCopy = VP_MakeLink;
while(--AL_FarNum >= 0)
{
AP_LinkOrgin= AP_LinkOrgin->GetNextPtr() ;
VP_MakeLink = new ZCLink(**AP_LinkOrgin) ;
if(VP_MakeLink==0)
{
ml_AllSize -= AL_FarNum+1 ;
APR_TailCopy = VP_TailLink ;
VB_IsHeapOver= true ;
break;
}/*
if(VP_MakeLink==0)*/
ZCLink::JoinLink
(VP_TailLink, VP_MakeLink);
VP_TailLink = VP_MakeLink;
}/*
while(--AL_FarNum >= 0)*/
APR_TailCopy=VP_TailLink;
// 메모리를 더 이상 할당할 수 없었다면
// 이미 만들어진 비원형 이중 링크를 지운다.
if(VB_IsHeapOver==true)
{
do //////
{
delete APR_HeadCopy;
if(APR_HeadCopy==APR_TailCopy)
{
DeleteHeap(); return;
}/*
if(APR_HeadCopy==APR_TailCopy)*/
APR_HeadCopy = APR_HeadCopy->mp_NextLink;
}
while(true);
}/*
if(VB_IsHeapOver==true)*/
}/*
_NP_ void MakeLinkCopy //////////////////////////////
(
ZCLink* AP_LinkOrgin, TypeSize AL_FarNum,
ZCLink*& APR_HeadCopy, ZCLink*& APR_TailCopy
)
///////////////////////////////////////////////////*/
_NP_ 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);
}/*
_NP_ void RecvFreeIn(ZCLink* AP_Link)*/
_NP_ 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 ;
}/*
_NP_ void RecvFreeIn //////////////////////////////////////////////
(
TypeSize AL_Count, ZCLink* AP_HeadLink, ZCLink* AP_TailLink
)
/////////////////////////////////////////////////////////////////*/
//public :
public :
ZtCBody()
{
ml_AllSize =
ml_UseSize = 0 ;
mp_NoUseHead =
mp_NoUseTail = 0 ;
}/*
ZtCBody()*/
~ZtCBody()
{
DeleteHeap();
}/*
~ZtCBody()*/
void DeleteHeap()
{
if(ml_UseSize<1) return ;
ZCLink* VP_DelLink = mp_NoUseHead;
do /*+++++++++++++++++++++++++++*/
{
mp_NoUseHead =
mp_NoUseHead->GetNextPtr() ;
delete VP_DelLink;
VP_DelLink = mp_NoUseHead ;
}
while(--ml_UseSize>0); /*+++++++*/
ml_AllSize -= ml_UseSize;
ml_UseSize = 0 ;
mp_NoUseHead =
mp_NoUseTail = 0 ;
}/*
void DeleteHeap()*/
TypeSize GetUseHeapSize() const
{
return ml_UseSize;
}/*
TypeSize GetUseHeapSize() const*/
TypeSize GetAllHeapSize() const
{
return ml_AllSize;
}/*
TypeSize GetAllHeapSize() const*/
TypeSize size() const
{
return ml_UseSize;
}/*
TypeSize size() const*/
TypeSize capacity() const
{
return ml_AllSize;
}/*
TypeSize capacity() const*/
public:
};/*
template<typename TSimList> class ZtCBody*/
public:
};/*
template<> class ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single >*/
}/*
namespace ZNsIFaceEx*/
template<typename TypeObjList> class ZtCSortObjList;
template /*##################################################################*/
<
typename TType
, typename TTypArgu = const TType&
, typename TTypCAlloc= ZCAllocator
, typename TTypCInit = ZtCInit<TType>
, typename TTypSize = ZTypLong
, typename TMoveObj = ZNsMain::
ZtCMoveObj<TType, TTypArgu, true>
, typename TFeeeHeap = ZNsIFaceEx::
ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single >
>
class ZtCSimList /*##########################################################*/
{
public:
typedef TType Type ;
typedef TType TypeData ;
typedef TTypArgu TypeArg ;
typedef TTypCAlloc TypeAlloc ;
typedef TTypCInit TypeInit ;
typedef TTypSize TypeSize ;
typedef TMoveObj TypeMoveObj;
public:
typedef typename TFeeeHeap::
template ZtCBody<ZtCSimList> ZCFreeHeap;
public:
class ZCLink : public TypeAlloc
{
public:
template<typename TypeObjList>
friend class ZtCSortObjList; /////////////
template<int>
friend class ZNsIFaceEx::ZtCFreeHeapSngl ;
public:
friend class ZtCSimList ;
private:
ZCLink* mp_NextLink;
TType mo_Data ;
private:
inline static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink)
{
// 두 개의 링크를 연결 상태로 만든다.
AP_PrevLink->mp_NextLink=AP_NextLink;
}/*
inline static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink)*/
inline static void MakeCircle(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)
{
// 처음과 끝 링크를 연결하여 원형상태로 만든다.
// 이것은 ZtCSimList class template 과 멤버 함수를 맞추기 위한 것으로
// 실제적으로는 별 쓸모는 없는 것 같다.
AP_TailLink->mp_NextLink=AP_HeadLink;
}/*
inline static void MakeCircle(ZCLink* AP_HeadLink, ZCLink* AP_TailLink)*/
//private:
public :
ZCLink():mp_NextLink(0)
{
}/*
ZCLink()*/
ZCLink(const ZCLink& rhs):mp_NextLink(0)
{
// TType 의 대입연산자는 반드시 public 영역에 있어야 한다.
mo_Data=rhs.mo_Data;
}/*
ZCLink(const ZCLink& rhs)*/
ZCLink(TypeArg AR_Type):mp_NextLink(0)
{
mo_Data=AR_Type;
}/*
ZCLink(TypeArg AR_Type)*/
operator TType&()
{
return mo_Data;
}/*
operator TType&()*/
operator TType()
{
return mo_Data;
}/*
operator TType()*/
TType& GetData()
{
return mo_Data;
}/*
TType& GetData()*/
const TType& GetData() const
{
return mo_Data;
}/*
const TType& GetData() const*/
TType& GetData(TTypSize AL_FarNum) // must AL_FarNum >= 0
{
return GetNextPtr(AL_FarNum)->mo_Data;
}/*
TType& GetData(TTypSize AL_FarNum)*/
const TType& GetData(TTypSize AL_FarNum) const
{
return GetNextPtr(AL_FarNum)->mo_Data;
}/*
const TType& GetData(TTypSize AL_FarNum) const*/
TType& operator*()
{
return mo_Data;
}/*
TType& operator*()*/
const TType& operator*() const
{
return mo_Data;
}/*
const TType& operator*() const*/
ZCLink* GetNextPtr(TTypSize AL_FarNum) // must AL_FarNum > 0
{
// 이 멤버 함수는 TTypSize 가 용랑이 큰 object 라 할지라도
// 이 함수 내부에서 값이 변하고 있으므로 참조로 받지 않는다.
ZCLink* VP_TmpLink=this;
while(--AL_FarNum>=0)
VP_TmpLink=VP_TmpLink->mp_NextLink;
/*:::::::::::::::::*/
return VP_TmpLink;
}/*
ZCLink* GetNextPtr(TTypSize AL_FarNum)*/
const ZCLink* const GetNextPtr(TTypSize AL_FarNum) const // or ZCLink const * const GetNextPtr(TTypSize AL_FarNum) const
{
// TTypSize 가 object 일 경우 AL_FarNum 의 값이 이 함수에서 변하고 있으므로
// TTypSize 을 참조로 받으면 안된다.
ZCLink* VP_TmpLink = const_cast<ZCLink*>(this);
// 이 함수는 뒤에 const keyword 가 붙어 있는데 이것 때문에 this pointer 는 상수 포인터로 간주된다.
// 윗줄에서 이 this 포인터를 비상수 포인터로 먼저 형변환하였다.
// ZCLink* VP_TmpLink=const_cast<ZCLink*>this; 라 하면 g++ 2.96 에서는 에러
while(--AL_FarNum>=0)
VP_TmpLink=VP_TmpLink->mp_NextLink;
/*:::::::::::::::::*/
return VP_TmpLink;
}/*
const ZCLink* const GetNextPtr(TTypSize AL_FarNum) const*/
inline ZCLink* GetNextPtr()
{
return mp_NextLink;
}/*
inline ZCLink* GetNextPtr()*/
inline const ZCLink* const GetNextPtr() const
{
return mp_NextLink;
}/*
inline const ZCLink* const GetNextPtr() const*/
ZCLink& operator=(TypeArg AR_Type)
{
mo_Data=AR_Type; return *this;
}/*
ZCLink& operator=(TypeArg AR_Type)*/
ZCLink* operator+(TypeSize AL_Offset)
{
ZCLink* VP_CLinkLoop=this;
__for0(TTypSize, i, AL_Offset)
{
VP_CLinkLoop = VP_CLinkLoop->mp_NextLink;
}/*
__for0(TTypSize, i, AL_Offset)*/
return *this;
}/*
ZCLink* operator+(TypeSize AL_Offset)
public:*/
};/*
class ZCLink*/
//////////////////////////////////////////////////
/*************** end class ZCLink ***************/
//////////////////////////////////////////////////
//public :
protected:
TTypSize ml_Size ;
ZCLink* mp_HeadLink ;
ZCLink* mp_TailLink ;
ZCFreeHeap mo_FreeObjt ;
///////////////////////////////////////////////////////////////
ZtCSimList& CopyLink /*######################################*/
(
const ZCLink* const AP_CopyLink ,
TTypSize AL_FarNum ,
ZtCSimList& ARR_StoreList
) const
/*###########################################################*/
{
// AP_CopyLink 부터 AP_CopyLink->GetNextPrePtr(AL_FarNum)
// 링크까지를 복사한다. 총 AL_FarNum + 1 개의 링크가 만들어 진다.
ZCLink* VP_HeadLink=0;
ZCLink* VP_TailLink=0;
GetCFreeHeap().SendFreeOutCopy
(
const_cast<ZCLink*>(AP_CopyLink), // g++ 에서는 반드시 AP_CopyLink 부분을 () 로 묶어 줄 것.
AL_FarNum ,
VP_HeadLink ,
VP_TailLink
);
//////////////////////////////
VP_TailLink->mp_NextLink=0;
ARR_StoreList.mp_HeadLink= VP_HeadLink ;
ARR_StoreList.mp_TailLink= VP_TailLink ;
ARR_StoreList.ml_Size = AL_FarNum+1 ;
return ARR_StoreList;
}/*
ZtCSimList& CopyLink ##########################################
(
const ZCLink* const AP_CopyLink ,
TTypSize AL_FarNum ,
ZtCSimList& ARR_StoreList
) const
#############################################################*/
ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)
{
// ZCLink* AP_PrevLink : 삭제하려는 링크의 이전 링크
// ZCLink* AP_CutLink : 삭제하려는 링크
if(AP_CutLink==mp_HeadLink)
{
if(mp_HeadLink==mp_TailLink)
{
mp_HeadLink=0;
mp_TailLink=0;
}
else
{
mp_HeadLink=mp_HeadLink->mp_NextLink;
}
//else
}
else if(AP_CutLink==mp_TailLink)
{
AP_PrevLink->mp_NextLink=0;
}
else
{
AP_PrevLink->mp_NextLink=AP_CutLink->mp_NextLink;
}
//else
return (--ml_Size, AP_CutLink);
}/*
ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)*/
ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize AL_CutPos)
{
if(AP_CutLink==mp_HeadLink)
{
if(mp_HeadLink==mp_TailLink)
{
mp_HeadLink=0;
mp_TailLink=0;
}
else
{
mp_HeadLink=mp_HeadLink->mp_NextLink;
}
//else
}
else if(AP_CutLink==mp_TailLink)
{
AP_PrevLink->mp_NextLink=0;
}
else
{
AP_PrevLink->mp_NextLink=AP_CutLink->mp_NextLink;
}
//else
return (--ml_Size, AP_CutLink);
}
//ZCLink* CutLink(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize AL_CutPos)
ZtCSimList& CutLink /*###############################*/
(
ZCLink* AP_CutHeadPrev,
ZCLink* AP_CutHead , TTypSize AL_CutHeadPos,
ZCLink* AP_CutTail , TTypSize AL_CutTailPos,
ZtCSimList& ARR_StoreList
)
/*###################################################*/
{
// AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크, AL_CutHeadPos 는 그 위치 ,AP_CutHeadPrev 는 그 이전 링크
// AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크, AL_CutTailPos 는 그 위치
// AP_CutTail 의 이전 링크도 대입받아야 짝아 맞을 것 같지만 안그래도 된다.
if(AP_CutHead==mp_HeadLink)
{
if(AP_CutTail==mp_TailLink)
{
// 모든 링크를 삭제할 때.
mp_HeadLink=0;
mp_TailLink=0;
}
else
{
mp_HeadLink=AP_CutTail->mp_NextLink;
}
}
else if(AP_CutTail==mp_TailLink) // 잘라내려는 링크가 끝 링크를 포함할 때.
{
mp_TailLink= AP_CutHeadPrev ;
mp_TailLink->mp_NextLink= 0 ;
}
else // 잘라내려는 링크가 처음과 끝 링크를 포함하지 않을 때.
{
AP_CutHeadPrev->mp_NextLink=AP_CutTail->mp_NextLink;
}
//else
ml_Size -= AL_CutTailPos-AL_CutHeadPos+1 ;
#ifdef _DEBUG
if(ARR_StoreList.IsEmpty()!=true)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZtCSimList& CutLink( ZCLink* AP_CutHead, TTypSize AL_CutHeadPos,"<<std::endl;
fileout<<" ZCLink* AP_CutTail, TTypSize AL_CutTailPos" <<std::endl;
fileout<<" /**************************/ )" <<std::endl;
fileout<<"Static Object ARR_StoreList is not empty"<<std::endl;
fileout.close();
exit(1);
}
//if(ARR_StoreList.IsEmpty()!=true)
#endif //_DEBUG
ARR_StoreList.mp_HeadLink=AP_CutHead;
ARR_StoreList.mp_TailLink=AP_CutTail;
ARR_StoreList.ml_Size =AL_CutTailPos-AL_CutHeadPos+1;
return ARR_StoreList;
}/*
ZtCSimList& CutLink ///////////////////////////////
(
ZCLink* AP_CutHeadPrev,
ZCLink* AP_CutHead, TTypSize AL_CutHeadPos,
ZCLink* AP_CutTail, TTypSize AL_CutTailPos,
ZtCSimList& ARR_StoreList
)
/////////////////////////////////////////////////*/
ZtCSimList& MakeDefault(TTypSize AL_DefaultSize, ZtCSimList& ARR_StoreList) const
{
// must AL_DefaultSize > 0
ZCLink* VP_HeadLink=0;
ZCLink* VP_TailLink=0;
GetCFreeHeap().SendFreeOut
(AL_DefaultSize, VP_HeadLink, VP_TailLink);
ZCLink::MakeCircle( VP_HeadLink, VP_TailLink );
ARR_StoreList.mp_HeadLink= VP_HeadLink ;
ARR_StoreList.mp_TailLink= VP_TailLink ;
ARR_StoreList.ml_Size = AL_DefaultSize ;
return ARR_StoreList;
}/*
ZtCSimList& MakeDefault(TTypSize AL_DefaultSize, ZtCSimList& ARR_StoreList) const
protected: */
public :
ZtCSimList()
{
ml_Size =0;
mp_HeadLink=0;
mp_TailLink=0;
}/*
ZtCSimList()*/
ZtCSimList(TypeArg AR_Type)
{
ml_Size =0;
mp_HeadLink=0;
mp_TailLink=0;
AddTail(AR_Type);
}/*
ZtCSimList(TypeArg AR_Type)*/
ZtCSimList(const ZtCSimList& rhs)
{
ml_Size =0;
mp_HeadLink=0;
mp_TailLink=0;
ZtCSimList VO_StoreList;
JoinHead( CopyLink(rhs.mp_HeadLink, rhs.ml_Size-1 ,VO_StoreList) );
}/*
ZtCSimList(const ZtCSimList& rhs)*/
ZtCSimList& operator=(const ZtCSimList& rhs)
{
if(&rhs ==this){return *this;}
{ DeleteAll(); }
if(rhs.ml_Size==0 ){return *this;}
ZtCSimList VO_StoreList;
JoinHead ///////////////////////////
(
CopyLink(rhs.mp_HeadLink, rhs.ml_Size-1 ,VO_StoreList)
);
return *this; //////////////////////
}/*
ZtCSimList& operator=(const ZtCSimList& rhs)*/
virtual ~ZtCSimList()
{
DeleteAll(); GetCFreeHeap().DeleteHeap();
}/*
virtual ~ZtCSimList()*/
ZtCSimList& operator()(TypeArg AR_Type)
{
AddTail(AR_Type); return *this;
}/*
ZtCSimList& operator()(TypeArg AR_Type)*/
TType& operator[](TTypSize AL_Index)
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN TType& ZtCSimList::TType& operator[](TTypSize AL_Index)"<<std::endl;
fileout<<" Parameter is Bad AL_Index"<<std::endl;
fileout.close();
exit(1);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AL_Index)->mo_Data;
}/*
TType& operator[](TTypSize AL_Index)*/
const TType& operator[](TTypSize AL_Index) const
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN const TType& ZtCSimList::TType& operator[](TTypSize AL_Index) const"<<std::endl;
fileout<<" Parameter is Bad AL_Index"<<std::endl;
fileout.close();
exit(1);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AL_Index)->mo_Data;
}
//const TType& operator[](TTypSize AL_Index) const
operator TType&(){return AddTailDefault()->mo_Data;}
TType& operator()()
{
return AddTailDefault()->mo_Data;
}/*
TType& operator()()*/
void AddHead(TypeArg AR_Type)
{
ZCLink* VP_AddLink = GetCFreeHeap().SendFreeOut() ;
#if(_CODE_NEW_)
if(TypeMoveObj::ZEUseMoveObj>0) ////////////////////
{
TypeMoveObj::Exec(VP_AddLink->mo_Data, AR_Type);
}
else ///////////////////////////////////////////////
#endif
VP_AddLink->mo_Data= AR_Type ;
if(++ml_Size==1) // ml_Size==0
{
mp_HeadLink =
mp_TailLink = VP_AddLink ;
}
else
{
VP_AddLink->mp_NextLink =mp_HeadLink;
mp_HeadLink=VP_AddLink;
}/*
else*/
}/*
void AddHead(TypeArg AR_Type)*/
ZCLink* AddHeadDefault()
{
ZCLink* VP_AddLink=GetCFreeHeap().SendFreeOut();
if(++ml_Size==1) // ml_Size==0
{
mp_HeadLink =
mp_TailLink = VP_AddLink ;
}
else
{
VP_AddLink->mp_NextLink =mp_HeadLink;
mp_HeadLink=VP_AddLink;
}
//else
}/*
ZCLink* AddHeadDefault()*/
void AddTail(TypeArg AR_Type)
{
ZCLink* VP_AddLink = GetCFreeHeap().SendFreeOut();
#if(_CODE_NEW_)
if(TypeMoveObj::ZEUseMoveObj>0) ////////////////////
{
TypeMoveObj::Exec(VP_AddLink->mo_Data, AR_Type);
}
else ///////////////////////////////////////////////
#endif
VP_AddLink->mo_Data= AR_Type ;
if(++ml_Size==1) // ml_Size==0
{
mp_HeadLink =
mp_TailLink = VP_AddLink ;
}
else
{
mp_TailLink->mp_NextLink=VP_AddLink ;
mp_TailLink=mp_TailLink->mp_NextLink;
}/*
else*/
}/*
void AddTail(TypeArg AR_Type)*/
ZCLink* AddTailDefault()
{
ZCLink* VP_AddLink = GetCFreeHeap().SendFreeOut();
if(++ml_Size==1) // ml_Size==0
{
mp_HeadLink =
mp_TailLink = VP_AddLink ;
}
else
{
mp_TailLink->mp_NextLink = VP_AddLink ;
mp_TailLink=mp_TailLink->mp_NextLink;
}/*
else*/
}/*
ZCLink* AddTailDefault()*/
void AddHeadDefault(TTypSize AL_DefaultSize)
{
if(AL_DefaultSize<1) return;
ZtCSimList VO_StoreList; JoinHead
(
MakeDefault(AL_DefaultSize ,VO_StoreList)
);
//////////////////////////////////
}/*
void AddHeadDefault(TTypSize AL_DefaultSize)*/
void AddTailDefault(TTypSize AL_DefaultSize)
{
if(AL_DefaultSize<1) return;
ZtCSimList VO_StoreList; JoinTail
(
MakeDefault(AL_DefaultSize ,VO_StoreList)
);
//////////////////////////////////
}/*
void AddTailDefault(TTypSize AL_DefaultSize)*/
ZCLink* GetHeadLinkPtr (){return mp_HeadLink;}
ZCLink* GetHeadIterEasy (){return mp_HeadLink;}
IterEasyID GetHeadIterEasyID(){return (IterEasyID)mp_HeadLink;}
ZCLink* GetTailLinkPtr (){return mp_TailLink;}
ZCLink* GetTailIterEasy (){return mp_TailLink;}
IterEasyID GetTailIterEasyID(){return (IterEasyID)mp_TailLink;}
TType& front(){return mp_HeadLink->mo_Data;}
TType& back (){return mp_TailLink->mo_Data;}
const ZCLink* GetHeadLinkPtr () const{return mp_HeadLink;}
const ZCLink* GetHeadIterEasy () const{return mp_HeadLink;}
const IterEasyID GetHeadIterEasyID() const{return (IterEasyID)mp_HeadLink;}
const ZCLink* GetTailLinkPtr () const{return mp_TailLink;}
const ZCLink* GetTailIterEasy () const{return mp_TailLink;}
const IterEasyID GetTailIterEasyID() const{return (IterEasyID)mp_TailLink;}
const TType& front() const{return mp_HeadLink->mo_Data;}
const TType& back () const{return mp_TailLink->mo_Data;}
void pop_back(TypeArg AR_Type)
{
return AddHead(AR_Type);
}/*
void pop_back(TypeArg AR_Type)*/
void push_back(TypeArg AR_Type)
{
return AddTail(AR_Type);
}/*
void push_back(TypeArg AR_Type)*/
TType& GetHeadData()
{
#ifdef _DEBUG
if(mp_HeadLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN TType& ZtCSimList::GetHeadData()"<<std::endl;
fileout<<" mp_HeadLink Pointer is NULL"<<std::endl;
fileout.close();
exit(1);
}/*
if(mp_HeadLink==0)*/
#endif //_DEBUG
return mp_HeadLink->mo_Data;
}/*
TType& GetHeadData()*/
const TType& GetHeadData() const
{
#ifdef _DEBUG
if(mp_HeadLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN const TType& ZtCSimList::GetHeadData() const"<<std::endl;
fileout<<" mp_HeadLink Pointer is NULL"<<std::endl;
fileout.close();
exit(1);
}/*
if(mp_HeadLink==0)*/
#endif //_DEBUG
return mp_HeadLink->mo_Data;
}/*
const TType& GetHeadData() const*/
TType& GetTailData()
{
#ifdef _DEBUG
if(mp_TailLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN const TType& ZtCSimList::GetTailData() const"<<std::endl;
fileout<<" mp_TailLink Pointer is NULL"<<std::endl;
fileout.close();
exit(1);
}/*
if(mp_TailLink==0)*/
#endif //_DEBUG
return mp_TailLink->mo_Data ;
}/*
TType& GetTailData()*/
const TType& GetTailData() const
{
#ifdef _DEBUG
if(mp_TailLink==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN const TType& ZtCSimList::GetTailData() const"<<std::endl;
fileout<<" mp_TailLink Pointer is NULL"<<std::endl;
fileout.close();
exit(1);
}/*
if(mp_TailLink==0)*/
#endif //_DEBUG
return mp_TailLink->mo_Data ;
}/*
const TType& GetTailData() const*/
TType& GetData(TTypSize AL_Index)
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN TType& ZtCSimList::GetData(TTypSize AL_Index)"<<std::endl;
fileout<<" Parameter is Bad AL_Index"<<std::endl;
fileout.close();
exit(1);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AL_Index)->mo_Data;
}/*
TType& GetData(TTypSize AL_Index)*/
TType GetData(TTypSize AL_Index) const
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error IN TType& ZtCSimList::GetData(TTypSize AL_Index)"<<std::endl;
fileout<<" Parameter is Bad AL_Index"<<std::endl;
fileout.close();
exit(1);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return GetLinkPtr(AL_Index)->mo_Data;
}/*
TType GetData(TTypSize AL_Index) const*/
void JoinHead(ZCLink* AP_Link)
{
#ifdef _DEBUG
if(AP_Link==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'void JoinHead(ZCLink* AP_Link)' : Parameter is null pointer"<<std::endl;
fileout.close();
exit(1);
}
else if(Find(AP_Link)!=0) // AP_Link 가 this 가 가리키는 연결리스트에 존재하는 링크인가.
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<"Error In 'void JoinHead(ZCLink* AP_Link)' : The list that parameter link belongs to is now list"<<std::endl;
fileout.close();
exit(1);
}/*
else if(Find(AP_Link)!=0)*/
#endif //_DEBUG
if(mp_HeadLink==0)
{
mp_HeadLink =
mp_TailLink = AP_Link ;
ml_Size = 1 ;
AP_Link->mp_NextLink=0;
return;
}/*
if(mp_HeadLink==0)*/
AP_Link->mp_NextLink= mp_HeadLink ;
mp_HeadLink = AP_Link ;
++ml_Size;
}/*
void JoinHead(ZCLink* AP_Link)*/
void JoinTail(ZCLink* AP_Link)
{
#ifdef _DEBUG
if(AP_Link==0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'void JoinTail(ZCLink* AP_Link)' : Parameter is null pointer"<<std::endl;
fileout.close();
exit(1);
}
else if(Find(AP_Link)!=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 'void JoinTail(ZCLink* AP_Link)' : The list that parameter link belongs to is now list"<<std::endl;
fileout.close();
exit(1);
}/*
else if(Find(AP_Link)!=0)*/
#endif //_DEBUG
AP_Link->mp_NextLink=0;
if(mp_HeadLink==0)
{
mp_HeadLink =
mp_TailLink = AP_Link ;
}
else
{
mp_TailLink->mp_NextLink=AP_Link;
mp_TailLink =AP_Link;
}/*
else*/
++ml_Size;
}/*
void JoinTail(ZCLink* AP_Link)*/
void JoinHead(ZtCSimList& rhs)
{
if(this==&rhs || rhs.mp_HeadLink==0)
{return;}
/*++++++++++++++++++++++++++++++++*/
if(mp_HeadLink==0)
{
mp_HeadLink=rhs.mp_HeadLink;
mp_TailLink=rhs.mp_TailLink;
ml_Size =rhs.ml_Size ;
}
else
{
rhs.mp_TailLink->mp_NextLink=mp_HeadLink;
mp_HeadLink= rhs.mp_HeadLink ;
ml_Size += rhs.ml_Size ;
}/*
else*/
rhs.mp_HeadLink=0;
rhs.mp_TailLink=0;
rhs.ml_Size =0;
}/*
void JoinHead(ZtCSimList& rhs)*/
void JoinTail(ZtCSimList& rhs)
{
if(this==&rhs || rhs.mp_HeadLink==0)
{ return; }
/*++++++++++++++++++++++++++++++++*/
if(mp_HeadLink==0)
{
mp_HeadLink=rhs.mp_HeadLink;
mp_TailLink=rhs.mp_TailLink;
ml_Size =rhs.ml_Size ;
}
else
{
mp_TailLink->mp_NextLink=rhs.mp_HeadLink;
mp_TailLink =rhs.mp_TailLink;
ml_Size += rhs.ml_Size;
}/*
else*/
rhs.mp_HeadLink=0;
rhs.mp_TailLink=0;
rhs.ml_Size =0;
}/*
void JoinTail(ZtCSimList& rhs)*/
void DeleteHead()
{
if(ml_Size==0) return;
ZCLink* VP_DelLink= mp_HeadLink ;
mp_HeadLink = mp_HeadLink->mp_NextLink;
GetCFreeHeap().RecvFreeIn(VP_DelLink);
if(--ml_Size==0)
{
mp_HeadLink =
mp_TailLink = 0 ;
}/*
if(--ml_Size==0)*/
}/*
void DeleteHead()*/
void DeleteHead(TTypSize AL_DelSize)
{
// AL_DelSize 개의 링크를 앞 부분에서 삭제
if(AL_DelSize < 1 ) AL_DelSize= 1 ;
if(AL_DelSize > ml_Size) AL_DelSize= ml_Size;
ZCLink* VP_CutTail =
mp_HeadLink->GetNextPtr(AL_DelSize-1);
ZtCSimList VO_StoreList; CutLink /////////////
(
0, mp_HeadLink
, 1, VP_CutTail
, AL_DelSize
, VO_StoreList
)
.DeleteAll();
////////////////////////////////////////////////
}/*
void DeleteHead(TTypSize AL_DelSize)*/
void DeleteTail()
{
if(ml_Size==0){return;}
ZCLink* VP_CutLink = mp_TailLink;
if(--ml_Size==0)
{
mp_HeadLink =
mp_TailLink = 0 ;
return;
}/*
if(--ml_Size==0)*/
mp_TailLink =
mp_HeadLink->GetNextPtr(ml_Size-1);
mp_TailLink->mp_NextLink=0 ;
GetCFreeHeap().RecvFreeIn(VP_CutLink);
}/*
void DeleteTail()*/
void DeleteTail(TTypSize AL_DelSize)
{
if(ml_Size==0){return;}
if(AL_DelSize> ml_Size){ AL_DelSize=ml_Size; }
if(AL_DelSize< 1 ){ AL_DelSize=1 ; }
if(AL_DelSize==ml_Size)
{
GetCFreeHeap().RecvFreeIn
(ml_Size, mp_HeadLink, mp_TailLink);
mp_HeadLink=0 ;
mp_TailLink=0 ;
ml_Size =0 ;
return;
}/*
if(AL_DelSize==ml_Size)*/
ZCLink* VP_NewTail= mp_HeadLink->
GetNextPtr( ml_Size-AL_DelSize-1 );
GetCFreeHeap().RecvFreeIn
(AL_DelSize, VP_NewTail->mp_NextLink, mp_TailLink);
mp_TailLink = VP_NewTail ;
mp_TailLink-> mp_NextLink=0 ;
ml_Size -= AL_DelSize ;
}/*
void DeleteTail(TTypSize AL_DelSize)*/
void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)
{
#ifdef _DEBUG
if ( Find(AP_CutLink)==0 ||
Find(AP_CutLink)!=Find(AP_PrevLink)+1
)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)' : Parameter is Bad Pointer"<<std::endl;
fileout.close();
exit(1);
}
#endif //_DEBUG
GetCFreeHeap().RecvFreeIn
( CutLink(AP_PrevLink, AP_CutLink) );
}/*
void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink)*/
void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize AL_CutPos)
{
#ifdef _DEBUG
if ( ml_Size==0 ||
Find(AP_CutLink) !=AL_CutPos ||
Find(AP_PrevLink)!=(AL_CutPos-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 'void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize AL_CutPos)' : Parameter is Bad Pointer or Bad AL_Index"<<std::endl;
fileout.close();
exit(1);
}
#endif //_DEBUG
GetCFreeHeap().RecvFreeIn
( CutLink(AP_PrevLink, AP_CutLink, AL_CutPos) );
}/*
void Delete(ZCLink* AP_PrevLink, ZCLink* AP_CutLink, TTypSize AL_CutPos)*/
void Delete /*###################################*/
(
ZCLink* AP_CutHeadPrev,
ZCLink* AP_CutHead, TTypSize AL_CutHeadPos,
ZCLink* AP_CutTail, TTypSize AL_CutTailPos
)
/*###############################################*/
{
#ifdef _DEBUG
if ( ml_Size==0 ||
AL_CutHeadPos>AL_CutTailPos ||
Find(AP_CutHead)!=AL_CutHeadPos ||
Find(AP_CutTail)!=AL_CutTailPos ||
(AL_CutHeadPos!=1 && AP_CutHeadPrev->mp_NextLink!=AP_CutHead)
)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'void Delete(ZCLink* AP_CutHeadPrev,ZCLink* AP_CutHead,TTypSize AL_CutHeadPos,ZCLink* AP_CutTail,TTypSize AL_CutTailPos)' : Parameter is Bad Pointer or Bad AL_Index"<<std::endl;
fileout.close();
exit(1);
}
/*////////////////////////////////////////////////////////////////*/
#endif //_DEBUG
ZtCSimList VO_StoreList;
CutLink /*==========================================*/
(
AP_CutHeadPrev, AP_CutHead , AL_CutHeadPos,
AP_CutTail , AL_CutTailPos , VO_StoreList
).
DeleteAll() ;
/*==================================================*/
}/*
void Delete ///////////////////////////////////////
(
ZCLink* AP_CutHeadPrev,
ZCLink* AP_CutHead, TTypSize AL_CutHeadPos,
ZCLink* AP_CutTail, TTypSize AL_CutTailPos
)
/////////////////////////////////////////////////*/
void DeleteAll()
{
if(ml_Size==0) {return;}
GetCFreeHeap().RecvFreeIn
(ml_Size, mp_HeadLink, mp_TailLink);
mp_HeadLink =
mp_TailLink =0;
ml_Size =0;
}/*
void DeleteAll()*/
void DeleteHeap()
{
GetCFreeHeap().DeleteHeap();
}/*
void DeleteHeap()*/
TTypSize Find(const ZCLink* AP_pSearchLink, TTypSize AL_FirstFindIndex=1) const
{
const bool CB_DoStop = ////////////
(
mp_HeadLink ==0 ||
AL_FirstFindIndex < 1 ||
AL_FirstFindIndex > ml_Size
);
if(CB_DoStop) {return 0;} /////////
TTypSize VL_FindIndex = AL_FirstFindIndex ;
ZCLink* VP_TempLink = const_cast
<ZCLink*>(GetLinkPtr(AL_FirstFindIndex));
do //////
{
if(VP_TempLink==AP_pSearchLink)
{ return VL_FindIndex; }
/*+++++++++++++++++++++++++++*/
if(VL_FindIndex==ml_Size){return 0; }
VP_TempLink = VP_TempLink->mp_NextLink;
VL_FindIndex= VL_FindIndex + 1 ;
}
while(true);
}/*
TTypSize Find(ZCLink* AP_pSearchLink, TTypSize AL_FirstFindIndex=1) const*/
TTypSize Find(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1)
{
const bool CB_DoStop =
(
mp_HeadLink==0 || AL_FirstFindIndex<1 || AL_FirstFindIndex>ml_Size
);
if(CB_DoStop) return 0;
TTypSize VL_FindIndex = AL_FirstFindIndex ;
ZCLink* VP_TempLink = const_cast
<ZCLink*>(GetLinkPtr(AL_FirstFindIndex));
do //////
{
if(**VP_TempLink==AR_TypeArg)
{return VL_FindIndex;}
/*+++++++++++++++++++++++++*/
if(VL_FindIndex==ml_Size){return 0; }
VP_TempLink = VP_TempLink->mp_NextLink;
VL_FindIndex= VL_FindIndex + 1 ;
}
while(true);
}/*
TTypSize Find(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1)*/
/*////////////////////////////////////////////////////////////////////////////////////////
■ FindData(TTypeArg, ~) 함수가 없다면, TypeCArg 이 const TType& 으로 정의되어 있는 경우,
const TType& 에 대해서만 찾기를 수행할 수 있고, TType& 에 대해서는 찾기를 수행할 수 없다.
-- 2010-05-29 21:31:00
////////////////////////////////////////////////////////////////////////////////////////*/
TTypSize FindData(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1) const
{
return Find(AR_TypeArg, AL_FirstFindIndex);
}/*
TTypSize FindData(TypeArg AR_TypeArg, TTypSize AL_FirstFindIndex=1) const*/
ZCLink* GetLinkPtr(TTypSize AL_Index)
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZCLink* GetLinkPtr(TTypSize AL_Index)' : Parameter is Bad AL_Index(AL_Index="<<AL_Index<<")"<<std::endl;
fileout.close();
exit(1);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return mp_HeadLink->GetNextPtr(AL_Index-1);
}/*
ZCLink* GetLinkPtr(TTypSize AL_Index)*/
const ZCLink* GetLinkPtr(TTypSize AL_Index) const
{
#ifdef _DEBUG
if(AL_Index<1 || AL_Index>ml_Size)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'const ZCLink* GetLinkPtr(TTypSize AL_Index) const' : Parameter is Bad AL_Index(AL_Index="<<AL_Index<<")"<<std::endl;
fileout.close();
exit(1);
}/*
if(AL_Index<1 || AL_Index>ml_Size)*/
#endif //_DEBUG
return mp_HeadLink->GetNextPtr(AL_Index-1);
}/*
const ZCLink* GetLinkPtr(TTypSize AL_Index) const*/
ZCFreeHeap& GetCFreeHeap()
{
return mo_FreeObjt;
}/*
ZCFreeHeap& GetCFreeHeap()*/
inline TTypSize GetSize() const
{
return ml_Size;
}/*
inline TTypSize GetSize() const*/
inline TTypSize size() const
{
return ml_Size;
}/*
inline TTypSize size() const*/
inline bool IsEmpty() const
{
return mp_HeadLink==0;
}/*
inline bool IsEmpty() const*/
// ***************************************************************** //
// *********************** Functor 부분 시작 *********************** //
// ***************************************************************** //
template<typename TFunctor> void IterElement(TFunctor AO_Functor)
{
ZCLink* VP_LoopLink = mp_HeadLink;
__for1(TTypSize, VL_Index, ml_Size)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)(VP_LoopLink->mo_Data);
VP_LoopLink = VP_LoopLink->mp_NextLink;
}/*
__for1(TTypSize, VL_Index, 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(TTypSize, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
VP_LoopLink->mo_Data, ZCCheckRef::PassData(AO_TypeHelp)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TTypSize, 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(TTypSize, i, ml_Size)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_Functor)
(
VP_LoopLink->mo_Data ,
ZCCheckRef1::PassData(AO_TypeHelp1),
ZCCheckRef2::PassData(AO_TypeHelp2)
);
////////////////////////////////////////////
VP_LoopLink = VP_LoopLink->mp_NextLink ;
}/*
__for0(TTypSize, i, ml_Size)*/
}/*
template
<typename TFunctor , typename TTypeHelp1 , typename TTypeHelp2 >
void IterElement
(TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2)
*/
template<typename TFunctor> void IterEleCutIf(TFunctor AO_Functor)
{
// 각 링크에 대하여 AO_Functor(ZCLink*) 함수를 실행한다.
// 이 함수를 설계한 이유는 각 링크를 순회하면서 삭제할 수 있도록 하기 위해서다.
ZCLink* VP_TempLink =mp_HeadLink ;
ZCLink* VP_TempPrev =0 ;
ZCLink* VP_TempBefore=VP_TempLink ;
// 순회 도중에 링크가 삭제되면 노드갯수가 변할 수 있으므로
// ml_Size 를 다른 변수에 담아 놓는다.
TTypSize VL_Count=ml_Size ;
TTypSize VL_Index=1 ;
__for1(TTypSize, VL_Loop, VL_Count)
{
VP_TempLink=VP_TempLink->mp_NextLink;
const bool CB_IsTrue = ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)( VP_TempBefore->mo_Data );
if(CB_IsTrue)
{
Delete(VP_TempPrev, VP_TempBefore, VL_Index);
}
else
{
++VL_Index;
if(VP_TempPrev==0)
VP_TempPrev=VP_TempBefore;
else VP_TempPrev=VP_TempPrev->mp_NextLink;
}/*
else*/
VP_TempBefore=VP_TempLink;
}/*
__for1(TTypSize, VL_Loop, VL_Count)*/
}/*
template<typename TFunctor> void IterEleCutIf(TFunctor AO_Functor) */
template<typename TFunctor> void IterEleLink
(
ZCLink* AP_StdLink ,
TTypSize AL_WorkDistance,
TFunctor AO_Functor
)
/*########################################*/
{
/* AP_StdLink 부터 AL_WorkDistance 만큼 이동하면서
* 각 ZCLink 에 대하여 AO_Functor() 함수를 수행한다.(총 수행 횟수는 (AL_WorkDistance)절대값+1)
* AL_WorkDistance>=0 이면 다음으로 이동하고
* AL_WorkDistance <0 이면 이전으로 이동한다.
*/
#ifdef _DEBUG
if(ml_Size==0 || Find(AP_StdLink)==0 || AL_WorkDistance>=ml_Size || AL_WorkDistance<0)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'void IterEleLink( ZCLink* AP_StdLink ,"<<std::endl;
fileout<<" TTypSize AL_WorkDistance,"<<std::endl;
fileout<<" TFunctor AO_Functor"<<std::endl;
fileout<<" )' :"<<std::endl;
fileout<<" Parameters are not valid"<<std::endl;
fileout.close();
exit(1);
}
/*if(ml_Size==0 || Find(AP_StdLink)==0 || AL_WorkDistance>=ml_Size || AL_WorkDistance<0)*/
#endif //_DEBUG
for(TTypSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_Functor)(AP_StdLink);
AP_StdLink = AP_StdLink->mp_NextLink ;
}/*
for(TTypSize VL_Loop=0; VL_Loop<=AL_WorkDistance; ++VL_Loop)*/
}/*
void IterEleLink /////////////////
(
ZCLink* AP_StdLink ,
TTypSize AL_WorkDistance,
TFunctor AO_Functor
)
////////////////////////////////*/
// ***************************************************************
// *********************** Functor 부분 끝 ***********************
// ***************************************************************
/*///////////////////////////////////////////////////////////////////////////
■ 순차적으로 각 원소를 순회할 수 있는 자료 구조, 즉 리스트나 배열 클래스는
MoveNextIter(), MovePrevIter()
멤버를 갖는 것으로 정했다. stl 의 반복자는 너무 일반화하다보니, 성능 상의
제약이 발생한 것 같다.
-- 2011-06-07 20:25:00
GetDataInIter() 를 추가했다.
-- 2011-06-12 17:12:00
///////////////////////////////////////////////////////////////////////////*/
void MoveNextIter(ZCLink*& APR_CLink)
{
APR_CLink=APR_CLink->GetNextPtr();
}/*
void MoveNextIter(ZCLink*& APR_CLink)*/
void MoveNextIter(IterEasyID& APPI_IterEasyID)
{
MoveNextIter((ZCLink*&)APPI_IterEasyID);
}/*
void MoveNextIter(IterEasyID& APPI_IterEasyID)*/
void MoveNextIter(const ZCLink*& APR_CLink) const
{
APR_CLink=APR_CLink->GetNextPtr();
}/*
void MoveNextIter(const ZCLink*& APR_CLink) const*/
void MoveNextIter(const IterEasyID& APPI_IterEasyID) const
{
MoveNextIter((const ZCLink*&)APPI_IterEasyID);
}/*
void MoveNextIter(const IterEasyID& APPI_IterEasyID) const*/
TType& GetDataInIter(ZCLink* AP_CLink)
{
return **AP_CLink;
}/*
TType& GetDataInIter(ZCLink* AP_CLink)*/
TType& GetDataInIter(IterEasyID APPI_IterEasyID)
{
return GetDataInIter((ZCLink*)APPI_IterEasyID);
}/*
TType& GetDataInIter(IterEasyID APPI_IterEasyID)*/
const TType& GetDataInIter(const ZCLink* AP_CLink) const
{
return **AP_CLink;
}/*
const TType& GetDataInIter(const ZCLink* AP_CLink) const*/
const TType& GetDataInIter(const IterEasyID APPI_IterEasyID) const
{
return GetDataInIter((const ZCLink*)APPI_IterEasyID);
}/*
const TType& GetDataInIter(const IterEasyID APPI_IterEasyID) const*/
ZCLink* ItHEasy(){return mp_HeadLink;}
IterEasyID ItHID (){return (IterEasyID)mp_HeadLink;}
ZCLink* ItTEasy(){return mp_TailLink;}
IterEasyID ItTID (){return (IterEasyID)mp_TailLink;}
const ZCLink* ItHEasy() const{return mp_HeadLink;}
const IterEasyID ItHID () const{return (IterEasyIDc)mp_HeadLink;}
const ZCLink* ItTEasy() const{return mp_TailLink;}
const IterEasyID ItTID () const{return (IterEasyIDc)mp_TailLink;}
void ItNext(ZCLink*& APR_CLink)
{
MoveNextIter(APR_CLink);
}/*
void ItNext(ZCLink*& APR_CLink)*/
void ItNext(IterEasyID& APPI_IterEasyID)
{
MoveNextIter(APPI_IterEasyID);
}/*
void ItNext(IterEasyID& APPI_IterEasyID)*/
void ItNext(const ZCLink*& APR_CLink) const
{
MoveNextIter(APR_CLink);
}/*
void ItNext(const ZCLink*& APR_CLink) const*/
void ItNext(const IterEasyID& APPI_IterEasyID) const
{
MoveNextIter(APPI_IterEasyID);
}/*
void ItNext(const IterEasyID& APPI_IterEasyID) const*/
TType& ItD(ZCLink* AP_CLink)
{
return **AP_CLink;
}/*
TType& ItD(ZCLink* AP_CLink)*/
TType& ItD(IterEasyID APPI_IterEasyID)
{
return ItD((ZCLink*)APPI_IterEasyID);
}/*
TType& ItD(IterEasyID APPI_IterEasyID)*/
const TType& ItD(const ZCLink* AP_CLink) const
{
return **AP_CLink;
}/*
const TType& ItD(const ZCLink* AP_CLink) const*/
const TType& ItD(const IterEasyID APPI_IterEasyID) const
{
return ItD((const ZCLink*)APPI_IterEasyID);
}/*
const TType& ItD(const IterEasyID APPI_IterEasyID) const*/
public:
};/*
template ######################################################################
<
typename TType
, typename TTypArgu = const TType&
, typename TTypCAlloc= ZCAllocator
, typename TTypCInit = ZtCInit<TType>
, typename TTypSize = ZTypLong
, typename TMoveObj = ZNsMain::
ZtCMoveObj<TType, TTypArgu, true>
, typename TFeeeHeap = ZNsIFaceEx::
ZtCFreeHeapSngl< ZNsConst::CI_ListKind_Single >
>
class ZtCSimList ##########################################################*/
}/*
namespace ZNsMain*/
#endif //__ZCPPMAIN__ZCSIMLIST_H__