151 lines
3.6 KiB
C++
151 lines
3.6 KiB
C++
/* -----------------------------------------------------------------------------
|
|
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 T> class Stack
|
|
{
|
|
protected:
|
|
|
|
Array <T> 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 <T> &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 <T> &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 <class T> struct AutoStack : public Stack <T>
|
|
{
|
|
//----------------------------------------------------------------------
|
|
virtual void Transfer(Stack <T> &from)
|
|
{
|
|
for (uint n = 0; n < this->usage; ++n)
|
|
delete this->data[n];
|
|
Stack <T> ::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 <T> ::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 <T> (size, step) {}
|
|
virtual ~AutoStack() { Clear(); }
|
|
};
|
|
|
|
} // GS
|
|
|
|
|
|
#endif // __NSTACK__
|