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