1 #ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT 2 #define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT 3 4 #include "gmock/gmock-generated-function-mockers.h" // NOLINT 5 #include "gmock/internal/gmock-pp.h" 6 7 #define MOCK_METHOD(...) \ 8 GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) 9 10 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \ 11 GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) 12 13 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \ 14 GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) 15 16 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \ 17 GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ()) 18 19 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ 20 GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ 21 GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ 22 GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ 23 GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ 24 GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ 25 GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ 26 GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ 27 GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ 28 GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \ 29 (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) 30 31 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ 32 GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) 33 34 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \ 35 GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) 36 37 #define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \ 38 GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) 39 40 #define GMOCK_INTERNAL_WRONG_ARITY(...) \ 41 static_assert( \ 42 false, \ 43 "MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \ 44 "_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \ 45 "enclosed in parentheses. If _Ret is a type with unprotected commas, " \ 46 "it must also be enclosed in parentheses.") 47 48 #define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \ 49 static_assert( \ 50 GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \ 51 GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.") 52 53 #define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \ 54 static_assert( \ 55 std::is_function<__VA_ARGS__>::value, \ 56 "Signature must be a function type, maybe return type contains " \ 57 "unprotected comma."); \ 58 static_assert( \ 59 ::testing::tuple_size<typename ::testing::internal::Function< \ 60 __VA_ARGS__>::ArgumentTuple>::value == _N, \ 61 "This method does not take " GMOCK_PP_STRINGIZE( \ 62 _N) " arguments. Parenthesize all types with unproctected commas.") 63 64 #define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ 65 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec) 66 67 #define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \ 68 _Override, _Final, _Noexcept, \ 69 _CallType, _Signature) \ 70 typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \ 71 _Signature)>::Result \ 72 GMOCK_INTERNAL_EXPAND(_CallType) \ 73 _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \ 74 GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \ 75 GMOCK_PP_IF(_Override, override, ) \ 76 GMOCK_PP_IF(_Final, final, ) { \ 77 GMOCK_MOCKER_(_N, _Constness, _MethodName) \ 78 .SetOwnerAndName(this, #_MethodName); \ 79 return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ 80 .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \ 81 } \ 82 ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ 83 GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ 84 GMOCK_PP_IF(_Constness, const, ) { \ 85 GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ 86 return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ 87 .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ 88 } \ 89 ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ 90 const ::testing::internal::WithoutMatchers&, \ 91 GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \ 92 GMOCK_PP_REMOVE_PARENS(_Signature)>*) \ 93 const GMOCK_PP_IF(_Noexcept, noexcept, ) { \ 94 return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \ 95 GMOCK_PP_IF(_Constness, const, ))(this) \ 96 ->gmock_##_MethodName(GMOCK_PP_REPEAT( \ 97 GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ 98 } \ 99 mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \ 100 GMOCK_MOCKER_(_N, _Constness, _MethodName) 101 102 #define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__ 103 104 // Five Valid modifiers. 105 #define GMOCK_INTERNAL_HAS_CONST(_Tuple) \ 106 GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple)) 107 108 #define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \ 109 GMOCK_PP_HAS_COMMA( \ 110 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple)) 111 112 #define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \ 113 GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple)) 114 115 #define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \ 116 GMOCK_PP_HAS_COMMA( \ 117 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple)) 118 119 #define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ 120 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) 121 122 #define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ 123 static_assert( \ 124 (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ 125 GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ 126 GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ 127 GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ 128 GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ 129 GMOCK_PP_STRINGIZE( \ 130 _elem) " cannot be recognized as a valid specification modifier."); 131 132 // Modifiers implementation. 133 #define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \ 134 GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem) 135 136 #define GMOCK_INTERNAL_DETECT_CONST_I_const , 137 138 #define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \ 139 GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem) 140 141 #define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override , 142 143 #define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \ 144 GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem) 145 146 #define GMOCK_INTERNAL_DETECT_FINAL_I_final , 147 148 // TODO(iserna): Maybe noexcept should accept an argument here as well. 149 #define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \ 150 GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem) 151 152 #define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept , 153 154 #define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ 155 GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ 156 GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ 157 (_elem) 158 159 // TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and 160 // GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows 161 // maybe they can be simplified somehow. 162 #define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \ 163 GMOCK_INTERNAL_IS_CALLTYPE_I( \ 164 GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) 165 #define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg) 166 167 #define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \ 168 GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ 169 GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) 170 #define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ 171 GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg) 172 173 #define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype 174 175 #define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ 176 GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \ 177 GMOCK_PP_IDENTITY) \ 178 (_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) 179 180 #define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ 181 GMOCK_PP_COMMA_IF(_i) \ 182 GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \ 183 GMOCK_PP_IDENTITY) \ 184 (_elem) 185 186 #define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ 187 GMOCK_PP_COMMA_IF(_i) \ 188 GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ 189 GMOCK_PP_REMOVE_PARENS(_Signature)) \ 190 gmock_a##_i 191 192 #define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ 193 GMOCK_PP_COMMA_IF(_i) \ 194 ::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ 195 GMOCK_PP_REMOVE_PARENS(_Signature))>( \ 196 gmock_a##_i) 197 198 #define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ 199 GMOCK_PP_COMMA_IF(_i) \ 200 GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \ 201 GMOCK_PP_REMOVE_PARENS(_Signature)) \ 202 gmock_a##_i 203 204 #define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ 205 GMOCK_PP_COMMA_IF(_i) \ 206 gmock_a##_i 207 208 #define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ 209 GMOCK_PP_COMMA_IF(_i) \ 210 ::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ 211 GMOCK_PP_REMOVE_PARENS(_Signature))>() 212 213 #define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__) 214 215 #define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \ 216 GMOCK_MATCHER_(_tn, _i, __VA_ARGS__) 217 218 #endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ 219