brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.2 KiB · 94d61c0 Raw
280 lines · c
1#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_2#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_3 4// Expands and concatenates the arguments. Constructed macros reevaluate.5#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)6 7// Expands and stringifies the only argument.8#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)9 10// Returns empty. Given a variadic number of arguments.11#define GMOCK_PP_EMPTY(...)12 13// Returns a comma. Given a variadic number of arguments.14#define GMOCK_PP_COMMA(...) ,15 16// Returns the only argument.17#define GMOCK_PP_IDENTITY(_1) _118 19// Evaluates to the number of arguments after expansion.20//21//   #define PAIR x, y22//23//   GMOCK_PP_NARG() => 124//   GMOCK_PP_NARG(x) => 125//   GMOCK_PP_NARG(x, y) => 226//   GMOCK_PP_NARG(PAIR) => 227//28// Requires: the number of arguments after expansion is at most 15.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, 0))32 33// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise34// returns 0. Requires no more than 15 unprotected commas.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, 0))38 39// Returns the first argument.40#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))41 42// Returns the tail. A variadic list of all arguments minus the first. Requires43// at least one argument.44#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))45 46// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)47#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \48  GMOCK_PP_IDENTITY(                        \49      GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))50 51// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise52// evaluates to `0`.53//54// Requires: * the number of arguments after expansion is at most 15.55//           * If the argument is a macro, it must be able to be called with one56//             argument.57//58// Implementation details:59//60// There is one case when it generates a compile error: if the argument is macro61// that cannot be called with one argument.62//63//   #define M(a, b)  // it doesn't matter what it expands to64//65//   // Expected: expands to `0`.66//   // Actual: compile error.67//   GMOCK_PP_IS_EMPTY(M)68//69// There are 4 cases tested:70//71// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.72// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.73// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.74//   Expected 075// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in76//   parenthesis, or is a macro that ()-evaluates to comma. Expected 1.77//78// We trigger detection on '0001', i.e. on empty.79#define GMOCK_PP_IS_EMPTY(...)                                               \80  GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__),                \81                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \82                             GMOCK_PP_HAS_COMMA(__VA_ARGS__()),              \83                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))84 85// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.86#define GMOCK_PP_IF(_Cond, _Then, _Else) \87  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)88 89// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.90//91// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c92// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f93//94#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \95  GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))96 97// Evaluates to the number of arguments after expansion. Identifies 'empty' as98// 0.99//100//   #define PAIR x, y101//102//   GMOCK_PP_NARG0() => 0103//   GMOCK_PP_NARG0(x) => 1104//   GMOCK_PP_NARG0(x, y) => 2105//   GMOCK_PP_NARG0(PAIR) => 2106//107// Requires: * the number of arguments after expansion is at most 15.108//           * If the argument is a macro, it must be able to be called with one109//             argument.110#define GMOCK_PP_NARG0(...) \111  GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))112 113// Expands to 1 if the first argument starts with something in parentheses,114// otherwise to 0.115#define GMOCK_PP_IS_BEGIN_PARENS(...)                              \116  GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \117                             GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))118 119// Expands to 1 is there is only one argument and it is enclosed in parentheses.120#define GMOCK_PP_IS_ENCLOSED_PARENS(...)             \121  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \122              GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)123 124// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.125#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__126 127// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,128// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.129// Requires: * |_Macro| can be called with 3 arguments.130//           * |_Tuple| expansion has no more than 15 elements.131#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple)                        \132  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \133  (0, _Macro, _Data, _Tuple)134 135// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )136// Empty if _K = 0.137// Requires: * |_Macro| can be called with 3 arguments.138//           * |_K| literal between 0 and 15139#define GMOCK_PP_REPEAT(_Macro, _Data, _N)           \140  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \141  (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)142 143// Increments the argument, requires the argument to be between 0 and 15.144#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)145 146// Returns comma if _i != 0. Requires _i to be between 0 and 15.147#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)148 149// Internal details follow. Do not use any of these symbols outside of this150// file or we will break your code.151#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )152#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2153#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__154#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5155#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4)                             \156  GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \157                                             _1, _2, _3, _4))158#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,159#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then160#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else161 162// Because of MSVC treating a token with a comma in it as a single token when163// passed to another macro, we need to force it to evaluate it as multiple164// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We165// define one per possible macro that relies on this behavior. Note "_Args" must166// be parenthesized.167#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \168                                        _10, _11, _12, _13, _14, _15, _16,  \169                                        ...)                                \170  _16171#define GMOCK_PP_INTERNAL_16TH(_Args) \172  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)173#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1174#define GMOCK_PP_INTERNAL_HEAD(_Args) \175  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)176#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__177#define GMOCK_PP_INTERNAL_TAIL(_Args) \178  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)179 180#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _181#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,182#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \183  0,184#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__185#define GMOCK_PP_INTERNAL_INC_0 1186#define GMOCK_PP_INTERNAL_INC_1 2187#define GMOCK_PP_INTERNAL_INC_2 3188#define GMOCK_PP_INTERNAL_INC_3 4189#define GMOCK_PP_INTERNAL_INC_4 5190#define GMOCK_PP_INTERNAL_INC_5 6191#define GMOCK_PP_INTERNAL_INC_6 7192#define GMOCK_PP_INTERNAL_INC_7 8193#define GMOCK_PP_INTERNAL_INC_8 9194#define GMOCK_PP_INTERNAL_INC_9 10195#define GMOCK_PP_INTERNAL_INC_10 11196#define GMOCK_PP_INTERNAL_INC_11 12197#define GMOCK_PP_INTERNAL_INC_12 13198#define GMOCK_PP_INTERNAL_INC_13 14199#define GMOCK_PP_INTERNAL_INC_14 15200#define GMOCK_PP_INTERNAL_INC_15 16201#define GMOCK_PP_INTERNAL_COMMA_IF_0202#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,203#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,204#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,205#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,206#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,207#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,208#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,209#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,210#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,211#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,212#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,213#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,214#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,215#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,216#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,217#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \218  _Macro(_i, _Data, _element)219#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)220#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \221  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)222#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple)    \223  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \224  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data,    \225                                    (GMOCK_PP_TAIL _Tuple))226#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple)    \227  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \228  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data,    \229                                    (GMOCK_PP_TAIL _Tuple))230#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple)    \231  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \232  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data,    \233                                    (GMOCK_PP_TAIL _Tuple))234#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple)    \235  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \236  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data,    \237                                    (GMOCK_PP_TAIL _Tuple))238#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple)    \239  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \240  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data,    \241                                    (GMOCK_PP_TAIL _Tuple))242#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple)    \243  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \244  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data,    \245                                    (GMOCK_PP_TAIL _Tuple))246#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple)    \247  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \248  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data,    \249                                    (GMOCK_PP_TAIL _Tuple))250#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple)    \251  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \252  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data,    \253                                    (GMOCK_PP_TAIL _Tuple))254#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple)   \255  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \256  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data,    \257                                    (GMOCK_PP_TAIL _Tuple))258#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple)   \259  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \260  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data,   \261                                     (GMOCK_PP_TAIL _Tuple))262#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple)   \263  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \264  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data,   \265                                     (GMOCK_PP_TAIL _Tuple))266#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple)   \267  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \268  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data,   \269                                     (GMOCK_PP_TAIL _Tuple))270#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple)   \271  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \272  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data,   \273                                     (GMOCK_PP_TAIL _Tuple))274#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple)   \275  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \276  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data,   \277                                     (GMOCK_PP_TAIL _Tuple))278 279#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_280