// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.

// IWYU pragma: private, include "testing/base/public/gunit.h"
// IWYU pragma: friend third_party/googletest/googlemock/.*
// IWYU pragma: friend third_party/googletest/googletest/.*

#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_

#include <atomic>
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>

#include "gtest/gtest-printers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"

// MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915
#define GTEST_MAYBE_5046_ 5046
#else
#define GTEST_MAYBE_5046_
#endif

GTEST_DISABLE_MSC_WARNINGS_PUSH_(
    4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
                              clients of class B */
    /* Symbol involving type with internal linkage not defined */)

namespace testing {

// To implement a matcher Foo for type T, define:
//   1. a class FooMatcherMatcher that implements the matcher interface:
//     using is_gtest_matcher = void;
//     bool MatchAndExplain(const T&, std::ostream*);
//     void DescribeTo(std::ostream*);
//     void DescribeNegationTo(std::ostream*);
//
//   2. a factory function that creates a Matcher<T> object from a
//      FooMatcherMatcher.

class MatchResultListener {
 public:
  // Creates a listener object with the given underlying ostream.  The
  // listener does not own the ostream, and does not dereference it
  // in the constructor or destructor.
  explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
  virtual ~MatchResultListener() = 0;  // Makes this class abstract.

  // Streams x to the underlying ostream; does nothing if the ostream
  // is NULL.
  template <typename T>
  MatchResultListener& operator<<(const T& x) {
    if (stream_ != nullptr) *stream_ << x;
    return *this;
  }

  // Returns the underlying ostream.
  ::std::ostream* stream() { return stream_; }

  // Returns true if and only if the listener is interested in an explanation
  // of the match result.  A matcher's MatchAndExplain() method can use
  // this information to avoid generating the explanation when no one
  // intends to hear it.
  bool IsInterested() const { return stream_ != nullptr; }

 private:
  ::std::ostream* const stream_;

  GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
};

inline MatchResultListener::~MatchResultListener() {
}

// An instance of a subclass of this knows how to describe itself as a
// matcher.
class MatcherDescriberInterface {
 public:
  virtual ~MatcherDescriberInterface() {}

  // Describes this matcher to an ostream.  The function should print
  // a verb phrase that describes the property a value matching this
  // matcher should have.  The subject of the verb phrase is the value
  // being matched.  For example, the DescribeTo() method of the Gt(7)
  // matcher prints "is greater than 7".
  virtual void DescribeTo(::std::ostream* os) const = 0;

  // Describes the negation of this matcher to an ostream.  For
  // example, if the description of this matcher is "is greater than
  // 7", the negated description could be "is not greater than 7".
  // You are not required to override this when implementing
  // MatcherInterface, but it is highly advised so that your matcher
  // can produce good error messages.
  virtual void DescribeNegationTo(::std::ostream* os) const {
    *os << "not (";
    DescribeTo(os);
    *os << ")";
  }
};

// The implementation of a matcher.
template <typename T>
class MatcherInterface : public MatcherDescriberInterface {
 public:
  // Returns true if and only if the matcher matches x; also explains the
  // match result to 'listener' if necessary (see the next paragraph), in
  // the form of a non-restrictive relative clause ("which ...",
  // "whose ...", etc) that describes x.  For example, the
  // MatchAndExplain() method of the Pointee(...) matcher should
  // generate an explanation like "which points to ...".
  //
  // Implementations of MatchAndExplain() should add an explanation of
  // the match result *if and only if* they can provide additional
  // information that's not already present (or not obvious) in the
  // print-out of x and the matcher's description.  Whether the match
  // succeeds is not a factor in deciding whether an explanation is
  // needed, as sometimes the caller needs to print a failure message
  // when the match succeeds (e.g. when the matcher is used inside
  // Not()).
  //
  // For example, a "has at least 10 elements" matcher should explain
  // what the actual element count is, regardless of the match result,
  // as it is useful information to the reader; on the other hand, an
  // "is empty" matcher probably only needs to explain what the actual
  // size is when the match fails, as it's redundant to say that the
  // size is 0 when the value is already known to be empty.
  //
  // You should override this method when defining a new matcher.
  //
  // It's the responsibility of the caller (Google Test) to guarantee
  // that 'listener' is not NULL.  This helps to simplify a matcher's
  // implementation when it doesn't care about the performance, as it
  // can talk to 'listener' without checking its validity first.
  // However, in order to implement dummy listeners efficiently,
  // listener->stream() may be NULL.
  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;

