128f6c2f2SEnji Cooper // Copyright 2007, Google Inc.
228f6c2f2SEnji Cooper // All rights reserved.
328f6c2f2SEnji Cooper //
428f6c2f2SEnji Cooper // Redistribution and use in source and binary forms, with or without
528f6c2f2SEnji Cooper // modification, are permitted provided that the following conditions are
628f6c2f2SEnji Cooper // met:
728f6c2f2SEnji Cooper //
828f6c2f2SEnji Cooper //     * Redistributions of source code must retain the above copyright
928f6c2f2SEnji Cooper // notice, this list of conditions and the following disclaimer.
1028f6c2f2SEnji Cooper //     * Redistributions in binary form must reproduce the above
1128f6c2f2SEnji Cooper // copyright notice, this list of conditions and the following disclaimer
1228f6c2f2SEnji Cooper // in the documentation and/or other materials provided with the
1328f6c2f2SEnji Cooper // distribution.
1428f6c2f2SEnji Cooper //     * Neither the name of Google Inc. nor the names of its
1528f6c2f2SEnji Cooper // contributors may be used to endorse or promote products derived from
1628f6c2f2SEnji Cooper // this software without specific prior written permission.
1728f6c2f2SEnji Cooper //
1828f6c2f2SEnji Cooper // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1928f6c2f2SEnji Cooper // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2028f6c2f2SEnji Cooper // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2128f6c2f2SEnji Cooper // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2228f6c2f2SEnji Cooper // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2328f6c2f2SEnji Cooper // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2428f6c2f2SEnji Cooper // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2528f6c2f2SEnji Cooper // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2628f6c2f2SEnji Cooper // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2728f6c2f2SEnji Cooper // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828f6c2f2SEnji Cooper // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2928f6c2f2SEnji Cooper 
3028f6c2f2SEnji Cooper // The Google C++ Testing and Mocking Framework (Google Test)
3128f6c2f2SEnji Cooper //
3228f6c2f2SEnji Cooper // This file implements just enough of the matcher interface to allow
3328f6c2f2SEnji Cooper // EXPECT_DEATH and friends to accept a matcher argument.
3428f6c2f2SEnji Cooper 
3528f6c2f2SEnji Cooper // IWYU pragma: private, include "gtest/gtest.h"
3628f6c2f2SEnji Cooper // IWYU pragma: friend gtest/.*
3728f6c2f2SEnji Cooper // IWYU pragma: friend gmock/.*
3828f6c2f2SEnji Cooper 
3928f6c2f2SEnji Cooper #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
4028f6c2f2SEnji Cooper #define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
4128f6c2f2SEnji Cooper 
4228f6c2f2SEnji Cooper #include <atomic>
4328f6c2f2SEnji Cooper #include <functional>
4428f6c2f2SEnji Cooper #include <memory>
4528f6c2f2SEnji Cooper #include <ostream>
4628f6c2f2SEnji Cooper #include <string>
4728f6c2f2SEnji Cooper #include <type_traits>
4828f6c2f2SEnji Cooper 
4928f6c2f2SEnji Cooper #include "gtest/gtest-printers.h"
5028f6c2f2SEnji Cooper #include "gtest/internal/gtest-internal.h"
5128f6c2f2SEnji Cooper #include "gtest/internal/gtest-port.h"
5228f6c2f2SEnji Cooper 
5328f6c2f2SEnji Cooper // MSVC warning C5046 is new as of VS2017 version 15.8.
5428f6c2f2SEnji Cooper #if defined(_MSC_VER) && _MSC_VER >= 1915
5528f6c2f2SEnji Cooper #define GTEST_MAYBE_5046_ 5046
5628f6c2f2SEnji Cooper #else
5728f6c2f2SEnji Cooper #define GTEST_MAYBE_5046_
5828f6c2f2SEnji Cooper #endif
5928f6c2f2SEnji Cooper 
6028f6c2f2SEnji Cooper GTEST_DISABLE_MSC_WARNINGS_PUSH_(
6128f6c2f2SEnji Cooper     4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
6228f6c2f2SEnji Cooper                               clients of class B */
6328f6c2f2SEnji Cooper     /* Symbol involving type with internal linkage not defined */)
6428f6c2f2SEnji Cooper 
6528f6c2f2SEnji Cooper namespace testing {
6628f6c2f2SEnji Cooper 
6728f6c2f2SEnji Cooper // To implement a matcher Foo for type T, define:
6828f6c2f2SEnji Cooper //   1. a class FooMatcherMatcher that implements the matcher interface:
6928f6c2f2SEnji Cooper //     using is_gtest_matcher = void;
7028f6c2f2SEnji Cooper //     bool MatchAndExplain(const T&, std::ostream*);
7128f6c2f2SEnji Cooper //       (MatchResultListener* can also be used instead of std::ostream*)
7228f6c2f2SEnji Cooper //     void DescribeTo(std::ostream*);
7328f6c2f2SEnji Cooper //     void DescribeNegationTo(std::ostream*);
7428f6c2f2SEnji Cooper //
7528f6c2f2SEnji Cooper //   2. a factory function that creates a Matcher<T> object from a
7628f6c2f2SEnji Cooper //      FooMatcherMatcher.
7728f6c2f2SEnji Cooper 
7828f6c2f2SEnji Cooper class MatchResultListener {
7928f6c2f2SEnji Cooper  public:
8028f6c2f2SEnji Cooper   // Creates a listener object with the given underlying ostream.  The
8128f6c2f2SEnji Cooper   // listener does not own the ostream, and does not dereference it
8228f6c2f2SEnji Cooper   // in the constructor or destructor.
MatchResultListener(::std::ostream * os)8328f6c2f2SEnji Cooper   explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
8428f6c2f2SEnji Cooper   virtual ~MatchResultListener() = 0;  // Makes this class abstract.
8528f6c2f2SEnji Cooper 
8628f6c2f2SEnji Cooper   // Streams x to the underlying ostream; does nothing if the ostream
8728f6c2f2SEnji Cooper   // is NULL.
8828f6c2f2SEnji Cooper   template <typename T>
8928f6c2f2SEnji Cooper   MatchResultListener& operator<<(const T& x) {
9028f6c2f2SEnji Cooper     if (stream_ != nullptr) *stream_ << x;
9128f6c2f2SEnji Cooper     return *this;
9228f6c2f2SEnji Cooper   }
9328f6c2f2SEnji Cooper 
9428f6c2f2SEnji Cooper   // Returns the underlying ostream.
stream()9528f6c2f2SEnji Cooper   ::std::ostream* stream() { return stream_; }
9628f6c2f2SEnji Cooper 
9728f6c2f2SEnji Cooper   // Returns true if and only if the listener is interested in an explanation
9828f6c2f2SEnji Cooper   // of the match result.  A matcher's MatchAndExplain() method can use
9928f6c2f2SEnji Cooper   // this information to avoid generating the explanation when no one
10028f6c2f2SEnji Cooper   // intends to hear it.
IsInterested()10128f6c2f2SEnji Cooper   bool IsInterested() const { return stream_ != nullptr; }
10228f6c2f2SEnji Cooper 
10328f6c2f2SEnji Cooper  private:
10428f6c2f2SEnji Cooper   ::std::ostream* const stream_;
10528f6c2f2SEnji Cooper 
10628f6c2f2SEnji Cooper   MatchResultListener(const MatchResultListener&) = delete;
10728f6c2f2SEnji Cooper   MatchResultListener& operator=(const MatchResultListener&) = delete;
10828f6c2f2SEnji Cooper };
10928f6c2f2SEnji Cooper 
11028f6c2f2SEnji Cooper inline MatchResultListener::~MatchResultListener() = default;
11128f6c2f2SEnji Cooper 
11228f6c2f2SEnji Cooper // An instance of a subclass of this knows how to describe itself as a
11328f6c2f2SEnji Cooper // matcher.
11428f6c2f2SEnji Cooper class GTEST_API_ MatcherDescriberInterface {
11528f6c2f2SEnji Cooper  public:
11628f6c2f2SEnji Cooper   virtual ~MatcherDescriberInterface() = default;
11728f6c2f2SEnji Cooper 
11828f6c2f2SEnji Cooper   // Describes this matcher to an ostream.  The function should print
11928f6c2f2SEnji Cooper   // a verb phrase that describes the property a value matching this
12028f6c2f2SEnji Cooper   // matcher should have.  The subject of the verb phrase is the value
12128f6c2f2SEnji Cooper   // being matched.  For example, the DescribeTo() method of the Gt(7)
12228f6c2f2SEnji Cooper   // matcher prints "is greater than 7".
12328f6c2f2SEnji Cooper   virtual void DescribeTo(::std::ostream* os) const = 0;
12428f6c2f2SEnji Cooper 
12528f6c2f2SEnji Cooper   // Describes the negation of this matcher to an ostream.  For
12628f6c2f2SEnji Cooper   // example, if the description of this matcher is "is greater than
12728f6c2f2SEnji Cooper   // 7", the negated description could be "is not greater than 7".
12828f6c2f2SEnji Cooper   // You are not required to override this when implementing
12928f6c2f2SEnji Cooper   // MatcherInterface, but it is highly advised so that your matcher
13028f6c2f2SEnji Cooper   // can produce good error messages.
DescribeNegationTo(::std::ostream * os)13128f6c2f2SEnji Cooper   virtual void DescribeNegationTo(::std::ostream* os) const {
13228f6c2f2SEnji Cooper     *os << "not (";
13328f6c2f2SEnji Cooper     DescribeTo(os);
13428f6c2f2SEnji Cooper     *os << ")";
13528f6c2f2SEnji Cooper   }
13628f6c2f2SEnji Cooper };
13728f6c2f2SEnji Cooper 
13828f6c2f2SEnji Cooper // The implementation of a matcher.
13928f6c2f2SEnji Cooper template <typename T>
14028f6c2f2SEnji Cooper class MatcherInterface : public MatcherDescriberInterface {
14128f6c2f2SEnji Cooper  public:
14228f6c2f2SEnji Cooper   // Returns true if and only if the matcher matches x; also explains the
14328f6c2f2SEnji Cooper   // match result to 'listener' if necessary (see the next paragraph), in
14428f6c2f2SEnji Cooper   // the form of a non-restrictive relative clause ("which ...",
14528f6c2f2SEnji Cooper   // "whose ...", etc) that describes x.  For example, the
14628f6c2f2SEnji Cooper   // MatchAndExplain() method of the Pointee(...) matcher should
14728f6c2f2SEnji Cooper   // generate an explanation like "which points to ...".
14828f6c2f2SEnji Cooper   //
14928f6c2f2SEnji Cooper   // Implementations of MatchAndExplain() should add an explanation of
15028f6c2f2SEnji Cooper   // the match result *if and only if* they can provide additional
15128f6c2f2SEnji Cooper   // information that's not already present (or not obvious) in the
15228f6c2f2SEnji Cooper   // print-out of x and the matcher's description.  Whether the match
15328f6c2f2SEnji Cooper   // succeeds is not a factor in deciding whether an explanation is
15428f6c2f2SEnji Cooper   // needed, as sometimes the caller needs to print a failure message
15528f6c2f2SEnji Cooper   // when the match succeeds (e.g. when the matcher is used inside
15628f6c2f2SEnji Cooper   // Not()).
15728f6c2f2SEnji Cooper   //
15828f6c2f2SEnji Cooper   // For example, a "has at least 10 elements" matcher should explain
15928f6c2f2SEnji Cooper   // what the actual element count is, regardless of the match result,
16028f6c2f2SEnji Cooper   // as it is useful information to the reader; on the other hand, an
16128f6c2f2SEnji Cooper   // "is empty" matcher probably only needs to explain what the actual
16228f6c2f2SEnji Cooper   // size is when the match fails, as it's redundant to say that the
16328f6c2f2SEnji Cooper   // size is 0 when the value is already known to be empty.
16428f6c2f2SEnji Cooper   //
16528f6c2f2SEnji Cooper   // You should override this method when defining a new matcher.
16628f6c2f2SEnji Cooper   //
16728f6c2f2SEnji Cooper   // It's the responsibility of the caller (Google Test) to guarantee
16828f6c2f2SEnji Cooper   // that 'listener' is not NULL.  This helps to simplify a matcher's
16928f6c2f2SEnji Cooper   // implementation when it doesn't care about the performance, as it
17028f6c2f2SEnji Cooper   // can talk to 'listener' without checking its validity first.
17128f6c2f2SEnji Cooper   // However, in order to implement dummy listeners efficiently,
17228f6c2f2SEnji Cooper   // listener->stream() may be NULL.
17328f6c2f2SEnji Cooper   virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
17428f6c2f2SEnji Cooper 
17528f6c2f2SEnji Cooper   // Inherits these methods from MatcherDescriberInterface:
17628f6c2f2SEnji Cooper   //   virtual void DescribeTo(::std::ostream* os) const = 0;
17728f6c2f2SEnji Cooper   //   virtual void DescribeNegationTo(::std::ostream* os) const;
17828f6c2f2SEnji Cooper };
17928f6c2f2SEnji Cooper 
18028f6c2f2SEnji Cooper namespace internal {
18128f6c2f2SEnji Cooper 
18228f6c2f2SEnji Cooper // A match result listener that ignores the explanation.
18328f6c2f2SEnji Cooper class DummyMatchResultListener : public MatchResultListener {
18428f6c2f2SEnji Cooper  public:
DummyMatchResultListener()18528f6c2f2SEnji Cooper   DummyMatchResultListener() : MatchResultListener(nullptr) {}
18628f6c2f2SEnji Cooper 
18728f6c2f2SEnji Cooper  private:
18828f6c2f2SEnji Cooper   DummyMatchResultListener(const DummyMatchResultListener&) = delete;
18928f6c2f2SEnji Cooper   DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;
19028f6c2f2SEnji Cooper };
19128f6c2f2SEnji Cooper 
19228f6c2f2SEnji Cooper // A match result listener that forwards the explanation to a given
19328f6c2f2SEnji Cooper // ostream.  The difference between this and MatchResultListener is
19428f6c2f2SEnji Cooper // that the former is concrete.
19528f6c2f2SEnji Cooper class StreamMatchResultListener : public MatchResultListener {
19628f6c2f2SEnji Cooper  public:
StreamMatchResultListener(::std::ostream * os)19728f6c2f2SEnji Cooper   explicit StreamMatchResultListener(::std::ostream* os)
19828f6c2f2SEnji Cooper       : MatchResultListener(os) {}
19928f6c2f2SEnji Cooper 
20028f6c2f2SEnji Cooper  private:
20128f6c2f2SEnji Cooper   StreamMatchResultListener(const StreamMatchResultListener&) = delete;
20228f6c2f2SEnji Cooper   StreamMatchResultListener& operator=(const StreamMatchResultListener&) =
20328f6c2f2SEnji Cooper       delete;
20428f6c2f2SEnji Cooper };
20528f6c2f2SEnji Cooper 
20628f6c2f2SEnji Cooper struct SharedPayloadBase {
20728f6c2f2SEnji Cooper   std::atomic<int> ref{1};
RefSharedPayloadBase20828f6c2f2SEnji Cooper   void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
UnrefSharedPayloadBase20928f6c2f2SEnji Cooper   bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
21028f6c2f2SEnji Cooper };
21128f6c2f2SEnji Cooper 
21228f6c2f2SEnji Cooper template <typename T>
21328f6c2f2SEnji Cooper struct SharedPayload : SharedPayloadBase {
SharedPayloadSharedPayload21428f6c2f2SEnji Cooper   explicit SharedPayload(const T& v) : value(v) {}
SharedPayloadSharedPayload21528f6c2f2SEnji Cooper   explicit SharedPayload(T&& v) : value(std::move(v)) {}
21628f6c2f2SEnji Cooper 
DestroySharedPayload21728f6c2f2SEnji Cooper   static void Destroy(SharedPayloadBase* shared) {
21828f6c2f2SEnji Cooper     delete static_cast<SharedPayload*>(shared);
21928f6c2f2SEnji Cooper   }
22028f6c2f2SEnji Cooper 
22128f6c2f2SEnji Cooper   T value;
22228f6c2f2SEnji Cooper };
22328f6c2f2SEnji Cooper 
22428f6c2f2SEnji Cooper // An internal class for implementing Matcher<T>, which will derive
22528f6c2f2SEnji Cooper // from it.  We put functionalities common to all Matcher<T>
22628f6c2f2SEnji Cooper // specializations here to avoid code duplication.
22728f6c2f2SEnji Cooper template <typename T>
22828f6c2f2SEnji Cooper class MatcherBase : private MatcherDescriberInterface {
22928f6c2f2SEnji Cooper  public:
23028f6c2f2SEnji Cooper   // Returns true if and only if the matcher matches x; also explains the
23128f6c2f2SEnji Cooper   // match result to 'listener'.
MatchAndExplain(const T & x,MatchResultListener * listener)23228f6c2f2SEnji Cooper   bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
23328f6c2f2SEnji Cooper     GTEST_CHECK_(vtable_ != nullptr);
23428f6c2f2SEnji Cooper     return vtable_->match_and_explain(*this, x, listener);
23528f6c2f2SEnji Cooper   }
23628f6c2f2SEnji Cooper 
23728f6c2f2SEnji Cooper   // Returns true if and only if this matcher matches x.
Matches(const T & x)23828f6c2f2SEnji Cooper   bool Matches(const T& x) const {
23928f6c2f2SEnji Cooper     DummyMatchResultListener dummy;
24028f6c2f2SEnji Cooper     return MatchAndExplain(x, &dummy);
24128f6c2f2SEnji Cooper   }
24228f6c2f2SEnji Cooper 
24328f6c2f2SEnji Cooper   // Describes this matcher to an ostream.
DescribeTo(::std::ostream * os)24428f6c2f2SEnji Cooper   void DescribeTo(::std::ostream* os) const final {
24528f6c2f2SEnji Cooper     GTEST_CHECK_(vtable_ != nullptr);
24628f6c2f2SEnji Cooper     vtable_->describe(*this, os, false);
24728f6c2f2SEnji Cooper   }
24828f6c2f2SEnji Cooper 
24928f6c2f2SEnji Cooper   // Describes the negation of this matcher to an ostream.
DescribeNegationTo(::std::ostream * os)25028f6c2f2SEnji Cooper   void DescribeNegationTo(::std::ostream* os) const final {
25128f6c2f2SEnji Cooper     GTEST_CHECK_(vtable_ != nullptr);
25228f6c2f2SEnji Cooper     vtable_->describe(*this, os, true);
25328f6c2f2SEnji Cooper   }
25428f6c2f2SEnji Cooper 
25528f6c2f2SEnji Cooper   // Explains why x matches, or doesn't match, the matcher.
ExplainMatchResultTo(const T & x,::std::ostream * os)25628f6c2f2SEnji Cooper   void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
25728f6c2f2SEnji Cooper     StreamMatchResultListener listener(os);
25828f6c2f2SEnji Cooper     MatchAndExplain(x, &listener);
25928f6c2f2SEnji Cooper   }
26028f6c2f2SEnji Cooper 
26128f6c2f2SEnji Cooper   // Returns the describer for this matcher object; retains ownership
26228f6c2f2SEnji Cooper   // of the describer, which is only guaranteed to be alive when
26328f6c2f2SEnji Cooper   // this matcher object is alive.
GetDescriber()26428f6c2f2SEnji Cooper   const MatcherDescriberInterface* GetDescriber() const {
26528f6c2f2SEnji Cooper     if (vtable_ == nullptr) return nullptr;
26628f6c2f2SEnji Cooper     return vtable_->get_describer(*this);
26728f6c2f2SEnji Cooper   }
26828f6c2f2SEnji Cooper 
26928f6c2f2SEnji Cooper  protected:
MatcherBase()27028f6c2f2SEnji Cooper   MatcherBase() : vtable_(nullptr), buffer_() {}
27128f6c2f2SEnji Cooper 
27228f6c2f2SEnji Cooper   // Constructs a matcher from its implementation.
27328f6c2f2SEnji Cooper   template <typename U>
MatcherBase(const MatcherInterface<U> * impl)27428f6c2f2SEnji Cooper   explicit MatcherBase(const MatcherInterface<U>* impl)
27528f6c2f2SEnji Cooper       : vtable_(nullptr), buffer_() {
27628f6c2f2SEnji Cooper     Init(impl);
27728f6c2f2SEnji Cooper   }
27828f6c2f2SEnji Cooper 
27928f6c2f2SEnji Cooper   template <typename M, typename = typename std::remove_reference<
28028f6c2f2SEnji Cooper                             M>::type::is_gtest_matcher>
MatcherBase(M && m)28128f6c2f2SEnji Cooper   MatcherBase(M&& m) : vtable_(nullptr), buffer_() {  // NOLINT
28228f6c2f2SEnji Cooper     Init(std::forward<M>(m));
28328f6c2f2SEnji Cooper   }
28428f6c2f2SEnji Cooper 
MatcherBase(const MatcherBase & other)28528f6c2f2SEnji Cooper   MatcherBase(const MatcherBase& other)
28628f6c2f2SEnji Cooper       : vtable_(other.vtable_), buffer_(other.buffer_) {
28728f6c2f2SEnji Cooper     if (IsShared()) buffer_.shared->Ref();
28828f6c2f2SEnji Cooper   }
28928f6c2f2SEnji Cooper 
29028f6c2f2SEnji Cooper   MatcherBase& operator=(const MatcherBase& other) {
29128f6c2f2SEnji Cooper     if (this == &other) return *this;
29228f6c2f2SEnji Cooper     Destroy();
29328f6c2f2SEnji Cooper     vtable_ = other.vtable_;
29428f6c2f2SEnji Cooper     buffer_ = other.buffer_;
29528f6c2f2SEnji Cooper     if (IsShared()) buffer_.shared->Ref();
29628f6c2f2SEnji Cooper     return *this;
29728f6c2f2SEnji Cooper   }
29828f6c2f2SEnji Cooper 
MatcherBase(MatcherBase && other)29928f6c2f2SEnji Cooper   MatcherBase(MatcherBase&& other)
30028f6c2f2SEnji Cooper       : vtable_(other.vtable_), buffer_(other.buffer_) {
30128f6c2f2SEnji Cooper     other.vtable_ = nullptr;
30228f6c2f2SEnji Cooper   }
30328f6c2f2SEnji Cooper 
30428f6c2f2SEnji Cooper   MatcherBase& operator=(MatcherBase&& other) {
30528f6c2f2SEnji Cooper     if (this == &other) return *this;
30628f6c2f2SEnji Cooper     Destroy();
30728f6c2f2SEnji Cooper     vtable_ = other.vtable_;
30828f6c2f2SEnji Cooper     buffer_ = other.buffer_;
30928f6c2f2SEnji Cooper     other.vtable_ = nullptr;
31028f6c2f2SEnji Cooper     return *this;
31128f6c2f2SEnji Cooper   }
31228f6c2f2SEnji Cooper 
~MatcherBase()31328f6c2f2SEnji Cooper   ~MatcherBase() override { Destroy(); }
31428f6c2f2SEnji Cooper 
31528f6c2f2SEnji Cooper  private:
31628f6c2f2SEnji Cooper   struct VTable {
31728f6c2f2SEnji Cooper     bool (*match_and_explain)(const MatcherBase&, const T&,
31828f6c2f2SEnji Cooper                               MatchResultListener*);
31928f6c2f2SEnji Cooper     void (*describe)(const MatcherBase&, std::ostream*, bool negation);
32028f6c2f2SEnji Cooper     // Returns the captured object if it implements the interface, otherwise
32128f6c2f2SEnji Cooper     // returns the MatcherBase itself.
32228f6c2f2SEnji Cooper     const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);
32328f6c2f2SEnji Cooper     // Called on shared instances when the reference count reaches 0.
32428f6c2f2SEnji Cooper     void (*shared_destroy)(SharedPayloadBase*);
32528f6c2f2SEnji Cooper   };
32628f6c2f2SEnji Cooper 
IsShared()32728f6c2f2SEnji Cooper   bool IsShared() const {
32828f6c2f2SEnji Cooper     return vtable_ != nullptr && vtable_->shared_destroy != nullptr;
32928f6c2f2SEnji Cooper   }
33028f6c2f2SEnji Cooper 
33128f6c2f2SEnji Cooper   // If the implementation uses a listener, call that.
33228f6c2f2SEnji Cooper   template <typename P>
33328f6c2f2SEnji Cooper   static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
33428f6c2f2SEnji Cooper                                   MatchResultListener* listener)
33528f6c2f2SEnji Cooper       -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
33628f6c2f2SEnji Cooper     return P::Get(m).MatchAndExplain(value, listener->stream());
33728f6c2f2SEnji Cooper   }
33828f6c2f2SEnji Cooper 
33928f6c2f2SEnji Cooper   template <typename P>
34028f6c2f2SEnji Cooper   static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
34128f6c2f2SEnji Cooper                                   MatchResultListener* listener)
34228f6c2f2SEnji Cooper       -> decltype(P::Get(m).MatchAndExplain(value, listener)) {
34328f6c2f2SEnji Cooper     return P::Get(m).MatchAndExplain(value, listener);
34428f6c2f2SEnji Cooper   }
34528f6c2f2SEnji Cooper 
34628f6c2f2SEnji Cooper   template <typename P>
DescribeImpl(const MatcherBase & m,std::ostream * os,bool negation)34728f6c2f2SEnji Cooper   static void DescribeImpl(const MatcherBase& m, std::ostream* os,
34828f6c2f2SEnji Cooper                            bool negation) {
34928f6c2f2SEnji Cooper     if (negation) {
35028f6c2f2SEnji Cooper       P::Get(m).DescribeNegationTo(os);
35128f6c2f2SEnji Cooper     } else {
35228f6c2f2SEnji Cooper       P::Get(m).DescribeTo(os);
35328f6c2f2SEnji Cooper     }
35428f6c2f2SEnji Cooper   }
35528f6c2f2SEnji Cooper 
35628f6c2f2SEnji Cooper   template <typename P>
GetDescriberImpl(const MatcherBase & m)35728f6c2f2SEnji Cooper   static const MatcherDescriberInterface* GetDescriberImpl(
35828f6c2f2SEnji Cooper       const MatcherBase& m) {
35928f6c2f2SEnji Cooper     // If the impl is a MatcherDescriberInterface, then return it.
36028f6c2f2SEnji Cooper     // Otherwise use MatcherBase itself.
36128f6c2f2SEnji Cooper     // This allows us to implement the GetDescriber() function without support
36228f6c2f2SEnji Cooper     // from the impl, but some users really want to get their impl back when
36328f6c2f2SEnji Cooper     // they call GetDescriber().
36428f6c2f2SEnji Cooper     // We use std::get on a tuple as a workaround of not having `if constexpr`.
36528f6c2f2SEnji Cooper     return std::get<(
36628f6c2f2SEnji Cooper         std::is_convertible<decltype(&P::Get(m)),
36728f6c2f2SEnji Cooper                             const MatcherDescriberInterface*>::value
36828f6c2f2SEnji Cooper             ? 1
36928f6c2f2SEnji Cooper             : 0)>(std::make_tuple(&m, &P::Get(m)));
37028f6c2f2SEnji Cooper   }
37128f6c2f2SEnji Cooper 
37228f6c2f2SEnji Cooper   template <typename P>
GetVTable()37328f6c2f2SEnji Cooper   const VTable* GetVTable() {
37428f6c2f2SEnji Cooper     static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
37528f6c2f2SEnji Cooper                                        &DescribeImpl<P>, &GetDescriberImpl<P>,
37628f6c2f2SEnji Cooper                                        P::shared_destroy};
37728f6c2f2SEnji Cooper     return &kVTable;
37828f6c2f2SEnji Cooper   }
37928f6c2f2SEnji Cooper 
38028f6c2f2SEnji Cooper   union Buffer {
38128f6c2f2SEnji Cooper     // Add some types to give Buffer some common alignment/size use cases.
38228f6c2f2SEnji Cooper     void* ptr;
38328f6c2f2SEnji Cooper     double d;
38428f6c2f2SEnji Cooper     int64_t i;
38528f6c2f2SEnji Cooper     // And add one for the out-of-line cases.
38628f6c2f2SEnji Cooper     SharedPayloadBase* shared;
38728f6c2f2SEnji Cooper   };
38828f6c2f2SEnji Cooper 
Destroy()38928f6c2f2SEnji Cooper   void Destroy() {
39028f6c2f2SEnji Cooper     if (IsShared() && buffer_.shared->Unref()) {
39128f6c2f2SEnji Cooper       vtable_->shared_destroy(buffer_.shared);
39228f6c2f2SEnji Cooper     }
39328f6c2f2SEnji Cooper   }
39428f6c2f2SEnji Cooper 
39528f6c2f2SEnji Cooper   template <typename M>
IsInlined()39628f6c2f2SEnji Cooper   static constexpr bool IsInlined() {
39728f6c2f2SEnji Cooper     return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
39828f6c2f2SEnji Cooper            std::is_trivially_copy_constructible<M>::value &&
39928f6c2f2SEnji Cooper            std::is_trivially_destructible<M>::value;
40028f6c2f2SEnji Cooper   }
40128f6c2f2SEnji Cooper 
40228f6c2f2SEnji Cooper   template <typename M, bool = MatcherBase::IsInlined<M>()>
40328f6c2f2SEnji Cooper   struct ValuePolicy {
GetValuePolicy40428f6c2f2SEnji Cooper     static const M& Get(const MatcherBase& m) {
40528f6c2f2SEnji Cooper       // When inlined along with Init, need to be explicit to avoid violating
40628f6c2f2SEnji Cooper       // strict aliasing rules.
40728f6c2f2SEnji Cooper       const M* ptr =
40828f6c2f2SEnji Cooper           static_cast<const M*>(static_cast<const void*>(&m.buffer_));
40928f6c2f2SEnji Cooper       return *ptr;
41028f6c2f2SEnji Cooper     }
InitValuePolicy41128f6c2f2SEnji Cooper     static void Init(MatcherBase& m, M impl) {
41228f6c2f2SEnji Cooper       ::new (static_cast<void*>(&m.buffer_)) M(impl);
41328f6c2f2SEnji Cooper     }
41428f6c2f2SEnji Cooper     static constexpr auto shared_destroy = nullptr;
41528f6c2f2SEnji Cooper   };
41628f6c2f2SEnji Cooper 
41728f6c2f2SEnji Cooper   template <typename M>
41828f6c2f2SEnji Cooper   struct ValuePolicy<M, false> {
41928f6c2f2SEnji Cooper     using Shared = SharedPayload<M>;
42028f6c2f2SEnji Cooper     static const M& Get(const MatcherBase& m) {
42128f6c2f2SEnji Cooper       return static_cast<Shared*>(m.buffer_.shared)->value;
42228f6c2f2SEnji Cooper     }
42328f6c2f2SEnji Cooper     template <typename Arg>
42428f6c2f2SEnji Cooper     static void Init(MatcherBase& m, Arg&& arg) {
42528f6c2f2SEnji Cooper       m.buffer_.shared = new Shared(std::forward<Arg>(arg));
42628f6c2f2SEnji Cooper     }
42728f6c2f2SEnji Cooper     static constexpr auto shared_destroy = &Shared::Destroy;
42828f6c2f2SEnji Cooper   };
42928f6c2f2SEnji Cooper 
43028f6c2f2SEnji Cooper   template <typename U, bool B>
43128f6c2f2SEnji Cooper   struct ValuePolicy<const MatcherInterface<U>*, B> {
43228f6c2f2SEnji Cooper     using M = const MatcherInterface<U>;
43328f6c2f2SEnji Cooper     using Shared = SharedPayload<std::unique_ptr<M>>;
43428f6c2f2SEnji Cooper     static const M& Get(const MatcherBase& m) {
43528f6c2f2SEnji Cooper       return *static_cast<Shared*>(m.buffer_.shared)->value;
43628f6c2f2SEnji Cooper     }
43728f6c2f2SEnji Cooper     static void Init(MatcherBase& m, M* impl) {
43828f6c2f2SEnji Cooper       m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));
43928f6c2f2SEnji Cooper     }
44028f6c2f2SEnji Cooper 
44128f6c2f2SEnji Cooper     static constexpr auto shared_destroy = &Shared::Destroy;
44228f6c2f2SEnji Cooper   };
44328f6c2f2SEnji Cooper 
44428f6c2f2SEnji Cooper   template <typename M>
44528f6c2f2SEnji Cooper   void Init(M&& m) {
44628f6c2f2SEnji Cooper     using MM = typename std::decay<M>::type;
44728f6c2f2SEnji Cooper     using Policy = ValuePolicy<MM>;
44828f6c2f2SEnji Cooper     vtable_ = GetVTable<Policy>();
44928f6c2f2SEnji Cooper     Policy::Init(*this, std::forward<M>(m));
45028f6c2f2SEnji Cooper   }
45128f6c2f2SEnji Cooper 
45228f6c2f2SEnji Cooper   const VTable* vtable_;
45328f6c2f2SEnji Cooper   Buffer buffer_;
45428f6c2f2SEnji Cooper };
45528f6c2f2SEnji Cooper 
45628f6c2f2SEnji Cooper }  // namespace internal
45728f6c2f2SEnji Cooper 
45828f6c2f2SEnji Cooper // A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
45928f6c2f2SEnji Cooper // object that can check whether a value of type T matches.  The
46028f6c2f2SEnji Cooper // implementation of Matcher<T> is just a std::shared_ptr to const
46128f6c2f2SEnji Cooper // MatcherInterface<T>.  Don't inherit from Matcher!
46228f6c2f2SEnji Cooper template <typename T>
46328f6c2f2SEnji Cooper class Matcher : public internal::MatcherBase<T> {
46428f6c2f2SEnji Cooper  public:
46528f6c2f2SEnji Cooper   // Constructs a null matcher.  Needed for storing Matcher objects in STL
46628f6c2f2SEnji Cooper   // containers.  A default-constructed matcher is not yet initialized.  You
46728f6c2f2SEnji Cooper   // cannot use it until a valid value has been assigned to it.
46828f6c2f2SEnji Cooper   explicit Matcher() {}  // NOLINT
46928f6c2f2SEnji Cooper 
47028f6c2f2SEnji Cooper   // Constructs a matcher from its implementation.
47128f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<const T&>* impl)
47228f6c2f2SEnji Cooper       : internal::MatcherBase<T>(impl) {}
47328f6c2f2SEnji Cooper 
47428f6c2f2SEnji Cooper   template <typename U>
47528f6c2f2SEnji Cooper   explicit Matcher(
47628f6c2f2SEnji Cooper       const MatcherInterface<U>* impl,
47728f6c2f2SEnji Cooper       typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
47828f6c2f2SEnji Cooper           nullptr)
47928f6c2f2SEnji Cooper       : internal::MatcherBase<T>(impl) {}
48028f6c2f2SEnji Cooper 
48128f6c2f2SEnji Cooper   template <typename M, typename = typename std::remove_reference<
48228f6c2f2SEnji Cooper                             M>::type::is_gtest_matcher>
48328f6c2f2SEnji Cooper   Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {}  // NOLINT
48428f6c2f2SEnji Cooper 
48528f6c2f2SEnji Cooper   // Implicit constructor here allows people to write
48628f6c2f2SEnji Cooper   // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
48728f6c2f2SEnji Cooper   Matcher(T value);  // NOLINT
48828f6c2f2SEnji Cooper };
48928f6c2f2SEnji Cooper 
49028f6c2f2SEnji Cooper // The following two specializations allow the user to write str
49128f6c2f2SEnji Cooper // instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
49228f6c2f2SEnji Cooper // matcher is expected.
49328f6c2f2SEnji Cooper template <>
49428f6c2f2SEnji Cooper class GTEST_API_ Matcher<const std::string&>
49528f6c2f2SEnji Cooper     : public internal::MatcherBase<const std::string&> {
49628f6c2f2SEnji Cooper  public:
49728f6c2f2SEnji Cooper   Matcher() = default;
49828f6c2f2SEnji Cooper 
49928f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<const std::string&>* impl)
50028f6c2f2SEnji Cooper       : internal::MatcherBase<const std::string&>(impl) {}
50128f6c2f2SEnji Cooper 
50228f6c2f2SEnji Cooper   template <typename M, typename = typename std::remove_reference<
50328f6c2f2SEnji Cooper                             M>::type::is_gtest_matcher>
50428f6c2f2SEnji Cooper   Matcher(M&& m)  // NOLINT
50528f6c2f2SEnji Cooper       : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
50628f6c2f2SEnji Cooper 
50728f6c2f2SEnji Cooper   // Allows the user to write str instead of Eq(str) sometimes, where
50828f6c2f2SEnji Cooper   // str is a std::string object.
50928f6c2f2SEnji Cooper   Matcher(const std::string& s);  // NOLINT
51028f6c2f2SEnji Cooper 
51128f6c2f2SEnji Cooper   // Allows the user to write "foo" instead of Eq("foo") sometimes.
51228f6c2f2SEnji Cooper   Matcher(const char* s);  // NOLINT
51328f6c2f2SEnji Cooper };
51428f6c2f2SEnji Cooper 
51528f6c2f2SEnji Cooper template <>
51628f6c2f2SEnji Cooper class GTEST_API_ Matcher<std::string>
51728f6c2f2SEnji Cooper     : public internal::MatcherBase<std::string> {
51828f6c2f2SEnji Cooper  public:
51928f6c2f2SEnji Cooper   Matcher() = default;
52028f6c2f2SEnji Cooper 
52128f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<const std::string&>* impl)
52228f6c2f2SEnji Cooper       : internal::MatcherBase<std::string>(impl) {}
52328f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<std::string>* impl)
52428f6c2f2SEnji Cooper       : internal::MatcherBase<std::string>(impl) {}
52528f6c2f2SEnji Cooper 
52628f6c2f2SEnji Cooper   template <typename M, typename = typename std::remove_reference<
52728f6c2f2SEnji Cooper                             M>::type::is_gtest_matcher>
52828f6c2f2SEnji Cooper   Matcher(M&& m)  // NOLINT
52928f6c2f2SEnji Cooper       : internal::MatcherBase<std::string>(std::forward<M>(m)) {}
53028f6c2f2SEnji Cooper 
53128f6c2f2SEnji Cooper   // Allows the user to write str instead of Eq(str) sometimes, where
53228f6c2f2SEnji Cooper   // str is a string object.
53328f6c2f2SEnji Cooper   Matcher(const std::string& s);  // NOLINT
53428f6c2f2SEnji Cooper 
53528f6c2f2SEnji Cooper   // Allows the user to write "foo" instead of Eq("foo") sometimes.
53628f6c2f2SEnji Cooper   Matcher(const char* s);  // NOLINT
53728f6c2f2SEnji Cooper };
53828f6c2f2SEnji Cooper 
53928f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_STRING_VIEW
54028f6c2f2SEnji Cooper // The following two specializations allow the user to write str
54128f6c2f2SEnji Cooper // instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
54228f6c2f2SEnji Cooper // matcher is expected.
54328f6c2f2SEnji Cooper template <>
54428f6c2f2SEnji Cooper class GTEST_API_ Matcher<const internal::StringView&>
54528f6c2f2SEnji Cooper     : public internal::MatcherBase<const internal::StringView&> {
54628f6c2f2SEnji Cooper  public:
54728f6c2f2SEnji Cooper   Matcher() = default;
54828f6c2f2SEnji Cooper 
54928f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
55028f6c2f2SEnji Cooper       : internal::MatcherBase<const internal::StringView&>(impl) {}
55128f6c2f2SEnji Cooper 
55228f6c2f2SEnji Cooper   template <typename M, typename = typename std::remove_reference<
55328f6c2f2SEnji Cooper                             M>::type::is_gtest_matcher>
55428f6c2f2SEnji Cooper   Matcher(M&& m)  // NOLINT
55528f6c2f2SEnji Cooper       : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
55628f6c2f2SEnji Cooper   }
55728f6c2f2SEnji Cooper 
55828f6c2f2SEnji Cooper   // Allows the user to write str instead of Eq(str) sometimes, where
55928f6c2f2SEnji Cooper   // str is a std::string object.
56028f6c2f2SEnji Cooper   Matcher(const std::string& s);  // NOLINT
56128f6c2f2SEnji Cooper 
56228f6c2f2SEnji Cooper   // Allows the user to write "foo" instead of Eq("foo") sometimes.
56328f6c2f2SEnji Cooper   Matcher(const char* s);  // NOLINT
56428f6c2f2SEnji Cooper 
56528f6c2f2SEnji Cooper   // Allows the user to pass absl::string_views or std::string_views directly.
56628f6c2f2SEnji Cooper   Matcher(internal::StringView s);  // NOLINT
56728f6c2f2SEnji Cooper };
56828f6c2f2SEnji Cooper 
56928f6c2f2SEnji Cooper template <>
57028f6c2f2SEnji Cooper class GTEST_API_ Matcher<internal::StringView>
57128f6c2f2SEnji Cooper     : public internal::MatcherBase<internal::StringView> {
57228f6c2f2SEnji Cooper  public:
57328f6c2f2SEnji Cooper   Matcher() = default;
57428f6c2f2SEnji Cooper 
57528f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
57628f6c2f2SEnji Cooper       : internal::MatcherBase<internal::StringView>(impl) {}
57728f6c2f2SEnji Cooper   explicit Matcher(const MatcherInterface<internal::StringView>* impl)
57828f6c2f2SEnji Cooper       : internal::MatcherBase<internal::StringView>(impl) {}
57928f6c2f2SEnji Cooper 
58028f6c2f2SEnji Cooper   template <typename M, typename = typename std::remove_reference<
58128f6c2f2SEnji Cooper                             M>::type::is_gtest_matcher>
58228f6c2f2SEnji Cooper   Matcher(M&& m)  // NOLINT
58328f6c2f2SEnji Cooper       : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
58428f6c2f2SEnji Cooper 
58528f6c2f2SEnji Cooper   // Allows the user to write str instead of Eq(str) sometimes, where
58628f6c2f2SEnji Cooper   // str is a std::string object.
58728f6c2f2SEnji Cooper   Matcher(const std::string& s);  // NOLINT
58828f6c2f2SEnji Cooper 
58928f6c2f2SEnji Cooper   // Allows the user to write "foo" instead of Eq("foo") sometimes.
59028f6c2f2SEnji Cooper   Matcher(const char* s);  // NOLINT
59128f6c2f2SEnji Cooper 
59228f6c2f2SEnji Cooper   // Allows the user to pass absl::string_views or std::string_views directly.
59328f6c2f2SEnji Cooper   Matcher(internal::StringView s);  // NOLINT
59428f6c2f2SEnji Cooper };
59528f6c2f2SEnji Cooper #endif  // GTEST_INTERNAL_HAS_STRING_VIEW
59628f6c2f2SEnji Cooper 
59728f6c2f2SEnji Cooper // Prints a matcher in a human-readable format.
59828f6c2f2SEnji Cooper template <typename T>
59928f6c2f2SEnji Cooper std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
60028f6c2f2SEnji Cooper   matcher.DescribeTo(&os);
60128f6c2f2SEnji Cooper   return os;
60228f6c2f2SEnji Cooper }
60328f6c2f2SEnji Cooper 
60428f6c2f2SEnji Cooper // The PolymorphicMatcher class template makes it easy to implement a
60528f6c2f2SEnji Cooper // polymorphic matcher (i.e. a matcher that can match values of more
60628f6c2f2SEnji Cooper // than one type, e.g. Eq(n) and NotNull()).
60728f6c2f2SEnji Cooper //
60828f6c2f2SEnji Cooper // To define a polymorphic matcher, a user should provide an Impl
60928f6c2f2SEnji Cooper // class that has a DescribeTo() method and a DescribeNegationTo()
61028f6c2f2SEnji Cooper // method, and define a member function (or member function template)
61128f6c2f2SEnji Cooper //
61228f6c2f2SEnji Cooper //   bool MatchAndExplain(const Value& value,
61328f6c2f2SEnji Cooper //                        MatchResultListener* listener) const;
61428f6c2f2SEnji Cooper //
61528f6c2f2SEnji Cooper // See the definition of NotNull() for a complete example.
61628f6c2f2SEnji Cooper template <class Impl>
61728f6c2f2SEnji Cooper class PolymorphicMatcher {
61828f6c2f2SEnji Cooper  public:
61928f6c2f2SEnji Cooper   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
62028f6c2f2SEnji Cooper 
62128f6c2f2SEnji Cooper   // Returns a mutable reference to the underlying matcher
62228f6c2f2SEnji Cooper   // implementation object.
62328f6c2f2SEnji Cooper   Impl& mutable_impl() { return impl_; }
62428f6c2f2SEnji Cooper 
62528f6c2f2SEnji Cooper   // Returns an immutable reference to the underlying matcher
62628f6c2f2SEnji Cooper   // implementation object.
62728f6c2f2SEnji Cooper   const Impl& impl() const { return impl_; }
62828f6c2f2SEnji Cooper 
62928f6c2f2SEnji Cooper   template <typename T>
63028f6c2f2SEnji Cooper   operator Matcher<T>() const {
63128f6c2f2SEnji Cooper     return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
63228f6c2f2SEnji Cooper   }
63328f6c2f2SEnji Cooper 
63428f6c2f2SEnji Cooper  private:
63528f6c2f2SEnji Cooper   template <typename T>
63628f6c2f2SEnji Cooper   class MonomorphicImpl : public MatcherInterface<T> {
63728f6c2f2SEnji Cooper    public:
63828f6c2f2SEnji Cooper     explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
63928f6c2f2SEnji Cooper 
64028f6c2f2SEnji Cooper     void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
64128f6c2f2SEnji Cooper 
64228f6c2f2SEnji Cooper     void DescribeNegationTo(::std::ostream* os) const override {
64328f6c2f2SEnji Cooper       impl_.DescribeNegationTo(os);
64428f6c2f2SEnji Cooper     }
64528f6c2f2SEnji Cooper 
64628f6c2f2SEnji Cooper     bool MatchAndExplain(T x, MatchResultListener* listener) const override {
64728f6c2f2SEnji Cooper       return impl_.MatchAndExplain(x, listener);
64828f6c2f2SEnji Cooper     }
64928f6c2f2SEnji Cooper 
65028f6c2f2SEnji Cooper    private:
65128f6c2f2SEnji Cooper     const Impl impl_;
65228f6c2f2SEnji Cooper   };
65328f6c2f2SEnji Cooper 
65428f6c2f2SEnji Cooper   Impl impl_;
65528f6c2f2SEnji Cooper };
65628f6c2f2SEnji Cooper 
65728f6c2f2SEnji Cooper // Creates a matcher from its implementation.
65828f6c2f2SEnji Cooper // DEPRECATED: Especially in the generic code, prefer:
65928f6c2f2SEnji Cooper //   Matcher<T>(new MyMatcherImpl<const T&>(...));
66028f6c2f2SEnji Cooper //
66128f6c2f2SEnji Cooper // MakeMatcher may create a Matcher that accepts its argument by value, which
66228f6c2f2SEnji Cooper // leads to unnecessary copies & lack of support for non-copyable types.
66328f6c2f2SEnji Cooper template <typename T>
66428f6c2f2SEnji Cooper inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
66528f6c2f2SEnji Cooper   return Matcher<T>(impl);
66628f6c2f2SEnji Cooper }
66728f6c2f2SEnji Cooper 
66828f6c2f2SEnji Cooper // Creates a polymorphic matcher from its implementation.  This is
66928f6c2f2SEnji Cooper // easier to use than the PolymorphicMatcher<Impl> constructor as it
67028f6c2f2SEnji Cooper // doesn't require you to explicitly write the template argument, e.g.
67128f6c2f2SEnji Cooper //
67228f6c2f2SEnji Cooper //   MakePolymorphicMatcher(foo);
67328f6c2f2SEnji Cooper // vs
67428f6c2f2SEnji Cooper //   PolymorphicMatcher<TypeOfFoo>(foo);
67528f6c2f2SEnji Cooper template <class Impl>
67628f6c2f2SEnji Cooper inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
67728f6c2f2SEnji Cooper   return PolymorphicMatcher<Impl>(impl);
67828f6c2f2SEnji Cooper }
67928f6c2f2SEnji Cooper 
68028f6c2f2SEnji Cooper namespace internal {
68128f6c2f2SEnji Cooper // Implements a matcher that compares a given value with a
68228f6c2f2SEnji Cooper // pre-supplied value using one of the ==, <=, <, etc, operators.  The
68328f6c2f2SEnji Cooper // two values being compared don't have to have the same type.
68428f6c2f2SEnji Cooper //
68528f6c2f2SEnji Cooper // The matcher defined here is polymorphic (for example, Eq(5) can be
68628f6c2f2SEnji Cooper // used to match an int, a short, a double, etc).  Therefore we use
68728f6c2f2SEnji Cooper // a template type conversion operator in the implementation.
68828f6c2f2SEnji Cooper //
68928f6c2f2SEnji Cooper // The following template definition assumes that the Rhs parameter is
69028f6c2f2SEnji Cooper // a "bare" type (i.e. neither 'const T' nor 'T&').
69128f6c2f2SEnji Cooper template <typename D, typename Rhs, typename Op>
69228f6c2f2SEnji Cooper class ComparisonBase {
69328f6c2f2SEnji Cooper  public:
69428f6c2f2SEnji Cooper   explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
69528f6c2f2SEnji Cooper 
69628f6c2f2SEnji Cooper   using is_gtest_matcher = void;
69728f6c2f2SEnji Cooper 
69828f6c2f2SEnji Cooper   template <typename Lhs>
69928f6c2f2SEnji Cooper   bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
70028f6c2f2SEnji Cooper     return Op()(lhs, Unwrap(rhs_));
70128f6c2f2SEnji Cooper   }
70228f6c2f2SEnji Cooper   void DescribeTo(std::ostream* os) const {
70328f6c2f2SEnji Cooper     *os << D::Desc() << " ";
70428f6c2f2SEnji Cooper     UniversalPrint(Unwrap(rhs_), os);
70528f6c2f2SEnji Cooper   }
70628f6c2f2SEnji Cooper   void DescribeNegationTo(std::ostream* os) const {
70728f6c2f2SEnji Cooper     *os << D::NegatedDesc() << " ";
70828f6c2f2SEnji Cooper     UniversalPrint(Unwrap(rhs_), os);
70928f6c2f2SEnji Cooper   }
71028f6c2f2SEnji Cooper 
71128f6c2f2SEnji Cooper  private:
71228f6c2f2SEnji Cooper   template <typename T>
71328f6c2f2SEnji Cooper   static const T& Unwrap(const T& v) {
71428f6c2f2SEnji Cooper     return v;
71528f6c2f2SEnji Cooper   }
71628f6c2f2SEnji Cooper   template <typename T>
71728f6c2f2SEnji Cooper   static const T& Unwrap(std::reference_wrapper<T> v) {
71828f6c2f2SEnji Cooper     return v;
71928f6c2f2SEnji Cooper   }
72028f6c2f2SEnji Cooper 
72128f6c2f2SEnji Cooper   Rhs rhs_;
72228f6c2f2SEnji Cooper };
72328f6c2f2SEnji Cooper 
72428f6c2f2SEnji Cooper template <typename Rhs>
72528f6c2f2SEnji Cooper class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
72628f6c2f2SEnji Cooper  public:
72728f6c2f2SEnji Cooper   explicit EqMatcher(const Rhs& rhs)
72828f6c2f2SEnji Cooper       : ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
72928f6c2f2SEnji Cooper   static const char* Desc() { return "is equal to"; }
73028f6c2f2SEnji Cooper   static const char* NegatedDesc() { return "isn't equal to"; }
73128f6c2f2SEnji Cooper };
73228f6c2f2SEnji Cooper template <typename Rhs>
73328f6c2f2SEnji Cooper class NeMatcher
73428f6c2f2SEnji Cooper     : public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
73528f6c2f2SEnji Cooper  public:
73628f6c2f2SEnji Cooper   explicit NeMatcher(const Rhs& rhs)
73728f6c2f2SEnji Cooper       : ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}
73828f6c2f2SEnji Cooper   static const char* Desc() { return "isn't equal to"; }
73928f6c2f2SEnji Cooper   static const char* NegatedDesc() { return "is equal to"; }
74028f6c2f2SEnji Cooper };
74128f6c2f2SEnji Cooper template <typename Rhs>
74228f6c2f2SEnji Cooper class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
74328f6c2f2SEnji Cooper  public:
74428f6c2f2SEnji Cooper   explicit LtMatcher(const Rhs& rhs)
74528f6c2f2SEnji Cooper       : ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
74628f6c2f2SEnji Cooper   static const char* Desc() { return "is <"; }
74728f6c2f2SEnji Cooper   static const char* NegatedDesc() { return "isn't <"; }
74828f6c2f2SEnji Cooper };
74928f6c2f2SEnji Cooper template <typename Rhs>
75028f6c2f2SEnji Cooper class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
75128f6c2f2SEnji Cooper  public:
75228f6c2f2SEnji Cooper   explicit GtMatcher(const Rhs& rhs)
75328f6c2f2SEnji Cooper       : ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
75428f6c2f2SEnji Cooper   static const char* Desc() { return "is >"; }
75528f6c2f2SEnji Cooper   static const char* NegatedDesc() { return "isn't >"; }
75628f6c2f2SEnji Cooper };
75728f6c2f2SEnji Cooper template <typename Rhs>
75828f6c2f2SEnji Cooper class LeMatcher
75928f6c2f2SEnji Cooper     : public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
76028f6c2f2SEnji Cooper  public:
76128f6c2f2SEnji Cooper   explicit LeMatcher(const Rhs& rhs)
76228f6c2f2SEnji Cooper       : ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}
76328f6c2f2SEnji Cooper   static const char* Desc() { return "is <="; }
76428f6c2f2SEnji Cooper   static const char* NegatedDesc() { return "isn't <="; }
76528f6c2f2SEnji Cooper };
76628f6c2f2SEnji Cooper template <typename Rhs>
76728f6c2f2SEnji Cooper class GeMatcher
76828f6c2f2SEnji Cooper     : public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
76928f6c2f2SEnji Cooper  public:
77028f6c2f2SEnji Cooper   explicit GeMatcher(const Rhs& rhs)
77128f6c2f2SEnji Cooper       : ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}
77228f6c2f2SEnji Cooper   static const char* Desc() { return "is >="; }
77328f6c2f2SEnji Cooper   static const char* NegatedDesc() { return "isn't >="; }
77428f6c2f2SEnji Cooper };
77528f6c2f2SEnji Cooper 
77628f6c2f2SEnji Cooper template <typename T, typename = typename std::enable_if<
77728f6c2f2SEnji Cooper                           std::is_constructible<std::string, T>::value>::type>
77828f6c2f2SEnji Cooper using StringLike = T;
77928f6c2f2SEnji Cooper 
78028f6c2f2SEnji Cooper // Implements polymorphic matchers MatchesRegex(regex) and
78128f6c2f2SEnji Cooper // ContainsRegex(regex), which can be used as a Matcher<T> as long as
78228f6c2f2SEnji Cooper // T can be converted to a string.
78328f6c2f2SEnji Cooper class MatchesRegexMatcher {
78428f6c2f2SEnji Cooper  public:
78528f6c2f2SEnji Cooper   MatchesRegexMatcher(const RE* regex, bool full_match)
78628f6c2f2SEnji Cooper       : regex_(regex), full_match_(full_match) {}
78728f6c2f2SEnji Cooper 
78828f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_STRING_VIEW
78928f6c2f2SEnji Cooper   bool MatchAndExplain(const internal::StringView& s,
79028f6c2f2SEnji Cooper                        MatchResultListener* listener) const {
79128f6c2f2SEnji Cooper     return MatchAndExplain(std::string(s), listener);
79228f6c2f2SEnji Cooper   }
79328f6c2f2SEnji Cooper #endif  // GTEST_INTERNAL_HAS_STRING_VIEW
79428f6c2f2SEnji Cooper 
79528f6c2f2SEnji Cooper   // Accepts pointer types, particularly:
79628f6c2f2SEnji Cooper   //   const char*
79728f6c2f2SEnji Cooper   //   char*
79828f6c2f2SEnji Cooper   //   const wchar_t*
79928f6c2f2SEnji Cooper   //   wchar_t*
80028f6c2f2SEnji Cooper   template <typename CharType>
80128f6c2f2SEnji Cooper   bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
80228f6c2f2SEnji Cooper     return s != nullptr && MatchAndExplain(std::string(s), listener);
80328f6c2f2SEnji Cooper   }
80428f6c2f2SEnji Cooper 
80528f6c2f2SEnji Cooper   // Matches anything that can convert to std::string.
80628f6c2f2SEnji Cooper   //
80728f6c2f2SEnji Cooper   // This is a template, not just a plain function with const std::string&,
80828f6c2f2SEnji Cooper   // because absl::string_view has some interfering non-explicit constructors.
80928f6c2f2SEnji Cooper   template <class MatcheeStringType>
81028f6c2f2SEnji Cooper   bool MatchAndExplain(const MatcheeStringType& s,
81128f6c2f2SEnji Cooper                        MatchResultListener* /* listener */) const {
81228f6c2f2SEnji Cooper     const std::string s2(s);
81328f6c2f2SEnji Cooper     return full_match_ ? RE::FullMatch(s2, *regex_)
81428f6c2f2SEnji Cooper                        : RE::PartialMatch(s2, *regex_);
81528f6c2f2SEnji Cooper   }
81628f6c2f2SEnji Cooper 
81728f6c2f2SEnji Cooper   void DescribeTo(::std::ostream* os) const {
81828f6c2f2SEnji Cooper     *os << (full_match_ ? "matches" : "contains") << " regular expression ";
81928f6c2f2SEnji Cooper     UniversalPrinter<std::string>::Print(regex_->pattern(), os);
82028f6c2f2SEnji Cooper   }
82128f6c2f2SEnji Cooper 
82228f6c2f2SEnji Cooper   void DescribeNegationTo(::std::ostream* os) const {
82328f6c2f2SEnji Cooper     *os << "doesn't " << (full_match_ ? "match" : "contain")
82428f6c2f2SEnji Cooper         << " regular expression ";
82528f6c2f2SEnji Cooper     UniversalPrinter<std::string>::Print(regex_->pattern(), os);
82628f6c2f2SEnji Cooper   }
82728f6c2f2SEnji Cooper 
82828f6c2f2SEnji Cooper  private:
82928f6c2f2SEnji Cooper   const std::shared_ptr<const RE> regex_;
83028f6c2f2SEnji Cooper   const bool full_match_;
83128f6c2f2SEnji Cooper };
83228f6c2f2SEnji Cooper }  // namespace internal
83328f6c2f2SEnji Cooper 
83428f6c2f2SEnji Cooper // Matches a string that fully matches regular expression 'regex'.
83528f6c2f2SEnji Cooper // The matcher takes ownership of 'regex'.
83628f6c2f2SEnji Cooper inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
83728f6c2f2SEnji Cooper     const internal::RE* regex) {
83828f6c2f2SEnji Cooper   return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
83928f6c2f2SEnji Cooper }
84028f6c2f2SEnji Cooper template <typename T = std::string>
84128f6c2f2SEnji Cooper PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
84228f6c2f2SEnji Cooper     const internal::StringLike<T>& regex) {
84328f6c2f2SEnji Cooper   return MatchesRegex(new internal::RE(std::string(regex)));
84428f6c2f2SEnji Cooper }
84528f6c2f2SEnji Cooper 
84628f6c2f2SEnji Cooper // Matches a string that contains regular expression 'regex'.
84728f6c2f2SEnji Cooper // The matcher takes ownership of 'regex'.
84828f6c2f2SEnji Cooper inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
84928f6c2f2SEnji Cooper     const internal::RE* regex) {
85028f6c2f2SEnji Cooper   return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
85128f6c2f2SEnji Cooper }
85228f6c2f2SEnji Cooper template <typename T = std::string>
85328f6c2f2SEnji Cooper PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
85428f6c2f2SEnji Cooper     const internal::StringLike<T>& regex) {
85528f6c2f2SEnji Cooper   return ContainsRegex(new internal::RE(std::string(regex)));
85628f6c2f2SEnji Cooper }
85728f6c2f2SEnji Cooper 
85828f6c2f2SEnji Cooper // Creates a polymorphic matcher that matches anything equal to x.
85928f6c2f2SEnji Cooper // Note: if the parameter of Eq() were declared as const T&, Eq("foo")
86028f6c2f2SEnji Cooper // wouldn't compile.
86128f6c2f2SEnji Cooper template <typename T>
86228f6c2f2SEnji Cooper inline internal::EqMatcher<T> Eq(T x) {
86328f6c2f2SEnji Cooper   return internal::EqMatcher<T>(x);
86428f6c2f2SEnji Cooper }
86528f6c2f2SEnji Cooper 
86628f6c2f2SEnji Cooper // Constructs a Matcher<T> from a 'value' of type T.  The constructed
86728f6c2f2SEnji Cooper // matcher matches any value that's equal to 'value'.
86828f6c2f2SEnji Cooper template <typename T>
86928f6c2f2SEnji Cooper Matcher<T>::Matcher(T value) {
87028f6c2f2SEnji Cooper   *this = Eq(value);
87128f6c2f2SEnji Cooper }
87228f6c2f2SEnji Cooper 
87328f6c2f2SEnji Cooper // Creates a monomorphic matcher that matches anything with type Lhs
87428f6c2f2SEnji Cooper // and equal to rhs.  A user may need to use this instead of Eq(...)
87528f6c2f2SEnji Cooper // in order to resolve an overloading ambiguity.
87628f6c2f2SEnji Cooper //
87728f6c2f2SEnji Cooper // TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
87828f6c2f2SEnji Cooper // or Matcher<T>(x), but more readable than the latter.
87928f6c2f2SEnji Cooper //
88028f6c2f2SEnji Cooper // We could define similar monomorphic matchers for other comparison
88128f6c2f2SEnji Cooper // operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
88228f6c2f2SEnji Cooper // it yet as those are used much less than Eq() in practice.  A user
88328f6c2f2SEnji Cooper // can always write Matcher<T>(Lt(5)) to be explicit about the type,
88428f6c2f2SEnji Cooper // for example.
88528f6c2f2SEnji Cooper template <typename Lhs, typename Rhs>
88628f6c2f2SEnji Cooper inline Matcher<Lhs> TypedEq(const Rhs& rhs) {
88728f6c2f2SEnji Cooper   return Eq(rhs);
88828f6c2f2SEnji Cooper }
88928f6c2f2SEnji Cooper 
89028f6c2f2SEnji Cooper // Creates a polymorphic matcher that matches anything >= x.
89128f6c2f2SEnji Cooper template <typename Rhs>
89228f6c2f2SEnji Cooper inline internal::GeMatcher<Rhs> Ge(Rhs x) {
89328f6c2f2SEnji Cooper   return internal::GeMatcher<Rhs>(x);
89428f6c2f2SEnji Cooper }
89528f6c2f2SEnji Cooper 
89628f6c2f2SEnji Cooper // Creates a polymorphic matcher that matches anything > x.
89728f6c2f2SEnji Cooper template <typename Rhs>
89828f6c2f2SEnji Cooper inline internal::GtMatcher<Rhs> Gt(Rhs x) {
89928f6c2f2SEnji Cooper   return internal::GtMatcher<Rhs>(x);
90028f6c2f2SEnji Cooper }
90128f6c2f2SEnji Cooper 
90228f6c2f2SEnji Cooper // Creates a polymorphic matcher that matches anything <= x.
90328f6c2f2SEnji Cooper template <typename Rhs>
90428f6c2f2SEnji Cooper inline internal::LeMatcher<Rhs> Le(Rhs x) {
90528f6c2f2SEnji Cooper   return internal::LeMatcher<Rhs>(x);
90628f6c2f2SEnji Cooper }
90728f6c2f2SEnji Cooper 
90828f6c2f2SEnji Cooper // Creates a polymorphic matcher that matches anything < x.
90928f6c2f2SEnji Cooper template <typename Rhs>
91028f6c2f2SEnji Cooper inline internal::LtMatcher<Rhs> Lt(Rhs x) {
91128f6c2f2SEnji Cooper   return internal::LtMatcher<Rhs>(x);
91228f6c2f2SEnji Cooper }
91328f6c2f2SEnji Cooper 
91428f6c2f2SEnji Cooper // Creates a polymorphic matcher that matches anything != x.
91528f6c2f2SEnji Cooper template <typename Rhs>
91628f6c2f2SEnji Cooper inline internal::NeMatcher<Rhs> Ne(Rhs x) {
91728f6c2f2SEnji Cooper   return internal::NeMatcher<Rhs>(x);
91828f6c2f2SEnji Cooper }
91928f6c2f2SEnji Cooper }  // namespace testing
92028f6c2f2SEnji Cooper 
92128f6c2f2SEnji Cooper GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046
92228f6c2f2SEnji Cooper 
92328f6c2f2SEnji Cooper #endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
924