//************************************************************************************** // Filename: AStdObjArrayNew.h // Part of Contextual Menu Workshop by Abracode Inc. // http://free.abracode.com/cmworkshop/ // Copyright © 2003 Abracode, Inc. All rights reserved. // // Description: Extension to David Catmull's ACCELA Mac toolbox C++ wrapper library //************************************************************************************** #pragma once #include "AMemoryCommon.h" #include "CThrownResult.h" #include template class AStdObjArrayNew { public: AStdObjArrayNew(ADisposeProc inProc = NULL) : mObject(NULL), mIsOwner(kMemObj_NotOwned), mSize(0), mObjDisposeProc(inProc) {} AStdObjArrayNew(T *inObj, SInt32 inSize, EMemObjOwnershipType inIsOwner = kMemObj_Owned, ADisposeProc inProc = NULL) : mObject(inObj), mIsOwner(inIsOwner), mSize(inSize), mObjDisposeProc(inProc) { } //copy constructor - only shallow copy is allowed here //the object is detached from the original AStdObjArrayNew(const AStdObjArrayNew& inOrig) { EMemObjOwnershipType isOwner = inOrig.mIsOwner; SInt32 newSize = inOrig.mSize; Reset(inOrig.Detach(), isOwner ); mObjDisposeProc = inOrig.mObjDisposeProc; mSize = newSize; } AStdObjArrayNew( SInt32 inSize, ADisposeProc inProc = NULL, EMemObjClearOption inClearOption = kMemObj_DontClearMemory) : mObject(NULL), mIsOwner(kMemObj_Owned), mSize(inSize), mObjDisposeProc(inProc) { if(mSize > 0) { mObject = new T [mSize]; if(kMemObj_ClearMemory == inClearOption) { for(SInt32 i = 0; i< mSize; i++) { std::memset( &mObject[i], 0, sizeof(T) ); } } } } virtual ~AStdObjArrayNew() { Dispose(); } //object assignment as a shallow copy with ownership change AStdObjArrayNew& operator=( const AStdObjArrayNew& inObj) { EMemObjOwnershipType isOwner = inObj.mIsOwner; SInt32 newSize = inOrig.mSize; Reset(inObj.Detach(), isOwner ); mObjDisposeProc = inObj.mObjDisposeProc; mSize = newSize; return *this; } T * Get() const { return mObject; } operator T*() const { return mObject; } T& operator [] (UInt32 index) { return mObject[index]; } T* operator -> () const { return mObject; } SInt32 GetSize() const { return mSize; } T * Detach() const { mIsOwner = kMemObj_NotOwned; return mObject; } void Reset( T *inObject, EMemObjOwnershipType inIsOwner = kMemObj_Owned) { if ((mIsOwner == kMemObj_Owned) && (mObject != NULL) && (inObject != mObject)) DisposeSelf(); mObject = inObject; mIsOwner = inIsOwner; } void Dispose() { if (mObject != NULL) { if(mIsOwner == kMemObj_Owned) DisposeSelf(); mObject = NULL; } mIsOwner = kMemObj_NotOwned; mSize = 0; } protected: //DisposeProc will receive a pointer to stored object, not the actual object //DisposeProc is responsible for checking if the object stored is valid void DisposeSelf() { if(mObjDisposeProc != NULL) { for(int i = 0; i< mSize; i++) { mObjDisposeProc( &(mObject[i]) ); } } delete [] mObject; } protected: T *mObject; mutable EMemObjOwnershipType mIsOwner; SInt32 mSize; ADisposeProc mObjDisposeProc; private: //plain pointer assignment cannot be used becuase we cannot obtain its size. private unimplemented AStdObjArrayNew& operator=( const T* inObj); };