]>
Commit | Line | Data |
---|---|---|
a5247580 VS |
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 | ||
25859335 VZ |
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 | ||
a5247580 VS |
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 | |
25859335 | 48 | wxDEFINE_CLASS_INT_CONST( level, 9999 ); |
a5247580 VS |
49 | }; |
50 | ||
51 | #define WX_TYPE_HIERARCHY_LEVEL(level_num, type) \ | |
52 | template<> struct TypeHierarchy<type> \ | |
53 | { \ | |
25859335 | 54 | wxDEFINE_CLASS_INT_CONST( level, level_num ); \ |
530646ca | 55 | } |
a5247580 VS |
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 | |
25859335 | 97 | (int)(wxPrivate::TypeHierarchy<T1>::level) < (int)(wxPrivate::TypeHierarchy<T2>::level), |
a5247580 VS |
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_ |