// $Id: PtrArray.h,v 1.5.2.1 2000/01/29 20:54:59 greear Exp $ // $Revision: 1.5.2.1 $ $Author: greear $ $Date: 2000/01/29 20:54:59 $ // //ScryMUD Server Code //Copyright (C) 1998 Ben Greear // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either version 2 //of the License, or (at your option) any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // To contact the Author, Ben Greear: greear@cyberhighway.net, (preferred) // greearb@agcs.com // // PtrArray #ifndef GRRMUD_PTR_ARRAY_H #define GRRMUD_PTR_ARRAY_H #ifndef FALSE #define FALSE 0 #define TRUE 1 #endif #include <bitfield.h> #include <assert.h> /** An array of type class T pointers. Does bounds checking * and will grow as needed. */ template <class T> class PtrArrayBase { private: //ensure it's never called, as dangling pointers suck! PtrArrayBase<T>& operator=(const PtrArrayBase<T>& src); PtrArrayBase(const PtrArrayBase<T>& src); //ensure it's never called protected: int max_len; int cur_len; T** ptr_list; public: PtrArrayBase(int mx); PtrArrayBase() { max_len = 10; cur_len = 0; ptr_list = new T*[max_len + 1]; for (int i = 0; i<max_len; i++) { ptr_list[i] = NULL; } } virtual ~PtrArrayBase(); /** Deep copy. * Virtually does a clearAndDestroy on Self!!!!!! */ virtual void becomeDeepCopyOf(const PtrArrayBase<T>& src); /** NOTE: Returns NULL if out of bounds or value is NULL. */ virtual T* elementAt(int i); /** NOTE: Returns NULL if out of bounds or value is NULL. */ virtual const T* constElementAt(int i) const; /** does NOT delete pointers */ virtual void clear(); /** Deletes any data pointed to by internal pointers. */ virtual void clearAndDestroy(); /** we won't allow it to grow shorter! */ virtual void ensureCapacity(int i); /** max len before we have to grow the array. */ virtual int getMaxLen() const; /** maximum element asigned a value. This may or may not be true, * depending on how you use the class. (It is meant to be used * with append() */ virtual int getCurLen() const; /** return TRUE if it worked..false otherwise */ virtual int setAndDestroy(T* val, int posn); virtual int set(T* val, int posn); /** Make a copy of the incomming object. */ virtual int appendDeepCopy(T& val); /** Just copy the pointer, not the real object. */ virtual int appendShallowCopy(T* val); /** This copies the data from the incomming src, NOT just a shallow copy. * Does not copy NULL's over, ie it packs the src when appending it. */ virtual int appendDeepCopy(const PtrArrayBase<T>& src); /** If it's not already in the array, * find the first open slot and dump it in... */ virtual int gainData(T* val); /** Return TRUE if val is in the array, false otherwise. */ virtual int haveData(const T* val); /** Find the first instance and delete it. */ virtual int loseData(const T* val); /** This just copies the pointers of the src array. */ virtual int appendShallowCopy(const PtrArrayBase<T>& src); };//PtrArrayBase<class T> /** This class will automatically instantiate new instances of type * class T if one tries to reference an index (within valid bounds) * that has a NULL value currently. Of course, if there is one already * there, then it just returns it. */ template <class T> class LazyPtrArray : public PtrArrayBase<T> { private: //ensure it's never called, as dangling pointers suck! LazyPtrArray<T>& operator=(const LazyPtrArray<T>& src); LazyPtrArray(const LazyPtrArray<T>& src); //ensure it's never called protected: public: LazyPtrArray(int mx) : PtrArrayBase<T>(mx) { }; LazyPtrArray() : PtrArrayBase<T>() { }; virtual ~LazyPtrArray() { }; //super-class destructor handles array. // NOTE: if elementAt returns null, this will SEGV, be carefull! T& operator[] (const int i); /** NOTE: If this value is NULL, we will create a default one * and return that. Funky but useful. * WARNING: Over-ridden from base class...and meaning has changed a bit */ virtual T* elementAt(int i); virtual T* elementAtNoCreate(int i); };//LazyPtrArray<class T> /** Simply an array of pointers of type class T. Will grow * as needed. */ template <class T> class PtrArray : public PtrArrayBase<T> { private: //ensure it's never called, as dangling pointers suck! PtrArray& operator=(const PtrArray<T>& src); PtrArray(const PtrArray<T>& src);//ensure it's never called protected: public: PtrArray(int mx) : PtrArrayBase<T>(mx) { }; PtrArray() : PtrArrayBase<T>() { }; virtual ~PtrArray() { }; //super class destructor handles the array. // Simply return the object stored at that offset. Returns NULL // if it does not exist, or out of bounds. T* operator[] (const int i); };//PtrArray<class T> /** This is a growable array of objects. */ template <class T> class ObjArray { private: int _cnt; protected: int len; bitfield bf; T* array; int init(int sz); public: ObjArray() { init(5); } ObjArray(int sz) { init(sz); } ObjArray(const ObjArray<T>& src); ObjArray<T>& operator=(const ObjArray<T>& src); ~ObjArray(); T& elementAt(int idx) const { assert((idx >= 0) && (idx < len)); return array[idx]; } void setElementAt(int idx, T& val) { assert((idx >= 0) && (idx < len)); array[idx] = val; bf.turn_on(idx); } void ensureCapacity(int sz); int isEmpty() const { return bf.is_zero(); } /** Get the next valid index. Uses internal bitfield to walk * over un-used spaces. Returns -1 when there is no next. */ int getNextIdx(int from_idx) const { return bf.nextSet(from_idx); } /** Insert in first free position. */ void addElement(T& val); /** Add to the end of the array. */ void appendElement(T& val); /** Mark spot in array is un-used. */ void removeElement(int idx) { assert((idx >= 0) && (idx < len)); bf.turn_off(idx); } /** Does not clean up memory, just marks all as un-used. */ void clear() { bf.off_all(); } /** Cleans up all the memory it can. */ void purge(); /** How many elements are valid in our array. */ int getElementCount() const { return bf.flagsSet(); } /** Get the maximum capacity available w/out grabbing more memory. */ int getCapacity() const { return len; } /** Returns TRUE if the array contains the element 'val', as * determined by operator= */ int contains(T& val) const ; };//ObjArray #ifndef __INCLUDE_PTR_ARRAY_CC__ #define __INCLUDE_PTR_ARRAY_CC__ #include "PtrArray.cc" #endif #endif