#ifndef __ZCPPMAIN__ZTCOBJLIST_H__ #define __ZCPPMAIN__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 class ZtCSortObjList; template< typename TType , typename TTypCArg =const TType&, typename TTypCAlloc=ZCAllocator , typename TTypCInit =ZCInit , typename TTypSize =ZTypLong > class ZtCObjList //////////////////////////// { public: template 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 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(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++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++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(this); while(VL_LoopIndex++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(this) ; while(VL_LoopIndex++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<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<AL_CutTailPos"<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<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<(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<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<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 ( 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<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<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<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<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<AL_CutTailPos) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<AL_CutTailPos"<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<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<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<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<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<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<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 void IterElement(TFunctor AO_Functor) { ZCLink* VP_LoopLink=mp_HeadLink; __for0(int, i, ml_Size) { ZtCTypeData::GetObjRef(AO_Functor)(VP_LoopLink->mo_Type); /* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator() 연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. */ VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(int, i, ml_Size)*/ }/* template void IterElement(TFunctor AO_Functor) */ template void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) { /*///////////////////////////////////////////////////////////////////////////// ■ TTypeHelp 가 class 일 경우, 크기가 커서 참조로 넘어가야 한다면, IterElement(myFunctor_obj, myClass_Obj); 의 형태로 호출할 게 아니라, ZtCObjectPtr<> 을 사용하여, myClass myClass_Obj; ZtCObjectPtr myCObjPtr(myClass_Obj); 나 IterElement(myFunctor_obj, ZtCObjectPtr(myClass_Obj)); 형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00 이제는 ZtCRef 과 ZCCheckRef 클래스 템플릿을 사용하면 된다. -- 2021-03-11 11:00 /////////////////////////////////////////////////////////////////////////////*/ typedef ZNsMain:: ZtCCheckRef ZCCheckRef; ZCLink* VP_LoopLink=mp_HeadLink; __for0(int, i, ml_Size) { ZtCTypeData::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 void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */ template /*###########*/ void IterElement ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) /*#############################################################################*/ { /*///////////////////////////////////////////////////////////////////////////// ■ TTypeHelp 가 class 일 경우, 크기가 커서 참조로 넘어가야 한다면, IterElement(myFunctor_obj, myClass_Obj); 의 형태로 호출할 게 아니라, ZtCObjectPtr<> 을 사용하여, myClass myClass_Obj; ZtCObjectPtr myCObjPtr(myClass_Obj); 나 IterElement(myFunctor_obj, ZtCObjectPtr(myClass_Obj)); 형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00 이제는 ZtCRef 과 ZCCheckRef 클래스 템플릿을 사용하면 된다. -- 2021-03-11 11:00 /////////////////////////////////////////////////////////////////////////////*/ typedef ZNsMain::ZtCCheckRef ZCCheckRef1; typedef ZNsMain::ZtCCheckRef ZCCheckRef2; ZCLink* VP_LoopLink=mp_HeadLink; __for0(int, i, ml_Size) { ZtCTypeData::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 ############### void IterElement ( TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 ) ###############################################################################*/ template 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::GetObjRef (AO_Functor)(VP_LoopLink->mo_Type, AR_TypeHelp); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(int, i, ml_Size)*/ }/* template void IterElemRef(TFunctor AO_Functor, TTypeHelp& AR_TypeHelp) */ template /*###########*/ 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::GetObjRef(AO_Functor) ( VP_LoopLink->mo_Type, AR_TypeHelp1, AR_TypeHelp2 ); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* __for0(int, i, ml_Size)*/ }/* template ############### void IterElemRef ( TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2 ) /*#############################################################################*/ /*/////////////////////////////////////////////////////////////////////////// ■ IterElement() 예제. #include #include "ZCppMain/ZtCObjList.H" using namespace std; int main() { ZNsMain:: ZtCObjList myObjList; myObjList.AddTail(10); myObjList.AddTail(20); myObjList.AddTail(30); myObjList.AddTail(40); struct StFunctor { static void ShowElement(int ArgiValue){cout<<"# Value="< CArray ; typedef ZtCObjList 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)"<