]>
Commit | Line | Data |
---|---|---|
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_ |