/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NSTACK__ #define __NSTACK__ #include "container/narray.h" namespace GS { /*! @short Simple value stack. @author Emmanuel Julien (ejulien@owloh.com) */ template class Stack { protected: Array data; uint usage; uint grow_step; public: inline const T &operator [] (int n) const { return data[n]; } inline const T &Top() const { return data[usage - 1]; } //---------------------------------------------------------------------- T *Detach() { usage = 0; return data.Detach(); } virtual void Transfer(Stack &from) { usage = from.GetCount(); data.Transfer(from.data); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- /// Push a value on top of the stack. virtual bool Push(const T &v) { if (usage == data.GetCount()) if (!data.Reallocate(usage + 64)) return false; data[usage++] = v; return true; } /// Pop a value from the stack. virtual void Pop() { if (usage > 0) --usage; } inline bool Add(const T &v) { return Push(v); } inline Stack &operator << (const T &v) { Add(v); return *this; } //---------------------------------------------------------------------- //---------------------------------------------------------------------- inline uint GetCount() const { return usage; } inline void SetGrowStep(uint step) { grow_step = step; } virtual void Clear(bool free_internals = true) { if (free_internals) data.Free(); usage = 0; } //---------------------------------------------------------------------- //---------------------------------------------------------------------- inline int Index(const T &v) const { for (uint n = 0; n < usage; ++n) if (data[n] == v) return n; return -1; } //---------------------------------------------------------------------- Stack(uint size = 0, uint step = 64) : usage(0), grow_step(step) { data.Allocate(size); } virtual ~Stack() {} }; /// Auto-stack. template struct AutoStack : public Stack { //---------------------------------------------------------------------- virtual void Transfer(Stack &from) { for (uint n = 0; n < this->usage; ++n) delete this->data[n]; Stack ::Transfer(from); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- virtual void Pop() { if (this->usage > 0) delete this->data[--this->usage]; } virtual void Clear(bool free_internals = true) { for (uint n = 0; n < this->usage; ++n) delete this->data[n]; Stack ::Clear(free_internals); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- /*! @short Drop all pointers managed by this stack, does not free the storage. The dropped pointers are expected to have been taken care of as this container will completely forget about them. */ void DropContentOwnership() { for (uint n = 0; n < this->usage; ++n) this->data[n] = 0; this->usage = 0; } //---------------------------------------------------------------------- AutoStack(uint size = 0, uint step = 64) : Stack (size, step) {} virtual ~AutoStack() { Clear(); } }; } // GS #endif // __NSTACK__