/
ScryMUD/mud/
ScryMUD/mud/grrmud/Boards/
ScryMUD/mud/grrmud/Help/
ScryMUD/mud/grrmud/Pfiles/
ScryMUD/mud/grrmud/PlayerSacks/
ScryMUD/mud/grrmud/PlayerShops/
ScryMUD/mud/grrmud/help_filter/
ScryMUD/mud/hegemon/
ScryMUD/mud/hegemon/data/
ScryMUD/mud/hegemon/data/help/battle/
ScryMUD/mud/hegemon/data/help/client/
ScryMUD/mud/hegemon/data/help/communications/
ScryMUD/mud/hegemon/data/help/skills/
ScryMUD/mud/hegemon/data/help/spells/
ScryMUD/mud/include/
ScryMUD/mud/lib/
ScryMUD/mud/lib/bitfield/
ScryMUD/mud/lib/log/
ScryMUD/mud/lib/string2/
// $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