first commit
This commit is contained in:
150
include/platform/container/nstack.h
Normal file
150
include/platform/container/nstack.h
Normal file
@ -0,0 +1,150 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
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__
|
||||
Reference in New Issue
Block a user