amorph.h
Go to the documentation of this file.
#include <iostream> // for noise
#include <wibble/mixin.h>
#include <wibble/cast.h>
#include <wibble/maybe.h>
#include <wibble/sfinae.h>
#include <wibble/test.h>
#ifndef WIBBLE_AMORPH_H
#define WIBBLE_AMORPH_H
namespace wibble {
template< typename _T >
struct ReturnType {
typedef _T T;
};
template<>
struct ReturnType< void > {
typedef Unit T;
};
template< typename F, typename R >
struct SanitizeReturn {
inline typename ReturnType< R >::T call(
typename F::argument_type a )
{
return f( a );
};
};
template< typename F >
struct SanitizeReturn< F, void > {
inline Unit call( typename F::argument_type a )
{
f( a );
return Unit();
}
};
template< int A >
struct IsZero {
static const bool value = false;
};
template<>
struct IsZero< 0 > {
static const bool value = true;
};
template< typename T >
struct IsPolymorphic {
struct A : T {
virtual ~A();
};
struct B : T {};
static const bool value = IsZero< sizeof( A ) - sizeof( B ) >::value;
};
template< typename F >
struct SanitizeResultType {
SanitizeResultType( F _f ) : f( _f ) {}
typedef typename ReturnType< typename F::result_type >::T result_type;
result_type operator()( typename F::argument_type a ) {
return SanitizeReturn< F, typename F::result_type >().call( a );
}
F f;
};
#ifndef SWIG_I
struct Baseless {};
struct VirtualBase {
virtual ~VirtualBase() {}
};
template< typename Interface >
struct MorphInterface : public Interface {
virtual VirtualBase *virtualBase() { return 0; }
virtual MorphInterface *constructCopy( void *where = 0, unsigned int available = 0 ) const = 0;
virtual void destroy( unsigned int available = 0 ) = 0;
virtual ~MorphInterface() {}
virtual bool leq( const MorphInterface * ) const = 0;
};
struct MorphAllocator {
void *operator new( size_t bytes, void *where, unsigned available ) {
if ( bytes > available || where == 0 ) {
where = ::operator new( bytes );
return where;
}
return where;
}
void *operator new( size_t bytes ) {
return ::operator new( bytes );
}
};
template< typename W, typename Interface >
struct MorphBase : MorphInterface< Interface > {
MorphBase( const W &w ) : m_wrapped( w ) {}
template< typename _W >
typename EnableIf< IsPolymorphic< _W >, VirtualBase *>::T virtualBase() {
return dynamic_cast< VirtualBase * >( &m_wrapped );
}
template< typename _W >
typename EnableIf< TNot< IsPolymorphic< _W > >, VirtualBase *>::T
virtualBase() {
return 0;
}
virtual VirtualBase *virtualBase() {
return virtualBase< W >();
}
W &wrapped() {
return m_wrapped;
}
protected:
W m_wrapped;
};
template< typename Self, typename W, typename Interface >
struct Morph : MorphBase< W, Interface >,
mixin::Comparable< Morph< Self, W, Interface > >,
MorphAllocator
{
typedef W Wrapped;
Morph( const Wrapped &w ) : MorphBase< W, Interface >( w ) {}
const Self &self() const { return *static_cast< const Self * >( this ); }
bool operator<=( const Morph &o ) const {
return wrapped().operator<=( o.wrapped() );
}
// evaluation of correctness of definition should be done
virtual bool leq( const MorphInterface< Interface > *_o ) const {
const Morph *o = dynamic_cast< const Morph * >( _o );
if ( !o ) {
if ( typeid( Morph ).before( typeid( _o ) ) )
return true;
else
return false;
}
return wrapped() <= o->wrapped();
}
virtual MorphInterface< Interface > *constructCopy(
void *where, unsigned int available ) const
{
return new( where, available ) Self( self() );
}
virtual void destroy( unsigned int available ) {
if ( sizeof( Morph ) <= available ) {
this->~Morph();
} else {
delete this;
}
}
const Wrapped &wrapped() const {
return this->m_wrapped;
}
Wrapped &wrapped() {
return this->m_wrapped;
}
virtual ~Morph() {}
};
#endif
#ifndef WIBBLE_AMORPH_PADDING
#define WIBBLE_AMORPH_PADDING 0
#endif
template<int Padding1> class AmorphPadder
{
int m_padding[ Padding1 ];
};
template<> class AmorphPadder<0>
{
};
template< typename Self, typename _Interface, int Padding = WIBBLE_AMORPH_PADDING >
struct Amorph {
typedef _Interface Interface;
// typedef MorphInterface< Interface > Morp;
template <typename T> struct Convert {
typedef T type;
};
/* Amorph( const Interface &b ) {
setInterfacePointer( &b );
} */
Amorph( const MorphInterface< Interface > &b ) {
setMorphInterfacePointer( &b );
}
Amorph( const Amorph &a ) {
setMorphInterfacePointer( a.morphInterface() );
// setInterfacePointer( a.implementation() );
}
Amorph() : m_impl( 0 ) {}
const Self &self() const {
return *static_cast< const Self * >( this );
}
Self &self() {
return *static_cast<Self *>( this );
}
bool leq( const Self &i ) const {
if ( morphInterface() )
if ( i.morphInterface() )
return morphInterface()->leq( i.morphInterface() );
else
return false; // it's false that non-0 <= 0
else
return !i.morphInterface(); // 0 <= 0 holds, but 0 <=
// non-0 doesn't
}
bool operator<=( const Self &i ) const { return leq( i ); }
void setInterfacePointer( const Interface *i ) {
if ( !i ) {
m_impl = 0;
return;
}
/* assert( dynamic_cast< const MorphInterface * >( i ) );
assert( dynamic_cast< const Interface * >(
dynamic_cast< const MorphInterface * >( i ) ) ); */
m_impl = dynamic_cast< const MorphInterface< Interface > * >( i )->constructCopy(
&m_padding, sizeof( m_padding ) );
// assert( dynamic_cast< const Interface * >( m_impl ) );
}
void setMorphInterfacePointer( const MorphInterface< Interface > *i ) {
if ( !i ) {
m_impl = 0;
return;
}
m_impl = i->constructCopy( &m_padding, sizeof( m_padding ) );
}
Amorph &operator=( const Amorph &i ) {
setInterfacePointer( i.implementation() );
return *this;
}
~Amorph() {
if ( morphInterface() )
morphInterface()->destroy( sizeof( m_padding ) );
}
template< typename F >
Maybe< typename F::result_type > ifType( F func ) {
typedef typename F::argument_type T;
typedef Maybe< typename F::result_type > rt;
T *ptr = impl<T>();
if (ptr) {
return rt::Just( func(*ptr) );
}
return rt::Nothing();
}
const Interface *implementation() const {
// return dynamic_cast< const Interface * >( m_impl );
return static_cast< const Interface * >( m_impl );
}
Interface *implementation() {
// return dynamic_cast< Interface * >( m_impl );
return static_cast< Interface * >( m_impl );
}
MorphInterface< Interface > *morphInterface() const {
return m_impl;
// return dynamic_cast< MorphInterface< * >( m_impl );
}
const Interface &wrapped() const {
return *implementation();
}
Interface &wrapped() {
return *implementation();
}
template< typename T >
bool is() const {
return impl< T >();
}
bool isVoid() const { return !m_impl; }
template< typename T >
T *impl() const {
T *p = dynamic_cast< T * >( m_impl );
if ( !p ) {
MorphBase< T, Interface > *m = dynamic_cast< MorphBase< T, Interface > * >( m_impl );
if ( m ) p = &(m->wrapped());
}
if ( !p ) {
p = dynamic_cast< T * >( morphInterface()->virtualBase() );
}
return p;
}
private:
unsigned int reservedSize() { return sizeof( m_padding ) + sizeof( m_impl ); }
AmorphPadder<Padding> m_padding;
MorphInterface< Interface > *m_impl;
// Interface *m_impl;
};
#ifndef SWIG_I
template< typename T, typename X >
typename X::template Convert<T>::type &downcast( const X &a )
{
return *a.template impl< T >();
}
#endif
}
#endif
cast.h
wibble::AmorphPadder
Definition: amorph.h:264
maybe.h
mixin.h
wibble
Definition: amorph.h:17
wibble::downcast
X::template Convert< T >::type & downcast(const X &a)
Definition: amorph.h:413
sfinae.h
wibble::Amorph::Convert
Definition: amorph.h:276
wibble::Amorph::Convert::type
T type
Definition: amorph.h:277
wibble::Amorph
Definition: amorph.h:272
wibble::Amorph::implementation
const Interface * implementation() const
Definition: amorph.h:361
wibble::Amorph::Amorph
Amorph(const Amorph &a)
Definition: amorph.h:288
wibble::Amorph::wrapped
Interface & wrapped()
Definition: amorph.h:380
wibble::Amorph::morphInterface
MorphInterface< Interface > * morphInterface() const
Definition: amorph.h:371
wibble::Amorph::leq
bool leq(const Self &i) const
Definition: amorph.h:303
wibble::Amorph::implementation
Interface * implementation()
Definition: amorph.h:366
wibble::Amorph::ifType
Maybe< typename F::result_type > ifType(F func)
Definition: amorph.h:351
wibble::Amorph::operator=
Amorph & operator=(const Amorph &i)
Definition: amorph.h:340
wibble::Amorph::impl
T * impl() const
Definition: amorph.h:392
wibble::Amorph::~Amorph
~Amorph()
Definition: amorph.h:345
wibble::Amorph::Amorph
Amorph()
Definition: amorph.h:293
wibble::Amorph::setInterfacePointer
void setInterfacePointer(const Interface *i)
Definition: amorph.h:316
wibble::Amorph::isVoid
bool isVoid() const
Definition: amorph.h:389
wibble::Amorph::operator<=
bool operator<=(const Self &i) const
Definition: amorph.h:314
wibble::Amorph::Interface
_Interface Interface
Definition: amorph.h:273
wibble::Amorph::setMorphInterfacePointer
void setMorphInterfacePointer(const MorphInterface< Interface > *i)
Definition: amorph.h:332
wibble::Amorph::Amorph
Amorph(const MorphInterface< Interface > &b)
Definition: amorph.h:284
wibble::Amorph::wrapped
const Interface & wrapped() const
Definition: amorph.h:376
wibble::Amorph::is
bool is() const
Definition: amorph.h:385
wibble::Baseless
Definition: amorph.h:81
wibble::EnableIf
Definition: sfinae.h:90
wibble::IsPolymorphic::A
Definition: amorph.h:60
wibble::IsPolymorphic::A::~A
virtual ~A()
wibble::IsPolymorphic::B
Definition: amorph.h:63
wibble::IsPolymorphic
Definition: amorph.h:59
wibble::IsPolymorphic::value
static const bool value
Definition: amorph.h:64
wibble::IsZero
Definition: amorph.h:49
wibble::IsZero::value
static const bool value
Definition: amorph.h:50
wibble::Maybe
Definition: maybe.h:29
wibble::MorphAllocator
custom allocator for morph classes
Definition: amorph.h:100
wibble::MorphBase
Definition: amorph.h:114
wibble::MorphBase::virtualBase
virtual VirtualBase * virtualBase()
Definition: amorph.h:128
wibble::MorphBase::m_wrapped
W m_wrapped
Definition: amorph.h:137
wibble::MorphBase::virtualBase
EnableIf< TNot< IsPolymorphic< _W > >, VirtualBase * >::T virtualBase()
Definition: amorph.h:124
wibble::MorphBase::MorphBase
MorphBase(const W &w)
Definition: amorph.h:115
wibble::MorphBase::virtualBase
EnableIf< IsPolymorphic< _W >, VirtualBase * >::T virtualBase()
Definition: amorph.h:118
wibble::MorphBase::wrapped
W & wrapped()
Definition: amorph.h:132
wibble::MorphInterface
An interface implemented by all morph classes.
Definition: amorph.h:91
wibble::MorphInterface::virtualBase
virtual VirtualBase * virtualBase()
Definition: amorph.h:92
wibble::MorphInterface::~MorphInterface
virtual ~MorphInterface()
Definition: amorph.h:95
wibble::MorphInterface::leq
virtual bool leq(const MorphInterface *) const =0
wibble::MorphInterface::constructCopy
virtual MorphInterface * constructCopy(void *where=0, unsigned int available=0) const =0
wibble::MorphInterface::destroy
virtual void destroy(unsigned int available=0)=0
wibble::Morph
Definition: amorph.h:144
wibble::Morph::Wrapped
W Wrapped
Definition: amorph.h:145
wibble::Morph::wrapped
Wrapped & wrapped()
Definition: amorph.h:185
wibble::Morph::operator<=
bool operator<=(const Morph &o) const
Definition: amorph.h:151
wibble::Morph::~Morph
virtual ~Morph()
Definition: amorph.h:189
wibble::Morph::Morph
Morph(const Wrapped &w)
Definition: amorph.h:147
wibble::Morph::constructCopy
virtual MorphInterface< Interface > * constructCopy(void *where, unsigned int available) const
Definition: amorph.h:167
wibble::Morph::leq
virtual bool leq(const MorphInterface< Interface > *_o) const
Definition: amorph.h:156
wibble::Morph::destroy
virtual void destroy(unsigned int available)
Definition: amorph.h:173
wibble::Morph::wrapped
const Wrapped & wrapped() const
Definition: amorph.h:181
wibble::ReturnType< void >::T
Unit T
Definition: amorph.h:26
wibble::ReturnType
Definition: amorph.h:20
wibble::ReturnType::T
_T T
Definition: amorph.h:21
wibble::SanitizeResultType
Definition: amorph.h:68
wibble::SanitizeResultType::operator()
result_type operator()(typename F::argument_type a)
Definition: amorph.h:72
wibble::SanitizeResultType::SanitizeResultType
SanitizeResultType(F _f)
Definition: amorph.h:69
wibble::SanitizeResultType::f
F f
Definition: amorph.h:77
wibble::SanitizeResultType::result_type
ReturnType< typename F::result_type >::T result_type
Definition: amorph.h:70
wibble::SanitizeReturn< F, void >::call
Unit call(typename F::argument_type a)
Definition: amorph.h:41
wibble::SanitizeReturn
Definition: amorph.h:30
wibble::SanitizeReturn::call
ReturnType< R >::T call(typename F::argument_type a)
Definition: amorph.h:31
wibble::Unit
Definition: sfinae.h:8
wibble::VirtualBase
Definition: amorph.h:83
wibble::VirtualBase::~VirtualBase
virtual ~VirtualBase()
Definition: amorph.h:84
wibble::mixin::Comparable
Definition: mixin.h:13
test.h