CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // ====================================================================== 00002 // -*- C++ -*- 00003 // $Id: testIsConvertible.cc,v 1.2 2010/06/16 14:15:01 garren Exp $ 00004 // --------------------------------------------------------------------------- 00005 // Test is_convertible type trait 00006 // 00007 // W. E. Brown, 2010-03-19 00008 // based on work by John Maddock 00009 // ====================================================================== 00010 00011 00012 #include <CLHEP/Utility/noncopyable.h> 00013 #include <CLHEP/Utility/type_traits.h> 00014 #include <cassert> 00015 00016 00017 using namespace CLHEP; 00018 00019 00020 // define some test types: 00021 00022 enum enum_UDT{ one, two, three }; 00023 struct UDT 00024 { 00025 UDT() { }; 00026 ~UDT() { }; 00027 UDT(const UDT&); 00028 UDT& operator=(const UDT&); 00029 int i; 00030 00031 void f1(); 00032 int f2(); 00033 int f3(int); 00034 int f4(int, float); 00035 }; 00036 00037 typedef void(*f1)(); 00038 typedef int(*f2)(int); 00039 typedef int(*f3)(int, bool); 00040 typedef void (UDT::*mf1)(); 00041 typedef int (UDT::*mf2)(); 00042 typedef int (UDT::*mf3)(int); 00043 typedef int (UDT::*mf4)(int, float); 00044 typedef int (UDT::*mp); 00045 typedef int (UDT::*cmf)(int) const; 00046 00047 struct POD_UDT { int x; }; 00048 struct empty_UDT 00049 { 00050 empty_UDT() { }; 00051 empty_UDT(const empty_UDT&) { }; 00052 ~empty_UDT() { }; 00053 empty_UDT& operator=(const empty_UDT&){ return *this; } 00054 bool operator==(const empty_UDT&)const 00055 { return true; } 00056 }; 00057 struct empty_POD_UDT 00058 { 00059 bool operator==(const empty_POD_UDT&)const 00060 { return true; } 00061 }; 00062 union union_UDT 00063 { 00064 int x; 00065 double y; 00066 ~union_UDT() { } 00067 }; 00068 union POD_union_UDT 00069 { 00070 int x; 00071 double y; 00072 }; 00073 union empty_union_UDT 00074 { 00075 ~empty_union_UDT() { } 00076 }; 00077 union empty_POD_union_UDT { }; 00078 00079 struct nothrow_copy_UDT 00080 { 00081 nothrow_copy_UDT(); 00082 nothrow_copy_UDT(const nothrow_copy_UDT&)throw(); 00083 ~nothrow_copy_UDT() { }; 00084 nothrow_copy_UDT& operator=(const nothrow_copy_UDT&){ return *this; } 00085 bool operator==(const nothrow_copy_UDT&)const 00086 { return true; } 00087 }; 00088 00089 struct nothrow_assign_UDT 00090 { 00091 nothrow_assign_UDT(); 00092 nothrow_assign_UDT(const nothrow_assign_UDT&); 00093 ~nothrow_assign_UDT() { }; 00094 nothrow_assign_UDT& operator=(const nothrow_assign_UDT&)throw(){ return *this; } 00095 bool operator==(const nothrow_assign_UDT&)const 00096 { return true; } 00097 }; 00098 00099 struct nothrow_construct_UDT 00100 { 00101 nothrow_construct_UDT()throw(); 00102 nothrow_construct_UDT(const nothrow_construct_UDT&); 00103 ~nothrow_construct_UDT() { }; 00104 nothrow_construct_UDT& operator=(const nothrow_construct_UDT&){ return *this; } 00105 bool operator==(const nothrow_construct_UDT&)const 00106 { return true; } 00107 }; 00108 00109 class Base { }; 00110 00111 class Derived : public Base { }; 00112 class Derived2 : public Base { }; 00113 class MultiBase : public Derived, public Derived2 { }; 00114 class PrivateBase : private Base { }; 00115 00116 class NonDerived { }; 00117 00118 enum enum1 00119 { 00120 one_,two_ 00121 }; 00122 00123 enum enum2 00124 { 00125 three_,four_ 00126 }; 00127 00128 struct VB 00129 { 00130 virtual ~VB() { }; 00131 }; 00132 00133 struct VD : VB 00134 { 00135 ~VD() { }; 00136 }; 00137 00138 // struct non_pointer: 00139 // used to verify that is_pointer does not return 00140 // true for class types that implement operator void*() 00141 // 00142 struct non_pointer 00143 { 00144 operator void*(){return this;} 00145 }; 00146 struct non_int_pointer 00147 { 00148 int i; 00149 operator int*(){return &i;} 00150 }; 00151 struct int_constructible 00152 { 00153 int_constructible(int); 00154 }; 00155 struct int_convertible 00156 { 00157 operator int(); 00158 }; 00159 // 00160 // struct non_empty: 00161 // used to verify that is_empty does not emit 00162 // spurious warnings or errors. 00163 // 00164 struct non_empty : private noncopyable 00165 { 00166 int i; 00167 }; 00168 // 00169 // abstract base classes: 00170 struct test_abc1 00171 { 00172 test_abc1(); 00173 virtual ~test_abc1(); 00174 test_abc1(const test_abc1&); 00175 test_abc1& operator=(const test_abc1&); 00176 virtual void foo() = 0; 00177 virtual void foo2() = 0; 00178 }; 00179 00180 struct test_abc2 00181 { 00182 virtual ~test_abc2(); 00183 virtual void foo() = 0; 00184 virtual void foo2() = 0; 00185 }; 00186 00187 struct test_abc3 : public test_abc1 00188 { 00189 virtual void foo3() = 0; 00190 }; 00191 00192 struct incomplete_type; 00193 00194 struct polymorphic_base 00195 { 00196 virtual ~polymorphic_base(); 00197 virtual void method(); 00198 }; 00199 00200 struct polymorphic_derived1 : polymorphic_base 00201 { 00202 }; 00203 00204 struct polymorphic_derived2 : polymorphic_base 00205 { 00206 virtual void method(); 00207 }; 00208 00209 struct virtual_inherit1 : virtual Base { }; 00210 struct virtual_inherit2 : virtual_inherit1 { }; 00211 struct virtual_inherit3 : private virtual Base { }; 00212 struct virtual_inherit4 : virtual noncopyable { }; 00213 struct virtual_inherit5 : virtual int_convertible { }; 00214 struct virtual_inherit6 : virtual Base { virtual ~virtual_inherit6()throw(); }; 00215 00216 typedef void foo0_t(); 00217 typedef void foo1_t(int); 00218 typedef void foo2_t(int&, double); 00219 typedef void foo3_t(int&, bool, int, int); 00220 typedef void foo4_t(int, bool, int*, int[], int, int, int, int, int); 00221 00222 struct trivial_except_construct 00223 { 00224 trivial_except_construct(); 00225 int i; 00226 }; 00227 00228 struct trivial_except_destroy 00229 { 00230 ~trivial_except_destroy(); 00231 int i; 00232 }; 00233 00234 struct trivial_except_copy 00235 { 00236 trivial_except_copy(trivial_except_copy const&); 00237 int i; 00238 }; 00239 00240 struct trivial_except_assign 00241 { 00242 trivial_except_assign& operator=(trivial_except_assign const&); 00243 int i; 00244 }; 00245 00246 template< typename T > 00247 struct wrap 00248 { 00249 T t; 00250 int j; 00251 protected: 00252 wrap(); 00253 wrap(const wrap&); 00254 wrap& operator=(const wrap&); 00255 }; 00256 00257 00258 template< typename T > 00259 struct convertible_from 00260 { convertible_from(T); }; 00261 00262 struct base2 { }; 00263 struct middle2 : virtual base2 { }; 00264 struct derived2 : middle2 { }; 00265 00266 00267 int main() 00268 { 00269 #define conversion_claim(From,To) (is_convertible<From,To>::value) 00270 #define does_convert(From,To) assert(conversion_claim(From,To)) 00271 #define does_not_convert(From,To) assert(!conversion_claim(From,To)) 00272 00273 does_not_convert(NonDerived,Base); 00274 00275 does_convert(Base,Base); 00276 does_convert(Derived,Base); 00277 does_convert(Derived,Derived); 00278 does_not_convert(Base,Derived); 00279 00280 does_convert(Derived&, Base&); 00281 does_convert(const Derived&, const Base&); 00282 does_not_convert(Base&, Derived&); 00283 does_not_convert(const Base&, const Derived&); 00284 00285 does_convert(Derived*, Base*); 00286 does_convert(const Derived*, const Base*); 00287 does_not_convert(Base*, Derived*); 00288 does_not_convert(const Base*, const Derived*); 00289 00290 does_convert(polymorphic_derived1,polymorphic_base); 00291 does_convert(polymorphic_derived2,polymorphic_base); 00292 does_not_convert(polymorphic_base,polymorphic_derived1); 00293 does_not_convert(polymorphic_base,polymorphic_derived2); 00294 00295 does_convert(virtual_inherit2,virtual_inherit1); 00296 does_convert(VD,VB); 00297 00298 does_convert(void,void); 00299 does_not_convert(void,float); 00300 does_convert(float,void); 00301 //does_convert(float,int); 00302 00303 does_convert(enum1, int); 00304 00305 does_not_convert(const int *, int*); 00306 does_not_convert(const int&, int&); 00307 does_not_convert(const int*, int[3]); 00308 does_convert(const int&, int); 00309 does_convert(int(&)[4], const int*); 00310 does_convert(int(&)(int), int(*)(int)); 00311 does_convert(int *, const int*); 00312 does_convert(int&, const int&); 00313 does_convert(int[2], int*); 00314 does_convert(int[2], const int*); 00315 does_not_convert(const int[2], int*); 00316 does_not_convert(int*, int[3]); 00317 //does_convert(test_abc3, const test_abc1&); 00318 00319 does_convert(non_pointer, void*); 00320 does_not_convert(non_pointer, int*); 00321 does_convert(non_int_pointer, int*); 00322 does_convert(non_int_pointer, void*); 00323 00324 does_not_convert(test_abc1&, test_abc2&); 00325 does_not_convert(test_abc1&, int_constructible); 00326 does_not_convert(int_constructible, test_abc1&); 00327 00328 does_not_convert(test_abc1&, test_abc2); 00329 00330 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC_MINOR__ < 2)) 00331 // known to be defective 00332 #elif defined(_MSC_VER) && (_MSC_VER <= 1400) 00333 // known to be defective 00334 #else 00335 // let's give it a try 00336 does_convert(int, int_constructible); 00337 does_convert(float,convertible_from<float> ); 00338 does_convert(float,convertible_from<float const&> ); 00339 does_convert(float,convertible_from<float&> ); 00340 00341 does_convert(float,convertible_from<char> ); 00342 does_convert(float,convertible_from<char const&> ); 00343 does_not_convert(float,convertible_from<char&> ); 00344 00345 does_convert(char,convertible_from<char> ); 00346 does_convert(char,convertible_from<char const&> ); 00347 does_convert(char,convertible_from<char&> ); 00348 00349 does_convert(float&,convertible_from<float> ); 00350 does_convert(float const&,convertible_from<float> ); 00351 does_convert(float&,convertible_from<float&> ); 00352 does_convert(float const&,convertible_from<float const&> ); 00353 does_convert(float&,convertible_from<float const&> ); 00354 #endif // compiler 00355 00356 return 0; 00357 }