// 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 "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*

#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GOOGLETEST_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*);
//       (MatchResultListener* can also be used instead of 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_;

  MatchResultListener(const MatchResultListener&) = delete;
  MatchResultListener& operator=(const MatchResultListener&) = delete;
};

inline MatchResultListener::~MatchResultListener() {}

// An instance of a subclass of this knows how to describe itself as a
// matcher.
class GTEST_API_ 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:
  DummyMatchResultListener(const DummyMatchResultListener&) = delete;
  DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;
};

// 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:
  StreamMatchResultListener(const StreamMatchResultListener&) = delete;
  StreamMatchResultListener& operator=(const StreamMatchResultListener&) =
      delete;
};

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), buffer_() {}

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

  template <typename M, typename = typename std::remove_reference<
                            M>::type::is_gtest_matcher>
  MatcherBase(M&& m) : vtable_(nullptr), buffer_() {  // 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 = MatcherBase::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  // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
