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