wibble  1.1
amorph.h
Go to the documentation of this file.
1 
6 #include <iostream> // for noise
7 
8 #include <wibble/mixin.h>
9 #include <wibble/cast.h>
10 #include <wibble/maybe.h>
11 #include <wibble/sfinae.h>
12 #include <wibble/test.h>
13 
14 #ifndef WIBBLE_AMORPH_H
15 #define WIBBLE_AMORPH_H
16 
17 namespace wibble {
18 
19 template< typename _T >
20 struct ReturnType {
21  typedef _T T;
22 };
23 
24 template<>
25 struct ReturnType< void > {
26  typedef Unit T;
27 };
28 
29 template< typename F, typename R >
31  inline typename ReturnType< R >::T call(
32  typename F::argument_type a )
33  {
34  return f( a );
35  };
36 };
37 
38 
39 template< typename F >
40 struct SanitizeReturn< F, void > {
41  inline Unit call( typename F::argument_type a )
42  {
43  f( a );
44  return Unit();
45  }
46 };
47 
48 template< int A >
49 struct IsZero {
50  static const bool value = false;
51 };
52 
53 template<>
54 struct IsZero< 0 > {
55  static const bool value = true;
56 };
57 
58 template< typename T >
59 struct IsPolymorphic {
60  struct A : T {
61  virtual ~A();
62  };
63  struct B : T {};
64  static const bool value = IsZero< sizeof( A ) - sizeof( B ) >::value;
65 };
66 
67 template< typename F >
69  SanitizeResultType( F _f ) : f( _f ) {}
71 
72  result_type operator()( typename F::argument_type a ) {
74  }
75 
76 
77  F f;
78 };
79 
80 #ifndef SWIG_I
81 struct Baseless {};
82 
83 struct VirtualBase {
84  virtual ~VirtualBase() {}
85 };
86 
90 template< typename Interface >
91 struct MorphInterface : public Interface {
92  virtual VirtualBase *virtualBase() { return 0; }
93  virtual MorphInterface *constructCopy( void *where = 0, unsigned int available = 0 ) const = 0;
94  virtual void destroy( unsigned int available = 0 ) = 0;
95  virtual ~MorphInterface() {}
96  virtual bool leq( const MorphInterface * ) const = 0;
97 };
98 
101  void *operator new( size_t bytes, void *where, unsigned available ) {
102  if ( bytes > available || where == 0 ) {
103  where = ::operator new( bytes );
104  return where;
105  }
106  return where;
107  }
108  void *operator new( size_t bytes ) {
109  return ::operator new( bytes );
110  }
111 };
112 
113 template< typename W, typename Interface >
114 struct MorphBase : MorphInterface< Interface > {
115  MorphBase( const W &w ) : m_wrapped( w ) {}
116 
117  template< typename _W >
119  return dynamic_cast< VirtualBase * >( &m_wrapped );
120  }
121 
122  template< typename _W >
125  return 0;
126  }
127 
129  return virtualBase< W >();
130  }
131 
132  W &wrapped() {
133  return m_wrapped;
134  }
135 
136 protected:
138 };
139 
140 template< typename Self, typename W, typename Interface >
141 struct Morph : MorphBase< W, Interface >,
142  mixin::Comparable< Morph< Self, W, Interface > >,
144 {
145  typedef W Wrapped;
146 
147  Morph( const Wrapped &w ) : MorphBase< W, Interface >( w ) {}
148 
149  const Self &self() const { return *static_cast< const Self * >( this ); }
150 
151  bool operator<=( const Morph &o ) const {
152  return wrapped().operator<=( o.wrapped() );
153  }
154 
155  // evaluation of correctness of definition should be done
156  virtual bool leq( const MorphInterface< Interface > *_o ) const {
157  const Morph *o = dynamic_cast< const Morph * >( _o );
158  if ( !o ) {
159  if ( typeid( Morph ).before( typeid( _o ) ) )
160  return true;
161  else
162  return false;
163  }
164  return wrapped() <= o->wrapped();
165  }
166 
168  void *where, unsigned int available ) const
169  {
170  return new( where, available ) Self( self() );
171  }
172 
173  virtual void destroy( unsigned int available ) {
174  if ( sizeof( Morph ) <= available ) {
175  this->~Morph();
176  } else {
177  delete this;
178  }
179  }
180 
181  const Wrapped &wrapped() const {
182  return this->m_wrapped;
183  }
184 
186  return this->m_wrapped;
187  }
188 
189  virtual ~Morph() {}
190 };
191 #endif
192 
260 #ifndef WIBBLE_AMORPH_PADDING
261 #define WIBBLE_AMORPH_PADDING 0
262 #endif
263 template<int Padding1> class AmorphPadder
264 {
265  int m_padding[ Padding1 ];
266 };
267 template<> class AmorphPadder<0>
268 {
269 };
270 
271 template< typename Self, typename _Interface, int Padding = WIBBLE_AMORPH_PADDING >
272 struct Amorph {
273  typedef _Interface Interface;
274  // typedef MorphInterface< Interface > Morp;
275 
276  template <typename T> struct Convert {
277  typedef T type;
278  };
279 
280  /* Amorph( const Interface &b ) {
281  setInterfacePointer( &b );
282  } */
283 
286  }
287 
288  Amorph( const Amorph &a ) {
290  // setInterfacePointer( a.implementation() );
291  }
292 
293  Amorph() : m_impl( 0 ) {}
294 
295  const Self &self() const {
296  return *static_cast< const Self * >( this );
297  }
298 
299  Self &self() {
300  return *static_cast<Self *>( this );
301  }
302 
303  bool leq( const Self &i ) const {
304  if ( morphInterface() )
305  if ( i.morphInterface() )
306  return morphInterface()->leq( i.morphInterface() );
307  else
308  return false; // it's false that non-0 <= 0
309  else
310  return !i.morphInterface(); // 0 <= 0 holds, but 0 <=
311  // non-0 doesn't
312  }
313 
314  bool operator<=( const Self &i ) const { return leq( i ); }
315 
316  void setInterfacePointer( const Interface *i ) {
317  if ( !i ) {
318  m_impl = 0;
319  return;
320  }
321 
322  /* assert( dynamic_cast< const MorphInterface * >( i ) );
323  assert( dynamic_cast< const Interface * >(
324  dynamic_cast< const MorphInterface * >( i ) ) ); */
325 
326  m_impl = dynamic_cast< const MorphInterface< Interface > * >( i )->constructCopy(
327  &m_padding, sizeof( m_padding ) );
328 
329  // assert( dynamic_cast< const Interface * >( m_impl ) );
330  }
331 
333  if ( !i ) {
334  m_impl = 0;
335  return;
336  }
337  m_impl = i->constructCopy( &m_padding, sizeof( m_padding ) );
338  }
339 
340  Amorph &operator=( const Amorph &i ) {
342  return *this;
343  }
344 
346  if ( morphInterface() )
347  morphInterface()->destroy( sizeof( m_padding ) );
348  }
349 
350  template< typename F >
352  typedef typename F::argument_type T;
354  T *ptr = impl<T>();
355  if (ptr) {
356  return rt::Just( func(*ptr) );
357  }
358  return rt::Nothing();
359  }
360 
361  const Interface *implementation() const {
362  // return dynamic_cast< const Interface * >( m_impl );
363  return static_cast< const Interface * >( m_impl );
364  }
365 
367  // return dynamic_cast< Interface * >( m_impl );
368  return static_cast< Interface * >( m_impl );
369  }
370 
372  return m_impl;
373  // return dynamic_cast< MorphInterface< * >( m_impl );
374  }
375 
376  const Interface &wrapped() const {
377  return *implementation();
378  }
379 
381  return *implementation();
382  }
383 
384  template< typename T >
385  bool is() const {
386  return impl< T >();
387  }
388 
389  bool isVoid() const { return !m_impl; }
390 
391  template< typename T >
392  T *impl() const {
393  T *p = dynamic_cast< T * >( m_impl );
394  if ( !p ) {
395  MorphBase< T, Interface > *m = dynamic_cast< MorphBase< T, Interface > * >( m_impl );
396  if ( m ) p = &(m->wrapped());
397  }
398  if ( !p ) {
399  p = dynamic_cast< T * >( morphInterface()->virtualBase() );
400  }
401  return p;
402  }
403 
404 private:
405  unsigned int reservedSize() { return sizeof( m_padding ) + sizeof( m_impl ); }
406  AmorphPadder<Padding> m_padding;
407  MorphInterface< Interface > *m_impl;
408  // Interface *m_impl;
409 };
410 
411 #ifndef SWIG_I
412 template< typename T, typename X >
413 typename X::template Convert<T>::type &downcast( const X &a )
414 {
415  return *a.template impl< T >();
416 }
417 
418 #endif
419 
420 }
421 
422 #endif