#if !defined(_INLINE)
static char cvsid[] = "@(#)$Id: Set.cpp,v 1.4 1999/05/22 13:00:54 philogelos Exp $";
static char debugFileId[] = __FILE__;
#endif
#include "iter/enumerations/MappedEnumeration.hpp"
#include "containers/EmptyContainer.hpp"
#include "containers/lists/List.hpp"
#include "containers/Set.hpp"
#include "Debug.hpp"
#include "LinkManager.hpp"
#include "OGuard.hpp"
#include "PGuard.hpp"
Set::Set()
{
core = new List();
LinkManager::reg( this, core );
}
Set::~Set()
{
LinkManager::free( this, core );
}
MutablePositionEnumeration *Set::getMutableEnumeration() const
{
return MutablePositionEnumeration::createMutableFrom
( TypedEnumeration< MutablePosition >::upcast
( new MappedEnumeration( core -> getEnumeration(),
new SetPositionMap( ( Set * ) this ) ) ) );
}
Top *Set::setValue( MutablePosition *aPosition, Top *aNewValue )
{
preC_( aPosition != ( MutablePosition * ) NIL );
preC_( aPosition -> isValid() );
return( aPosition -> setValue( aNewValue ) );
}
Top *Set::getValue( const Position *aPosition )
{
preC_( aPosition != ( MutablePosition * ) NIL );
preC_( aPosition -> isValid() );
return( aPosition -> getValue() );
}
PositionFactory *Set::getDefaultPositionFactory() const
{
return new SetPositionFactory( ( Set * ) this );
}
boolean Set::canRemoveSlot( Position *aPosition ) const
{
return false;
}
void Set::removeSlot( Position *aPosition )
{
}
void Set::add( const Top *anObject )
{
OGuard _this( this, this );
OGuard _core( getCore(), this );
OGuard _obj( anObject, this );
MutablePosition *pos;
pos = getNew( anObject );
OGuard _pos( pos, this );
OGuard _oldValue( pos -> setValue( ( Top * ) anObject ),
this );
}
Top *Set::getAny() const THROWS( EmptyContainer * )
{
OGuard _this( this, this );
OGuard _core( getCore(), this );
if( isEmpty() )
{
throw new EmptyContainer( "Set::getAny()", null );
}
return( getCore() -> car() );
}
Top *Set::getAndRemove() const
{
OGuard _this( this, this );
OGuard _core( getCore(), this );
Top *element;
element = getAny();
OGuard _element( element, this );
getCore() -> behead();
return element;
}
boolean Set::isEmpty() const
{
return( getCore() -> isEmpty() );
}
Index Set::getCardinality() const
{
return( getCore() -> getCardinality() );
}
Set::Set( List *aCore )
{
core = aCore;
LinkManager::reg( this, core );
}
Position *Set::unify( const Top *anObject ) const
{
OGuard _this( this, this );
OGuard _core( getCore(), this );
return( getCore() -> find( anObject ) );
}
MutablePosition *Set::getNew( const Top *anObject ) const
{
OGuard _this( this, this );
OGuard _core( getCore(), this );
OGuard _obj( anObject, this );
Position *pos;
MutablePosition *mpos;
pos = unify( anObject );
if( pos == ( Position * ) NIL )
{
PositionFactory *factory;
factory = getCore() -> getDefaultPositionFactory();
OGuard _factory( factory, this );
pos = factory -> createPosition();
}
mpos = DCAST( pos, MutablePosition );
PGuard _mpos( mpos, this );
postC_( mpos != ( MutablePosition * ) NIL );
postC_( mpos -> isValid() );
return mpos;
}
List *Set::getCore() const
{
return core;
}
Top *Set::clone() const
{
return new Set( new List( *getCore() ) );
}
String Set::getClassName() const
{
return "Set";
}
#if defined( TESTING )
boolean Set::tester( int ) const
{
{
Debug::getLogger() -> log( "Set Testing: constructor" );
Set *target;
target = new Set();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
if( !( target -> isEmpty() ) )
{
return false;
}
}
{
Debug::getLogger() -> log( "Set Testing: add" );
Set *target;
target = new Set();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> add( new String( "element-the-only" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
if( ( target -> getCardinality() ) != 1 )
{
return false;
}
}
{
Debug::getLogger() -> log( "Set Testing: add different" );
Set *target;
target = new Set();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> add( new String( "element-1" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
target -> add( new String( "element-2" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
if( ( target -> getCardinality() ) != 2 )
{
return false;
}
}
{
Debug::getLogger() -> log( "Set Testing: add same" );
Set *target;
target = new Set();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> add( new String( "element-the-same" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
target -> add( new String( "element-the-same" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
if( ( target -> getCardinality() ) != 1 )
{
return false;
}
}
{
Debug::getLogger() -> log( "Set Testing: getAny" );
Set *target;
target = new Set();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> add( new String( "element-get-any" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
if( !( target -> getAny() -> equals( new String( "element-get-any" ) ) ) )
{
return false;
}
}
{
Debug::getLogger() -> log( "Set Testing: getAndRemove" );
Set *target;
target = new Set();
OGuard _target( target, this );
Debug::getLogger() -> logObject( "Created fresh: %s", target );
target -> add( new String( "element-get-and-remove" ) );
Debug::getLogger() -> logObject( "Added: %s", target );
if( !( target -> getAny() -> equals( new String( "element-get-and-remove" ) ) ) )
{
return false;
}
}
return true;
}
#endif
SetPositionFactory::SetPositionFactory( Set *aSet )
{
preC_( aSet != ( Set * ) NIL );
LinkManager::reg( this, aSet );
set = aSet;
}
SetPositionFactory::~SetPositionFactory()
{
LinkManager::free( this, set );
}
MutablePosition *SetPositionFactory::createPosition()
{
return( set -> getNew( null ) );
}
SetPosition::SetPosition( Set *aContainer ) :
PositionAdapter( aContainer )
{
corePosition = ( MutablePosition * ) NIL;
}
SetPosition::~SetPosition()
{
LinkManager::free( this, corePosition );
}
void SetPosition::setCore( MutablePosition *aCorePosition )
{
preC_( aCorePosition != ( MutablePosition * ) NIL );
LinkManager::move( this, corePosition, aCorePosition );
corePosition = aCorePosition;
}
boolean SetPosition::isValid () const
{
preC_( corePosition != ( MutablePosition * ) NIL );
return( corePosition -> isValid() );
}
Top *SetPosition::setValue( Top *aNewValue )
{
preC_( corePosition != ( MutablePosition * ) NIL );
Position *pos;
MutablePosition *mpos;
OGuard _host( getContainer(), this );
pos = getSet() -> unify( aNewValue );
if( pos == ( Position * ) NIL )
{
return( corePosition -> setValue( aNewValue ) );
}
else
{
Top *oldValue;
mpos = DCAST( pos, MutablePosition );
PGuard _mpos( mpos, this );
postC_( mpos != ( MutablePosition * ) NIL );
postC_( mpos -> isValid() );
oldValue = getValue();
PGuard _oldValue( oldValue, this );
setCore( mpos );
return oldValue;
}
}
Top *SetPosition::getValue() const
{
preC_( corePosition != ( MutablePosition * ) NIL );
return( corePosition -> getValue() );
}
Set *SetPosition::getSet() const
{
Container *hostSet;
hostSet = getContainer();
test_( hostSet != ( Container * ) NIL );
return DCAST( hostSet, Set );
}
String SetPosition::getClassName() const
{
return "SetPosition";
}
SetPositionMap::SetPositionMap( Set *aSet )
{
preC_( aSet != ( Set * ) NIL );
LinkManager::reg( this, aSet );
set = aSet;
}
SetPositionMap::~SetPositionMap()
{
preC_( set != ( Set * ) NIL );
LinkManager::free( this, set );
set = ( Set * ) NIL;
}
Top *SetPositionMap::apply( Top *anArg )
{
preC_( set != ( Set * ) NIL );
preC_( anArg != ( Top * ) nil );
MutablePosition *position;
SetPosition *wrapper;
position = DCAST( anArg, MutablePosition );
test_( position != null );
OGuard _position( position, this );
wrapper = new SetPosition( set );
PGuard _wrapper( wrapper, this );
wrapper -> setCore( position );
return wrapper;
}
#if defined(_INLINE)
#include "../src/Debug.ipp"
#endif