]>
Commit | Line | Data |
---|---|---|
cdd8d745 VZ |
1 | /* |
2 | * Name: wx/cpp.h | |
3 | * Purpose: Various preprocessor helpers | |
4 | * Author: Vadim Zeitlin | |
5 | * Created: 2006-09-30 | |
6 | * RCS-ID: $Id$ | |
7 | * Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org> | |
8 | * Licence: wxWindows licence | |
9 | */ | |
10 | ||
11 | /* THIS IS A C FILE, DON'T USE C++ FEATURES (IN PARTICULAR COMMENTS) IN IT */ | |
12 | ||
13 | #ifndef _WX_CPP_H_ | |
14 | #define _WX_CPP_H_ | |
15 | ||
20125017 VZ |
16 | #include "wx/compiler.h" /* wxCHECK_XXX_VERSION() macros */ |
17 | ||
cdd8d745 VZ |
18 | /* wxCONCAT works like preprocessor ## operator but also works with macros */ |
19 | #define wxCONCAT_HELPER(text, line) text ## line | |
cdd8d745 | 20 | |
47eab2f2 VZ |
21 | #define wxCONCAT(x1, x2) \ |
22 | wxCONCAT_HELPER(x1, x2) | |
23 | #define wxCONCAT3(x1, x2, x3) \ | |
24 | wxCONCAT(wxCONCAT(x1, x2), x3) | |
25 | #define wxCONCAT4(x1, x2, x3, x4) \ | |
26 | wxCONCAT(wxCONCAT3(x1, x2, x3), x4) | |
27 | #define wxCONCAT5(x1, x2, x3, x4, x5) \ | |
28 | wxCONCAT(wxCONCAT4(x1, x2, x3, x4), x5) | |
29 | #define wxCONCAT6(x1, x2, x3, x4, x5, x6) \ | |
30 | wxCONCAT(wxCONCAT5(x1, x2, x3, x4, x5), x6) | |
31 | #define wxCONCAT7(x1, x2, x3, x4, x5, x6, x7) \ | |
32 | wxCONCAT(wxCONCAT6(x1, x2, x3, x4, x5, x6), x7) | |
33 | #define wxCONCAT8(x1, x2, x3, x4, x5, x6, x7, x8) \ | |
34 | wxCONCAT(wxCONCAT7(x1, x2, x3, x4, x5, x6, x7), x8) | |
35 | #define wxCONCAT9(x1, x2, x3, x4, x5, x6, x7, x8, x9) \ | |
36 | wxCONCAT(wxCONCAT8(x1, x2, x3, x4, x5, x6, x7, x8), x9) | |
1894e49f | 37 | |
cdd8d745 VZ |
38 | /* wxSTRINGIZE works as the preprocessor # operator but also works with macros */ |
39 | #define wxSTRINGIZE_HELPER(x) #x | |
40 | #define wxSTRINGIZE(x) wxSTRINGIZE_HELPER(x) | |
41 | ||
84206bbb VZ |
42 | /* a Unicode-friendly version of wxSTRINGIZE_T */ |
43 | #define wxSTRINGIZE_T(x) wxAPPLY_T(wxSTRINGIZE(x)) | |
44 | ||
25859335 VZ |
45 | /* |
46 | Special workarounds for compilers with broken "##" operator. For all the | |
47 | other ones we can just use it directly. | |
48 | */ | |
49 | #ifdef wxCOMPILER_BROKEN_CONCAT_OPER | |
50 | #define wxPREPEND_L(x) L ## x | |
51 | #define wxAPPEND_i64(x) x ## i64 | |
52 | #define wxAPPEND_ui64(x) x ## ui64 | |
53 | #endif /* wxCOMPILER_BROKEN_CONCAT_OPER */ | |
54 | ||
cdd8d745 VZ |
55 | /* |
56 | Helper macros for wxMAKE_UNIQUE_NAME: normally this works by appending the | |
57 | current line number to the given identifier to reduce the probability of the | |
58 | conflict (it may still happen if this is used in the headers, hence you | |
59 | should avoid doing it or provide unique prefixes then) but we have to do it | |
60 | differently for VC++ | |
61 | */ | |
62 | #if defined(__VISUALC__) && (__VISUALC__ >= 1300) | |
63 | /* | |
64 | __LINE__ handling is completely broken in VC++ when using "Edit and | |
65 | Continue" (/ZI option) and results in preprocessor errors if we use it | |
66 | inside the macros. Luckily VC7 has another standard macro which can be | |
67 | used like this and is even better than __LINE__ because it is globally | |
68 | unique. | |
69 | */ | |
70 | # define wxCONCAT_LINE(text) wxCONCAT(text, __COUNTER__) | |
71 | #else /* normal compilers */ | |
72 | # define wxCONCAT_LINE(text) wxCONCAT(text, __LINE__) | |
73 | #endif | |
74 | ||
75 | /* Create a "unique" name with the given prefix */ | |
76 | #define wxMAKE_UNIQUE_NAME(text) wxCONCAT_LINE(text) | |
77 | ||
bde626ce VZ |
78 | /* |
79 | This macro can be passed as argument to another macro when you don't have | |
80 | anything to pass in fact. | |
81 | */ | |
82 | #define wxEMPTY_PARAMETER_VALUE /* Fake macro parameter value */ | |
83 | ||
4d3845c0 VZ |
84 | /* |
85 | Helpers for defining macros that expand into a single statement. | |
86 | ||
87 | The standatd solution is to use "do { ... } while (0)" statement but MSVC | |
88 | generates a C4127 "condition expression is constant" warning for it so we | |
89 | use something which is just complicated enough to not be recognized as a | |
90 | constant but still simple enough to be optimized away. | |
91 | ||
92 | Another solution would be to use __pragma() to temporarily disable C4127. | |
93 | ||
94 | Notice that wxASSERT_ARG_TYPE in wx/strvargarg.h relies on these macros | |
95 | creating some kind of a loop because it uses "break". | |
96 | */ | |
97 | #ifdef __WATCOMC__ | |
98 | #define wxFOR_ONCE(name) for(int name=0; name<1; name++) | |
99 | #define wxSTATEMENT_MACRO_BEGIN wxFOR_ONCE(wxMAKE_UNIQUE_NAME(wxmacro)) { | |
100 | #define wxSTATEMENT_MACRO_END } | |
101 | #else | |
102 | #define wxSTATEMENT_MACRO_BEGIN do { | |
103 | #define wxSTATEMENT_MACRO_END } while ( (void)0, 0 ) | |
104 | #endif | |
105 | ||
a6ebdba6 VZ |
106 | /* |
107 | Define __WXFUNCTION__ which is like standard __FUNCTION__ but defined as | |
108 | NULL for the compilers which don't support the latter. | |
109 | */ | |
110 | #ifndef __WXFUNCTION__ | |
111 | /* TODO: add more compilers supporting __FUNCTION__ */ | |
112 | #if defined(__DMC__) | |
113 | /* | |
114 | __FUNCTION__ happens to be not defined within class members | |
115 | http://www.digitalmars.com/drn-bin/wwwnews?c%2B%2B.beta/485 | |
116 | */ | |
117 | #define __WXFUNCTION__ (NULL) | |
118 | #elif defined(__GNUC__) || \ | |
119 | (defined(_MSC_VER) && _MSC_VER >= 1300) || \ | |
120 | defined(__FUNCTION__) | |
121 | #define __WXFUNCTION__ __FUNCTION__ | |
122 | #else | |
123 | /* still define __WXFUNCTION__ to avoid #ifdefs elsewhere */ | |
124 | #define __WXFUNCTION__ (NULL) | |
125 | #endif | |
126 | #endif /* __WXFUNCTION__ already defined */ | |
127 | ||
a4d982a7 | 128 | |
168d1f65 VZ |
129 | /* Auto-detect variadic macros support unless explicitly disabled. */ |
130 | #if !defined(HAVE_VARIADIC_MACROS) && !defined(wxNO_VARIADIC_MACROS) | |
131 | /* Any C99 or C++11 compiler should have them. */ | |
132 | #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ | |
133 | (defined(__cplusplus) && __cplusplus >= 201103L) | |
134 | #define HAVE_VARIADIC_MACROS | |
20125017 | 135 | #elif wxCHECK_GCC_VERSION(3,0) |
168d1f65 VZ |
136 | #define HAVE_VARIADIC_MACROS |
137 | #elif wxCHECK_VISUALC_VERSION(8) | |
138 | #define HAVE_VARIADIC_MACROS | |
139 | #elif wxCHECK_WATCOM_VERSION(1,2) | |
140 | #define HAVE_VARIADIC_MACROS | |
141 | #endif | |
142 | #endif /* !HAVE_VARIADIC_MACROS */ | |
143 | ||
144 | ||
a4d982a7 | 145 | |
168d1f65 | 146 | #ifdef HAVE_VARIADIC_MACROS |
a4d982a7 VS |
147 | /* |
148 | wxCALL_FOR_EACH(what, ...) calls the macro from its first argument, what(pos, x), | |
149 | for every remaining argument 'x', with 'pos' being its 1-based index in | |
150 | *reverse* order (with the last argument being numbered 1). | |
151 | ||
152 | For example, wxCALL_FOR_EACH(test, a, b, c) expands into this: | |
153 | ||
154 | test(3, a) \ | |
155 | test(2, b) \ | |
156 | test(1, c) | |
157 | ||
158 | Up to eight arguments are supported. | |
159 | ||
160 | (With thanks to https://groups.google.com/d/topic/comp.std.c/d-6Mj5Lko_s/discussion | |
161 | and http://stackoverflow.com/questions/1872220/is-it-possible-to-iterate-over-arguments-in-variadic-macros) | |
162 | */ | |
e08d449f VS |
163 | #define wxCALL_FOR_EACH_NARG(...) wxCALL_FOR_EACH_NARG_((__VA_ARGS__, wxCALL_FOR_EACH_RSEQ_N())) |
164 | #define wxCALL_FOR_EACH_NARG_(args) wxCALL_FOR_EACH_ARG_N args | |
a4d982a7 VS |
165 | #define wxCALL_FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N |
166 | #define wxCALL_FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 | |
167 | ||
168 | #define wxCALL_FOR_EACH_1(what, x) what(1, x) | |
169 | #define wxCALL_FOR_EACH_2(what, x, ...) what(2, x) wxCALL_FOR_EACH_1(what, __VA_ARGS__) | |
170 | #define wxCALL_FOR_EACH_3(what, x, ...) what(3, x) wxCALL_FOR_EACH_2(what, __VA_ARGS__) | |
171 | #define wxCALL_FOR_EACH_4(what, x, ...) what(4, x) wxCALL_FOR_EACH_3(what, __VA_ARGS__) | |
172 | #define wxCALL_FOR_EACH_5(what, x, ...) what(5, x) wxCALL_FOR_EACH_4(what, __VA_ARGS__) | |
173 | #define wxCALL_FOR_EACH_6(what, x, ...) what(6, x) wxCALL_FOR_EACH_5(what, __VA_ARGS__) | |
174 | #define wxCALL_FOR_EACH_7(what, x, ...) what(7, x) wxCALL_FOR_EACH_6(what, __VA_ARGS__) | |
175 | #define wxCALL_FOR_EACH_8(what, x, ...) what(8, x) wxCALL_FOR_EACH_7(what, __VA_ARGS__) | |
176 | ||
e08d449f VS |
177 | #define wxCALL_FOR_EACH_(N, args) \ |
178 | wxCONCAT(wxCALL_FOR_EACH_, N) args | |
a4d982a7 VS |
179 | |
180 | #define wxCALL_FOR_EACH(what, ...) \ | |
e08d449f | 181 | wxCALL_FOR_EACH_(wxCALL_FOR_EACH_NARG(__VA_ARGS__), (what, __VA_ARGS__)) |
a4d982a7 VS |
182 | |
183 | #else | |
184 | #define wxCALL_FOR_EACH Error_wx_CALL_FOR_EACH_requires_variadic_macros_support | |
168d1f65 | 185 | #endif /* HAVE_VARIADIC_MACROS */ |
a4d982a7 | 186 | |
28efe654 | 187 | #endif /* _WX_CPP_H_ */ |
cdd8d745 | 188 |