#ifndef __ZTCARRAY_H__ #define __ZTCARRAY_H__ #include "ZMainHead.H" namespace ZNsMain { template< typename Type , typename TypeArg=const Type&, typename TSize =long > class ZtCArray ///////////////////////// { public: typedef TSize TypeSize; typedef Type TypeData; typedef ZtCArray ZCArray ; public: class ZCIterator; public: typedef Type* IterEasy; typedef ZCIterator iterator; typedef const ZCIterator const_iterator; public: class ZCIterator { private: mutable Type* mp_Data ; mutable TSize ml_ElePos; // *mp_Data 가 배열에서 차지하는 위치 ZCArray* mp_CArray; public: ZCIterator() { mp_Data =0; mp_CArray=0; ml_ElePos=0; }/* ZCIterator()*/ ZCIterator(ZCArray& AR_CArray, Type& AR_CData, TSize AL_ElePos) { mp_Data =&AR_CData ; mp_CArray=&AR_CArray; ml_ElePos=AL_ElePos ; }/* ZCIterator(ZCArray& AR_CArray, Type& AR_CData, TSize AL_ElePos)*/ ZCIterator(ZCArray& AR_CArray) { mp_Data = AR_CArray.mp_TypeArr ; mp_CArray=&AR_CArray ; ml_ElePos=(AR_CArray.size()>0 ? 1 : 0 ) ; }/* ZCIterator(ZCArray& AR_CArray)*/ ZCIterator(const ZCArray& AR_CArray) { mp_Data = AR_CArray.mp_TypeArr; mp_CArray=const_cast(&AR_CArray); ml_ElePos=(AR_CArray.size()>0 ? 1 : 0 ) ; }/* ZCIterator(const ZCArray& AR_CArray)*/ Type& operator*( ){return *mp_Data;} Type* operator->(){return mp_Data;} const Type& operator* () const{return *mp_Data;} const Type* operator->() const{return mp_Data;} ZCIterator& operator++( ){++mp_Data; ++ml_ElePos; return *this;} ZCIterator operator++(int){++mp_Data; ++ml_ElePos; return *this;} const ZCIterator& operator++( ) const{++mp_Data; ++ml_ElePos; return *this;} const ZCIterator operator++(int) const{++mp_Data; ++ml_ElePos; return *this;} ZCIterator operator+(TSize AL_AddPos) const { return ZCIterator(*this, mp_Data+AL_AddPos, ml_ElePos+AL_AddPos); }/* ZCIterator operator+(TSize AL_AddPos) const*/ public: };/* class ZCIterator public :*/ protected: enum{ZEAddSize=20}; protected: Type* mp_TypeArr ; TypeSize ml_AllSize ; TypeSize ml_UseSize ; TypeSize ml_AddSize ; /* TSize ml_AddSize 는 추가 메모리를 지정. 한 개의 원소가 삽입되서 재할당해야 할 경우, ml_AddSize 개 만큼을 미리 할당한다. protected:*/ public : ZtCArray() { mp_TypeArr =0; ml_AllSize =0; ml_UseSize =0; ml_AddSize =ZEAddSize; }/* ZtCArray()*/ ZtCArray(const ZtCArray& rhs) { mp_TypeArr =0; ml_AllSize =0; ml_UseSize =0; ml_AddSize =ZEAddSize; *this=rhs; }/* ZtCArray(const ZtCArray& rhs)*/ ~ZtCArray() { Delete(); }/* ~ZtCArray()*/ ZCArray& operator=(const ZCArray& rhs) { ReAlloc(rhs.ml_UseSize, false); ml_UseSize=rhs.ml_UseSize; ml_AllSize=rhs.ml_AllSize; for(TypeSize i=0; i=1) ml_AddSize=AL_NewAddSize; }/* void SetAddSize(TypeSize AL_NewAddSize)*/ void SetUseSize(TypeSize AL_NewUseSize) { if(AL_NewUseSize>=0 && AL_NewUseSize<=ml_AllSize) { ml_UseSize=AL_NewUseSize; }/* if(AL_NewUseSize>=0 && AL_NewUseSize<=ml_AllSize)*/ }/* void SetUseSize(TypeSize AL_NewUseSize)*/ void ReAlloc(TypeSize AL_AllocSize, bool AB_DoKeep=true) { if(AL_AllocSize<1) return ; if(AL_AllocSize::assign(size_type _Count, const type&); void assign(TypeSize AL_AllocSize, bool AB_DoKeep=true) { this->ReAlloc(AL_AllocSize, AB_DoKeep); this->SetUseSize(AL_AllocSize); }/* void assign(TypeSize AL_AllocSize, bool AB_DoKeep=true)*/ Type& operator[](TypeSize AL_Index) { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<<", "<="<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index] ; }/* Type& operator[](TypeSize AL_Index)*/ const Type& operator[](TypeSize AL_Index) const { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt", std::ios::out | std::ios::app); fileout<=ml_UseSize"<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index] ; }/* const Type& operator[](TypeSize AL_Index) const*/ Type& GetData(TypeSize AL_Index) { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index] ; }/* Type& GetData(TypeSize AL_Index)*/ const Type& GetData(TypeSize AL_Index) const { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index]; }/* const Type& GetData(TypeSize AL_Index) const*/ void AddHead(TypeArg AR_TypeArg) { ReAlloc((ml_UseSize++)+1); for(TypeSize i=ml_UseSize-2; i>=0; --i) { mp_TypeArr[i+1]=mp_TypeArr[i] ; }/* for(TypeSize i=ml_UseSize-2; i>=0; --i)*/ mp_TypeArr[0]=AR_TypeArg ; }/* void AddHead(TypeArg AR_TypeArg)*/ Type& AddHead() { // 앞에 빈 원소를 삽입하고 그 원소를 반환한다. ReAlloc((ml_UseSize++)+1); for(TypeSize i=ml_UseSize-2; i>=0; --i) { mp_TypeArr[i+1]=mp_TypeArr[i] ; }/* for(TypeSize i=ml_UseSize-2; i>=0; --i)*/ return mp_TypeArr[0] ; }/* Type& AddHead()*/ void AddTail(TypeArg AR_TypeArg) { ReAlloc((ml_UseSize++)+1); mp_TypeArr[ml_UseSize-1]=AR_TypeArg ; }/* void AddTail(TypeArg AR_TypeArg)*/ Type& AddTail() { // 끝에 빈 원소를 삽입하고 그 원소를 반환한다. ReAlloc((ml_UseSize++)+1); return mp_TypeArr[ml_UseSize-1]; }/* Type& AddTail()*/ operator Type&() { return AddTail(); }/* operator Type&()*/ void push_back(TypeArg AR_TypeArg) { AddTail(AR_TypeArg); }/* void push_back(TypeArg AR_TypeArg)*/ Type& push_back() { return AddTail(); }/* Type& push_back()*/ ZCIterator begin() { return ZCIterator(*this); }/* ZCIterator begin()*/ const ZCIterator begin() const { return ZCIterator(*this); }/* const ZCIterator begin() const*/ template void IterElement(TFunctor AO_Functor) { Type* VP_TypeArr = mp_TypeArr; __for0(TypeSize, i, ml_UseSize) { ZNsMain::CTypeData_T:: GetObjRef(AO_Functor)(*VP_TypeArr); ++VP_TypeArr; /* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator() 연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. */ }/* __for0(TypeSize, i, ml_UseSize)*/ }/* template void IterElement(TFunctor AO_Functor)*/ template void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) { /*///////////////////////////////////////////////////////////////////////////// ■ TTypeHelp 가 class 일 경우, 크기가 커서 참조로 넘어가야 한다면, IterElement(myFunctor_obj, myClass_Obj); 의 형태로 호출할 게 아니라, ZNsMain::ZtCObjectPtr<> 을 사용하여, myClass myClass_Obj; ZNsMain::ZtCObjectPtr myCObjPtr(myClass_Obj); 나 IterElement(myFunctor_obj, ZNsMain::ZtCObjectPtr(myClass_Obj)); 형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00 /////////////////////////////////////////////////////////////////////////////*/ Type* VP_TypeArr = mp_TypeArr; __for0(TypeSize, i, ml_UseSize) { ZNsMain::CTypeData_T:: GetObjRef(AO_Functor)(*VP_TypeArr, AO_TypeHelp); ++VP_TypeArr; }/* __for0(TypeSize, i, ml_UseSize)*/ }/* 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); 의 형태로 호출할 게 아니라, ZNsMain::ZtCObjectPtr<> 을 사용하여, myClass myClass_Obj; ZNsMain::ZtCObjectPtr myCObjPtr(myClass_Obj); 나 IterElement(myFunctor_obj, ZNsMain::ZtCObjectPtr(myClass_Obj)); 형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00 /////////////////////////////////////////////////////////////////////////////*/ Type* VP_TypeArr = mp_TypeArr; __for0(TypeSize, i, ml_UseSize) { ZNsMain::CTypeData_T::GetObjRef(AO_Functor) (*VP_TypeArr, AO_TypeHelp1, AO_TypeHelp2); ++VP_TypeArr; /////////////////////////////////////// }/* __for0(TypeSize, i, ml_UseSize)*/ }/* template void IterElement(TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2)*/ /*/////////////////////////////////////////////////////////////////////////// ■ IterElement() 예제. #include #include "ZCArray.H" using namespace std ; using namespace ZNsMain; int main() { std:: ZtCArray myArray; myArray.AddTail(10); myArray.AddTail(20); myArray.AddTail(30); myArray.AddTail(40); struct StFunctor { static void ShowElement(int ArgiValue){cout<<"# Value="< class ZtCArray ////////////////////////*/ ////////////////////////////////////////////// ////////////// end class ZCArray ////////////// ////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////// ■ class ZtCArrayFixed<> 는 배열 메모리를 자체 할당하지 않고, 이미 외부에서 new 나 정적으로 선언되어 있는 배열을 사용한다. 따라서 ZtCArrayFixed<> 내부에서 임의로 배열 크기를 조절할 수 없다. -- 2011-08-05 20:40:00 ////////////////////////////////////////////////////////////////////*/ template< typename Type, typename TSize=long > class ZtCArrayFixed /////////// { public: typedef Type TypeData; public: typedef const Type* const_iterator; typedef Type* iterator; private: Type* mp_TypeArr; TSize ml_UseSize; public: ZtCArrayFixed() { Init(0, 0); } ZtCArrayFixed(TypeData* AP_DataArr, TSize AL_ArrSize) { Init(AP_DataArr, AL_ArrSize); } void Init(TypeData* AP_DataArr, TSize AL_ArrSize) { mp_TypeArr=AP_DataArr; ml_UseSize=AL_ArrSize; }/* void Init(TypeData* AP_DataArr,TSize AL_ArrSize)*/ TSize size() const{return ml_UseSize;} Type& operator[](TSize AL_Index) { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<<", "<="<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index] ; }/* Type& operator[](TSize AL_Index)*/ const Type& operator[](TSize AL_Index) const { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index] ; }/* const Type& operator[](TSize AL_Index) const*/ Type& GetData(TSize AL_Index) { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index] ; }/* Type& GetData(TSize AL_Index)*/ const Type& GetData(TSize AL_Index) const { #ifdef _DEBUG if(AL_Index>=ml_UseSize) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<=ml_UseSize"<=ml_UseSize)*/ #endif //_DEBUG return mp_TypeArr[AL_Index]; }/* const Type& GetData(TSize AL_Index) const*/ Type* begin() { return mp_TypeArr; } const Type* begin() const { return mp_TypeArr; } void MoveNextIter(Type*& ARR_CIterator) const { ++ARR_CIterator; }/* void MoveNextIter(Type*& ARR_CIterator) const*/ void MovePrevIter(iterator& ARR_CIterator) { --ARR_CIterator; }/* void MovePrevIter(iterator& ARR_CIterator)*/ void MoveNextIter(const_iterator& ARR_CIterator) const { ++ARR_CIterator; }/* void MoveNextIter(const_iterator& ARR_CIterator) const*/ void MovePrevIter(const_iterator& ARR_CIterator) const { --ARR_CIterator; }/* void MovePrevIter(const_iterator& ARR_CIterator) const*/ /*//////////////////////////////////////////////////// 위 코드를 아래로 하면 안된다. void MoveNextIter(const iterator& ARR_CIterator) const { ++ARR_CIterator; } //void MoveNextIter(const iterator& ARR_CIterator) const void MovePrevIter(const iterator& ARR_CIterator) const { --ARR_CIterator; } //void MovePrevIter(const iterator& ARR_CIterator) const const iterator 는 Type const * const 이지 Type const * 가 아니다. -- 2011-08-05 23:49:00 ////////////////////////////////////////////////////*/ Type& GetDataInIter(iterator& ARR_CIterator) { return *ARR_CIterator; }/* Type& GetDataInIter(iterator& ARR_CIterator)*/ const Type& GetDataInIter(const_iterator& ARR_CIterator) const { return *ARR_CIterator; }/* const Type& GetDataInIter(const_iterator& ARR_CIterator) const*/ public: };/* template< typename Type, typename TSize=long > class ZtCArrayFixed /////////*/ }/* namespace ZNsMain*/ #endif //__ZTCARRAY_H__