diff options
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 13 | ||||
-rw-r--r-- | googlemock/test/gmock-matchers_test.cc | 9 |
2 files changed, 15 insertions, 7 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 4b6ac56..fe88a7c 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -424,7 +424,14 @@ class MatcherCastImpl<T, Matcher<U> > { !std::is_base_of<FromType, ToType>::value, "Can't implicitly convert from <base> to <derived>"); - return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); + // Do the cast to `U` explicitly if necessary. + // Otherwise, let implicit conversions do the trick. + using CastType = + typename std::conditional<std::is_convertible<T&, const U&>::value, + T&, U>::type; + + return source_matcher_.MatchAndExplain(static_cast<CastType>(x), + listener); } void DescribeTo(::std::ostream* os) const override { @@ -524,8 +531,8 @@ inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) { template <typename T, typename U> inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { // Enforce that T can be implicitly converted to U. - GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value), - "T must be implicitly convertible to U"); + static_assert(std::is_convertible<const T&, const U&>::value, + "T must be implicitly convertible to U"); // Enforce that we are not converting a non-reference type T to a reference // type U. GTEST_COMPILE_ASSERT_( diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index c1949e6..3619959 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -765,10 +765,11 @@ TEST(SafeMatcherCastTest, FromConstReferenceToReference) { // Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) { - Matcher<int> m1 = Eq(0); - Matcher<const int&> m2 = SafeMatcherCast<const int&>(m1); - EXPECT_TRUE(m2.Matches(0)); - EXPECT_FALSE(m2.Matches(1)); + Matcher<std::unique_ptr<int>> m1 = IsNull(); + Matcher<const std::unique_ptr<int>&> m2 = + SafeMatcherCast<const std::unique_ptr<int>&>(m1); + EXPECT_TRUE(m2.Matches(std::unique_ptr<int>())); + EXPECT_FALSE(m2.Matches(std::unique_ptr<int>(new int))); } // Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>. |