  // Inherits these methods from MatcherDescriberInterface:
  //   virtual void DescribeTo(::std::ostream* os) const = 0;
  //   virtual void DescribeNegationTo(::std::ostream* os) const;
};

namespace internal {

struct AnyEq {
  template <typename A, typename B>
  bool operator()(const A& a, const B& b) const { return a == b; }
};
struct AnyNe {
  template <typename A, typename B>
  bool operator()(const A& a, const B& b) const { return a != b; }
};
struct AnyLt {
  template <typename A, typename B>
  bool operator()(const A& a, const B& b) const { return a < b; }
};
struct AnyGt {
  template <typename A, typename B>
  bool operator()(const A& a, const B& b) const { return a > b; }
};
struct AnyLe {
  template <typename A, typename B>
  bool operator()(const A& a, const B& b) const { return a <= b; }
};
struct AnyGe {
  template <typename A, typename B>
  bool operator()(const A& a, const B& b) const { return a >= b; }
};

// A match result listener that ignores the explanation.
class DummyMatchResultListener : public MatchResultListener {
 public:
  DummyMatchResultListener() : MatchResultListener(nullptr) {}

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
};

// A match result listener that forwards the explanation to a given
// ostream.  The difference between this and MatchResultListener is
// that the former is concrete.
class StreamMatchResultListener : public MatchResultListener {
 public:
  explicit StreamMatchResultListener(::std::ostream* os)
      : MatchResultListener(os) {}

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
};

struct SharedPayloadBase {
  std::atomic<int> ref{1};
  void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
  bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
};

template <typename T>
struct SharedPayload : SharedPayloadBase {
  explicit SharedPayload(const T& v) : value(v) {}
  explicit SharedPayload(T&& v) : value(std::move(v)) {}

  static void Destroy(SharedPayloadBase* shared) {
    delete static_cast<SharedPayload*>(shared);
  }

  T value;
};

// An internal class for implementing Matcher<T>, which will derive
// from it.  We put functionalities common to all Matcher<T>
// specializations here to avoid code duplication.
template <typename T>
class MatcherBase : private MatcherDescriberInterface {
 public:
  // Returns true if and only if the matcher matches x; also explains the
  // match result to 'listener'.
  bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
    GTEST_CHECK_(vtable_ != nullptr);
    return vtable_->match_and_explain(*this, x, listener);
  }

  // Returns true if and only if this matcher matches x.
  bool Matches(const T& x) const {
    DummyMatchResultListener dummy;
    return MatchAndExplain(x, &dummy);
  }

  // Describes this matcher to an ostream.
  void DescribeTo(::std::ostream* os) const final {
    GTEST_CHECK_(vtable_ != nullptr);
    vtable_->describe(*this, os, false);
  }

  // Describes the negation of this matcher to an ostream.
  void DescribeNegationTo(::std::ostream* os) const final {
    GTEST_CHECK_(vtable_ != nullptr);
    vtable_->describe(*this, os, true);
  }

  // Explains why x matches, or doesn't match, the matcher.
  void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
    StreamMatchResultListener listener(os);
    MatchAndExplain(x, &listener);
  }

  // Returns the describer for this matcher object; retains ownership
  // of the describer, which is only guaranteed to be alive when
  // this matcher object is alive.
  const MatcherDescriberInterface* GetDescriber() const {
    if (vtable_ == nullptr) return nullptr;
    return vtable_->get_describer(*this);
  }

 protected:
  MatcherBase() : vtable_(nullptr) {}

  // Constructs a matcher from its implementation.
  template <typename U>
  explicit MatcherBase(const MatcherInterface<U>* impl) {
    Init(impl);
  }

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  MatcherBase(M&& m) {  // NOLINT
    Init(std::forward<M>(m));
  }

  MatcherBase(const MatcherBase& other)
      : vtable_(other.vtable_), buffer_(other.buffer_) {
    if (IsShared()) buffer_.shared->Ref();
  }

  MatcherBase& operator=(const MatcherBase& other) {
    if (this == &other) return *this;
    Destroy();
    vtable_ = other.vtable_;
    buffer_ = other.buffer_;
    if (IsShared()) buffer_.shared->Ref();
    return *this;
  }

  MatcherBase(MatcherBase&& other)
      : vtable_(other.vtable_), buffer_(other.buffer_) {
    other.vtable_ = nullptr;
  }

