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