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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -71,20 +71,6 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields);
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// PointeeOf<Pointer>::type is the type of a value pointed to by a
|
||||
// Pointer, which can be either a smart pointer or a raw pointer. The
|
||||
// following default implementation is for the case where Pointer is a
|
||||
// smart pointer.
|
||||
template <typename Pointer>
|
||||
struct PointeeOf {
|
||||
// Smart pointer classes define type element_type as the type of
|
||||
// their pointees.
|
||||
typedef typename Pointer::element_type type;
|
||||
};
|
||||
// This specialization is for the raw pointer case.
|
||||
template <typename T>
|
||||
struct PointeeOf<T*> { typedef T type; }; // NOLINT
|
||||
|
||||
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||
// The following default implementation is for the smart pointer case.
|
||||
@@ -378,7 +364,8 @@ template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef typename std::remove_const<
|
||||
typename internal::PointeeOf<ElementPointer>::type>::type RawElement;
|
||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||
RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
typedef const type const_reference;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user