wibble 0.1.28
|
00001 00006 #include <iostream> // for noise 00007 00008 #include <wibble/mixin.h> 00009 #include <wibble/cast.h> 00010 #include <wibble/maybe.h> 00011 #include <wibble/sfinae.h> 00012 #include <wibble/test.h> 00013 00014 #ifndef WIBBLE_AMORPH_H 00015 #define WIBBLE_AMORPH_H 00016 00017 namespace wibble { 00018 00019 template< typename _T > 00020 struct ReturnType { 00021 typedef _T T; 00022 }; 00023 00024 template<> 00025 struct ReturnType< void > { 00026 typedef Unit T; 00027 }; 00028 00029 template< typename F, typename R > 00030 struct SanitizeReturn { 00031 inline typename ReturnType< R >::T call( 00032 typename F::argument_type a ) 00033 { 00034 return f( a ); 00035 }; 00036 }; 00037 00038 00039 template< typename F > 00040 struct SanitizeReturn< F, void > { 00041 inline Unit call( typename F::argument_type a ) 00042 { 00043 f( a ); 00044 return Unit(); 00045 } 00046 }; 00047 00048 template< int A > 00049 struct IsZero { 00050 static const bool value = false; 00051 }; 00052 00053 template<> 00054 struct IsZero< 0 > { 00055 static const bool value = true; 00056 }; 00057 00058 template< typename T > 00059 struct IsPolymorphic { 00060 struct A : T { 00061 virtual ~A(); 00062 }; 00063 struct B : T {}; 00064 static const bool value = IsZero< sizeof( A ) - sizeof( B ) >::value; 00065 }; 00066 00067 template< typename F > 00068 struct SanitizeResultType { 00069 SanitizeResultType( F _f ) : f( _f ) {} 00070 typedef typename ReturnType< typename F::result_type >::T result_type; 00071 00072 result_type operator()( typename F::argument_type a ) { 00073 return SanitizeReturn< F, typename F::result_type >().call( a ); 00074 } 00075 00076 00077 F f; 00078 }; 00079 00080 #ifndef SWIG_I 00081 struct Baseless {}; 00082 00083 struct VirtualBase { 00084 virtual ~VirtualBase() {} 00085 }; 00086 00090 template< typename Interface > 00091 struct MorphInterface : public Interface { 00092 virtual VirtualBase *virtualBase() { return 0; } 00093 virtual MorphInterface *constructCopy( void *where = 0, unsigned int available = 0 ) const = 0; 00094 virtual void destroy( unsigned int available = 0 ) = 0; 00095 virtual ~MorphInterface() {} 00096 virtual bool leq( const MorphInterface * ) const = 0; 00097 }; 00098 00100 struct MorphAllocator { 00101 void *operator new( size_t bytes, void *where, unsigned available ) { 00102 if ( bytes > available || where == 0 ) { 00103 where = ::operator new( bytes ); 00104 return where; 00105 } 00106 return where; 00107 } 00108 void *operator new( size_t bytes ) { 00109 return ::operator new( bytes ); 00110 } 00111 }; 00112 00113 template< typename W, typename Interface > 00114 struct MorphBase : MorphInterface< Interface > { 00115 MorphBase( const W &w ) : m_wrapped( w ) {} 00116 00117 template< typename _W > 00118 typename EnableIf< IsPolymorphic< _W >, VirtualBase *>::T virtualBase() { 00119 return dynamic_cast< VirtualBase * >( &m_wrapped ); 00120 } 00121 00122 template< typename _W > 00123 typename EnableIf< TNot< IsPolymorphic< _W > >, VirtualBase *>::T 00124 virtualBase() { 00125 return 0; 00126 } 00127 00128 virtual VirtualBase *virtualBase() { 00129 return virtualBase< W >(); 00130 } 00131 00132 W &wrapped() { 00133 return m_wrapped; 00134 } 00135 00136 protected: 00137 W m_wrapped; 00138 }; 00139 00140 template< typename Self, typename W, typename Interface > 00141 struct Morph : MorphBase< W, Interface >, 00142 mixin::Comparable< Morph< Self, W, Interface > >, 00143 MorphAllocator 00144 { 00145 typedef W Wrapped; 00146 00147 Morph( const Wrapped &w ) : MorphBase< W, Interface >( w ) {} 00148 00149 const Self &self() const { return *static_cast< const Self * >( this ); } 00150 00151 bool operator<=( const Morph &o ) const { 00152 return wrapped().operator<=( o.wrapped() ); 00153 } 00154 00155 // evaluation of correctness of definition should be done 00156 virtual bool leq( const MorphInterface< Interface > *_o ) const { 00157 const Morph *o = dynamic_cast< const Morph * >( _o ); 00158 if ( !o ) { 00159 if ( typeid( Morph ).before( typeid( _o ) ) ) 00160 return true; 00161 else 00162 return false; 00163 } 00164 return wrapped() <= o->wrapped(); 00165 } 00166 00167 virtual MorphInterface< Interface > *constructCopy( 00168 void *where, unsigned int available ) const 00169 { 00170 return new( where, available ) Self( self() ); 00171 } 00172 00173 virtual void destroy( unsigned int available ) { 00174 if ( sizeof( Morph ) <= available ) { 00175 this->~Morph(); 00176 } else { 00177 delete this; 00178 } 00179 } 00180 00181 const Wrapped &wrapped() const { 00182 return this->m_wrapped; 00183 } 00184 00185 Wrapped &wrapped() { 00186 return this->m_wrapped; 00187 } 00188 00189 virtual ~Morph() {} 00190 }; 00191 #endif 00192 00260 #ifndef WIBBLE_AMORPH_PADDING 00261 #define WIBBLE_AMORPH_PADDING 0 00262 #endif 00263 template<int Padding1> class AmorphPadder 00264 { 00265 int m_padding[ Padding1 ]; 00266 }; 00267 template<> class AmorphPadder<0> 00268 { 00269 }; 00270 00271 template< typename Self, typename _Interface, int Padding = WIBBLE_AMORPH_PADDING > 00272 struct Amorph { 00273 typedef _Interface Interface; 00274 // typedef MorphInterface< Interface > Morp; 00275 00276 template <typename T> struct Convert { 00277 typedef T type; 00278 }; 00279 00280 /* Amorph( const Interface &b ) { 00281 setInterfacePointer( &b ); 00282 } */ 00283 00284 Amorph( const MorphInterface< Interface > &b ) { 00285 setMorphInterfacePointer( &b ); 00286 } 00287 00288 Amorph( const Amorph &a ) { 00289 setMorphInterfacePointer( a.morphInterface() ); 00290 // setInterfacePointer( a.implementation() ); 00291 } 00292 00293 Amorph() : m_impl( 0 ) {} 00294 00295 const Self &self() const { 00296 return *static_cast< const Self * >( this ); 00297 } 00298 00299 Self &self() { 00300 return *static_cast<Self *>( this ); 00301 } 00302 00303 bool leq( const Self &i ) const { 00304 if ( morphInterface() ) 00305 if ( i.morphInterface() ) 00306 return morphInterface()->leq( i.morphInterface() ); 00307 else 00308 return false; // it's false that non-0 <= 0 00309 else 00310 return !i.morphInterface(); // 0 <= 0 holds, but 0 <= 00311 // non-0 doesn't 00312 } 00313 00314 bool operator<=( const Self &i ) const { return leq( i ); } 00315 00316 void setInterfacePointer( const Interface *i ) { 00317 if ( !i ) { 00318 m_impl = 0; 00319 return; 00320 } 00321 00322 /* assert( dynamic_cast< const MorphInterface * >( i ) ); 00323 assert( dynamic_cast< const Interface * >( 00324 dynamic_cast< const MorphInterface * >( i ) ) ); */ 00325 00326 m_impl = dynamic_cast< const MorphInterface< Interface > * >( i )->constructCopy( 00327 &m_padding, sizeof( m_padding ) ); 00328 00329 // assert( dynamic_cast< const Interface * >( m_impl ) ); 00330 } 00331 00332 void setMorphInterfacePointer( const MorphInterface< Interface > *i ) { 00333 if ( !i ) { 00334 m_impl = 0; 00335 return; 00336 } 00337 m_impl = i->constructCopy( &m_padding, sizeof( m_padding ) ); 00338 } 00339 00340 Amorph &operator=( const Amorph &i ) { 00341 setInterfacePointer( i.implementation() ); 00342 return *this; 00343 } 00344 00345 ~Amorph() { 00346 if ( morphInterface() ) 00347 morphInterface()->destroy( sizeof( m_padding ) ); 00348 } 00349 00350 template< typename F > 00351 Maybe< typename F::result_type > ifType( F func ) { 00352 typedef typename F::argument_type T; 00353 typedef Maybe< typename F::result_type > rt; 00354 T *ptr = impl<T>(); 00355 if (ptr) { 00356 return rt::Just( func(*ptr) ); 00357 } 00358 return rt::Nothing(); 00359 } 00360 00361 const Interface *implementation() const { 00362 // return dynamic_cast< const Interface * >( m_impl ); 00363 return static_cast< const Interface * >( m_impl ); 00364 } 00365 00366 Interface *implementation() { 00367 // return dynamic_cast< Interface * >( m_impl ); 00368 return static_cast< Interface * >( m_impl ); 00369 } 00370 00371 MorphInterface< Interface > *morphInterface() const { 00372 return m_impl; 00373 // return dynamic_cast< MorphInterface< * >( m_impl ); 00374 } 00375 00376 const Interface &wrapped() const { 00377 return *implementation(); 00378 } 00379 00380 Interface &wrapped() { 00381 return *implementation(); 00382 } 00383 00384 template< typename T > 00385 bool is() const { 00386 return impl< T >(); 00387 } 00388 00389 bool isVoid() const { return !m_impl; } 00390 00391 template< typename T > 00392 T *impl() const { 00393 T *p = dynamic_cast< T * >( m_impl ); 00394 if ( !p ) { 00395 MorphBase< T, Interface > *m = dynamic_cast< MorphBase< T, Interface > * >( m_impl ); 00396 if ( m ) p = &(m->wrapped()); 00397 } 00398 if ( !p ) { 00399 p = dynamic_cast< T * >( morphInterface()->virtualBase() ); 00400 } 00401 return p; 00402 } 00403 00404 private: 00405 unsigned int reservedSize() { return sizeof( m_padding ) + sizeof( m_impl ); } 00406 AmorphPadder<Padding> m_padding; 00407 MorphInterface< Interface > *m_impl; 00408 // Interface *m_impl; 00409 }; 00410 00411 #ifndef SWIG_I 00412 template< typename T, typename X > 00413 typename X::template Convert<T>::type &downcast( const X &a ) 00414 { 00415 return *a.template impl< T >(); 00416 } 00417 00418 #endif 00419 00420 } 00421 00422 #endif