#include <jem/base/limits.h>
#include <jem/base/System.h>
#include <jem/util/Timer.h>
#include <jem/util/FastAllocator.h>
#include <jem/util/StdAllocator.h>
#include <jem/util/MallocAllocator.h>
#include <new>
template <class T, class Alloc = StdAllocator>
class Stack
{
public:
Stack ();
~Stack ();
inline void push
( const T& val );
void clear
( int n = maxOf<int>() );
private:
struct Node_
{
inline Node_
( Node_* nxt,
const T& val );
Node_* next;
T value;
};
Node_* top_;
Alloc allocator_;
};
template <class T, class Alloc>
Stack<T,Alloc>::Stack() :
top_ ( 0 ),
allocator_ ( sizeof(Node_) )
{}
template <class T, class Alloc>
Stack<T,Alloc>::~Stack ()
{
clear ();
}
template <class T, class Alloc>
inline void Stack<T,Alloc>::push ( const T& val )
{
Node_* n = (Node_*) allocator_.alloc ();
new (n) Node_ ( top_, val );
top_ = n;
}
template <class T, class Alloc>
void Stack<T,Alloc>::clear ( int k )
{
Node_* n;
while ( top_ && k > 0 )
{
n = top_;
top_ = top_->next;
n->~Node_ ();
allocator_.dealloc ( n );
k--;
}
}
template <class T, class Alloc>
inline Stack<T,Alloc>::Node_::Node_
( Node_* nxt,
const T& val ) :
next ( nxt ),
value ( val )
{}
template <class Alloc>
void pushInts
( Stack<int,Alloc>& stack,
int n )
{
for ( int i = 0; i < n; i++ )
{
stack.push ( i );
}
}
template <class Alloc>
void perftest
( Stack<int,Alloc>& s,
{
const int N = 1000000;
print ( out,
"Testing ", allocName,
" ... ", flush );
pushInts ( s, N );
s.clear ( N / 2 );
pushInts ( s, N / 2 );
s.clear ( 2 * N / 3 );
pushInts ( s, N / 3 );
s.clear ();
}
int run ()
{
Stack<int,FastAllocator > s1;
Stack<int,StdAllocator > s2;
Stack<int,MallocAllocator> s3;
print ( System::out(),
'\n' );
perftest ( s1, "FastAllocator " );
perftest ( s2, "StdAllocator " );
perftest ( s3, "MallocAllocator" );
print ( System::out(),
'\n' );
return 0;
}
int main ()
{
return System::exec ( & run );
}