1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: wx/meta/implicitconversion.h 3 // Purpose: Determine resulting type from implicit conversion 4 // Author: Vaclav Slavik 5 // Created: 2010-10-22 6 // Copyright: (c) 2010 Vaclav Slavik 7 // Licence: wxWindows licence 8 ///////////////////////////////////////////////////////////////////////////// 9 10 #ifndef _WX_META_IMPLICITCONVERSION_H_ 11 #define _WX_META_IMPLICITCONVERSION_H_ 12 13 #include "wx/defs.h" 14 #include "wx/meta/if.h" 15 16 // C++ hierarchy of data types is: 17 // 18 // Long double (highest) 19 // Double 20 // Float 21 // Unsigned long int 22 // Long int 23 // Unsigned int 24 // Int (lowest) 25 // 26 // Types lower in the hierarchy are converted into ones higher up if both are 27 // involved e.g. in arithmetic expressions. 28 29 namespace wxPrivate 30 { 31 32 // Helper macro to define a constant inside a template class: it's needed 33 // because MSVC6 doesn't support initializing static integer members but the 34 // usual workaround of using enums instead doesn't work for Borland (at least 35 // in template classes). 36 #ifdef __VISUALC6__ 37 #define wxDEFINE_CLASS_INT_CONST(name, value) enum { name = value } 38 #else 39 #define wxDEFINE_CLASS_INT_CONST(name, value) static const int name = value 40 #endif 41 42 template<typename T> 43 struct TypeHierarchy 44 { 45 // consider unknown types (e.g. objects, pointers) to be of highest 46 // level, always convert to them if they occur 47 wxDEFINE_CLASS_INT_CONST( level, 9999 ); 48 }; 49 50 #define WX_TYPE_HIERARCHY_LEVEL(level_num, type) \ 51 template<> struct TypeHierarchy<type> \ 52 { \ 53 wxDEFINE_CLASS_INT_CONST( level, level_num ); \ 54 } 55 56 WX_TYPE_HIERARCHY_LEVEL( 1, char); 57 WX_TYPE_HIERARCHY_LEVEL( 2, unsigned char); 58 WX_TYPE_HIERARCHY_LEVEL( 3, short); 59 WX_TYPE_HIERARCHY_LEVEL( 4, unsigned short); 60 WX_TYPE_HIERARCHY_LEVEL( 5, int); 61 WX_TYPE_HIERARCHY_LEVEL( 6, unsigned int); 62 WX_TYPE_HIERARCHY_LEVEL( 7, long); 63 WX_TYPE_HIERARCHY_LEVEL( 8, unsigned long); 64 #ifdef wxLongLong_t 65 WX_TYPE_HIERARCHY_LEVEL( 9, wxLongLong_t); 66 WX_TYPE_HIERARCHY_LEVEL(10, wxULongLong_t); 67 #endif 68 WX_TYPE_HIERARCHY_LEVEL(11, float); 69 WX_TYPE_HIERARCHY_LEVEL(12, double); 70 WX_TYPE_HIERARCHY_LEVEL(13, long double); 71 72 #if wxWCHAR_T_IS_REAL_TYPE 73 #if SIZEOF_WCHAR_T == SIZEOF_SHORT 74 template<> struct TypeHierarchy<wchar_t> : public TypeHierarchy<short> {}; 75 #elif SIZEOF_WCHAR_T == SIZEOF_INT 76 template<> struct TypeHierarchy<wchar_t> : public TypeHierarchy<int> {}; 77 #elif SIZEOF_WCHAR_T == SIZEOF_LONG 78 template<> struct TypeHierarchy<wchar_t> : public TypeHierarchy<long> {}; 79 #else 80 #error "weird wchar_t size, please update this code" 81 #endif 82 #endif 83 84 #undef WX_TYPE_HIERARCHY_LEVEL 85 86 } // namespace wxPrivate 87 88 // Helper to determine resulting type of implicit conversion in 89 // an expression with two arithmetic types. 90 template<typename T1, typename T2> 91 struct wxImplicitConversionType 92 { 93 typedef typename wxIf 94 < 95 // if T2 is "higher" type, convert to it 96 (int)(wxPrivate::TypeHierarchy<T1>::level) < (int)(wxPrivate::TypeHierarchy<T2>::level), 97 T2, 98 // otherwise use T1 99 T1 100 >::value 101 value; 102 }; 103 104 105 template<typename T1, typename T2, typename T3> 106 struct wxImplicitConversionType3 : public wxImplicitConversionType< 107 T1, 108 typename wxImplicitConversionType<T2,T3>::value> 109 { 110 }; 111 112 #endif // _WX_META_IMPLICITCONVERSION_H_ 113