  MatcherBase& operator=(MatcherBase&& other) {
    if (this == &other) return *this;
    Destroy();
    vtable_ = other.vtable_;
    buffer_ = other.buffer_;
    other.vtable_ = nullptr;
    return *this;
  }

  ~MatcherBase() override { Destroy(); }

 private:
  struct VTable {
    bool (*match_and_explain)(const MatcherBase&, const T&,
                              MatchResultListener*);
    void (*describe)(const MatcherBase&, std::ostream*, bool negation);
    // Returns the captured object if it implements the interface, otherwise
    // returns the MatcherBase itself.
    const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);
    // Called on shared instances when the reference count reaches 0.
    void (*shared_destroy)(SharedPayloadBase*);
  };

  bool IsShared() const {
    return vtable_ != nullptr && vtable_->shared_destroy != nullptr;
  }

  // If the implementation uses a listener, call that.
  template <typename P>
  static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
                                  MatchResultListener* listener)
      -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
    return P::Get(m).MatchAndExplain(value, listener->stream());
  }

  template <typename P>
  static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
                                  MatchResultListener* listener)
      -> decltype(P::Get(m).MatchAndExplain(value, listener)) {
    return P::Get(m).MatchAndExplain(value, listener);
  }

  template <typename P>
  static void DescribeImpl(const MatcherBase& m, std::ostream* os,
                           bool negation) {
    if (negation) {
      P::Get(m).DescribeNegationTo(os);
    } else {
      P::Get(m).DescribeTo(os);
    }
  }

  template <typename P>
  static const MatcherDescriberInterface* GetDescriberImpl(
      const MatcherBase& m) {
    // If the impl is a MatcherDescriberInterface, then return it.
    // Otherwise use MatcherBase itself.
    // This allows us to implement the GetDescriber() function without support
    // from the impl, but some users really want to get their impl back when
    // they call GetDescriber().
    // We use std::get on a tuple as a workaround of not having `if constexpr`.
    return std::get<(
        std::is_convertible<decltype(&P::Get(m)),
                            const MatcherDescriberInterface*>::value
            ? 1
            : 0)>(std::make_tuple(&m, &P::Get(m)));
  }

  template <typename P>
  const VTable* GetVTable() {
    static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
                                       &DescribeImpl<P>, &GetDescriberImpl<P>,
                                       P::shared_destroy};
    return &kVTable;
  }

  union Buffer {
    // Add some types to give Buffer some common alignment/size use cases.
    void* ptr;
    double d;
    int64_t i;
    // And add one for the out-of-line cases.
    SharedPayloadBase* shared;
  };

  void Destroy() {
    if (IsShared() && buffer_.shared->Unref()) {
      vtable_->shared_destroy(buffer_.shared);
    }
  }

  template <typename M>
  static constexpr bool IsInlined() {
    return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
           std::is_trivially_copy_constructible<M>::value &&
           std::is_trivially_destructible<M>::value;
  }

  template <typename M, bool = IsInlined<M>()>
  struct ValuePolicy {
    static const M& Get(const MatcherBase& m) {
      // When inlined along with Init, need to be explicit to avoid violating
      // strict aliasing rules.
      const M *ptr = static_cast<const M*>(
          static_cast<const void*>(&m.buffer_));
      return *ptr;
    }
    static void Init(MatcherBase& m, M impl) {
      ::new (static_cast<void*>(&m.buffer_)) M(impl);
    }
    static constexpr auto shared_destroy = nullptr;
  };

  template <typename M>
  struct ValuePolicy<M, false> {
    using Shared = SharedPayload<M>;
    static const M& Get(const MatcherBase& m) {
      return static_cast<Shared*>(m.buffer_.shared)->value;
    }
    template <typename Arg>
    static void Init(MatcherBase& m, Arg&& arg) {
      m.buffer_.shared = new Shared(std::forward<Arg>(arg));
    }
    static constexpr auto shared_destroy = &Shared::Destroy;
  };

  template <typename U, bool B>
  struct ValuePolicy<const MatcherInterface<U>*, B> {
    using M = const MatcherInterface<U>;
    using Shared = SharedPayload<std::unique_ptr<M>>;
    static const M& Get(const MatcherBase& m) {
      return *static_cast<Shared*>(m.buffer_.shared)->value;
    }
    static void Init(MatcherBase& m, M* impl) {
      m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));
    }

    static constexpr auto shared_destroy = &Shared::Destroy;
  };

  template <typename M>
  void Init(M&& m) {
    using MM = typename std::decay<M>::type;
    using Policy = ValuePolicy<MM>;
    vtable_ = GetVTable<Policy>();
    Policy::Init(*this, std::forward<M>(m));
  }

  const VTable* vtable_;
  Buffer buffer_;
};

}  // namespace internal

// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
// object that can check whether a value of type T matches.  The
// implementation of Matcher<T> is just a std::shared_ptr to const
// MatcherInterface<T>.  Don't inherit from Matcher!
template <typename T>
class Matcher : public internal::MatcherBase<T> {
 public:
  // Constructs a null matcher.  Needed for storing Matcher objects in STL
  // containers.  A default-constructed matcher is not yet initialized.  You
  // cannot use it until a valid value has been assigned to it.
  explicit Matcher() {}  // NOLINT

  // Constructs a matcher from its implementation.
  explicit Matcher(const MatcherInterface<const T&>* impl)
      : internal::MatcherBase<T>(impl) {}

  template <typename U>
  explicit Matcher(
      const MatcherInterface<U>* impl,
      typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
          nullptr)
      : internal::MatcherBase<T>(impl) {}

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {}  // NOLINT

  // Implicit constructor here allows people to write
  // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
  Matcher(T value);  // NOLINT
};

// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected.
template <>
class GTEST_API_ Matcher<const std::string&>
    : public internal::MatcherBase<const std::string&> {
 public:
  Matcher() {}

  explicit Matcher(const MatcherInterface<const std::string&>* impl)
      : internal::MatcherBase<const std::string&>(impl) {}

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  Matcher(M&& m)  // NOLINT
      : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}

  // Allows the user to write str instead of Eq(str) sometimes, where
  // str is a std::string object.
  Matcher(const std::string& s);  // NOLINT

  // Allows the user to write "foo" instead of Eq("foo") sometimes.
  Matcher(const char* s);  // NOLINT
};

template <>
class GTEST_API_ Matcher<std::string>
    : public internal::MatcherBase<std::string> {
 public:
  Matcher() {}

  explicit Matcher(const MatcherInterface<const std::string&>* impl)
      : internal::MatcherBase<std::string>(impl) {}
  explicit Matcher(const MatcherInterface<std::string>* impl)
      : internal::MatcherBase<std::string>(impl) {}

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  Matcher(M&& m)  // NOLINT
      : internal::MatcherBase<std::string>(std::forward<M>(m)) {}

  // Allows the user to write str instead of Eq(str) sometimes, where
  // str is a string object.
  Matcher(const std::string& s);  // NOLINT

  // Allows the user to write "foo" instead of Eq("foo") sometimes.
  Matcher(const char* s);  // NOLINT
};

#if GTEST_INTERNAL_HAS_STRING_VIEW
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
// matcher is expected.
template <>
class GTEST_API_ Matcher<const internal::StringView&>
    : public internal::MatcherBase<const internal::StringView&> {
 public:
  Matcher() {}

  explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
      : internal::MatcherBase<const internal::StringView&>(impl) {}

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  Matcher(M&& m)  // NOLINT
      : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
  }

  // Allows the user to write str instead of Eq(str) sometimes, where
  // str is a std::string object.
  Matcher(const std::string& s);  // NOLINT

  // Allows the user to write "foo" instead of Eq("foo") sometimes.
  Matcher(const char* s);  // NOLINT

  // Allows the user to pass absl::string_views or std::string_views directly.
  Matcher(internal::StringView s);  // NOLINT
};

template <>
class GTEST_API_ Matcher<internal::StringView>
    : public internal::MatcherBase<internal::StringView> {
 public:
  Matcher() {}

  explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
      : internal::MatcherBase<internal::StringView>(impl) {}
  explicit Matcher(const MatcherInterface<internal::StringView>* impl)
      : internal::MatcherBase<internal::StringView>(impl) {}

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  Matcher(M&& m)  // NOLINT
      : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}

  // Allows the user to write str instead of Eq(str) sometimes, where
  // str is a std::string object.
  Matcher(const std::string& s);  // NOLINT

  // Allows the user to write "foo" instead of Eq("foo") sometimes.
  Matcher(const char* s);  // NOLINT

  // Allows the user to pass absl::string_views or std::string_views directly.
  Matcher(internal::StringView s);  // NOLINT
};
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW

