static char cvsid[] = "@(#)$Id: Stack.cpp,v 1.2 1999/03/03 19:09:39 philogelos Exp $";
static char debugFileId[] = __FILE__;
#include "containers/lists/List.hpp"
#include "containers/EmptyStack.hpp"
#include "containers/Stack.hpp"
#include "LinkManager.hpp"
#include "PGuard.hpp"
#include "OGuard.hpp"
#include "Debug.hpp"
Stack::Stack()
{
init();
}
Stack::Stack( Stack &aSource )
{
PGuard _this( this, this );
OGuard _source( &aSource, this );
init();
for( aSource.elements -> toFirst() ;
!( aSource.elements -> atEnd() ) ;
aSource.elements -> next() )
{
push( aSource.elements -> getCurrentValue() );
}
postC_( getCardinality() == aSource.getCardinality() );
postC_( equals( &aSource ) );
}
Stack::~Stack()
{
preC_( elements != ( List * ) NULL );
LinkManager::free( this, elements );
}
void Stack::push( Top *anElement )
{
elements -> append( anElement );
}
Top *Stack::pop() THROWS( EmptyStack * )
{
OGuard _this( this, this );
if( isEmpty() )
{
throw new EmptyStack( "Stack::pop()", null );
}
return( elements -> betail() );
}
void Stack::dup()
{
OGuard _this( this, this );
push( top() );
}
void Stack::swap() THROWS( EmptyStack * )
{
Top *first;
Top *second;
OGuard _this( this, this );
if( isEmpty() )
{
throw new EmptyStack( "Stack::swap()", null );
}
first = pop();
if( isEmpty() )
{
throw new EmptyStack( "Stack::swap()-2", null );
}
second = pop();
push( first );
push( second );
}
Top *Stack::exchange( Top *anElement ) THROWS( EmptyStack * )
{
OGuard _this( this, this );
OGuard _element( anElement, this );
Top *element;
if( isEmpty() )
{
throw new EmptyStack( "Stack::exchange()", null );
}
element = pop();
push( anElement );
return element;
}
Top *Stack::top() const THROWS( EmptyStack * )
{
OGuard _this( this, this );
Top *element;
if( isEmpty() )
{
throw new EmptyStack( "Stack::top()", null );
}
element = ( ( Stack * ) this ) -> pop();
( ( Stack * ) this ) -> push( element );
return element;
}
PositionFactory *Stack::getDefaultPositionFactory() const
{
return ( PositionFactory * ) NIL;
}
boolean Stack::canRemoveSlot( Position *aPosition ) const
{
return false;
}
void Stack::removeSlot( Position *aPosition )
{
}
boolean Stack::isEmpty() const
{
return( elements -> isEmpty() );
}
Index Stack::getCardinality() const
{
return( elements -> getCardinality() );
}
boolean Stack::isValid( const Position *aPosition ) const
{
OGuard _position( aPosition, this );
preC_( aPosition != ( const Position * ) NIL );
return( aPosition -> isValid() );
}
PositionEnumeration *Stack::getEnumeration() const
{
return LayeredContainer::getEnumeration();
}
MutablePositionEnumeration *Stack::getMutableEnumeration() const
{
return MutableLayeredContainer::getMutableEnumeration();
}
Position *Stack::getCurrentPunct() const
{
return new FromBottomOfStackPosition
( this, elements -> getCardinality() - 1 );
}
Position *Stack::getAlwaysPunct() const
{
return new FromTopOfStackPosition( this, 0 );
}
Top *Stack::clone() const
{
return new Stack( ( Stack & ) *this );
}
String Stack::getClassName() const
{
return "Stack";
}
void Stack::init()
{
elements = new List();
LinkManager::reg( this, elements );
}
MutableContainer *Stack::getBaseMutableContainer() const
{
return elements;
}
StackPosition::StackPosition( const Stack *aHost, const Index anOffset ) :
PositionAdapter( ( Container * ) aHost ),
offset( anOffset )
{
stack = aHost;
postC_( isValid() );
}
Stack *StackPosition::getStack() const
{
return ( Stack * ) stack;
}
boolean StackPosition::isValid() const
{
return( ( 0 <= offset ) &&
( offset < ( getStack() -> getCardinality() ) ) );
}
FromTopOfStackPosition::FromTopOfStackPosition( const Stack *aHost, const Index anOffset ) :
StackPosition( aHost, anOffset ),
PositionAdapter( ( Container * ) aHost )
{}
Top *FromTopOfStackPosition::getValue() const
{
preC_( isValid() );
return( getStack() -> elements ->
getAt( getStack() -> getCardinality() - offset - 1 ) );
}
FromBottomOfStackPosition::FromBottomOfStackPosition( const Stack *aHost, const Index anOffset ) :
StackPosition( aHost, anOffset ),
PositionAdapter( ( Container * ) aHost )
{}
Top *FromBottomOfStackPosition::getValue() const
{
preC_( isValid() );
return( getStack() -> elements -> getAt( offset ) );
}
#if defined( TESTING )
boolean Stack::tester( int ) const
{
{
Debug::getLogger() -> log( "Stack Testing: constructor" );
Stack *target;
target = new Stack();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
}
{
Debug::getLogger() -> log( "Stack Testing: push" );
Stack *target;
target = new Stack();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> push( new String( "1" ) );
target -> push( new String( "2" ) );
target -> push( new String( "3" ) );
Debug::getLogger() -> logObject( "filled: %s", target );
}
{
Debug::getLogger() -> log( "Stack Testing: copy" );
Stack *target;
Stack *copy;
Top *raw;
target = new Stack();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> push( new String( "1" ) );
target -> push( new String( "2" ) );
target -> push( new String( "3" ) );
Debug::getLogger() -> logObject( "filled: %s", target );
raw = target -> clone();
copy = TCAST( raw, Stack );
OGuard _copy( copy, this );
Debug::getLogger() -> logObject( "copy: %s", target );
}
return true;
}
#endif
#if defined(_INLINE)
#include "../src/Debug.ipp"
#endif