1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: wx/meta/convertible.h 3 // Purpose: Test if types are convertible 4 // Author: Arne Steinarson 5 // Created: 2008-01-10 6 // Copyright: (c) 2008 Arne Steinarson 7 // Licence: wxWindows licence 8 ///////////////////////////////////////////////////////////////////////////// 9 10 #ifndef _WX_META_CONVERTIBLE_H_ 11 #define _WX_META_CONVERTIBLE_H_ 12 13 // 14 // Introduce an extra class to make this header compilable with g++3.2 15 // 16 template <class D, class B> 17 struct wxConvertibleTo_SizeHelper 18 { 19 static char Match(B* pb); 20 static int Match(...); 21 }; 22 23 // Helper to decide if an object of type D is convertible to type B (the test 24 // succeeds in particular when D derives from B) 25 template <class D, class B> 26 struct wxConvertibleTo 27 { 28 enum 29 { 30 value = 31 sizeof(wxConvertibleTo_SizeHelper<D,B>::Match(static_cast<D*>(NULL))) 32 == 33 sizeof(char) 34 }; 35 }; 36 37 // This is similar to wxConvertibleTo, except that when using a C++11 compiler, 38 // the case of D deriving from B non-publicly will be detected and the correct 39 // value (false) will be deduced instead of getting a compile-time error as 40 // with wxConvertibleTo. For pre-C++11 compilers there is no difference between 41 // this helper and wxConvertibleTo. 42 template <class D, class B> 43 struct wxIsPubliclyDerived 44 { 45 enum 46 { 47 #if __cplusplus >= 201103 || (defined(_MSC_VER) && _MSC_VER >= 1600) 48 // If C++11 is available we use this, as on most compilers it's a 49 // built-in and will be evaluated at compile-time. 50 value = std::is_base_of<B, D>::value && std::is_convertible<D*, B*>::value 51 #else 52 // When not using C++11, we fall back to wxConvertibleTo, which fails 53 // at compile-time if D doesn't publicly derive from B. 54 value = wxConvertibleTo<D, B>::value 55 #endif 56 }; 57 }; 58 59 #endif // _WX_META_CONVERTIBLE_H_ 60 61