// Prints a matcher in a human-readable format.
template <typename T>
std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
  matcher.DescribeTo(&os);
  return os;
}

// The PolymorphicMatcher class template makes it easy to implement a
// polymorphic matcher (i.e. a matcher that can match values of more
// than one type, e.g. Eq(n) and NotNull()).
//
// To define a polymorphic matcher, a user should provide an Impl
// class that has a DescribeTo() method and a DescribeNegationTo()
// method, and define a member function (or member function template)
//
//   bool MatchAndExplain(const Value& value,
//                        MatchResultListener* listener) const;
//
// See the definition of NotNull() for a complete example.
template <class Impl>
class PolymorphicMatcher {
 public:
  explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}

  // Returns a mutable reference to the underlying matcher
  // implementation object.
  Impl& mutable_impl() { return impl_; }

  // Returns an immutable reference to the underlying matcher
  // implementation object.
  const Impl& impl() const { return impl_; }

  template <typename T>
  operator Matcher<T>() const {
    return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
  }

 private:
  template <typename T>
  class MonomorphicImpl : public MatcherInterface<T> {
   public:
    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}

    void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }

    void DescribeNegationTo(::std::ostream* os) const override {
      impl_.DescribeNegationTo(os);
    }

    bool MatchAndExplain(T x, MatchResultListener* listener) const override {
      return impl_.MatchAndExplain(x, listener);
    }

   private:
    const Impl impl_;
  };

  Impl impl_;
};

// Creates a matcher from its implementation.
// DEPRECATED: Especially in the generic code, prefer:
//   Matcher<T>(new MyMatcherImpl<const T&>(...));
//
// MakeMatcher may create a Matcher that accepts its argument by value, which
// leads to unnecessary copies & lack of support for non-copyable types.
template <typename T>
inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
  return Matcher<T>(impl);
}

// Creates a polymorphic matcher from its implementation.  This is
// easier to use than the PolymorphicMatcher<Impl> constructor as it
// doesn't require you to explicitly write the template argument, e.g.
//
//   MakePolymorphicMatcher(foo);
// vs
//   PolymorphicMatcher<TypeOfFoo>(foo);
template <class Impl>
inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
  return PolymorphicMatcher<Impl>(impl);
}

namespace internal {
// Implements a matcher that compares a given value with a
// pre-supplied value using one of the ==, <=, <, etc, operators.  The
// two values being compared don't have to have the same type.
//
// The matcher defined here is polymorphic (for example, Eq(5) can be
// used to match an int, a short, a double, etc).  Therefore we use
// a template type conversion operator in the implementation.
//
// The following template definition assumes that the Rhs parameter is
// a "bare" type (i.e. neither 'const T' nor 'T&').
template <typename D, typename Rhs, typename Op>
class ComparisonBase {
 public:
  explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}

  using is_gtest_matcher = void;

  template <typename Lhs>
  bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
    return Op()(lhs, Unwrap(rhs_));
  }
  void DescribeTo(std::ostream* os) const {
    *os << D::Desc() << " ";
    UniversalPrint(Unwrap(rhs_), os);
  }
  void DescribeNegationTo(std::ostream* os) const {
    *os << D::NegatedDesc() << " ";
    UniversalPrint(Unwrap(rhs_), os);
  }

 private:
  template <typename T>
  static const T& Unwrap(const T& v) {
    return v;
  }
  template <typename T>
  static const T& Unwrap(std::reference_wrapper<T> v) {
    return v;
  }

  Rhs rhs_;
};

template <typename Rhs>
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
 public:
  explicit EqMatcher(const Rhs& rhs)
      : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
  static const char* Desc() { return "is equal to"; }
  static const char* NegatedDesc() { return "isn't equal to"; }
};
template <typename Rhs>
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
 public:
  explicit NeMatcher(const Rhs& rhs)
      : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
  static const char* Desc() { return "isn't equal to"; }
  static const char* NegatedDesc() { return "is equal to"; }
};
template <typename Rhs>
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
 public:
  explicit LtMatcher(const Rhs& rhs)
      : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
  static const char* Desc() { return "is <"; }
  static const char* NegatedDesc() { return "isn't <"; }
};
template <typename Rhs>
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
 public:
  explicit GtMatcher(const Rhs& rhs)
      : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
  static const char* Desc() { return "is >"; }
  static const char* NegatedDesc() { return "isn't >"; }
};
template <typename Rhs>
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
 public:
  explicit LeMatcher(const Rhs& rhs)
      : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
  static const char* Desc() { return "is <="; }
  static const char* NegatedDesc() { return "isn't <="; }
};
template <typename Rhs>
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
 public:
  explicit GeMatcher(const Rhs& rhs)
      : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
  static const char* Desc() { return "is >="; }
  static const char* NegatedDesc() { return "isn't >="; }
};

