summaryrefslogtreecommitdiffstats
path: root/googlemock/include/gmock/gmock-function-mocker.h
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2021-08-12 12:23:14 (GMT)
committerDerek Mauro <dmauro@google.com>2021-08-13 16:42:17 (GMT)
commit21514e0be79776cd3822b7c03bf2ddd497a0ac7e (patch)
tree83dad9aa9858c963f00431d5c742206ad9db6722 /googlemock/include/gmock/gmock-function-mocker.h
parent47f819c3ca54fb602f432904443e00a0a1fe2f42 (diff)
downloadgoogletest-21514e0be79776cd3822b7c03bf2ddd497a0ac7e.zip
googletest-21514e0be79776cd3822b7c03bf2ddd497a0ac7e.tar.gz
googletest-21514e0be79776cd3822b7c03bf2ddd497a0ac7e.tar.bz2
Googletest export
Identify bad specs of the type (const something, ...). PiperOrigin-RevId: 390346843
Diffstat (limited to 'googlemock/include/gmock/gmock-function-mocker.h')
-rw-r--r--googlemock/include/gmock/gmock-function-mocker.h120
1 files changed, 77 insertions, 43 deletions
diff --git a/googlemock/include/gmock/gmock-function-mocker.h b/googlemock/include/gmock/gmock-function-mocker.h
index 36bab78..e6913e5 100644
--- a/googlemock/include/gmock/gmock-function-mocker.h
+++ b/googlemock/include/gmock/gmock-function-mocker.h
@@ -62,6 +62,39 @@ struct ThisRefAdjuster {
}
};
+constexpr bool PrefixOf(const char* a, const char* b) {
+ return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
+}
+
+template <int N, int M>
+constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
+ return N <= M && internal::PrefixOf(prefix, str);
+}
+
+template <int N, int M>
+constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
+ return N <= M && internal::PrefixOf(suffix, str + M - N);
+}
+
+template <int N, int M>
+constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
+ return N == M && internal::PrefixOf(a, b);
+}
+
+template <int N>
+constexpr bool ValidateSpec(const char (&spec)[N]) {
+ return internal::Equals("const", spec) ||
+ internal::Equals("override", spec) ||
+ internal::Equals("final", spec) ||
+ internal::Equals("noexcept", spec) ||
+ (internal::StartsWith("noexcept(", spec) &&
+ internal::EndsWith(")", spec)) ||
+ internal::Equals("ref(&)", spec) ||
+ internal::Equals("ref(&&)", spec) ||
+ (internal::StartsWith("Calltype(", spec) &&
+ internal::EndsWith(")", spec));
+}
+
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
@@ -84,17 +117,18 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
-#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
- GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
- GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
- GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
- GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
- GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
- GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
- GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
- GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
- GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
- GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
+ GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
+ GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
+ GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
+ GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
+ GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
+ GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
+ GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
+ GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
+ GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
+ GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec), \
+ GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
@@ -168,7 +202,7 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
-// Five Valid modifiers.
+// Valid modifiers.
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
@@ -187,6 +221,14 @@ using internal::FunctionMocker;
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
_elem, )
+#define GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Tuple) \
+ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple)
+
+#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem) \
+ GMOCK_PP_IF( \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
+
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
@@ -194,19 +236,25 @@ using internal::FunctionMocker;
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
-#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
- GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
-
-#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
- static_assert( \
- (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
- GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
- GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
- GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
- GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
- GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
- GMOCK_PP_STRINGIZE( \
+#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT
+#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
+ static_assert( \
+ ::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)), \
+ "Token \'" GMOCK_PP_STRINGIZE( \
+ _elem) "\' cannot be recognized as a valid specification " \
+ "modifier. Is a ',' missing?");
+#else
+#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
+ static_assert( \
+ (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \
+ GMOCK_PP_STRINGIZE( \
_elem) " cannot be recognized as a valid specification modifier.");
+#endif // GMOCK_INTERNAL_STRICT_SPEC_ASSERT
// Modifiers implementation.
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
@@ -236,26 +284,12 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_UNPACK_ref(x) x
-#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
- GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
- GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
- (_elem)
+#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype ,
-// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
-// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
-// maybe they can be simplified somehow.
-#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
- GMOCK_INTERNAL_IS_CALLTYPE_I( \
- GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
-#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
-
-#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
- GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
- GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
-#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
- GMOCK_PP_IDENTITY _arg
-
-#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
+#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__
// Note: The use of `identity_t` here allows _Ret to represent return types that
// would normally need to be specified in a different way. For example, a method