00001
00002
00003 #include <wibble/amorph.h>
00004
00005 namespace {
00006
00007 using namespace wibble;
00008
00009 struct TInterface {
00010 virtual int value() = 0;
00011 };
00012
00013 template< typename W >
00014 struct TMorph : Morph< TMorph< W >, W, TInterface >
00015 {
00016 TMorph() {}
00017 TMorph( const W &w ) : Morph< TMorph, W, TInterface >( w ) {}
00018
00019 virtual int value() { return this->wrapped().value(); }
00020 };
00021
00022 struct T : Amorph< T, TInterface >
00023 {
00024 T( const MorphInterface< TInterface > &i )
00025 : Amorph< T, TInterface >( i ) {}
00026 T() {}
00027
00028 int value() {
00029 return this->implementation()->value();
00030 }
00031 };
00032
00033 struct T1 : VirtualBase {
00034 virtual int value() const { return 1; }
00035 bool operator<=( const T1 &o ) const {
00036 return value() <= o.value();
00037 }
00038
00039 };
00040
00041 struct T3 : T1 {
00042 virtual int value() const { return 3; }
00043 };
00044
00045 struct T2 : VirtualBase {
00046 int value() const { return 2; }
00047 bool operator<=( const T2 &o ) const {
00048 return value() <= o.value();
00049 }
00050 };
00051
00052 struct ExtractT1Value {
00053 typedef int result_type;
00054 typedef T1 argument_type;
00055 int operator()( const T1 &t ) {
00056 return t.value();
00057 }
00058 };
00059
00060 template< typename T >
00061 TMorph< T > testMorph( T t ) {
00062 return TMorph< T >( t );
00063 }
00064
00065 struct TestAmorph {
00066 Test basic()
00067 {
00068 T1 t1;
00069 T2 t2;
00070 T3 t3;
00071 T t = testMorph( t1 );
00072 assert_eq( t.value(), 1 );
00073 assert_eq( t.ifType( ExtractT1Value() ), Maybe< int >::Just( 1 ) );
00074 t = testMorph( t2 );
00075 assert_eq( t.value(), 2 );
00076 assert_eq( t.ifType( ExtractT1Value() ), Maybe< int >::Nothing() );
00077 t = testMorph( t3 );
00078 assert_eq( t.value(), 3 );
00079 assert_eq( t.ifType( ExtractT1Value() ), Maybe< int >::Just( 3 ) );
00080 }
00081 };
00082
00083 }