wibble
0.1.28
|
00001 // -*- C++ -*- (c) 2007 Petr Rockai <me@mornfall.net> 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 }