template <typename T, typename = typename std::enable_if<
                          std::is_constructible<std::string, T>::value>::type>
using StringLike = T;

// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
class MatchesRegexMatcher {
 public:
  MatchesRegexMatcher(const RE* regex, bool full_match)
      : regex_(regex), full_match_(full_match) {}

#if GTEST_INTERNAL_HAS_STRING_VIEW
  bool MatchAndExplain(const internal::StringView& s,
                       MatchResultListener* listener) const {
    return MatchAndExplain(std::string(s), listener);
  }
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW

  // Accepts pointer types, particularly:
  //   const char*
  //   char*
  //   const wchar_t*
  //   wchar_t*
  template <typename CharType>
  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
    return s != nullptr && MatchAndExplain(std::string(s), listener);
  }

  // Matches anything that can convert to std::string.
  //
  // This is a template, not just a plain function with const std::string&,
  // because absl::string_view has some interfering non-explicit constructors.
  template <class MatcheeStringType>
  bool MatchAndExplain(const MatcheeStringType& s,
                       MatchResultListener* /* listener */) const {
    const std::string& s2(s);
    return full_match_ ? RE::FullMatch(s2, *regex_)
                       : RE::PartialMatch(s2, *regex_);
  }

  void DescribeTo(::std::ostream* os) const {
    *os << (full_match_ ? "matches" : "contains") << " regular expression ";
    UniversalPrinter<std::string>::Print(regex_->pattern(), os);
  }

  void DescribeNegationTo(::std::ostream* os) const {
    *os << "doesn't " << (full_match_ ? "match" : "contain")
        << " regular expression ";
    UniversalPrinter<std::string>::Print(regex_->pattern(), os);
  }

 private:
  const std::shared_ptr<const RE> regex_;
  const bool full_match_;
};
}  // namespace internal

// Matches a string that fully matches regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
    const internal::RE* regex) {
  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
}
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
    const internal::StringLike<T>& regex) {
  return MatchesRegex(new internal::RE(std::string(regex)));
}

// Matches a string that contains regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
    const internal::RE* regex) {
  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
}
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
    const internal::StringLike<T>& regex) {
  return ContainsRegex(new internal::RE(std::string(regex)));
}

// Creates a polymorphic matcher that matches anything equal to x.
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// wouldn't compile.
template <typename T>
inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }

// Constructs a Matcher<T> from a 'value' of type T.  The constructed
// matcher matches any value that's equal to 'value'.
template <typename T>
Matcher<T>::Matcher(T value) { *this = Eq(value); }

// Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs.  A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity.
//
// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
// or Matcher<T>(x), but more readable than the latter.
//
// We could define similar monomorphic matchers for other comparison
// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
// it yet as those are used much less than Eq() in practice.  A user
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
// for example.
template <typename Lhs, typename Rhs>
inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }

// Creates a polymorphic matcher that matches anything >= x.
template <typename Rhs>
inline internal::GeMatcher<Rhs> Ge(Rhs x) {
  return internal::GeMatcher<Rhs>(x);
}

// Creates a polymorphic matcher that matches anything > x.
template <typename Rhs>
inline internal::GtMatcher<Rhs> Gt(Rhs x) {
  return internal::GtMatcher<Rhs>(x);
}

// Creates a polymorphic matcher that matches anything <= x.
template <typename Rhs>
inline internal::LeMatcher<Rhs> Le(Rhs x) {
  return internal::LeMatcher<Rhs>(x);
}

// Creates a polymorphic matcher that matches anything < x.
template <typename Rhs>
inline internal::LtMatcher<Rhs> Lt(Rhs x) {
  return internal::LtMatcher<Rhs>(x);
}

// Creates a polymorphic matcher that matches anything != x.
template <typename Rhs>
inline internal::NeMatcher<Rhs> Ne(Rhs x) {
  return internal::NeMatcher<Rhs>(x);
}
}  // namespace testing

GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046

#endif  // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
