mirror of
https://github.com/google/googletest.git
synced 2026-07-30 16:26:24 +08:00
Delay name resolution by un-qualifying DynamicCastMessage calls from gMock.
Since we can't directly depend on proto headers, we rely on ADL + proto headers being included by calling code for this matcher to choose the right overload of `DynamicCastMessage`. PiperOrigin-RevId: 940593408 Change-Id: I7374aed3c5cfe61a183d28ea02e6583ab340f647
This commit is contained in:
parent
78f6d54f9f
commit
973323ed64
@ -284,6 +284,44 @@
|
|||||||
#define GMOCK_MAYBE_5046_
|
#define GMOCK_MAYBE_5046_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_HAS_RTTI
|
||||||
|
namespace proto2 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// A type trait to essentially determine if `DynamicCastMessage` is available,
|
||||||
|
// since older versions of protobuf don't have this function.
|
||||||
|
template <typename T, typename = void>
|
||||||
|
static constexpr bool kHasDynamicCastMessage = false;
|
||||||
|
template <typename T>
|
||||||
|
static constexpr bool kHasDynamicCastMessage<
|
||||||
|
T, std::void_t<decltype(DynamicCastMessage<T>(
|
||||||
|
std::declval<const proto2::MessageLite*>()))>> = true;
|
||||||
|
|
||||||
|
// A helper function to call `DynamicCastMessage` if available, otherwise
|
||||||
|
// falling back to `dynamic_cast`. Note that we must declare this function in
|
||||||
|
// the `proto2` namespace because we need ADL to find the right
|
||||||
|
// `DynamicCastMessage`, and ADL only applies to unqualified function calls.
|
||||||
|
template <typename T>
|
||||||
|
const T* DynamicCastMessageForGtest(const proto2::MessageLite* msg) {
|
||||||
|
if constexpr (kHasDynamicCastMessage<T>) {
|
||||||
|
return DynamicCastMessage<T>(msg);
|
||||||
|
} else {
|
||||||
|
return dynamic_cast<const T*>(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
T* DynamicCastMessageForGtest(proto2::MessageLite* msg) {
|
||||||
|
if constexpr (kHasDynamicCastMessage<T>) {
|
||||||
|
return DynamicCastMessage<T>(msg);
|
||||||
|
} else {
|
||||||
|
return dynamic_cast<T*>(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace proto2
|
||||||
|
#endif // GTEST_HAS_RTTI
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
||||||
4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by
|
4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by
|
||||||
clients of class B */
|
clients of class B */
|
||||||
@ -2060,15 +2098,6 @@ class [[nodiscard]] PointerMatcher {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if GTEST_HAS_RTTI
|
#if GTEST_HAS_RTTI
|
||||||
// A type trait to essentially determine if `DynamicCastMessage` is available,
|
|
||||||
// since older versions of protobuf don't have this function.
|
|
||||||
template <typename T, typename = void>
|
|
||||||
static constexpr bool kHasDynamicCastMessage = false;
|
|
||||||
template <typename T>
|
|
||||||
static constexpr bool kHasDynamicCastMessage<
|
|
||||||
T, std::void_t<decltype(proto2::DynamicCastMessage<T>(
|
|
||||||
std::declval<const proto2::MessageLite*>()))>> = true;
|
|
||||||
|
|
||||||
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
|
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
|
||||||
// reference that matches inner_matcher when dynamic_cast<T> is applied.
|
// reference that matches inner_matcher when dynamic_cast<T> is applied.
|
||||||
// The result of dynamic_cast<To> is forwarded to the inner matcher.
|
// The result of dynamic_cast<To> is forwarded to the inner matcher.
|
||||||
@ -2101,13 +2130,12 @@ class [[nodiscard]] WhenDynamicCastToMatcherBase {
|
|||||||
using ToType =
|
using ToType =
|
||||||
std::remove_const_t<std::remove_reference_t<std::remove_pointer_t<To>>>;
|
std::remove_const_t<std::remove_reference_t<std::remove_pointer_t<To>>>;
|
||||||
|
|
||||||
if constexpr (std::is_base_of_v<proto2::MessageLite, ToType> &&
|
if constexpr (std::is_base_of_v<proto2::MessageLite, ToType>) {
|
||||||
kHasDynamicCastMessage<ToType>) {
|
if constexpr (std::is_pointer_v<To>) {
|
||||||
if constexpr (std::is_pointer_v<From>) {
|
return proto2::internal::DynamicCastMessageForGtest<ToType>(from);
|
||||||
return proto2::DynamicCastMessage<ToType>(from);
|
|
||||||
} else {
|
} else {
|
||||||
// We don't want an std::bad_cast here, so do the cast with pointers.
|
// We don't want an std::bad_cast here, so do the cast with pointers.
|
||||||
return proto2::DynamicCastMessage<ToType>(&from);
|
return proto2::internal::DynamicCastMessageForGtest<ToType>(&from);
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_pointer_v<To>) {
|
} else if constexpr (std::is_pointer_v<To>) {
|
||||||
return dynamic_cast<To>(from);
|
return dynamic_cast<To>(from);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user