#ifndef AU_ACCESSOR #define AU_ACCESSOR /********************\ * auAccessor Class * \********************/ template class auAccessor { friend class auNullAcessorClass; protected: T* Ptr; auAccessor *Prev, *Next; auInt m_Size; public: void Delete(); // Deletes the object/array being pointed to. Resets // this and all auAccessors pointing there to NULL. void Remove(); // Stops pointing to the current address, points to NULL. void Assign(auAccessor &A); // Assigns a new place to point to void New(long Count=1); // Creates a new object or array on the heap. void Copy(auInt Extra=0); // Creates a copy of the current object or array // being pointed to, and starts pointing there. // Adds extra elements if necessary. void CopyElements(auAccessor &A, auUInt SourceBegin, auUInt SourceEnd, auUInt DestBegin); // Copies // elements from one array to another, clips overflows inline auInt ArraySize(); // Returns the copy of the size of the array being // pointed to. A single object is an array of 1 element. inline auAccessor(); // Constructor. Initializes values to 0. inline auAccessor(auAccessor &A); // Copy constructor. Calls Assign(A); inline ~auAccessor(); // Destructor. Calls Remove(); inline T& operator*(); inline T* operator->(); inline T* operator+(long Index); inline T& operator[](long Index); inline T& operator==(auAccessor Compare); // compare pointers //inline T& operator==(auNullAccessor Compare) // if you really want to write "== auNull" :-) inline operator bool(); // Used to test if pointer is NULL inline auAccessor& operator=(auAccessor &A); inline T* Address(); // Only if you want to hack (for efficiency?). inline void AddressAssign(T* Addr, auInt Count); // Only if you want to hack (for external data?). //inline void operator delete(void* pmem) }; //auNullAccessor auNull; template void auAccessor::Delete() // Deletes the object/array being pointed to. // Resets this and all auAccessors pointing there to NULL. { auAccessor* a; if (Ptr) { if (m_Size > 1) delete[] Ptr; else delete Ptr; // Clear all previous pointers in doubly linked list... a = this; // start from the current one while (a) { a->Ptr = 0; a = a->Prev; } a = Next; // start from the next one while (a) { a->Ptr = 0; a = a->Next; } } m_Size = 0; } template void auAccessor::Remove() // Stops pointing to the current address, points to NULL. { // Remove this object from its current doubly linked list if (Prev) Prev->Next = Next; if (Next) Next->Prev = Prev; // If it was already a single object, delete it. if (!Prev && !Next) Delete(); // And we're clean again :-) Ptr = 0; Prev = 0; Next = 0; m_Size = 0; } template void auAccessor::Assign(auAccessor &A) // Assigns a new place to point to { // Remove this object from its current doubly linked list Remove(); // Add this object into A's doubly linked list // A will be Prev. Prev = &A; Next = A.Next; if (A.Next) A.Next->Prev = this; A.Next = this; Ptr = A.Ptr; m_Size = A.m_Size; } template void auAccessor::New(long Count) // Creates a new object or array on the heap. { Remove(); // Allocate new data on the free store. if (Count == 1) Ptr = new T; else Ptr = new T[Count]; m_Size = Count; }; template void auAccessor::Copy(auInt extra) // Creates a copy of the current // object or array being pointed to, and starts pointing there. { // Special case. if (!Ptr) // sound the alarm. :-) throw new auError(AU_STDERROR_MISSING); if (!Prev && !Next) return; // the only copy, anyway. // Save the pointer. The data won't be deleted. T* p; p = Ptr; // Create new data and copy to it. New(m_Size+extra); memcpy(Ptr, p, sizeof(T) * m_Size); // m_Size remains the same. Unless something's weird. :-) } template auInt auAccessor::ArraySize() // Returns the copy of the size of the array being pointed to. A single object is an array of 1 element. { return m_Size } template void auAccessor::CopyElements (auAccessor &A, auUInt sb, auUInt se, auUInt db) // Copies elements from one array to another { if (!Ptr) // sound the alarm. :-) throw new auError(AU_STDERROR_MISSING); if (!A.Ptr) // sound the alarm. :-) throw new auError(AU_STDERROR_MISSING); // Bounds checks if (db >= m_Size) throw new auError(AU_STDERROR_PARAMS); if (sb >= A.m_Size) throw new auError(AU_STDERROR_PARAMS); // Bounds adjusting if (se >= A.m_Size) se = A.m_Size-1; if (db+(se-sb) >= A.m_Size) se = m_Size-1-(db-sb); memcpy(Ptr+db, A.Ptr+sb, se-sb+1); } template auAccessor::auAccessor() // Constructor. Initializes values to 0. { // Be kind, rewind. :-) Ptr = 0; Prev = 0; Next = 0; m_Size = 0; } template auAccessor::auAccessor(auAccessor &A) // Copy constructor. Calls Assign(A); { Assign(A); } template auAccessor::~auAccessor() // Destructor. Calls Remove(); { Remove(); } template T& auAccessor::operator*() { if (!Ptr) throw new auError(AU_STDERROR_MISSING); return *Ptr; } template T* auAccessor::operator->() { if (!Ptr) throw new auError(AU_STDERROR_MISSING); return Ptr; } template T* auAccessor::operator+(long Index) { if (!Ptr) throw new auError(AU_STDERROR_MISSING); if (Index < 0) throw new auError(AU_STDERROR_BOUNDS); if (Index >= m_Size) throw new auError(AU_STDERROR_BOUNDS); return Ptr+Index; } template T& auAccessor::operator[](long Index) { if (!Ptr) throw new auError(AU_STDERROR_MISSING); if (Index < 0) throw new auError(AU_STDERROR_BOUNDS); if (Index >= m_Size) throw new auError(AU_STDERROR_BOUNDS); return Ptr[Index]; } template T& auAccessor::operator==(auAccessor Compare) // compare pointers { return (Ptr == Compare.Ptr); } // //inline T& auAccessor::operator==(auNullAccessor Compare) // if you really want to write "== auNull" :-) //{ // return (Ptr == Compare.Ptr); //} template auAccessor::operator bool() // Used to test if pointer is NULL { if (Ptr) return true; else return false; } template auAccessor& auAccessor::operator=(auAccessor &A) { Assign(A); return A; } template T* auAccessor::Address() // Only if you want to hack (for efficiency?). { return Ptr; } template void auAccessor::AddressAssign(T* p, auInt count) // Only if you want to hack (for efficiency?). { Remove(); Ptr = p; m_Size = count; }