11#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
22#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
33
4- #undef GMOCK_PP_INTERNAL_USE_MSVC
5- #if defined(__clang__ )
6- #define GMOCK_PP_INTERNAL_USE_MSVC 0
7- #elif defined(_MSC_VER )
8- // TODO(iserna): Also verify tradional versus comformant preprocessor.
9- static_assert (
10- _MSC_VER >= 1900 ,
11- "MSVC version not supported. There is support for MSVC 14.0 and above." );
12- #define GMOCK_PP_INTERNAL_USE_MSVC 1
13- #else
14- #define GMOCK_PP_INTERNAL_USE_MSVC 0
15- #endif
16-
174// Expands and concatenates the arguments. Constructed macros reevaluate.
185#define GMOCK_PP_CAT (_1 , _2 ) GMOCK_PP_INTERNAL_CAT(_1, _2)
196
@@ -29,10 +16,6 @@ static_assert(
2916// Returns the only argument.
3017#define GMOCK_PP_IDENTITY (_1 ) _1
3118
32- // MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
33- // CAT-like directive to force correct evaluation. Each macro has its own.
34- #if GMOCK_PP_INTERNAL_USE_MSVC
35-
3619// Evaluates to the number of arguments after expansion.
3720//
3821// #define PAIR x, y
@@ -43,45 +26,29 @@ static_assert(
4326// GMOCK_PP_NARG(PAIR) => 2
4427//
4528// Requires: the number of arguments after expansion is at most 15.
46- #define GMOCK_PP_NARG (...) \
47- GMOCK_PP_INTERNAL_NARG_CAT( \
48- GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
49- 8, 7, 6, 5, 4, 3, 2, 1), )
29+ #define GMOCK_PP_NARG (...) \
30+ GMOCK_PP_INTERNAL_16TH( \
31+ (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
5032
5133// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
5234// returns 0. Requires no more than 15 unprotected commas.
53- #define GMOCK_PP_HAS_COMMA (...) \
54- GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \
55- GMOCK_PP_INTERNAL_INTERNAL_16TH (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
56- 1, 1, 1, 1, 1, 0), )
35+ #define GMOCK_PP_HAS_COMMA (...) \
36+ GMOCK_PP_INTERNAL_16TH( \
37+ (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0))
38+
5739// Returns the first argument.
5840#define GMOCK_PP_HEAD (...) \
59- GMOCK_PP_INTERNAL_HEAD_CAT( GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
41+ GMOCK_PP_INTERNAL_HEAD(( __VA_ARGS__))
6042
6143// Returns the tail. A variadic list of all arguments minus the first. Requires
6244// at least one argument.
6345#define GMOCK_PP_TAIL (...) \
64- GMOCK_PP_INTERNAL_TAIL_CAT( GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
46+ GMOCK_PP_INTERNAL_TAIL(( __VA_ARGS__))
6547
6648// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
6749#define GMOCK_PP_VARIADIC_CALL (_Macro , ...) \
68- GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
69- GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
70-
71- #else // GMOCK_PP_INTERNAL_USE_MSVC
72-
73- #define GMOCK_PP_NARG (...) \
74- GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
75- 7, 6, 5, 4, 3, 2, 1)
76- #define GMOCK_PP_HAS_COMMA (...) \
77- GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
78- 1, 1, 1, 1, 0)
79- #define GMOCK_PP_HEAD (...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
80- #define GMOCK_PP_TAIL (...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
81- #define GMOCK_PP_VARIADIC_CALL (_Macro , ...) \
82- GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
83-
84- #endif // GMOCK_PP_INTERNAL_USE_MSVC
50+ GMOCK_PP_IDENTITY( \
51+ GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
8552
8653// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
8754// evaluates to `0`.
@@ -140,7 +107,7 @@ static_assert(
140107// Expands to 1 if the first argument starts with something in parentheses,
141108// otherwise to 0.
142109#define GMOCK_PP_IS_BEGIN_PARENS (...) \
143- GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \
110+ GMOCK_PP_HEAD( \
144111 GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
145112 GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
146113
@@ -179,41 +146,31 @@ static_assert(
179146#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
180147#define GMOCK_PP_INTERNAL_CAT (_1 , _2 ) _1##_2
181148#define GMOCK_PP_INTERNAL_STRINGIZE (...) #__VA_ARGS__
182- #define GMOCK_PP_INTERNAL_INTERNAL_16TH (_1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , \
183- _10 , _11 , _12 , _13 , _14 , _15 , _16 , \
184- ...) \
185- _16
186149#define GMOCK_PP_INTERNAL_CAT_5 (_1 , _2 , _3 , _4 , _5 ) _1##_2##_3##_4##_5
187150#define GMOCK_PP_INTERNAL_IS_EMPTY (_1 , _2 , _3 , _4 ) \
188151 GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
189152 _1, _2, _3, _4))
190153#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
191154#define GMOCK_PP_INTERNAL_IF_1 (_Then , _Else ) _Then
192155#define GMOCK_PP_INTERNAL_IF_0 (_Then , _Else ) _Else
193- #define GMOCK_PP_INTERNAL_HEAD (_1 , ...) _1
194- #define GMOCK_PP_INTERNAL_TAIL (_1 , ...) __VA_ARGS__
195156
196- #if GMOCK_PP_INTERNAL_USE_MSVC
197- #define GMOCK_PP_INTERNAL_NARG_CAT (_1 , _2 ) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
198- #define GMOCK_PP_INTERNAL_HEAD_CAT (_1 , _2 ) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
199- #define GMOCK_PP_INTERNAL_HAS_COMMA_CAT (_1 , _2 ) \
200- GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
201- #define GMOCK_PP_INTERNAL_TAIL_CAT (_1 , _2 ) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
202- #define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT (_1 , _2 ) \
203- GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
204- #define GMOCK_PP_INTERNAL_NARG_CAT_I (_1 , _2 ) _1##_2
205- #define GMOCK_PP_INTERNAL_HEAD_CAT_I (_1 , _2 ) _1##_2
206- #define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I (_1 , _2 ) _1##_2
207- #define GMOCK_PP_INTERNAL_TAIL_CAT_I (_1 , _2 ) _1##_2
208- #define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I (_1 , _2 ) _1##_2
209- #define GMOCK_PP_INTERNAL_ALTERNATE_HEAD (...) \
210- GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
211- #define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT (_1 , _2 ) \
212- GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
213- #define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I (_1 , _2 ) _1##_2
214- #else // GMOCK_PP_INTERNAL_USE_MSVC
215- #define GMOCK_PP_INTERNAL_ALTERNATE_HEAD (...) GMOCK_PP_HEAD(__VA_ARGS__)
216- #endif // GMOCK_PP_INTERNAL_USE_MSVC
157+ // Because of MSVC treating a token with a comma in it as a single token when passed
158+ // to another macro, we need to force it to evaluate it as multiple tokens. We do that
159+ // by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro.
160+ // We define one per possible macro that relies on this behavior.
161+ // Note "_Args" must be parenthesized.
162+ #define GMOCK_PP_INTERNAL_INTERNAL_16TH (_1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , \
163+ _10 , _11 , _12 , _13 , _14 , _15 , _16 , \
164+ ...) \
165+ _16
166+ #define GMOCK_PP_INTERNAL_16TH (_Args ) \
167+ GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
168+ #define GMOCK_PP_INTERNAL_INTERNAL_HEAD (_1 , ...) _1
169+ #define GMOCK_PP_INTERNAL_HEAD (_Args ) \
170+ GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
171+ #define GMOCK_PP_INTERNAL_INTERNAL_TAIL (_1 , ...) __VA_ARGS__
172+ #define GMOCK_PP_INTERNAL_TAIL (_Args ) \
173+ GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
217174
218175#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C (...) 1 _
219176#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
0 commit comments