diff options
author | Abseil Team <absl-team@google.com> | 2020-12-07 21:17:26 (GMT) |
---|---|---|
committer | Andy Getz <durandal@google.com> | 2020-12-07 23:04:12 (GMT) |
commit | a02a591605dfef9addde49634bf010dbe8f95c50 (patch) | |
tree | 6258f1a86109731e61e328b5eac6cdce89146f85 /googlemock/include/gmock/gmock-matchers.h | |
parent | 7bf5057a04eebb12cb731bfd6b3a19c510dc5087 (diff) | |
download | googletest-a02a591605dfef9addde49634bf010dbe8f95c50.zip googletest-a02a591605dfef9addde49634bf010dbe8f95c50.tar.gz googletest-a02a591605dfef9addde49634bf010dbe8f95c50.tar.bz2 |
Googletest export
Add a `Pointer` matcher as an analog to `Pointee`.
Similar to `Pointee`, `Pointer` works with either raw or smart pointers and
allows creating a matcher like Pointer(Eq(foo)) for smart pointers.
PiperOrigin-RevId: 346164768
Diffstat (limited to 'googlemock/include/gmock/gmock-matchers.h')
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index d12d7bf..ae064b5 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -1841,8 +1841,9 @@ class PointeeMatcher { template <typename Pointer> class Impl : public MatcherInterface<Pointer> { public: - typedef typename PointeeOf<GTEST_REMOVE_REFERENCE_AND_CONST_(Pointer)>::type - Pointee; + using Pointee = + typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( + Pointer)>::element_type; explicit Impl(const InnerMatcher& matcher) : matcher_(MatcherCast<const Pointee&>(matcher)) {} @@ -1872,6 +1873,64 @@ class PointeeMatcher { const InnerMatcher matcher_; }; +// Implements the Pointer(m) matcher +// Implements the Pointer(m) matcher for matching a pointer that matches matcher +// m. The pointer can be either raw or smart, and will match `m` against the +// raw pointer. +template <typename InnerMatcher> +class PointerMatcher { + public: + explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} + + // This type conversion operator template allows Pointer(m) to be + // used as a matcher for any pointer type whose pointer type is + // compatible with the inner matcher, where type PointerType can be + // either a raw pointer or a smart pointer. + // + // The reason we do this instead of relying on + // MakePolymorphicMatcher() is that the latter is not flexible + // enough for implementing the DescribeTo() method of Pointer(). + template <typename PointerType> + operator Matcher<PointerType>() const { // NOLINT + return Matcher<PointerType>(new Impl<const PointerType&>(matcher_)); + } + + private: + // The monomorphic implementation that works for a particular pointer type. + template <typename PointerType> + class Impl : public MatcherInterface<PointerType> { + public: + using Pointer = + const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( + PointerType)>::element_type*; + + explicit Impl(const InnerMatcher& matcher) + : matcher_(MatcherCast<Pointer>(matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "is a pointer that "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "is not a pointer that "; + matcher_.DescribeTo(os); + } + + bool MatchAndExplain(PointerType pointer, + MatchResultListener* listener) const override { + *listener << "which is a pointer that "; + Pointer p = GetRawPointer(pointer); + return MatchPrintAndExplain(p, matcher_, listener); + } + + private: + Matcher<Pointer> matcher_; + }; + + const InnerMatcher matcher_; +}; + #if GTEST_HAS_RTTI // Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or // reference that matches inner_matcher when dynamic_cast<T> is applied. @@ -4720,6 +4779,14 @@ internal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre( return internal::FieldsAreMatcher<typename std::decay<M>::type...>( std::forward<M>(matchers)...); } + +// Creates a matcher that matches a pointer (raw or smart) that matches +// inner_matcher. +template <typename InnerMatcher> +inline internal::PointerMatcher<InnerMatcher> Pointer( + const InnerMatcher& inner_matcher) { + return internal::PointerMatcher<InnerMatcher>(inner_matcher); +} } // namespace no_adl // Returns a predicate that is satisfied by anything that matches the |