113481Sgiacomo.travaglini@arm.com// Copyright 2007, Google Inc. 213481Sgiacomo.travaglini@arm.com// All rights reserved. 313481Sgiacomo.travaglini@arm.com// 413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without 513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are 613481Sgiacomo.travaglini@arm.com// met: 713481Sgiacomo.travaglini@arm.com// 813481Sgiacomo.travaglini@arm.com// * Redistributions of source code must retain the above copyright 913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer. 1013481Sgiacomo.travaglini@arm.com// * Redistributions in binary form must reproduce the above 1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer 1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the 1313481Sgiacomo.travaglini@arm.com// distribution. 1413481Sgiacomo.travaglini@arm.com// * Neither the name of Google Inc. nor the names of its 1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from 1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission. 1713481Sgiacomo.travaglini@arm.com// 1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2913481Sgiacomo.travaglini@arm.com// 3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan) 3113481Sgiacomo.travaglini@arm.com 3213481Sgiacomo.travaglini@arm.com// Google Mock - a framework for writing C++ mock classes. 3313481Sgiacomo.travaglini@arm.com// 3413481Sgiacomo.travaglini@arm.com// This file implements some commonly used argument matchers. More 3513481Sgiacomo.travaglini@arm.com// matchers can be defined by the user implementing the 3613481Sgiacomo.travaglini@arm.com// MatcherInterface<T> interface if necessary. 3713481Sgiacomo.travaglini@arm.com 3813481Sgiacomo.travaglini@arm.com#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ 3913481Sgiacomo.travaglini@arm.com#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ 4013481Sgiacomo.travaglini@arm.com 4113481Sgiacomo.travaglini@arm.com#include <math.h> 4213481Sgiacomo.travaglini@arm.com#include <algorithm> 4313481Sgiacomo.travaglini@arm.com#include <iterator> 4413481Sgiacomo.travaglini@arm.com#include <limits> 4513481Sgiacomo.travaglini@arm.com#include <ostream> // NOLINT 4613481Sgiacomo.travaglini@arm.com#include <sstream> 4713481Sgiacomo.travaglini@arm.com#include <string> 4813481Sgiacomo.travaglini@arm.com#include <utility> 4913481Sgiacomo.travaglini@arm.com#include <vector> 5013481Sgiacomo.travaglini@arm.com 5113481Sgiacomo.travaglini@arm.com#include "gmock/internal/gmock-internal-utils.h" 5213481Sgiacomo.travaglini@arm.com#include "gmock/internal/gmock-port.h" 5313481Sgiacomo.travaglini@arm.com#include "gtest/gtest.h" 5413481Sgiacomo.travaglini@arm.com 5513481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_INITIALIZER_LIST_ 5613481Sgiacomo.travaglini@arm.com# include <initializer_list> // NOLINT -- must be after gtest.h 5713481Sgiacomo.travaglini@arm.com#endif 5813481Sgiacomo.travaglini@arm.com 5913481Sgiacomo.travaglini@arm.comnamespace testing { 6013481Sgiacomo.travaglini@arm.com 6113481Sgiacomo.travaglini@arm.com// To implement a matcher Foo for type T, define: 6213481Sgiacomo.travaglini@arm.com// 1. a class FooMatcherImpl that implements the 6313481Sgiacomo.travaglini@arm.com// MatcherInterface<T> interface, and 6413481Sgiacomo.travaglini@arm.com// 2. a factory function that creates a Matcher<T> object from a 6513481Sgiacomo.travaglini@arm.com// FooMatcherImpl*. 6613481Sgiacomo.travaglini@arm.com// 6713481Sgiacomo.travaglini@arm.com// The two-level delegation design makes it possible to allow a user 6813481Sgiacomo.travaglini@arm.com// to write "v" instead of "Eq(v)" where a Matcher is expected, which 6913481Sgiacomo.travaglini@arm.com// is impossible if we pass matchers by pointers. It also eases 7013481Sgiacomo.travaglini@arm.com// ownership management as Matcher objects can now be copied like 7113481Sgiacomo.travaglini@arm.com// plain values. 7213481Sgiacomo.travaglini@arm.com 7313481Sgiacomo.travaglini@arm.com// MatchResultListener is an abstract class. Its << operator can be 7413481Sgiacomo.travaglini@arm.com// used by a matcher to explain why a value matches or doesn't match. 7513481Sgiacomo.travaglini@arm.com// 7613481Sgiacomo.travaglini@arm.com// TODO(wan@google.com): add method 7713481Sgiacomo.travaglini@arm.com// bool InterestedInWhy(bool result) const; 7813481Sgiacomo.travaglini@arm.com// to indicate whether the listener is interested in why the match 7913481Sgiacomo.travaglini@arm.com// result is 'result'. 8013481Sgiacomo.travaglini@arm.comclass MatchResultListener { 8113481Sgiacomo.travaglini@arm.com public: 8213481Sgiacomo.travaglini@arm.com // Creates a listener object with the given underlying ostream. The 8313481Sgiacomo.travaglini@arm.com // listener does not own the ostream, and does not dereference it 8413481Sgiacomo.travaglini@arm.com // in the constructor or destructor. 8513481Sgiacomo.travaglini@arm.com explicit MatchResultListener(::std::ostream* os) : stream_(os) {} 8613481Sgiacomo.travaglini@arm.com virtual ~MatchResultListener() = 0; // Makes this class abstract. 8713481Sgiacomo.travaglini@arm.com 8813481Sgiacomo.travaglini@arm.com // Streams x to the underlying ostream; does nothing if the ostream 8913481Sgiacomo.travaglini@arm.com // is NULL. 9013481Sgiacomo.travaglini@arm.com template <typename T> 9113481Sgiacomo.travaglini@arm.com MatchResultListener& operator<<(const T& x) { 9213481Sgiacomo.travaglini@arm.com if (stream_ != NULL) 9313481Sgiacomo.travaglini@arm.com *stream_ << x; 9413481Sgiacomo.travaglini@arm.com return *this; 9513481Sgiacomo.travaglini@arm.com } 9613481Sgiacomo.travaglini@arm.com 9713481Sgiacomo.travaglini@arm.com // Returns the underlying ostream. 9813481Sgiacomo.travaglini@arm.com ::std::ostream* stream() { return stream_; } 9913481Sgiacomo.travaglini@arm.com 10013481Sgiacomo.travaglini@arm.com // Returns true iff the listener is interested in an explanation of 10113481Sgiacomo.travaglini@arm.com // the match result. A matcher's MatchAndExplain() method can use 10213481Sgiacomo.travaglini@arm.com // this information to avoid generating the explanation when no one 10313481Sgiacomo.travaglini@arm.com // intends to hear it. 10413481Sgiacomo.travaglini@arm.com bool IsInterested() const { return stream_ != NULL; } 10513481Sgiacomo.travaglini@arm.com 10613481Sgiacomo.travaglini@arm.com private: 10713481Sgiacomo.travaglini@arm.com ::std::ostream* const stream_; 10813481Sgiacomo.travaglini@arm.com 10913481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); 11013481Sgiacomo.travaglini@arm.com}; 11113481Sgiacomo.travaglini@arm.com 11213481Sgiacomo.travaglini@arm.cominline MatchResultListener::~MatchResultListener() { 11313481Sgiacomo.travaglini@arm.com} 11413481Sgiacomo.travaglini@arm.com 11513481Sgiacomo.travaglini@arm.com// An instance of a subclass of this knows how to describe itself as a 11613481Sgiacomo.travaglini@arm.com// matcher. 11713481Sgiacomo.travaglini@arm.comclass MatcherDescriberInterface { 11813481Sgiacomo.travaglini@arm.com public: 11913481Sgiacomo.travaglini@arm.com virtual ~MatcherDescriberInterface() {} 12013481Sgiacomo.travaglini@arm.com 12113481Sgiacomo.travaglini@arm.com // Describes this matcher to an ostream. The function should print 12213481Sgiacomo.travaglini@arm.com // a verb phrase that describes the property a value matching this 12313481Sgiacomo.travaglini@arm.com // matcher should have. The subject of the verb phrase is the value 12413481Sgiacomo.travaglini@arm.com // being matched. For example, the DescribeTo() method of the Gt(7) 12513481Sgiacomo.travaglini@arm.com // matcher prints "is greater than 7". 12613481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const = 0; 12713481Sgiacomo.travaglini@arm.com 12813481Sgiacomo.travaglini@arm.com // Describes the negation of this matcher to an ostream. For 12913481Sgiacomo.travaglini@arm.com // example, if the description of this matcher is "is greater than 13013481Sgiacomo.travaglini@arm.com // 7", the negated description could be "is not greater than 7". 13113481Sgiacomo.travaglini@arm.com // You are not required to override this when implementing 13213481Sgiacomo.travaglini@arm.com // MatcherInterface, but it is highly advised so that your matcher 13313481Sgiacomo.travaglini@arm.com // can produce good error messages. 13413481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 13513481Sgiacomo.travaglini@arm.com *os << "not ("; 13613481Sgiacomo.travaglini@arm.com DescribeTo(os); 13713481Sgiacomo.travaglini@arm.com *os << ")"; 13813481Sgiacomo.travaglini@arm.com } 13913481Sgiacomo.travaglini@arm.com}; 14013481Sgiacomo.travaglini@arm.com 14113481Sgiacomo.travaglini@arm.com// The implementation of a matcher. 14213481Sgiacomo.travaglini@arm.comtemplate <typename T> 14313481Sgiacomo.travaglini@arm.comclass MatcherInterface : public MatcherDescriberInterface { 14413481Sgiacomo.travaglini@arm.com public: 14513481Sgiacomo.travaglini@arm.com // Returns true iff the matcher matches x; also explains the match 14613481Sgiacomo.travaglini@arm.com // result to 'listener' if necessary (see the next paragraph), in 14713481Sgiacomo.travaglini@arm.com // the form of a non-restrictive relative clause ("which ...", 14813481Sgiacomo.travaglini@arm.com // "whose ...", etc) that describes x. For example, the 14913481Sgiacomo.travaglini@arm.com // MatchAndExplain() method of the Pointee(...) matcher should 15013481Sgiacomo.travaglini@arm.com // generate an explanation like "which points to ...". 15113481Sgiacomo.travaglini@arm.com // 15213481Sgiacomo.travaglini@arm.com // Implementations of MatchAndExplain() should add an explanation of 15313481Sgiacomo.travaglini@arm.com // the match result *if and only if* they can provide additional 15413481Sgiacomo.travaglini@arm.com // information that's not already present (or not obvious) in the 15513481Sgiacomo.travaglini@arm.com // print-out of x and the matcher's description. Whether the match 15613481Sgiacomo.travaglini@arm.com // succeeds is not a factor in deciding whether an explanation is 15713481Sgiacomo.travaglini@arm.com // needed, as sometimes the caller needs to print a failure message 15813481Sgiacomo.travaglini@arm.com // when the match succeeds (e.g. when the matcher is used inside 15913481Sgiacomo.travaglini@arm.com // Not()). 16013481Sgiacomo.travaglini@arm.com // 16113481Sgiacomo.travaglini@arm.com // For example, a "has at least 10 elements" matcher should explain 16213481Sgiacomo.travaglini@arm.com // what the actual element count is, regardless of the match result, 16313481Sgiacomo.travaglini@arm.com // as it is useful information to the reader; on the other hand, an 16413481Sgiacomo.travaglini@arm.com // "is empty" matcher probably only needs to explain what the actual 16513481Sgiacomo.travaglini@arm.com // size is when the match fails, as it's redundant to say that the 16613481Sgiacomo.travaglini@arm.com // size is 0 when the value is already known to be empty. 16713481Sgiacomo.travaglini@arm.com // 16813481Sgiacomo.travaglini@arm.com // You should override this method when defining a new matcher. 16913481Sgiacomo.travaglini@arm.com // 17013481Sgiacomo.travaglini@arm.com // It's the responsibility of the caller (Google Mock) to guarantee 17113481Sgiacomo.travaglini@arm.com // that 'listener' is not NULL. This helps to simplify a matcher's 17213481Sgiacomo.travaglini@arm.com // implementation when it doesn't care about the performance, as it 17313481Sgiacomo.travaglini@arm.com // can talk to 'listener' without checking its validity first. 17413481Sgiacomo.travaglini@arm.com // However, in order to implement dummy listeners efficiently, 17513481Sgiacomo.travaglini@arm.com // listener->stream() may be NULL. 17613481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; 17713481Sgiacomo.travaglini@arm.com 17813481Sgiacomo.travaglini@arm.com // Inherits these methods from MatcherDescriberInterface: 17913481Sgiacomo.travaglini@arm.com // virtual void DescribeTo(::std::ostream* os) const = 0; 18013481Sgiacomo.travaglini@arm.com // virtual void DescribeNegationTo(::std::ostream* os) const; 18113481Sgiacomo.travaglini@arm.com}; 18213481Sgiacomo.travaglini@arm.com 18313481Sgiacomo.travaglini@arm.com// A match result listener that stores the explanation in a string. 18413481Sgiacomo.travaglini@arm.comclass StringMatchResultListener : public MatchResultListener { 18513481Sgiacomo.travaglini@arm.com public: 18613481Sgiacomo.travaglini@arm.com StringMatchResultListener() : MatchResultListener(&ss_) {} 18713481Sgiacomo.travaglini@arm.com 18813481Sgiacomo.travaglini@arm.com // Returns the explanation accumulated so far. 18913481Sgiacomo.travaglini@arm.com internal::string str() const { return ss_.str(); } 19013481Sgiacomo.travaglini@arm.com 19113481Sgiacomo.travaglini@arm.com // Clears the explanation accumulated so far. 19213481Sgiacomo.travaglini@arm.com void Clear() { ss_.str(""); } 19313481Sgiacomo.travaglini@arm.com 19413481Sgiacomo.travaglini@arm.com private: 19513481Sgiacomo.travaglini@arm.com ::std::stringstream ss_; 19613481Sgiacomo.travaglini@arm.com 19713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); 19813481Sgiacomo.travaglini@arm.com}; 19913481Sgiacomo.travaglini@arm.com 20013481Sgiacomo.travaglini@arm.comnamespace internal { 20113481Sgiacomo.travaglini@arm.com 20213481Sgiacomo.travaglini@arm.comstruct AnyEq { 20313481Sgiacomo.travaglini@arm.com template <typename A, typename B> 20413481Sgiacomo.travaglini@arm.com bool operator()(const A& a, const B& b) const { return a == b; } 20513481Sgiacomo.travaglini@arm.com}; 20613481Sgiacomo.travaglini@arm.comstruct AnyNe { 20713481Sgiacomo.travaglini@arm.com template <typename A, typename B> 20813481Sgiacomo.travaglini@arm.com bool operator()(const A& a, const B& b) const { return a != b; } 20913481Sgiacomo.travaglini@arm.com}; 21013481Sgiacomo.travaglini@arm.comstruct AnyLt { 21113481Sgiacomo.travaglini@arm.com template <typename A, typename B> 21213481Sgiacomo.travaglini@arm.com bool operator()(const A& a, const B& b) const { return a < b; } 21313481Sgiacomo.travaglini@arm.com}; 21413481Sgiacomo.travaglini@arm.comstruct AnyGt { 21513481Sgiacomo.travaglini@arm.com template <typename A, typename B> 21613481Sgiacomo.travaglini@arm.com bool operator()(const A& a, const B& b) const { return a > b; } 21713481Sgiacomo.travaglini@arm.com}; 21813481Sgiacomo.travaglini@arm.comstruct AnyLe { 21913481Sgiacomo.travaglini@arm.com template <typename A, typename B> 22013481Sgiacomo.travaglini@arm.com bool operator()(const A& a, const B& b) const { return a <= b; } 22113481Sgiacomo.travaglini@arm.com}; 22213481Sgiacomo.travaglini@arm.comstruct AnyGe { 22313481Sgiacomo.travaglini@arm.com template <typename A, typename B> 22413481Sgiacomo.travaglini@arm.com bool operator()(const A& a, const B& b) const { return a >= b; } 22513481Sgiacomo.travaglini@arm.com}; 22613481Sgiacomo.travaglini@arm.com 22713481Sgiacomo.travaglini@arm.com// A match result listener that ignores the explanation. 22813481Sgiacomo.travaglini@arm.comclass DummyMatchResultListener : public MatchResultListener { 22913481Sgiacomo.travaglini@arm.com public: 23013481Sgiacomo.travaglini@arm.com DummyMatchResultListener() : MatchResultListener(NULL) {} 23113481Sgiacomo.travaglini@arm.com 23213481Sgiacomo.travaglini@arm.com private: 23313481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); 23413481Sgiacomo.travaglini@arm.com}; 23513481Sgiacomo.travaglini@arm.com 23613481Sgiacomo.travaglini@arm.com// A match result listener that forwards the explanation to a given 23713481Sgiacomo.travaglini@arm.com// ostream. The difference between this and MatchResultListener is 23813481Sgiacomo.travaglini@arm.com// that the former is concrete. 23913481Sgiacomo.travaglini@arm.comclass StreamMatchResultListener : public MatchResultListener { 24013481Sgiacomo.travaglini@arm.com public: 24113481Sgiacomo.travaglini@arm.com explicit StreamMatchResultListener(::std::ostream* os) 24213481Sgiacomo.travaglini@arm.com : MatchResultListener(os) {} 24313481Sgiacomo.travaglini@arm.com 24413481Sgiacomo.travaglini@arm.com private: 24513481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); 24613481Sgiacomo.travaglini@arm.com}; 24713481Sgiacomo.travaglini@arm.com 24813481Sgiacomo.travaglini@arm.com// An internal class for implementing Matcher<T>, which will derive 24913481Sgiacomo.travaglini@arm.com// from it. We put functionalities common to all Matcher<T> 25013481Sgiacomo.travaglini@arm.com// specializations here to avoid code duplication. 25113481Sgiacomo.travaglini@arm.comtemplate <typename T> 25213481Sgiacomo.travaglini@arm.comclass MatcherBase { 25313481Sgiacomo.travaglini@arm.com public: 25413481Sgiacomo.travaglini@arm.com // Returns true iff the matcher matches x; also explains the match 25513481Sgiacomo.travaglini@arm.com // result to 'listener'. 25613481Sgiacomo.travaglini@arm.com bool MatchAndExplain(T x, MatchResultListener* listener) const { 25713481Sgiacomo.travaglini@arm.com return impl_->MatchAndExplain(x, listener); 25813481Sgiacomo.travaglini@arm.com } 25913481Sgiacomo.travaglini@arm.com 26013481Sgiacomo.travaglini@arm.com // Returns true iff this matcher matches x. 26113481Sgiacomo.travaglini@arm.com bool Matches(T x) const { 26213481Sgiacomo.travaglini@arm.com DummyMatchResultListener dummy; 26313481Sgiacomo.travaglini@arm.com return MatchAndExplain(x, &dummy); 26413481Sgiacomo.travaglini@arm.com } 26513481Sgiacomo.travaglini@arm.com 26613481Sgiacomo.travaglini@arm.com // Describes this matcher to an ostream. 26713481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } 26813481Sgiacomo.travaglini@arm.com 26913481Sgiacomo.travaglini@arm.com // Describes the negation of this matcher to an ostream. 27013481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 27113481Sgiacomo.travaglini@arm.com impl_->DescribeNegationTo(os); 27213481Sgiacomo.travaglini@arm.com } 27313481Sgiacomo.travaglini@arm.com 27413481Sgiacomo.travaglini@arm.com // Explains why x matches, or doesn't match, the matcher. 27513481Sgiacomo.travaglini@arm.com void ExplainMatchResultTo(T x, ::std::ostream* os) const { 27613481Sgiacomo.travaglini@arm.com StreamMatchResultListener listener(os); 27713481Sgiacomo.travaglini@arm.com MatchAndExplain(x, &listener); 27813481Sgiacomo.travaglini@arm.com } 27913481Sgiacomo.travaglini@arm.com 28013481Sgiacomo.travaglini@arm.com // Returns the describer for this matcher object; retains ownership 28113481Sgiacomo.travaglini@arm.com // of the describer, which is only guaranteed to be alive when 28213481Sgiacomo.travaglini@arm.com // this matcher object is alive. 28313481Sgiacomo.travaglini@arm.com const MatcherDescriberInterface* GetDescriber() const { 28413481Sgiacomo.travaglini@arm.com return impl_.get(); 28513481Sgiacomo.travaglini@arm.com } 28613481Sgiacomo.travaglini@arm.com 28713481Sgiacomo.travaglini@arm.com protected: 28813481Sgiacomo.travaglini@arm.com MatcherBase() {} 28913481Sgiacomo.travaglini@arm.com 29013481Sgiacomo.travaglini@arm.com // Constructs a matcher from its implementation. 29113481Sgiacomo.travaglini@arm.com explicit MatcherBase(const MatcherInterface<T>* impl) 29213481Sgiacomo.travaglini@arm.com : impl_(impl) {} 29313481Sgiacomo.travaglini@arm.com 29413481Sgiacomo.travaglini@arm.com virtual ~MatcherBase() {} 29513481Sgiacomo.travaglini@arm.com 29613481Sgiacomo.travaglini@arm.com private: 29713481Sgiacomo.travaglini@arm.com // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar 29813481Sgiacomo.travaglini@arm.com // interfaces. The former dynamically allocates a chunk of memory 29913481Sgiacomo.travaglini@arm.com // to hold the reference count, while the latter tracks all 30013481Sgiacomo.travaglini@arm.com // references using a circular linked list without allocating 30113481Sgiacomo.travaglini@arm.com // memory. It has been observed that linked_ptr performs better in 30213481Sgiacomo.travaglini@arm.com // typical scenarios. However, shared_ptr can out-perform 30313481Sgiacomo.travaglini@arm.com // linked_ptr when there are many more uses of the copy constructor 30413481Sgiacomo.travaglini@arm.com // than the default constructor. 30513481Sgiacomo.travaglini@arm.com // 30613481Sgiacomo.travaglini@arm.com // If performance becomes a problem, we should see if using 30713481Sgiacomo.travaglini@arm.com // shared_ptr helps. 30813481Sgiacomo.travaglini@arm.com ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_; 30913481Sgiacomo.travaglini@arm.com}; 31013481Sgiacomo.travaglini@arm.com 31113481Sgiacomo.travaglini@arm.com} // namespace internal 31213481Sgiacomo.travaglini@arm.com 31313481Sgiacomo.travaglini@arm.com// A Matcher<T> is a copyable and IMMUTABLE (except by assignment) 31413481Sgiacomo.travaglini@arm.com// object that can check whether a value of type T matches. The 31513481Sgiacomo.travaglini@arm.com// implementation of Matcher<T> is just a linked_ptr to const 31613481Sgiacomo.travaglini@arm.com// MatcherInterface<T>, so copying is fairly cheap. Don't inherit 31713481Sgiacomo.travaglini@arm.com// from Matcher! 31813481Sgiacomo.travaglini@arm.comtemplate <typename T> 31913481Sgiacomo.travaglini@arm.comclass Matcher : public internal::MatcherBase<T> { 32013481Sgiacomo.travaglini@arm.com public: 32113481Sgiacomo.travaglini@arm.com // Constructs a null matcher. Needed for storing Matcher objects in STL 32213481Sgiacomo.travaglini@arm.com // containers. A default-constructed matcher is not yet initialized. You 32313481Sgiacomo.travaglini@arm.com // cannot use it until a valid value has been assigned to it. 32413481Sgiacomo.travaglini@arm.com explicit Matcher() {} // NOLINT 32513481Sgiacomo.travaglini@arm.com 32613481Sgiacomo.travaglini@arm.com // Constructs a matcher from its implementation. 32713481Sgiacomo.travaglini@arm.com explicit Matcher(const MatcherInterface<T>* impl) 32813481Sgiacomo.travaglini@arm.com : internal::MatcherBase<T>(impl) {} 32913481Sgiacomo.travaglini@arm.com 33013481Sgiacomo.travaglini@arm.com // Implicit constructor here allows people to write 33113481Sgiacomo.travaglini@arm.com // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes 33213481Sgiacomo.travaglini@arm.com Matcher(T value); // NOLINT 33313481Sgiacomo.travaglini@arm.com}; 33413481Sgiacomo.travaglini@arm.com 33513481Sgiacomo.travaglini@arm.com// The following two specializations allow the user to write str 33613481Sgiacomo.travaglini@arm.com// instead of Eq(str) and "foo" instead of Eq("foo") when a string 33713481Sgiacomo.travaglini@arm.com// matcher is expected. 33813481Sgiacomo.travaglini@arm.comtemplate <> 33913481Sgiacomo.travaglini@arm.comclass GTEST_API_ Matcher<const internal::string&> 34013481Sgiacomo.travaglini@arm.com : public internal::MatcherBase<const internal::string&> { 34113481Sgiacomo.travaglini@arm.com public: 34213481Sgiacomo.travaglini@arm.com Matcher() {} 34313481Sgiacomo.travaglini@arm.com 34413481Sgiacomo.travaglini@arm.com explicit Matcher(const MatcherInterface<const internal::string&>* impl) 34513481Sgiacomo.travaglini@arm.com : internal::MatcherBase<const internal::string&>(impl) {} 34613481Sgiacomo.travaglini@arm.com 34713481Sgiacomo.travaglini@arm.com // Allows the user to write str instead of Eq(str) sometimes, where 34813481Sgiacomo.travaglini@arm.com // str is a string object. 34913481Sgiacomo.travaglini@arm.com Matcher(const internal::string& s); // NOLINT 35013481Sgiacomo.travaglini@arm.com 35113481Sgiacomo.travaglini@arm.com // Allows the user to write "foo" instead of Eq("foo") sometimes. 35213481Sgiacomo.travaglini@arm.com Matcher(const char* s); // NOLINT 35313481Sgiacomo.travaglini@arm.com}; 35413481Sgiacomo.travaglini@arm.com 35513481Sgiacomo.travaglini@arm.comtemplate <> 35613481Sgiacomo.travaglini@arm.comclass GTEST_API_ Matcher<internal::string> 35713481Sgiacomo.travaglini@arm.com : public internal::MatcherBase<internal::string> { 35813481Sgiacomo.travaglini@arm.com public: 35913481Sgiacomo.travaglini@arm.com Matcher() {} 36013481Sgiacomo.travaglini@arm.com 36113481Sgiacomo.travaglini@arm.com explicit Matcher(const MatcherInterface<internal::string>* impl) 36213481Sgiacomo.travaglini@arm.com : internal::MatcherBase<internal::string>(impl) {} 36313481Sgiacomo.travaglini@arm.com 36413481Sgiacomo.travaglini@arm.com // Allows the user to write str instead of Eq(str) sometimes, where 36513481Sgiacomo.travaglini@arm.com // str is a string object. 36613481Sgiacomo.travaglini@arm.com Matcher(const internal::string& s); // NOLINT 36713481Sgiacomo.travaglini@arm.com 36813481Sgiacomo.travaglini@arm.com // Allows the user to write "foo" instead of Eq("foo") sometimes. 36913481Sgiacomo.travaglini@arm.com Matcher(const char* s); // NOLINT 37013481Sgiacomo.travaglini@arm.com}; 37113481Sgiacomo.travaglini@arm.com 37213481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STRING_PIECE_ 37313481Sgiacomo.travaglini@arm.com// The following two specializations allow the user to write str 37413481Sgiacomo.travaglini@arm.com// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece 37513481Sgiacomo.travaglini@arm.com// matcher is expected. 37613481Sgiacomo.travaglini@arm.comtemplate <> 37713481Sgiacomo.travaglini@arm.comclass GTEST_API_ Matcher<const StringPiece&> 37813481Sgiacomo.travaglini@arm.com : public internal::MatcherBase<const StringPiece&> { 37913481Sgiacomo.travaglini@arm.com public: 38013481Sgiacomo.travaglini@arm.com Matcher() {} 38113481Sgiacomo.travaglini@arm.com 38213481Sgiacomo.travaglini@arm.com explicit Matcher(const MatcherInterface<const StringPiece&>* impl) 38313481Sgiacomo.travaglini@arm.com : internal::MatcherBase<const StringPiece&>(impl) {} 38413481Sgiacomo.travaglini@arm.com 38513481Sgiacomo.travaglini@arm.com // Allows the user to write str instead of Eq(str) sometimes, where 38613481Sgiacomo.travaglini@arm.com // str is a string object. 38713481Sgiacomo.travaglini@arm.com Matcher(const internal::string& s); // NOLINT 38813481Sgiacomo.travaglini@arm.com 38913481Sgiacomo.travaglini@arm.com // Allows the user to write "foo" instead of Eq("foo") sometimes. 39013481Sgiacomo.travaglini@arm.com Matcher(const char* s); // NOLINT 39113481Sgiacomo.travaglini@arm.com 39213481Sgiacomo.travaglini@arm.com // Allows the user to pass StringPieces directly. 39313481Sgiacomo.travaglini@arm.com Matcher(StringPiece s); // NOLINT 39413481Sgiacomo.travaglini@arm.com}; 39513481Sgiacomo.travaglini@arm.com 39613481Sgiacomo.travaglini@arm.comtemplate <> 39713481Sgiacomo.travaglini@arm.comclass GTEST_API_ Matcher<StringPiece> 39813481Sgiacomo.travaglini@arm.com : public internal::MatcherBase<StringPiece> { 39913481Sgiacomo.travaglini@arm.com public: 40013481Sgiacomo.travaglini@arm.com Matcher() {} 40113481Sgiacomo.travaglini@arm.com 40213481Sgiacomo.travaglini@arm.com explicit Matcher(const MatcherInterface<StringPiece>* impl) 40313481Sgiacomo.travaglini@arm.com : internal::MatcherBase<StringPiece>(impl) {} 40413481Sgiacomo.travaglini@arm.com 40513481Sgiacomo.travaglini@arm.com // Allows the user to write str instead of Eq(str) sometimes, where 40613481Sgiacomo.travaglini@arm.com // str is a string object. 40713481Sgiacomo.travaglini@arm.com Matcher(const internal::string& s); // NOLINT 40813481Sgiacomo.travaglini@arm.com 40913481Sgiacomo.travaglini@arm.com // Allows the user to write "foo" instead of Eq("foo") sometimes. 41013481Sgiacomo.travaglini@arm.com Matcher(const char* s); // NOLINT 41113481Sgiacomo.travaglini@arm.com 41213481Sgiacomo.travaglini@arm.com // Allows the user to pass StringPieces directly. 41313481Sgiacomo.travaglini@arm.com Matcher(StringPiece s); // NOLINT 41413481Sgiacomo.travaglini@arm.com}; 41513481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_STRING_PIECE_ 41613481Sgiacomo.travaglini@arm.com 41713481Sgiacomo.travaglini@arm.com// The PolymorphicMatcher class template makes it easy to implement a 41813481Sgiacomo.travaglini@arm.com// polymorphic matcher (i.e. a matcher that can match values of more 41913481Sgiacomo.travaglini@arm.com// than one type, e.g. Eq(n) and NotNull()). 42013481Sgiacomo.travaglini@arm.com// 42113481Sgiacomo.travaglini@arm.com// To define a polymorphic matcher, a user should provide an Impl 42213481Sgiacomo.travaglini@arm.com// class that has a DescribeTo() method and a DescribeNegationTo() 42313481Sgiacomo.travaglini@arm.com// method, and define a member function (or member function template) 42413481Sgiacomo.travaglini@arm.com// 42513481Sgiacomo.travaglini@arm.com// bool MatchAndExplain(const Value& value, 42613481Sgiacomo.travaglini@arm.com// MatchResultListener* listener) const; 42713481Sgiacomo.travaglini@arm.com// 42813481Sgiacomo.travaglini@arm.com// See the definition of NotNull() for a complete example. 42913481Sgiacomo.travaglini@arm.comtemplate <class Impl> 43013481Sgiacomo.travaglini@arm.comclass PolymorphicMatcher { 43113481Sgiacomo.travaglini@arm.com public: 43213481Sgiacomo.travaglini@arm.com explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} 43313481Sgiacomo.travaglini@arm.com 43413481Sgiacomo.travaglini@arm.com // Returns a mutable reference to the underlying matcher 43513481Sgiacomo.travaglini@arm.com // implementation object. 43613481Sgiacomo.travaglini@arm.com Impl& mutable_impl() { return impl_; } 43713481Sgiacomo.travaglini@arm.com 43813481Sgiacomo.travaglini@arm.com // Returns an immutable reference to the underlying matcher 43913481Sgiacomo.travaglini@arm.com // implementation object. 44013481Sgiacomo.travaglini@arm.com const Impl& impl() const { return impl_; } 44113481Sgiacomo.travaglini@arm.com 44213481Sgiacomo.travaglini@arm.com template <typename T> 44313481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 44413481Sgiacomo.travaglini@arm.com return Matcher<T>(new MonomorphicImpl<T>(impl_)); 44513481Sgiacomo.travaglini@arm.com } 44613481Sgiacomo.travaglini@arm.com 44713481Sgiacomo.travaglini@arm.com private: 44813481Sgiacomo.travaglini@arm.com template <typename T> 44913481Sgiacomo.travaglini@arm.com class MonomorphicImpl : public MatcherInterface<T> { 45013481Sgiacomo.travaglini@arm.com public: 45113481Sgiacomo.travaglini@arm.com explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} 45213481Sgiacomo.travaglini@arm.com 45313481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 45413481Sgiacomo.travaglini@arm.com impl_.DescribeTo(os); 45513481Sgiacomo.travaglini@arm.com } 45613481Sgiacomo.travaglini@arm.com 45713481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 45813481Sgiacomo.travaglini@arm.com impl_.DescribeNegationTo(os); 45913481Sgiacomo.travaglini@arm.com } 46013481Sgiacomo.travaglini@arm.com 46113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { 46213481Sgiacomo.travaglini@arm.com return impl_.MatchAndExplain(x, listener); 46313481Sgiacomo.travaglini@arm.com } 46413481Sgiacomo.travaglini@arm.com 46513481Sgiacomo.travaglini@arm.com private: 46613481Sgiacomo.travaglini@arm.com const Impl impl_; 46713481Sgiacomo.travaglini@arm.com 46813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); 46913481Sgiacomo.travaglini@arm.com }; 47013481Sgiacomo.travaglini@arm.com 47113481Sgiacomo.travaglini@arm.com Impl impl_; 47213481Sgiacomo.travaglini@arm.com 47313481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher); 47413481Sgiacomo.travaglini@arm.com}; 47513481Sgiacomo.travaglini@arm.com 47613481Sgiacomo.travaglini@arm.com// Creates a matcher from its implementation. This is easier to use 47713481Sgiacomo.travaglini@arm.com// than the Matcher<T> constructor as it doesn't require you to 47813481Sgiacomo.travaglini@arm.com// explicitly write the template argument, e.g. 47913481Sgiacomo.travaglini@arm.com// 48013481Sgiacomo.travaglini@arm.com// MakeMatcher(foo); 48113481Sgiacomo.travaglini@arm.com// vs 48213481Sgiacomo.travaglini@arm.com// Matcher<const string&>(foo); 48313481Sgiacomo.travaglini@arm.comtemplate <typename T> 48413481Sgiacomo.travaglini@arm.cominline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) { 48513481Sgiacomo.travaglini@arm.com return Matcher<T>(impl); 48613481Sgiacomo.travaglini@arm.com} 48713481Sgiacomo.travaglini@arm.com 48813481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher from its implementation. This is 48913481Sgiacomo.travaglini@arm.com// easier to use than the PolymorphicMatcher<Impl> constructor as it 49013481Sgiacomo.travaglini@arm.com// doesn't require you to explicitly write the template argument, e.g. 49113481Sgiacomo.travaglini@arm.com// 49213481Sgiacomo.travaglini@arm.com// MakePolymorphicMatcher(foo); 49313481Sgiacomo.travaglini@arm.com// vs 49413481Sgiacomo.travaglini@arm.com// PolymorphicMatcher<TypeOfFoo>(foo); 49513481Sgiacomo.travaglini@arm.comtemplate <class Impl> 49613481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) { 49713481Sgiacomo.travaglini@arm.com return PolymorphicMatcher<Impl>(impl); 49813481Sgiacomo.travaglini@arm.com} 49913481Sgiacomo.travaglini@arm.com 50013481Sgiacomo.travaglini@arm.com// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION 50113481Sgiacomo.travaglini@arm.com// and MUST NOT BE USED IN USER CODE!!! 50213481Sgiacomo.travaglini@arm.comnamespace internal { 50313481Sgiacomo.travaglini@arm.com 50413481Sgiacomo.travaglini@arm.com// The MatcherCastImpl class template is a helper for implementing 50513481Sgiacomo.travaglini@arm.com// MatcherCast(). We need this helper in order to partially 50613481Sgiacomo.travaglini@arm.com// specialize the implementation of MatcherCast() (C++ allows 50713481Sgiacomo.travaglini@arm.com// class/struct templates to be partially specialized, but not 50813481Sgiacomo.travaglini@arm.com// function templates.). 50913481Sgiacomo.travaglini@arm.com 51013481Sgiacomo.travaglini@arm.com// This general version is used when MatcherCast()'s argument is a 51113481Sgiacomo.travaglini@arm.com// polymorphic matcher (i.e. something that can be converted to a 51213481Sgiacomo.travaglini@arm.com// Matcher but is not one yet; for example, Eq(value)) or a value (for 51313481Sgiacomo.travaglini@arm.com// example, "hello"). 51413481Sgiacomo.travaglini@arm.comtemplate <typename T, typename M> 51513481Sgiacomo.travaglini@arm.comclass MatcherCastImpl { 51613481Sgiacomo.travaglini@arm.com public: 51713481Sgiacomo.travaglini@arm.com static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { 51813481Sgiacomo.travaglini@arm.com // M can be a polymorhic matcher, in which case we want to use 51913481Sgiacomo.travaglini@arm.com // its conversion operator to create Matcher<T>. Or it can be a value 52013481Sgiacomo.travaglini@arm.com // that should be passed to the Matcher<T>'s constructor. 52113481Sgiacomo.travaglini@arm.com // 52213481Sgiacomo.travaglini@arm.com // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a 52313481Sgiacomo.travaglini@arm.com // polymorphic matcher because it'll be ambiguous if T has an implicit 52413481Sgiacomo.travaglini@arm.com // constructor from M (this usually happens when T has an implicit 52513481Sgiacomo.travaglini@arm.com // constructor from any type). 52613481Sgiacomo.travaglini@arm.com // 52713481Sgiacomo.travaglini@arm.com // It won't work to unconditionally implict_cast 52813481Sgiacomo.travaglini@arm.com // polymorphic_matcher_or_value to Matcher<T> because it won't trigger 52913481Sgiacomo.travaglini@arm.com // a user-defined conversion from M to T if one exists (assuming M is 53013481Sgiacomo.travaglini@arm.com // a value). 53113481Sgiacomo.travaglini@arm.com return CastImpl( 53213481Sgiacomo.travaglini@arm.com polymorphic_matcher_or_value, 53313481Sgiacomo.travaglini@arm.com BooleanConstant< 53413481Sgiacomo.travaglini@arm.com internal::ImplicitlyConvertible<M, Matcher<T> >::value>()); 53513481Sgiacomo.travaglini@arm.com } 53613481Sgiacomo.travaglini@arm.com 53713481Sgiacomo.travaglini@arm.com private: 53813481Sgiacomo.travaglini@arm.com static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) { 53913481Sgiacomo.travaglini@arm.com // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic 54013481Sgiacomo.travaglini@arm.com // matcher. It must be a value then. Use direct initialization to create 54113481Sgiacomo.travaglini@arm.com // a matcher. 54213481Sgiacomo.travaglini@arm.com return Matcher<T>(ImplicitCast_<T>(value)); 54313481Sgiacomo.travaglini@arm.com } 54413481Sgiacomo.travaglini@arm.com 54513481Sgiacomo.travaglini@arm.com static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, 54613481Sgiacomo.travaglini@arm.com BooleanConstant<true>) { 54713481Sgiacomo.travaglini@arm.com // M is implicitly convertible to Matcher<T>, which means that either 54813481Sgiacomo.travaglini@arm.com // M is a polymorhpic matcher or Matcher<T> has an implicit constructor 54913481Sgiacomo.travaglini@arm.com // from M. In both cases using the implicit conversion will produce a 55013481Sgiacomo.travaglini@arm.com // matcher. 55113481Sgiacomo.travaglini@arm.com // 55213481Sgiacomo.travaglini@arm.com // Even if T has an implicit constructor from M, it won't be called because 55313481Sgiacomo.travaglini@arm.com // creating Matcher<T> would require a chain of two user-defined conversions 55413481Sgiacomo.travaglini@arm.com // (first to create T from M and then to create Matcher<T> from T). 55513481Sgiacomo.travaglini@arm.com return polymorphic_matcher_or_value; 55613481Sgiacomo.travaglini@arm.com } 55713481Sgiacomo.travaglini@arm.com}; 55813481Sgiacomo.travaglini@arm.com 55913481Sgiacomo.travaglini@arm.com// This more specialized version is used when MatcherCast()'s argument 56013481Sgiacomo.travaglini@arm.com// is already a Matcher. This only compiles when type T can be 56113481Sgiacomo.travaglini@arm.com// statically converted to type U. 56213481Sgiacomo.travaglini@arm.comtemplate <typename T, typename U> 56313481Sgiacomo.travaglini@arm.comclass MatcherCastImpl<T, Matcher<U> > { 56413481Sgiacomo.travaglini@arm.com public: 56513481Sgiacomo.travaglini@arm.com static Matcher<T> Cast(const Matcher<U>& source_matcher) { 56613481Sgiacomo.travaglini@arm.com return Matcher<T>(new Impl(source_matcher)); 56713481Sgiacomo.travaglini@arm.com } 56813481Sgiacomo.travaglini@arm.com 56913481Sgiacomo.travaglini@arm.com private: 57013481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<T> { 57113481Sgiacomo.travaglini@arm.com public: 57213481Sgiacomo.travaglini@arm.com explicit Impl(const Matcher<U>& source_matcher) 57313481Sgiacomo.travaglini@arm.com : source_matcher_(source_matcher) {} 57413481Sgiacomo.travaglini@arm.com 57513481Sgiacomo.travaglini@arm.com // We delegate the matching logic to the source matcher. 57613481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { 57713481Sgiacomo.travaglini@arm.com return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); 57813481Sgiacomo.travaglini@arm.com } 57913481Sgiacomo.travaglini@arm.com 58013481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 58113481Sgiacomo.travaglini@arm.com source_matcher_.DescribeTo(os); 58213481Sgiacomo.travaglini@arm.com } 58313481Sgiacomo.travaglini@arm.com 58413481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 58513481Sgiacomo.travaglini@arm.com source_matcher_.DescribeNegationTo(os); 58613481Sgiacomo.travaglini@arm.com } 58713481Sgiacomo.travaglini@arm.com 58813481Sgiacomo.travaglini@arm.com private: 58913481Sgiacomo.travaglini@arm.com const Matcher<U> source_matcher_; 59013481Sgiacomo.travaglini@arm.com 59113481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 59213481Sgiacomo.travaglini@arm.com }; 59313481Sgiacomo.travaglini@arm.com}; 59413481Sgiacomo.travaglini@arm.com 59513481Sgiacomo.travaglini@arm.com// This even more specialized version is used for efficiently casting 59613481Sgiacomo.travaglini@arm.com// a matcher to its own type. 59713481Sgiacomo.travaglini@arm.comtemplate <typename T> 59813481Sgiacomo.travaglini@arm.comclass MatcherCastImpl<T, Matcher<T> > { 59913481Sgiacomo.travaglini@arm.com public: 60013481Sgiacomo.travaglini@arm.com static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } 60113481Sgiacomo.travaglini@arm.com}; 60213481Sgiacomo.travaglini@arm.com 60313481Sgiacomo.travaglini@arm.com} // namespace internal 60413481Sgiacomo.travaglini@arm.com 60513481Sgiacomo.travaglini@arm.com// In order to be safe and clear, casting between different matcher 60613481Sgiacomo.travaglini@arm.com// types is done explicitly via MatcherCast<T>(m), which takes a 60713481Sgiacomo.travaglini@arm.com// matcher m and returns a Matcher<T>. It compiles only when T can be 60813481Sgiacomo.travaglini@arm.com// statically converted to the argument type of m. 60913481Sgiacomo.travaglini@arm.comtemplate <typename T, typename M> 61013481Sgiacomo.travaglini@arm.cominline Matcher<T> MatcherCast(const M& matcher) { 61113481Sgiacomo.travaglini@arm.com return internal::MatcherCastImpl<T, M>::Cast(matcher); 61213481Sgiacomo.travaglini@arm.com} 61313481Sgiacomo.travaglini@arm.com 61413481Sgiacomo.travaglini@arm.com// Implements SafeMatcherCast(). 61513481Sgiacomo.travaglini@arm.com// 61613481Sgiacomo.travaglini@arm.com// We use an intermediate class to do the actual safe casting as Nokia's 61713481Sgiacomo.travaglini@arm.com// Symbian compiler cannot decide between 61813481Sgiacomo.travaglini@arm.com// template <T, M> ... (M) and 61913481Sgiacomo.travaglini@arm.com// template <T, U> ... (const Matcher<U>&) 62013481Sgiacomo.travaglini@arm.com// for function templates but can for member function templates. 62113481Sgiacomo.travaglini@arm.comtemplate <typename T> 62213481Sgiacomo.travaglini@arm.comclass SafeMatcherCastImpl { 62313481Sgiacomo.travaglini@arm.com public: 62413481Sgiacomo.travaglini@arm.com // This overload handles polymorphic matchers and values only since 62513481Sgiacomo.travaglini@arm.com // monomorphic matchers are handled by the next one. 62613481Sgiacomo.travaglini@arm.com template <typename M> 62713481Sgiacomo.travaglini@arm.com static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) { 62813481Sgiacomo.travaglini@arm.com return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value); 62913481Sgiacomo.travaglini@arm.com } 63013481Sgiacomo.travaglini@arm.com 63113481Sgiacomo.travaglini@arm.com // This overload handles monomorphic matchers. 63213481Sgiacomo.travaglini@arm.com // 63313481Sgiacomo.travaglini@arm.com // In general, if type T can be implicitly converted to type U, we can 63413481Sgiacomo.travaglini@arm.com // safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is 63513481Sgiacomo.travaglini@arm.com // contravariant): just keep a copy of the original Matcher<U>, convert the 63613481Sgiacomo.travaglini@arm.com // argument from type T to U, and then pass it to the underlying Matcher<U>. 63713481Sgiacomo.travaglini@arm.com // The only exception is when U is a reference and T is not, as the 63813481Sgiacomo.travaglini@arm.com // underlying Matcher<U> may be interested in the argument's address, which 63913481Sgiacomo.travaglini@arm.com // is not preserved in the conversion from T to U. 64013481Sgiacomo.travaglini@arm.com template <typename U> 64113481Sgiacomo.travaglini@arm.com static inline Matcher<T> Cast(const Matcher<U>& matcher) { 64213481Sgiacomo.travaglini@arm.com // Enforce that T can be implicitly converted to U. 64313481Sgiacomo.travaglini@arm.com GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value), 64413481Sgiacomo.travaglini@arm.com T_must_be_implicitly_convertible_to_U); 64513481Sgiacomo.travaglini@arm.com // Enforce that we are not converting a non-reference type T to a reference 64613481Sgiacomo.travaglini@arm.com // type U. 64713481Sgiacomo.travaglini@arm.com GTEST_COMPILE_ASSERT_( 64813481Sgiacomo.travaglini@arm.com internal::is_reference<T>::value || !internal::is_reference<U>::value, 64913481Sgiacomo.travaglini@arm.com cannot_convert_non_referentce_arg_to_reference); 65013481Sgiacomo.travaglini@arm.com // In case both T and U are arithmetic types, enforce that the 65113481Sgiacomo.travaglini@arm.com // conversion is not lossy. 65213481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; 65313481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; 65413481Sgiacomo.travaglini@arm.com const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; 65513481Sgiacomo.travaglini@arm.com const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; 65613481Sgiacomo.travaglini@arm.com GTEST_COMPILE_ASSERT_( 65713481Sgiacomo.travaglini@arm.com kTIsOther || kUIsOther || 65813481Sgiacomo.travaglini@arm.com (internal::LosslessArithmeticConvertible<RawT, RawU>::value), 65913481Sgiacomo.travaglini@arm.com conversion_of_arithmetic_types_must_be_lossless); 66013481Sgiacomo.travaglini@arm.com return MatcherCast<T>(matcher); 66113481Sgiacomo.travaglini@arm.com } 66213481Sgiacomo.travaglini@arm.com}; 66313481Sgiacomo.travaglini@arm.com 66413481Sgiacomo.travaglini@arm.comtemplate <typename T, typename M> 66513481Sgiacomo.travaglini@arm.cominline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) { 66613481Sgiacomo.travaglini@arm.com return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); 66713481Sgiacomo.travaglini@arm.com} 66813481Sgiacomo.travaglini@arm.com 66913481Sgiacomo.travaglini@arm.com// A<T>() returns a matcher that matches any value of type T. 67013481Sgiacomo.travaglini@arm.comtemplate <typename T> 67113481Sgiacomo.travaglini@arm.comMatcher<T> A(); 67213481Sgiacomo.travaglini@arm.com 67313481Sgiacomo.travaglini@arm.com// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION 67413481Sgiacomo.travaglini@arm.com// and MUST NOT BE USED IN USER CODE!!! 67513481Sgiacomo.travaglini@arm.comnamespace internal { 67613481Sgiacomo.travaglini@arm.com 67713481Sgiacomo.travaglini@arm.com// If the explanation is not empty, prints it to the ostream. 67813481Sgiacomo.travaglini@arm.cominline void PrintIfNotEmpty(const internal::string& explanation, 67913481Sgiacomo.travaglini@arm.com ::std::ostream* os) { 68013481Sgiacomo.travaglini@arm.com if (explanation != "" && os != NULL) { 68113481Sgiacomo.travaglini@arm.com *os << ", " << explanation; 68213481Sgiacomo.travaglini@arm.com } 68313481Sgiacomo.travaglini@arm.com} 68413481Sgiacomo.travaglini@arm.com 68513481Sgiacomo.travaglini@arm.com// Returns true if the given type name is easy to read by a human. 68613481Sgiacomo.travaglini@arm.com// This is used to decide whether printing the type of a value might 68713481Sgiacomo.travaglini@arm.com// be helpful. 68813481Sgiacomo.travaglini@arm.cominline bool IsReadableTypeName(const string& type_name) { 68913481Sgiacomo.travaglini@arm.com // We consider a type name readable if it's short or doesn't contain 69013481Sgiacomo.travaglini@arm.com // a template or function type. 69113481Sgiacomo.travaglini@arm.com return (type_name.length() <= 20 || 69213481Sgiacomo.travaglini@arm.com type_name.find_first_of("<(") == string::npos); 69313481Sgiacomo.travaglini@arm.com} 69413481Sgiacomo.travaglini@arm.com 69513481Sgiacomo.travaglini@arm.com// Matches the value against the given matcher, prints the value and explains 69613481Sgiacomo.travaglini@arm.com// the match result to the listener. Returns the match result. 69713481Sgiacomo.travaglini@arm.com// 'listener' must not be NULL. 69813481Sgiacomo.travaglini@arm.com// Value cannot be passed by const reference, because some matchers take a 69913481Sgiacomo.travaglini@arm.com// non-const argument. 70013481Sgiacomo.travaglini@arm.comtemplate <typename Value, typename T> 70113481Sgiacomo.travaglini@arm.combool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher, 70213481Sgiacomo.travaglini@arm.com MatchResultListener* listener) { 70313481Sgiacomo.travaglini@arm.com if (!listener->IsInterested()) { 70413481Sgiacomo.travaglini@arm.com // If the listener is not interested, we do not need to construct the 70513481Sgiacomo.travaglini@arm.com // inner explanation. 70613481Sgiacomo.travaglini@arm.com return matcher.Matches(value); 70713481Sgiacomo.travaglini@arm.com } 70813481Sgiacomo.travaglini@arm.com 70913481Sgiacomo.travaglini@arm.com StringMatchResultListener inner_listener; 71013481Sgiacomo.travaglini@arm.com const bool match = matcher.MatchAndExplain(value, &inner_listener); 71113481Sgiacomo.travaglini@arm.com 71213481Sgiacomo.travaglini@arm.com UniversalPrint(value, listener->stream()); 71313481Sgiacomo.travaglini@arm.com#if GTEST_HAS_RTTI 71413481Sgiacomo.travaglini@arm.com const string& type_name = GetTypeName<Value>(); 71513481Sgiacomo.travaglini@arm.com if (IsReadableTypeName(type_name)) 71613481Sgiacomo.travaglini@arm.com *listener->stream() << " (of type " << type_name << ")"; 71713481Sgiacomo.travaglini@arm.com#endif 71813481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(inner_listener.str(), listener->stream()); 71913481Sgiacomo.travaglini@arm.com 72013481Sgiacomo.travaglini@arm.com return match; 72113481Sgiacomo.travaglini@arm.com} 72213481Sgiacomo.travaglini@arm.com 72313481Sgiacomo.travaglini@arm.com// An internal helper class for doing compile-time loop on a tuple's 72413481Sgiacomo.travaglini@arm.com// fields. 72513481Sgiacomo.travaglini@arm.comtemplate <size_t N> 72613481Sgiacomo.travaglini@arm.comclass TuplePrefix { 72713481Sgiacomo.travaglini@arm.com public: 72813481Sgiacomo.travaglini@arm.com // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true 72913481Sgiacomo.travaglini@arm.com // iff the first N fields of matcher_tuple matches the first N 73013481Sgiacomo.travaglini@arm.com // fields of value_tuple, respectively. 73113481Sgiacomo.travaglini@arm.com template <typename MatcherTuple, typename ValueTuple> 73213481Sgiacomo.travaglini@arm.com static bool Matches(const MatcherTuple& matcher_tuple, 73313481Sgiacomo.travaglini@arm.com const ValueTuple& value_tuple) { 73413481Sgiacomo.travaglini@arm.com return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) 73513481Sgiacomo.travaglini@arm.com && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple)); 73613481Sgiacomo.travaglini@arm.com } 73713481Sgiacomo.travaglini@arm.com 73813481Sgiacomo.travaglini@arm.com // TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os) 73913481Sgiacomo.travaglini@arm.com // describes failures in matching the first N fields of matchers 74013481Sgiacomo.travaglini@arm.com // against the first N fields of values. If there is no failure, 74113481Sgiacomo.travaglini@arm.com // nothing will be streamed to os. 74213481Sgiacomo.travaglini@arm.com template <typename MatcherTuple, typename ValueTuple> 74313481Sgiacomo.travaglini@arm.com static void ExplainMatchFailuresTo(const MatcherTuple& matchers, 74413481Sgiacomo.travaglini@arm.com const ValueTuple& values, 74513481Sgiacomo.travaglini@arm.com ::std::ostream* os) { 74613481Sgiacomo.travaglini@arm.com // First, describes failures in the first N - 1 fields. 74713481Sgiacomo.travaglini@arm.com TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os); 74813481Sgiacomo.travaglini@arm.com 74913481Sgiacomo.travaglini@arm.com // Then describes the failure (if any) in the (N - 1)-th (0-based) 75013481Sgiacomo.travaglini@arm.com // field. 75113481Sgiacomo.travaglini@arm.com typename tuple_element<N - 1, MatcherTuple>::type matcher = 75213481Sgiacomo.travaglini@arm.com get<N - 1>(matchers); 75313481Sgiacomo.travaglini@arm.com typedef typename tuple_element<N - 1, ValueTuple>::type Value; 75413481Sgiacomo.travaglini@arm.com Value value = get<N - 1>(values); 75513481Sgiacomo.travaglini@arm.com StringMatchResultListener listener; 75613481Sgiacomo.travaglini@arm.com if (!matcher.MatchAndExplain(value, &listener)) { 75713481Sgiacomo.travaglini@arm.com // TODO(wan): include in the message the name of the parameter 75813481Sgiacomo.travaglini@arm.com // as used in MOCK_METHOD*() when possible. 75913481Sgiacomo.travaglini@arm.com *os << " Expected arg #" << N - 1 << ": "; 76013481Sgiacomo.travaglini@arm.com get<N - 1>(matchers).DescribeTo(os); 76113481Sgiacomo.travaglini@arm.com *os << "\n Actual: "; 76213481Sgiacomo.travaglini@arm.com // We remove the reference in type Value to prevent the 76313481Sgiacomo.travaglini@arm.com // universal printer from printing the address of value, which 76413481Sgiacomo.travaglini@arm.com // isn't interesting to the user most of the time. The 76513481Sgiacomo.travaglini@arm.com // matcher's MatchAndExplain() method handles the case when 76613481Sgiacomo.travaglini@arm.com // the address is interesting. 76713481Sgiacomo.travaglini@arm.com internal::UniversalPrint(value, os); 76813481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(listener.str(), os); 76913481Sgiacomo.travaglini@arm.com *os << "\n"; 77013481Sgiacomo.travaglini@arm.com } 77113481Sgiacomo.travaglini@arm.com } 77213481Sgiacomo.travaglini@arm.com}; 77313481Sgiacomo.travaglini@arm.com 77413481Sgiacomo.travaglini@arm.com// The base case. 77513481Sgiacomo.travaglini@arm.comtemplate <> 77613481Sgiacomo.travaglini@arm.comclass TuplePrefix<0> { 77713481Sgiacomo.travaglini@arm.com public: 77813481Sgiacomo.travaglini@arm.com template <typename MatcherTuple, typename ValueTuple> 77913481Sgiacomo.travaglini@arm.com static bool Matches(const MatcherTuple& /* matcher_tuple */, 78013481Sgiacomo.travaglini@arm.com const ValueTuple& /* value_tuple */) { 78113481Sgiacomo.travaglini@arm.com return true; 78213481Sgiacomo.travaglini@arm.com } 78313481Sgiacomo.travaglini@arm.com 78413481Sgiacomo.travaglini@arm.com template <typename MatcherTuple, typename ValueTuple> 78513481Sgiacomo.travaglini@arm.com static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, 78613481Sgiacomo.travaglini@arm.com const ValueTuple& /* values */, 78713481Sgiacomo.travaglini@arm.com ::std::ostream* /* os */) {} 78813481Sgiacomo.travaglini@arm.com}; 78913481Sgiacomo.travaglini@arm.com 79013481Sgiacomo.travaglini@arm.com// TupleMatches(matcher_tuple, value_tuple) returns true iff all 79113481Sgiacomo.travaglini@arm.com// matchers in matcher_tuple match the corresponding fields in 79213481Sgiacomo.travaglini@arm.com// value_tuple. It is a compiler error if matcher_tuple and 79313481Sgiacomo.travaglini@arm.com// value_tuple have different number of fields or incompatible field 79413481Sgiacomo.travaglini@arm.com// types. 79513481Sgiacomo.travaglini@arm.comtemplate <typename MatcherTuple, typename ValueTuple> 79613481Sgiacomo.travaglini@arm.combool TupleMatches(const MatcherTuple& matcher_tuple, 79713481Sgiacomo.travaglini@arm.com const ValueTuple& value_tuple) { 79813481Sgiacomo.travaglini@arm.com // Makes sure that matcher_tuple and value_tuple have the same 79913481Sgiacomo.travaglini@arm.com // number of fields. 80013481Sgiacomo.travaglini@arm.com GTEST_COMPILE_ASSERT_(tuple_size<MatcherTuple>::value == 80113481Sgiacomo.travaglini@arm.com tuple_size<ValueTuple>::value, 80213481Sgiacomo.travaglini@arm.com matcher_and_value_have_different_numbers_of_fields); 80313481Sgiacomo.travaglini@arm.com return TuplePrefix<tuple_size<ValueTuple>::value>:: 80413481Sgiacomo.travaglini@arm.com Matches(matcher_tuple, value_tuple); 80513481Sgiacomo.travaglini@arm.com} 80613481Sgiacomo.travaglini@arm.com 80713481Sgiacomo.travaglini@arm.com// Describes failures in matching matchers against values. If there 80813481Sgiacomo.travaglini@arm.com// is no failure, nothing will be streamed to os. 80913481Sgiacomo.travaglini@arm.comtemplate <typename MatcherTuple, typename ValueTuple> 81013481Sgiacomo.travaglini@arm.comvoid ExplainMatchFailureTupleTo(const MatcherTuple& matchers, 81113481Sgiacomo.travaglini@arm.com const ValueTuple& values, 81213481Sgiacomo.travaglini@arm.com ::std::ostream* os) { 81313481Sgiacomo.travaglini@arm.com TuplePrefix<tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( 81413481Sgiacomo.travaglini@arm.com matchers, values, os); 81513481Sgiacomo.travaglini@arm.com} 81613481Sgiacomo.travaglini@arm.com 81713481Sgiacomo.travaglini@arm.com// TransformTupleValues and its helper. 81813481Sgiacomo.travaglini@arm.com// 81913481Sgiacomo.travaglini@arm.com// TransformTupleValuesHelper hides the internal machinery that 82013481Sgiacomo.travaglini@arm.com// TransformTupleValues uses to implement a tuple traversal. 82113481Sgiacomo.travaglini@arm.comtemplate <typename Tuple, typename Func, typename OutIter> 82213481Sgiacomo.travaglini@arm.comclass TransformTupleValuesHelper { 82313481Sgiacomo.travaglini@arm.com private: 82413481Sgiacomo.travaglini@arm.com typedef ::testing::tuple_size<Tuple> TupleSize; 82513481Sgiacomo.travaglini@arm.com 82613481Sgiacomo.travaglini@arm.com public: 82713481Sgiacomo.travaglini@arm.com // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. 82813481Sgiacomo.travaglini@arm.com // Returns the final value of 'out' in case the caller needs it. 82913481Sgiacomo.travaglini@arm.com static OutIter Run(Func f, const Tuple& t, OutIter out) { 83013481Sgiacomo.travaglini@arm.com return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out); 83113481Sgiacomo.travaglini@arm.com } 83213481Sgiacomo.travaglini@arm.com 83313481Sgiacomo.travaglini@arm.com private: 83413481Sgiacomo.travaglini@arm.com template <typename Tup, size_t kRemainingSize> 83513481Sgiacomo.travaglini@arm.com struct IterateOverTuple { 83613481Sgiacomo.travaglini@arm.com OutIter operator() (Func f, const Tup& t, OutIter out) const { 83713481Sgiacomo.travaglini@arm.com *out++ = f(::testing::get<TupleSize::value - kRemainingSize>(t)); 83813481Sgiacomo.travaglini@arm.com return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out); 83913481Sgiacomo.travaglini@arm.com } 84013481Sgiacomo.travaglini@arm.com }; 84113481Sgiacomo.travaglini@arm.com template <typename Tup> 84213481Sgiacomo.travaglini@arm.com struct IterateOverTuple<Tup, 0> { 84313481Sgiacomo.travaglini@arm.com OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { 84413481Sgiacomo.travaglini@arm.com return out; 84513481Sgiacomo.travaglini@arm.com } 84613481Sgiacomo.travaglini@arm.com }; 84713481Sgiacomo.travaglini@arm.com}; 84813481Sgiacomo.travaglini@arm.com 84913481Sgiacomo.travaglini@arm.com// Successively invokes 'f(element)' on each element of the tuple 't', 85013481Sgiacomo.travaglini@arm.com// appending each result to the 'out' iterator. Returns the final value 85113481Sgiacomo.travaglini@arm.com// of 'out'. 85213481Sgiacomo.travaglini@arm.comtemplate <typename Tuple, typename Func, typename OutIter> 85313481Sgiacomo.travaglini@arm.comOutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { 85413481Sgiacomo.travaglini@arm.com return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out); 85513481Sgiacomo.travaglini@arm.com} 85613481Sgiacomo.travaglini@arm.com 85713481Sgiacomo.travaglini@arm.com// Implements A<T>(). 85813481Sgiacomo.travaglini@arm.comtemplate <typename T> 85913481Sgiacomo.travaglini@arm.comclass AnyMatcherImpl : public MatcherInterface<T> { 86013481Sgiacomo.travaglini@arm.com public: 86113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain( 86213481Sgiacomo.travaglini@arm.com T /* x */, MatchResultListener* /* listener */) const { return true; } 86313481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } 86413481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 86513481Sgiacomo.travaglini@arm.com // This is mostly for completeness' safe, as it's not very useful 86613481Sgiacomo.travaglini@arm.com // to write Not(A<bool>()). However we cannot completely rule out 86713481Sgiacomo.travaglini@arm.com // such a possibility, and it doesn't hurt to be prepared. 86813481Sgiacomo.travaglini@arm.com *os << "never matches"; 86913481Sgiacomo.travaglini@arm.com } 87013481Sgiacomo.travaglini@arm.com}; 87113481Sgiacomo.travaglini@arm.com 87213481Sgiacomo.travaglini@arm.com// Implements _, a matcher that matches any value of any 87313481Sgiacomo.travaglini@arm.com// type. This is a polymorphic matcher, so we need a template type 87413481Sgiacomo.travaglini@arm.com// conversion operator to make it appearing as a Matcher<T> for any 87513481Sgiacomo.travaglini@arm.com// type T. 87613481Sgiacomo.travaglini@arm.comclass AnythingMatcher { 87713481Sgiacomo.travaglini@arm.com public: 87813481Sgiacomo.travaglini@arm.com template <typename T> 87913481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { return A<T>(); } 88013481Sgiacomo.travaglini@arm.com}; 88113481Sgiacomo.travaglini@arm.com 88213481Sgiacomo.travaglini@arm.com// Implements a matcher that compares a given value with a 88313481Sgiacomo.travaglini@arm.com// pre-supplied value using one of the ==, <=, <, etc, operators. The 88413481Sgiacomo.travaglini@arm.com// two values being compared don't have to have the same type. 88513481Sgiacomo.travaglini@arm.com// 88613481Sgiacomo.travaglini@arm.com// The matcher defined here is polymorphic (for example, Eq(5) can be 88713481Sgiacomo.travaglini@arm.com// used to match an int, a short, a double, etc). Therefore we use 88813481Sgiacomo.travaglini@arm.com// a template type conversion operator in the implementation. 88913481Sgiacomo.travaglini@arm.com// 89013481Sgiacomo.travaglini@arm.com// The following template definition assumes that the Rhs parameter is 89113481Sgiacomo.travaglini@arm.com// a "bare" type (i.e. neither 'const T' nor 'T&'). 89213481Sgiacomo.travaglini@arm.comtemplate <typename D, typename Rhs, typename Op> 89313481Sgiacomo.travaglini@arm.comclass ComparisonBase { 89413481Sgiacomo.travaglini@arm.com public: 89513481Sgiacomo.travaglini@arm.com explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} 89613481Sgiacomo.travaglini@arm.com template <typename Lhs> 89713481Sgiacomo.travaglini@arm.com operator Matcher<Lhs>() const { 89813481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<Lhs>(rhs_)); 89913481Sgiacomo.travaglini@arm.com } 90013481Sgiacomo.travaglini@arm.com 90113481Sgiacomo.travaglini@arm.com private: 90213481Sgiacomo.travaglini@arm.com template <typename Lhs> 90313481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<Lhs> { 90413481Sgiacomo.travaglini@arm.com public: 90513481Sgiacomo.travaglini@arm.com explicit Impl(const Rhs& rhs) : rhs_(rhs) {} 90613481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain( 90713481Sgiacomo.travaglini@arm.com Lhs lhs, MatchResultListener* /* listener */) const { 90813481Sgiacomo.travaglini@arm.com return Op()(lhs, rhs_); 90913481Sgiacomo.travaglini@arm.com } 91013481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 91113481Sgiacomo.travaglini@arm.com *os << D::Desc() << " "; 91213481Sgiacomo.travaglini@arm.com UniversalPrint(rhs_, os); 91313481Sgiacomo.travaglini@arm.com } 91413481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 91513481Sgiacomo.travaglini@arm.com *os << D::NegatedDesc() << " "; 91613481Sgiacomo.travaglini@arm.com UniversalPrint(rhs_, os); 91713481Sgiacomo.travaglini@arm.com } 91813481Sgiacomo.travaglini@arm.com private: 91913481Sgiacomo.travaglini@arm.com Rhs rhs_; 92013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 92113481Sgiacomo.travaglini@arm.com }; 92213481Sgiacomo.travaglini@arm.com Rhs rhs_; 92313481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ComparisonBase); 92413481Sgiacomo.travaglini@arm.com}; 92513481Sgiacomo.travaglini@arm.com 92613481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 92713481Sgiacomo.travaglini@arm.comclass EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> { 92813481Sgiacomo.travaglini@arm.com public: 92913481Sgiacomo.travaglini@arm.com explicit EqMatcher(const Rhs& rhs) 93013481Sgiacomo.travaglini@arm.com : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { } 93113481Sgiacomo.travaglini@arm.com static const char* Desc() { return "is equal to"; } 93213481Sgiacomo.travaglini@arm.com static const char* NegatedDesc() { return "isn't equal to"; } 93313481Sgiacomo.travaglini@arm.com}; 93413481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 93513481Sgiacomo.travaglini@arm.comclass NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> { 93613481Sgiacomo.travaglini@arm.com public: 93713481Sgiacomo.travaglini@arm.com explicit NeMatcher(const Rhs& rhs) 93813481Sgiacomo.travaglini@arm.com : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { } 93913481Sgiacomo.travaglini@arm.com static const char* Desc() { return "isn't equal to"; } 94013481Sgiacomo.travaglini@arm.com static const char* NegatedDesc() { return "is equal to"; } 94113481Sgiacomo.travaglini@arm.com}; 94213481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 94313481Sgiacomo.travaglini@arm.comclass LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> { 94413481Sgiacomo.travaglini@arm.com public: 94513481Sgiacomo.travaglini@arm.com explicit LtMatcher(const Rhs& rhs) 94613481Sgiacomo.travaglini@arm.com : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { } 94713481Sgiacomo.travaglini@arm.com static const char* Desc() { return "is <"; } 94813481Sgiacomo.travaglini@arm.com static const char* NegatedDesc() { return "isn't <"; } 94913481Sgiacomo.travaglini@arm.com}; 95013481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 95113481Sgiacomo.travaglini@arm.comclass GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> { 95213481Sgiacomo.travaglini@arm.com public: 95313481Sgiacomo.travaglini@arm.com explicit GtMatcher(const Rhs& rhs) 95413481Sgiacomo.travaglini@arm.com : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { } 95513481Sgiacomo.travaglini@arm.com static const char* Desc() { return "is >"; } 95613481Sgiacomo.travaglini@arm.com static const char* NegatedDesc() { return "isn't >"; } 95713481Sgiacomo.travaglini@arm.com}; 95813481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 95913481Sgiacomo.travaglini@arm.comclass LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> { 96013481Sgiacomo.travaglini@arm.com public: 96113481Sgiacomo.travaglini@arm.com explicit LeMatcher(const Rhs& rhs) 96213481Sgiacomo.travaglini@arm.com : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { } 96313481Sgiacomo.travaglini@arm.com static const char* Desc() { return "is <="; } 96413481Sgiacomo.travaglini@arm.com static const char* NegatedDesc() { return "isn't <="; } 96513481Sgiacomo.travaglini@arm.com}; 96613481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 96713481Sgiacomo.travaglini@arm.comclass GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> { 96813481Sgiacomo.travaglini@arm.com public: 96913481Sgiacomo.travaglini@arm.com explicit GeMatcher(const Rhs& rhs) 97013481Sgiacomo.travaglini@arm.com : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { } 97113481Sgiacomo.travaglini@arm.com static const char* Desc() { return "is >="; } 97213481Sgiacomo.travaglini@arm.com static const char* NegatedDesc() { return "isn't >="; } 97313481Sgiacomo.travaglini@arm.com}; 97413481Sgiacomo.travaglini@arm.com 97513481Sgiacomo.travaglini@arm.com// Implements the polymorphic IsNull() matcher, which matches any raw or smart 97613481Sgiacomo.travaglini@arm.com// pointer that is NULL. 97713481Sgiacomo.travaglini@arm.comclass IsNullMatcher { 97813481Sgiacomo.travaglini@arm.com public: 97913481Sgiacomo.travaglini@arm.com template <typename Pointer> 98013481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const Pointer& p, 98113481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 98213481Sgiacomo.travaglini@arm.com#if GTEST_LANG_CXX11 98313481Sgiacomo.travaglini@arm.com return p == nullptr; 98413481Sgiacomo.travaglini@arm.com#else // GTEST_LANG_CXX11 98513481Sgiacomo.travaglini@arm.com return GetRawPointer(p) == NULL; 98613481Sgiacomo.travaglini@arm.com#endif // GTEST_LANG_CXX11 98713481Sgiacomo.travaglini@arm.com } 98813481Sgiacomo.travaglini@arm.com 98913481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } 99013481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 99113481Sgiacomo.travaglini@arm.com *os << "isn't NULL"; 99213481Sgiacomo.travaglini@arm.com } 99313481Sgiacomo.travaglini@arm.com}; 99413481Sgiacomo.travaglini@arm.com 99513481Sgiacomo.travaglini@arm.com// Implements the polymorphic NotNull() matcher, which matches any raw or smart 99613481Sgiacomo.travaglini@arm.com// pointer that is not NULL. 99713481Sgiacomo.travaglini@arm.comclass NotNullMatcher { 99813481Sgiacomo.travaglini@arm.com public: 99913481Sgiacomo.travaglini@arm.com template <typename Pointer> 100013481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const Pointer& p, 100113481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 100213481Sgiacomo.travaglini@arm.com#if GTEST_LANG_CXX11 100313481Sgiacomo.travaglini@arm.com return p != nullptr; 100413481Sgiacomo.travaglini@arm.com#else // GTEST_LANG_CXX11 100513481Sgiacomo.travaglini@arm.com return GetRawPointer(p) != NULL; 100613481Sgiacomo.travaglini@arm.com#endif // GTEST_LANG_CXX11 100713481Sgiacomo.travaglini@arm.com } 100813481Sgiacomo.travaglini@arm.com 100913481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } 101013481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 101113481Sgiacomo.travaglini@arm.com *os << "is NULL"; 101213481Sgiacomo.travaglini@arm.com } 101313481Sgiacomo.travaglini@arm.com}; 101413481Sgiacomo.travaglini@arm.com 101513481Sgiacomo.travaglini@arm.com// Ref(variable) matches any argument that is a reference to 101613481Sgiacomo.travaglini@arm.com// 'variable'. This matcher is polymorphic as it can match any 101713481Sgiacomo.travaglini@arm.com// super type of the type of 'variable'. 101813481Sgiacomo.travaglini@arm.com// 101913481Sgiacomo.travaglini@arm.com// The RefMatcher template class implements Ref(variable). It can 102013481Sgiacomo.travaglini@arm.com// only be instantiated with a reference type. This prevents a user 102113481Sgiacomo.travaglini@arm.com// from mistakenly using Ref(x) to match a non-reference function 102213481Sgiacomo.travaglini@arm.com// argument. For example, the following will righteously cause a 102313481Sgiacomo.travaglini@arm.com// compiler error: 102413481Sgiacomo.travaglini@arm.com// 102513481Sgiacomo.travaglini@arm.com// int n; 102613481Sgiacomo.travaglini@arm.com// Matcher<int> m1 = Ref(n); // This won't compile. 102713481Sgiacomo.travaglini@arm.com// Matcher<int&> m2 = Ref(n); // This will compile. 102813481Sgiacomo.travaglini@arm.comtemplate <typename T> 102913481Sgiacomo.travaglini@arm.comclass RefMatcher; 103013481Sgiacomo.travaglini@arm.com 103113481Sgiacomo.travaglini@arm.comtemplate <typename T> 103213481Sgiacomo.travaglini@arm.comclass RefMatcher<T&> { 103313481Sgiacomo.travaglini@arm.com // Google Mock is a generic framework and thus needs to support 103413481Sgiacomo.travaglini@arm.com // mocking any function types, including those that take non-const 103513481Sgiacomo.travaglini@arm.com // reference arguments. Therefore the template parameter T (and 103613481Sgiacomo.travaglini@arm.com // Super below) can be instantiated to either a const type or a 103713481Sgiacomo.travaglini@arm.com // non-const type. 103813481Sgiacomo.travaglini@arm.com public: 103913481Sgiacomo.travaglini@arm.com // RefMatcher() takes a T& instead of const T&, as we want the 104013481Sgiacomo.travaglini@arm.com // compiler to catch using Ref(const_value) as a matcher for a 104113481Sgiacomo.travaglini@arm.com // non-const reference. 104213481Sgiacomo.travaglini@arm.com explicit RefMatcher(T& x) : object_(x) {} // NOLINT 104313481Sgiacomo.travaglini@arm.com 104413481Sgiacomo.travaglini@arm.com template <typename Super> 104513481Sgiacomo.travaglini@arm.com operator Matcher<Super&>() const { 104613481Sgiacomo.travaglini@arm.com // By passing object_ (type T&) to Impl(), which expects a Super&, 104713481Sgiacomo.travaglini@arm.com // we make sure that Super is a super type of T. In particular, 104813481Sgiacomo.travaglini@arm.com // this catches using Ref(const_value) as a matcher for a 104913481Sgiacomo.travaglini@arm.com // non-const reference, as you cannot implicitly convert a const 105013481Sgiacomo.travaglini@arm.com // reference to a non-const reference. 105113481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<Super>(object_)); 105213481Sgiacomo.travaglini@arm.com } 105313481Sgiacomo.travaglini@arm.com 105413481Sgiacomo.travaglini@arm.com private: 105513481Sgiacomo.travaglini@arm.com template <typename Super> 105613481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<Super&> { 105713481Sgiacomo.travaglini@arm.com public: 105813481Sgiacomo.travaglini@arm.com explicit Impl(Super& x) : object_(x) {} // NOLINT 105913481Sgiacomo.travaglini@arm.com 106013481Sgiacomo.travaglini@arm.com // MatchAndExplain() takes a Super& (as opposed to const Super&) 106113481Sgiacomo.travaglini@arm.com // in order to match the interface MatcherInterface<Super&>. 106213481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain( 106313481Sgiacomo.travaglini@arm.com Super& x, MatchResultListener* listener) const { 106413481Sgiacomo.travaglini@arm.com *listener << "which is located @" << static_cast<const void*>(&x); 106513481Sgiacomo.travaglini@arm.com return &x == &object_; 106613481Sgiacomo.travaglini@arm.com } 106713481Sgiacomo.travaglini@arm.com 106813481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 106913481Sgiacomo.travaglini@arm.com *os << "references the variable "; 107013481Sgiacomo.travaglini@arm.com UniversalPrinter<Super&>::Print(object_, os); 107113481Sgiacomo.travaglini@arm.com } 107213481Sgiacomo.travaglini@arm.com 107313481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 107413481Sgiacomo.travaglini@arm.com *os << "does not reference the variable "; 107513481Sgiacomo.travaglini@arm.com UniversalPrinter<Super&>::Print(object_, os); 107613481Sgiacomo.travaglini@arm.com } 107713481Sgiacomo.travaglini@arm.com 107813481Sgiacomo.travaglini@arm.com private: 107913481Sgiacomo.travaglini@arm.com const Super& object_; 108013481Sgiacomo.travaglini@arm.com 108113481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 108213481Sgiacomo.travaglini@arm.com }; 108313481Sgiacomo.travaglini@arm.com 108413481Sgiacomo.travaglini@arm.com T& object_; 108513481Sgiacomo.travaglini@arm.com 108613481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(RefMatcher); 108713481Sgiacomo.travaglini@arm.com}; 108813481Sgiacomo.travaglini@arm.com 108913481Sgiacomo.travaglini@arm.com// Polymorphic helper functions for narrow and wide string matchers. 109013481Sgiacomo.travaglini@arm.cominline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { 109113481Sgiacomo.travaglini@arm.com return String::CaseInsensitiveCStringEquals(lhs, rhs); 109213481Sgiacomo.travaglini@arm.com} 109313481Sgiacomo.travaglini@arm.com 109413481Sgiacomo.travaglini@arm.cominline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, 109513481Sgiacomo.travaglini@arm.com const wchar_t* rhs) { 109613481Sgiacomo.travaglini@arm.com return String::CaseInsensitiveWideCStringEquals(lhs, rhs); 109713481Sgiacomo.travaglini@arm.com} 109813481Sgiacomo.travaglini@arm.com 109913481Sgiacomo.travaglini@arm.com// String comparison for narrow or wide strings that can have embedded NUL 110013481Sgiacomo.travaglini@arm.com// characters. 110113481Sgiacomo.travaglini@arm.comtemplate <typename StringType> 110213481Sgiacomo.travaglini@arm.combool CaseInsensitiveStringEquals(const StringType& s1, 110313481Sgiacomo.travaglini@arm.com const StringType& s2) { 110413481Sgiacomo.travaglini@arm.com // Are the heads equal? 110513481Sgiacomo.travaglini@arm.com if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { 110613481Sgiacomo.travaglini@arm.com return false; 110713481Sgiacomo.travaglini@arm.com } 110813481Sgiacomo.travaglini@arm.com 110913481Sgiacomo.travaglini@arm.com // Skip the equal heads. 111013481Sgiacomo.travaglini@arm.com const typename StringType::value_type nul = 0; 111113481Sgiacomo.travaglini@arm.com const size_t i1 = s1.find(nul), i2 = s2.find(nul); 111213481Sgiacomo.travaglini@arm.com 111313481Sgiacomo.travaglini@arm.com // Are we at the end of either s1 or s2? 111413481Sgiacomo.travaglini@arm.com if (i1 == StringType::npos || i2 == StringType::npos) { 111513481Sgiacomo.travaglini@arm.com return i1 == i2; 111613481Sgiacomo.travaglini@arm.com } 111713481Sgiacomo.travaglini@arm.com 111813481Sgiacomo.travaglini@arm.com // Are the tails equal? 111913481Sgiacomo.travaglini@arm.com return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); 112013481Sgiacomo.travaglini@arm.com} 112113481Sgiacomo.travaglini@arm.com 112213481Sgiacomo.travaglini@arm.com// String matchers. 112313481Sgiacomo.travaglini@arm.com 112413481Sgiacomo.travaglini@arm.com// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. 112513481Sgiacomo.travaglini@arm.comtemplate <typename StringType> 112613481Sgiacomo.travaglini@arm.comclass StrEqualityMatcher { 112713481Sgiacomo.travaglini@arm.com public: 112813481Sgiacomo.travaglini@arm.com StrEqualityMatcher(const StringType& str, bool expect_eq, 112913481Sgiacomo.travaglini@arm.com bool case_sensitive) 113013481Sgiacomo.travaglini@arm.com : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} 113113481Sgiacomo.travaglini@arm.com 113213481Sgiacomo.travaglini@arm.com // Accepts pointer types, particularly: 113313481Sgiacomo.travaglini@arm.com // const char* 113413481Sgiacomo.travaglini@arm.com // char* 113513481Sgiacomo.travaglini@arm.com // const wchar_t* 113613481Sgiacomo.travaglini@arm.com // wchar_t* 113713481Sgiacomo.travaglini@arm.com template <typename CharType> 113813481Sgiacomo.travaglini@arm.com bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { 113913481Sgiacomo.travaglini@arm.com if (s == NULL) { 114013481Sgiacomo.travaglini@arm.com return !expect_eq_; 114113481Sgiacomo.travaglini@arm.com } 114213481Sgiacomo.travaglini@arm.com return MatchAndExplain(StringType(s), listener); 114313481Sgiacomo.travaglini@arm.com } 114413481Sgiacomo.travaglini@arm.com 114513481Sgiacomo.travaglini@arm.com // Matches anything that can convert to StringType. 114613481Sgiacomo.travaglini@arm.com // 114713481Sgiacomo.travaglini@arm.com // This is a template, not just a plain function with const StringType&, 114813481Sgiacomo.travaglini@arm.com // because StringPiece has some interfering non-explicit constructors. 114913481Sgiacomo.travaglini@arm.com template <typename MatcheeStringType> 115013481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const MatcheeStringType& s, 115113481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 115213481Sgiacomo.travaglini@arm.com const StringType& s2(s); 115313481Sgiacomo.travaglini@arm.com const bool eq = case_sensitive_ ? s2 == string_ : 115413481Sgiacomo.travaglini@arm.com CaseInsensitiveStringEquals(s2, string_); 115513481Sgiacomo.travaglini@arm.com return expect_eq_ == eq; 115613481Sgiacomo.travaglini@arm.com } 115713481Sgiacomo.travaglini@arm.com 115813481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 115913481Sgiacomo.travaglini@arm.com DescribeToHelper(expect_eq_, os); 116013481Sgiacomo.travaglini@arm.com } 116113481Sgiacomo.travaglini@arm.com 116213481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 116313481Sgiacomo.travaglini@arm.com DescribeToHelper(!expect_eq_, os); 116413481Sgiacomo.travaglini@arm.com } 116513481Sgiacomo.travaglini@arm.com 116613481Sgiacomo.travaglini@arm.com private: 116713481Sgiacomo.travaglini@arm.com void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { 116813481Sgiacomo.travaglini@arm.com *os << (expect_eq ? "is " : "isn't "); 116913481Sgiacomo.travaglini@arm.com *os << "equal to "; 117013481Sgiacomo.travaglini@arm.com if (!case_sensitive_) { 117113481Sgiacomo.travaglini@arm.com *os << "(ignoring case) "; 117213481Sgiacomo.travaglini@arm.com } 117313481Sgiacomo.travaglini@arm.com UniversalPrint(string_, os); 117413481Sgiacomo.travaglini@arm.com } 117513481Sgiacomo.travaglini@arm.com 117613481Sgiacomo.travaglini@arm.com const StringType string_; 117713481Sgiacomo.travaglini@arm.com const bool expect_eq_; 117813481Sgiacomo.travaglini@arm.com const bool case_sensitive_; 117913481Sgiacomo.travaglini@arm.com 118013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); 118113481Sgiacomo.travaglini@arm.com}; 118213481Sgiacomo.travaglini@arm.com 118313481Sgiacomo.travaglini@arm.com// Implements the polymorphic HasSubstr(substring) matcher, which 118413481Sgiacomo.travaglini@arm.com// can be used as a Matcher<T> as long as T can be converted to a 118513481Sgiacomo.travaglini@arm.com// string. 118613481Sgiacomo.travaglini@arm.comtemplate <typename StringType> 118713481Sgiacomo.travaglini@arm.comclass HasSubstrMatcher { 118813481Sgiacomo.travaglini@arm.com public: 118913481Sgiacomo.travaglini@arm.com explicit HasSubstrMatcher(const StringType& substring) 119013481Sgiacomo.travaglini@arm.com : substring_(substring) {} 119113481Sgiacomo.travaglini@arm.com 119213481Sgiacomo.travaglini@arm.com // Accepts pointer types, particularly: 119313481Sgiacomo.travaglini@arm.com // const char* 119413481Sgiacomo.travaglini@arm.com // char* 119513481Sgiacomo.travaglini@arm.com // const wchar_t* 119613481Sgiacomo.travaglini@arm.com // wchar_t* 119713481Sgiacomo.travaglini@arm.com template <typename CharType> 119813481Sgiacomo.travaglini@arm.com bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { 119913481Sgiacomo.travaglini@arm.com return s != NULL && MatchAndExplain(StringType(s), listener); 120013481Sgiacomo.travaglini@arm.com } 120113481Sgiacomo.travaglini@arm.com 120213481Sgiacomo.travaglini@arm.com // Matches anything that can convert to StringType. 120313481Sgiacomo.travaglini@arm.com // 120413481Sgiacomo.travaglini@arm.com // This is a template, not just a plain function with const StringType&, 120513481Sgiacomo.travaglini@arm.com // because StringPiece has some interfering non-explicit constructors. 120613481Sgiacomo.travaglini@arm.com template <typename MatcheeStringType> 120713481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const MatcheeStringType& s, 120813481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 120913481Sgiacomo.travaglini@arm.com const StringType& s2(s); 121013481Sgiacomo.travaglini@arm.com return s2.find(substring_) != StringType::npos; 121113481Sgiacomo.travaglini@arm.com } 121213481Sgiacomo.travaglini@arm.com 121313481Sgiacomo.travaglini@arm.com // Describes what this matcher matches. 121413481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 121513481Sgiacomo.travaglini@arm.com *os << "has substring "; 121613481Sgiacomo.travaglini@arm.com UniversalPrint(substring_, os); 121713481Sgiacomo.travaglini@arm.com } 121813481Sgiacomo.travaglini@arm.com 121913481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 122013481Sgiacomo.travaglini@arm.com *os << "has no substring "; 122113481Sgiacomo.travaglini@arm.com UniversalPrint(substring_, os); 122213481Sgiacomo.travaglini@arm.com } 122313481Sgiacomo.travaglini@arm.com 122413481Sgiacomo.travaglini@arm.com private: 122513481Sgiacomo.travaglini@arm.com const StringType substring_; 122613481Sgiacomo.travaglini@arm.com 122713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); 122813481Sgiacomo.travaglini@arm.com}; 122913481Sgiacomo.travaglini@arm.com 123013481Sgiacomo.travaglini@arm.com// Implements the polymorphic StartsWith(substring) matcher, which 123113481Sgiacomo.travaglini@arm.com// can be used as a Matcher<T> as long as T can be converted to a 123213481Sgiacomo.travaglini@arm.com// string. 123313481Sgiacomo.travaglini@arm.comtemplate <typename StringType> 123413481Sgiacomo.travaglini@arm.comclass StartsWithMatcher { 123513481Sgiacomo.travaglini@arm.com public: 123613481Sgiacomo.travaglini@arm.com explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { 123713481Sgiacomo.travaglini@arm.com } 123813481Sgiacomo.travaglini@arm.com 123913481Sgiacomo.travaglini@arm.com // Accepts pointer types, particularly: 124013481Sgiacomo.travaglini@arm.com // const char* 124113481Sgiacomo.travaglini@arm.com // char* 124213481Sgiacomo.travaglini@arm.com // const wchar_t* 124313481Sgiacomo.travaglini@arm.com // wchar_t* 124413481Sgiacomo.travaglini@arm.com template <typename CharType> 124513481Sgiacomo.travaglini@arm.com bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { 124613481Sgiacomo.travaglini@arm.com return s != NULL && MatchAndExplain(StringType(s), listener); 124713481Sgiacomo.travaglini@arm.com } 124813481Sgiacomo.travaglini@arm.com 124913481Sgiacomo.travaglini@arm.com // Matches anything that can convert to StringType. 125013481Sgiacomo.travaglini@arm.com // 125113481Sgiacomo.travaglini@arm.com // This is a template, not just a plain function with const StringType&, 125213481Sgiacomo.travaglini@arm.com // because StringPiece has some interfering non-explicit constructors. 125313481Sgiacomo.travaglini@arm.com template <typename MatcheeStringType> 125413481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const MatcheeStringType& s, 125513481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 125613481Sgiacomo.travaglini@arm.com const StringType& s2(s); 125713481Sgiacomo.travaglini@arm.com return s2.length() >= prefix_.length() && 125813481Sgiacomo.travaglini@arm.com s2.substr(0, prefix_.length()) == prefix_; 125913481Sgiacomo.travaglini@arm.com } 126013481Sgiacomo.travaglini@arm.com 126113481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 126213481Sgiacomo.travaglini@arm.com *os << "starts with "; 126313481Sgiacomo.travaglini@arm.com UniversalPrint(prefix_, os); 126413481Sgiacomo.travaglini@arm.com } 126513481Sgiacomo.travaglini@arm.com 126613481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 126713481Sgiacomo.travaglini@arm.com *os << "doesn't start with "; 126813481Sgiacomo.travaglini@arm.com UniversalPrint(prefix_, os); 126913481Sgiacomo.travaglini@arm.com } 127013481Sgiacomo.travaglini@arm.com 127113481Sgiacomo.travaglini@arm.com private: 127213481Sgiacomo.travaglini@arm.com const StringType prefix_; 127313481Sgiacomo.travaglini@arm.com 127413481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); 127513481Sgiacomo.travaglini@arm.com}; 127613481Sgiacomo.travaglini@arm.com 127713481Sgiacomo.travaglini@arm.com// Implements the polymorphic EndsWith(substring) matcher, which 127813481Sgiacomo.travaglini@arm.com// can be used as a Matcher<T> as long as T can be converted to a 127913481Sgiacomo.travaglini@arm.com// string. 128013481Sgiacomo.travaglini@arm.comtemplate <typename StringType> 128113481Sgiacomo.travaglini@arm.comclass EndsWithMatcher { 128213481Sgiacomo.travaglini@arm.com public: 128313481Sgiacomo.travaglini@arm.com explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} 128413481Sgiacomo.travaglini@arm.com 128513481Sgiacomo.travaglini@arm.com // Accepts pointer types, particularly: 128613481Sgiacomo.travaglini@arm.com // const char* 128713481Sgiacomo.travaglini@arm.com // char* 128813481Sgiacomo.travaglini@arm.com // const wchar_t* 128913481Sgiacomo.travaglini@arm.com // wchar_t* 129013481Sgiacomo.travaglini@arm.com template <typename CharType> 129113481Sgiacomo.travaglini@arm.com bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { 129213481Sgiacomo.travaglini@arm.com return s != NULL && MatchAndExplain(StringType(s), listener); 129313481Sgiacomo.travaglini@arm.com } 129413481Sgiacomo.travaglini@arm.com 129513481Sgiacomo.travaglini@arm.com // Matches anything that can convert to StringType. 129613481Sgiacomo.travaglini@arm.com // 129713481Sgiacomo.travaglini@arm.com // This is a template, not just a plain function with const StringType&, 129813481Sgiacomo.travaglini@arm.com // because StringPiece has some interfering non-explicit constructors. 129913481Sgiacomo.travaglini@arm.com template <typename MatcheeStringType> 130013481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const MatcheeStringType& s, 130113481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 130213481Sgiacomo.travaglini@arm.com const StringType& s2(s); 130313481Sgiacomo.travaglini@arm.com return s2.length() >= suffix_.length() && 130413481Sgiacomo.travaglini@arm.com s2.substr(s2.length() - suffix_.length()) == suffix_; 130513481Sgiacomo.travaglini@arm.com } 130613481Sgiacomo.travaglini@arm.com 130713481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 130813481Sgiacomo.travaglini@arm.com *os << "ends with "; 130913481Sgiacomo.travaglini@arm.com UniversalPrint(suffix_, os); 131013481Sgiacomo.travaglini@arm.com } 131113481Sgiacomo.travaglini@arm.com 131213481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 131313481Sgiacomo.travaglini@arm.com *os << "doesn't end with "; 131413481Sgiacomo.travaglini@arm.com UniversalPrint(suffix_, os); 131513481Sgiacomo.travaglini@arm.com } 131613481Sgiacomo.travaglini@arm.com 131713481Sgiacomo.travaglini@arm.com private: 131813481Sgiacomo.travaglini@arm.com const StringType suffix_; 131913481Sgiacomo.travaglini@arm.com 132013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); 132113481Sgiacomo.travaglini@arm.com}; 132213481Sgiacomo.travaglini@arm.com 132313481Sgiacomo.travaglini@arm.com// Implements polymorphic matchers MatchesRegex(regex) and 132413481Sgiacomo.travaglini@arm.com// ContainsRegex(regex), which can be used as a Matcher<T> as long as 132513481Sgiacomo.travaglini@arm.com// T can be converted to a string. 132613481Sgiacomo.travaglini@arm.comclass MatchesRegexMatcher { 132713481Sgiacomo.travaglini@arm.com public: 132813481Sgiacomo.travaglini@arm.com MatchesRegexMatcher(const RE* regex, bool full_match) 132913481Sgiacomo.travaglini@arm.com : regex_(regex), full_match_(full_match) {} 133013481Sgiacomo.travaglini@arm.com 133113481Sgiacomo.travaglini@arm.com // Accepts pointer types, particularly: 133213481Sgiacomo.travaglini@arm.com // const char* 133313481Sgiacomo.travaglini@arm.com // char* 133413481Sgiacomo.travaglini@arm.com // const wchar_t* 133513481Sgiacomo.travaglini@arm.com // wchar_t* 133613481Sgiacomo.travaglini@arm.com template <typename CharType> 133713481Sgiacomo.travaglini@arm.com bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { 133813481Sgiacomo.travaglini@arm.com return s != NULL && MatchAndExplain(internal::string(s), listener); 133913481Sgiacomo.travaglini@arm.com } 134013481Sgiacomo.travaglini@arm.com 134113481Sgiacomo.travaglini@arm.com // Matches anything that can convert to internal::string. 134213481Sgiacomo.travaglini@arm.com // 134313481Sgiacomo.travaglini@arm.com // This is a template, not just a plain function with const internal::string&, 134413481Sgiacomo.travaglini@arm.com // because StringPiece has some interfering non-explicit constructors. 134513481Sgiacomo.travaglini@arm.com template <class MatcheeStringType> 134613481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const MatcheeStringType& s, 134713481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 134813481Sgiacomo.travaglini@arm.com const internal::string& s2(s); 134913481Sgiacomo.travaglini@arm.com return full_match_ ? RE::FullMatch(s2, *regex_) : 135013481Sgiacomo.travaglini@arm.com RE::PartialMatch(s2, *regex_); 135113481Sgiacomo.travaglini@arm.com } 135213481Sgiacomo.travaglini@arm.com 135313481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 135413481Sgiacomo.travaglini@arm.com *os << (full_match_ ? "matches" : "contains") 135513481Sgiacomo.travaglini@arm.com << " regular expression "; 135613481Sgiacomo.travaglini@arm.com UniversalPrinter<internal::string>::Print(regex_->pattern(), os); 135713481Sgiacomo.travaglini@arm.com } 135813481Sgiacomo.travaglini@arm.com 135913481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 136013481Sgiacomo.travaglini@arm.com *os << "doesn't " << (full_match_ ? "match" : "contain") 136113481Sgiacomo.travaglini@arm.com << " regular expression "; 136213481Sgiacomo.travaglini@arm.com UniversalPrinter<internal::string>::Print(regex_->pattern(), os); 136313481Sgiacomo.travaglini@arm.com } 136413481Sgiacomo.travaglini@arm.com 136513481Sgiacomo.travaglini@arm.com private: 136613481Sgiacomo.travaglini@arm.com const internal::linked_ptr<const RE> regex_; 136713481Sgiacomo.travaglini@arm.com const bool full_match_; 136813481Sgiacomo.travaglini@arm.com 136913481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); 137013481Sgiacomo.travaglini@arm.com}; 137113481Sgiacomo.travaglini@arm.com 137213481Sgiacomo.travaglini@arm.com// Implements a matcher that compares the two fields of a 2-tuple 137313481Sgiacomo.travaglini@arm.com// using one of the ==, <=, <, etc, operators. The two fields being 137413481Sgiacomo.travaglini@arm.com// compared don't have to have the same type. 137513481Sgiacomo.travaglini@arm.com// 137613481Sgiacomo.travaglini@arm.com// The matcher defined here is polymorphic (for example, Eq() can be 137713481Sgiacomo.travaglini@arm.com// used to match a tuple<int, short>, a tuple<const long&, double>, 137813481Sgiacomo.travaglini@arm.com// etc). Therefore we use a template type conversion operator in the 137913481Sgiacomo.travaglini@arm.com// implementation. 138013481Sgiacomo.travaglini@arm.comtemplate <typename D, typename Op> 138113481Sgiacomo.travaglini@arm.comclass PairMatchBase { 138213481Sgiacomo.travaglini@arm.com public: 138313481Sgiacomo.travaglini@arm.com template <typename T1, typename T2> 138413481Sgiacomo.travaglini@arm.com operator Matcher< ::testing::tuple<T1, T2> >() const { 138513481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl< ::testing::tuple<T1, T2> >); 138613481Sgiacomo.travaglini@arm.com } 138713481Sgiacomo.travaglini@arm.com template <typename T1, typename T2> 138813481Sgiacomo.travaglini@arm.com operator Matcher<const ::testing::tuple<T1, T2>&>() const { 138913481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<const ::testing::tuple<T1, T2>&>); 139013481Sgiacomo.travaglini@arm.com } 139113481Sgiacomo.travaglini@arm.com 139213481Sgiacomo.travaglini@arm.com private: 139313481Sgiacomo.travaglini@arm.com static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT 139413481Sgiacomo.travaglini@arm.com return os << D::Desc(); 139513481Sgiacomo.travaglini@arm.com } 139613481Sgiacomo.travaglini@arm.com 139713481Sgiacomo.travaglini@arm.com template <typename Tuple> 139813481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<Tuple> { 139913481Sgiacomo.travaglini@arm.com public: 140013481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain( 140113481Sgiacomo.travaglini@arm.com Tuple args, 140213481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 140313481Sgiacomo.travaglini@arm.com return Op()(::testing::get<0>(args), ::testing::get<1>(args)); 140413481Sgiacomo.travaglini@arm.com } 140513481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 140613481Sgiacomo.travaglini@arm.com *os << "are " << GetDesc; 140713481Sgiacomo.travaglini@arm.com } 140813481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 140913481Sgiacomo.travaglini@arm.com *os << "aren't " << GetDesc; 141013481Sgiacomo.travaglini@arm.com } 141113481Sgiacomo.travaglini@arm.com }; 141213481Sgiacomo.travaglini@arm.com}; 141313481Sgiacomo.travaglini@arm.com 141413481Sgiacomo.travaglini@arm.comclass Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> { 141513481Sgiacomo.travaglini@arm.com public: 141613481Sgiacomo.travaglini@arm.com static const char* Desc() { return "an equal pair"; } 141713481Sgiacomo.travaglini@arm.com}; 141813481Sgiacomo.travaglini@arm.comclass Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> { 141913481Sgiacomo.travaglini@arm.com public: 142013481Sgiacomo.travaglini@arm.com static const char* Desc() { return "an unequal pair"; } 142113481Sgiacomo.travaglini@arm.com}; 142213481Sgiacomo.travaglini@arm.comclass Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> { 142313481Sgiacomo.travaglini@arm.com public: 142413481Sgiacomo.travaglini@arm.com static const char* Desc() { return "a pair where the first < the second"; } 142513481Sgiacomo.travaglini@arm.com}; 142613481Sgiacomo.travaglini@arm.comclass Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> { 142713481Sgiacomo.travaglini@arm.com public: 142813481Sgiacomo.travaglini@arm.com static const char* Desc() { return "a pair where the first > the second"; } 142913481Sgiacomo.travaglini@arm.com}; 143013481Sgiacomo.travaglini@arm.comclass Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> { 143113481Sgiacomo.travaglini@arm.com public: 143213481Sgiacomo.travaglini@arm.com static const char* Desc() { return "a pair where the first <= the second"; } 143313481Sgiacomo.travaglini@arm.com}; 143413481Sgiacomo.travaglini@arm.comclass Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { 143513481Sgiacomo.travaglini@arm.com public: 143613481Sgiacomo.travaglini@arm.com static const char* Desc() { return "a pair where the first >= the second"; } 143713481Sgiacomo.travaglini@arm.com}; 143813481Sgiacomo.travaglini@arm.com 143913481Sgiacomo.travaglini@arm.com// Implements the Not(...) matcher for a particular argument type T. 144013481Sgiacomo.travaglini@arm.com// We do not nest it inside the NotMatcher class template, as that 144113481Sgiacomo.travaglini@arm.com// will prevent different instantiations of NotMatcher from sharing 144213481Sgiacomo.travaglini@arm.com// the same NotMatcherImpl<T> class. 144313481Sgiacomo.travaglini@arm.comtemplate <typename T> 144413481Sgiacomo.travaglini@arm.comclass NotMatcherImpl : public MatcherInterface<T> { 144513481Sgiacomo.travaglini@arm.com public: 144613481Sgiacomo.travaglini@arm.com explicit NotMatcherImpl(const Matcher<T>& matcher) 144713481Sgiacomo.travaglini@arm.com : matcher_(matcher) {} 144813481Sgiacomo.travaglini@arm.com 144913481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { 145013481Sgiacomo.travaglini@arm.com return !matcher_.MatchAndExplain(x, listener); 145113481Sgiacomo.travaglini@arm.com } 145213481Sgiacomo.travaglini@arm.com 145313481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 145413481Sgiacomo.travaglini@arm.com matcher_.DescribeNegationTo(os); 145513481Sgiacomo.travaglini@arm.com } 145613481Sgiacomo.travaglini@arm.com 145713481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 145813481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 145913481Sgiacomo.travaglini@arm.com } 146013481Sgiacomo.travaglini@arm.com 146113481Sgiacomo.travaglini@arm.com private: 146213481Sgiacomo.travaglini@arm.com const Matcher<T> matcher_; 146313481Sgiacomo.travaglini@arm.com 146413481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); 146513481Sgiacomo.travaglini@arm.com}; 146613481Sgiacomo.travaglini@arm.com 146713481Sgiacomo.travaglini@arm.com// Implements the Not(m) matcher, which matches a value that doesn't 146813481Sgiacomo.travaglini@arm.com// match matcher m. 146913481Sgiacomo.travaglini@arm.comtemplate <typename InnerMatcher> 147013481Sgiacomo.travaglini@arm.comclass NotMatcher { 147113481Sgiacomo.travaglini@arm.com public: 147213481Sgiacomo.travaglini@arm.com explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} 147313481Sgiacomo.travaglini@arm.com 147413481Sgiacomo.travaglini@arm.com // This template type conversion operator allows Not(m) to be used 147513481Sgiacomo.travaglini@arm.com // to match any type m can match. 147613481Sgiacomo.travaglini@arm.com template <typename T> 147713481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 147813481Sgiacomo.travaglini@arm.com return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_))); 147913481Sgiacomo.travaglini@arm.com } 148013481Sgiacomo.travaglini@arm.com 148113481Sgiacomo.travaglini@arm.com private: 148213481Sgiacomo.travaglini@arm.com InnerMatcher matcher_; 148313481Sgiacomo.travaglini@arm.com 148413481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(NotMatcher); 148513481Sgiacomo.travaglini@arm.com}; 148613481Sgiacomo.travaglini@arm.com 148713481Sgiacomo.travaglini@arm.com// Implements the AllOf(m1, m2) matcher for a particular argument type 148813481Sgiacomo.travaglini@arm.com// T. We do not nest it inside the BothOfMatcher class template, as 148913481Sgiacomo.travaglini@arm.com// that will prevent different instantiations of BothOfMatcher from 149013481Sgiacomo.travaglini@arm.com// sharing the same BothOfMatcherImpl<T> class. 149113481Sgiacomo.travaglini@arm.comtemplate <typename T> 149213481Sgiacomo.travaglini@arm.comclass BothOfMatcherImpl : public MatcherInterface<T> { 149313481Sgiacomo.travaglini@arm.com public: 149413481Sgiacomo.travaglini@arm.com BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) 149513481Sgiacomo.travaglini@arm.com : matcher1_(matcher1), matcher2_(matcher2) {} 149613481Sgiacomo.travaglini@arm.com 149713481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 149813481Sgiacomo.travaglini@arm.com *os << "("; 149913481Sgiacomo.travaglini@arm.com matcher1_.DescribeTo(os); 150013481Sgiacomo.travaglini@arm.com *os << ") and ("; 150113481Sgiacomo.travaglini@arm.com matcher2_.DescribeTo(os); 150213481Sgiacomo.travaglini@arm.com *os << ")"; 150313481Sgiacomo.travaglini@arm.com } 150413481Sgiacomo.travaglini@arm.com 150513481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 150613481Sgiacomo.travaglini@arm.com *os << "("; 150713481Sgiacomo.travaglini@arm.com matcher1_.DescribeNegationTo(os); 150813481Sgiacomo.travaglini@arm.com *os << ") or ("; 150913481Sgiacomo.travaglini@arm.com matcher2_.DescribeNegationTo(os); 151013481Sgiacomo.travaglini@arm.com *os << ")"; 151113481Sgiacomo.travaglini@arm.com } 151213481Sgiacomo.travaglini@arm.com 151313481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { 151413481Sgiacomo.travaglini@arm.com // If either matcher1_ or matcher2_ doesn't match x, we only need 151513481Sgiacomo.travaglini@arm.com // to explain why one of them fails. 151613481Sgiacomo.travaglini@arm.com StringMatchResultListener listener1; 151713481Sgiacomo.travaglini@arm.com if (!matcher1_.MatchAndExplain(x, &listener1)) { 151813481Sgiacomo.travaglini@arm.com *listener << listener1.str(); 151913481Sgiacomo.travaglini@arm.com return false; 152013481Sgiacomo.travaglini@arm.com } 152113481Sgiacomo.travaglini@arm.com 152213481Sgiacomo.travaglini@arm.com StringMatchResultListener listener2; 152313481Sgiacomo.travaglini@arm.com if (!matcher2_.MatchAndExplain(x, &listener2)) { 152413481Sgiacomo.travaglini@arm.com *listener << listener2.str(); 152513481Sgiacomo.travaglini@arm.com return false; 152613481Sgiacomo.travaglini@arm.com } 152713481Sgiacomo.travaglini@arm.com 152813481Sgiacomo.travaglini@arm.com // Otherwise we need to explain why *both* of them match. 152913481Sgiacomo.travaglini@arm.com const internal::string s1 = listener1.str(); 153013481Sgiacomo.travaglini@arm.com const internal::string s2 = listener2.str(); 153113481Sgiacomo.travaglini@arm.com 153213481Sgiacomo.travaglini@arm.com if (s1 == "") { 153313481Sgiacomo.travaglini@arm.com *listener << s2; 153413481Sgiacomo.travaglini@arm.com } else { 153513481Sgiacomo.travaglini@arm.com *listener << s1; 153613481Sgiacomo.travaglini@arm.com if (s2 != "") { 153713481Sgiacomo.travaglini@arm.com *listener << ", and " << s2; 153813481Sgiacomo.travaglini@arm.com } 153913481Sgiacomo.travaglini@arm.com } 154013481Sgiacomo.travaglini@arm.com return true; 154113481Sgiacomo.travaglini@arm.com } 154213481Sgiacomo.travaglini@arm.com 154313481Sgiacomo.travaglini@arm.com private: 154413481Sgiacomo.travaglini@arm.com const Matcher<T> matcher1_; 154513481Sgiacomo.travaglini@arm.com const Matcher<T> matcher2_; 154613481Sgiacomo.travaglini@arm.com 154713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl); 154813481Sgiacomo.travaglini@arm.com}; 154913481Sgiacomo.travaglini@arm.com 155013481Sgiacomo.travaglini@arm.com#if GTEST_LANG_CXX11 155113481Sgiacomo.travaglini@arm.com// MatcherList provides mechanisms for storing a variable number of matchers in 155213481Sgiacomo.travaglini@arm.com// a list structure (ListType) and creating a combining matcher from such a 155313481Sgiacomo.travaglini@arm.com// list. 155413481Sgiacomo.travaglini@arm.com// The template is defined recursively using the following template paramters: 155513481Sgiacomo.travaglini@arm.com// * kSize is the length of the MatcherList. 155613481Sgiacomo.travaglini@arm.com// * Head is the type of the first matcher of the list. 155713481Sgiacomo.travaglini@arm.com// * Tail denotes the types of the remaining matchers of the list. 155813481Sgiacomo.travaglini@arm.comtemplate <int kSize, typename Head, typename... Tail> 155913481Sgiacomo.travaglini@arm.comstruct MatcherList { 156013481Sgiacomo.travaglini@arm.com typedef MatcherList<kSize - 1, Tail...> MatcherListTail; 156113481Sgiacomo.travaglini@arm.com typedef ::std::pair<Head, typename MatcherListTail::ListType> ListType; 156213481Sgiacomo.travaglini@arm.com 156313481Sgiacomo.travaglini@arm.com // BuildList stores variadic type values in a nested pair structure. 156413481Sgiacomo.travaglini@arm.com // Example: 156513481Sgiacomo.travaglini@arm.com // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return 156613481Sgiacomo.travaglini@arm.com // the corresponding result of type pair<int, pair<string, float>>. 156713481Sgiacomo.travaglini@arm.com static ListType BuildList(const Head& matcher, const Tail&... tail) { 156813481Sgiacomo.travaglini@arm.com return ListType(matcher, MatcherListTail::BuildList(tail...)); 156913481Sgiacomo.travaglini@arm.com } 157013481Sgiacomo.travaglini@arm.com 157113481Sgiacomo.travaglini@arm.com // CreateMatcher<T> creates a Matcher<T> from a given list of matchers (built 157213481Sgiacomo.travaglini@arm.com // by BuildList()). CombiningMatcher<T> is used to combine the matchers of the 157313481Sgiacomo.travaglini@arm.com // list. CombiningMatcher<T> must implement MatcherInterface<T> and have a 157413481Sgiacomo.travaglini@arm.com // constructor taking two Matcher<T>s as input. 157513481Sgiacomo.travaglini@arm.com template <typename T, template <typename /* T */> class CombiningMatcher> 157613481Sgiacomo.travaglini@arm.com static Matcher<T> CreateMatcher(const ListType& matchers) { 157713481Sgiacomo.travaglini@arm.com return Matcher<T>(new CombiningMatcher<T>( 157813481Sgiacomo.travaglini@arm.com SafeMatcherCast<T>(matchers.first), 157913481Sgiacomo.travaglini@arm.com MatcherListTail::template CreateMatcher<T, CombiningMatcher>( 158013481Sgiacomo.travaglini@arm.com matchers.second))); 158113481Sgiacomo.travaglini@arm.com } 158213481Sgiacomo.travaglini@arm.com}; 158313481Sgiacomo.travaglini@arm.com 158413481Sgiacomo.travaglini@arm.com// The following defines the base case for the recursive definition of 158513481Sgiacomo.travaglini@arm.com// MatcherList. 158613481Sgiacomo.travaglini@arm.comtemplate <typename Matcher1, typename Matcher2> 158713481Sgiacomo.travaglini@arm.comstruct MatcherList<2, Matcher1, Matcher2> { 158813481Sgiacomo.travaglini@arm.com typedef ::std::pair<Matcher1, Matcher2> ListType; 158913481Sgiacomo.travaglini@arm.com 159013481Sgiacomo.travaglini@arm.com static ListType BuildList(const Matcher1& matcher1, 159113481Sgiacomo.travaglini@arm.com const Matcher2& matcher2) { 159213481Sgiacomo.travaglini@arm.com return ::std::pair<Matcher1, Matcher2>(matcher1, matcher2); 159313481Sgiacomo.travaglini@arm.com } 159413481Sgiacomo.travaglini@arm.com 159513481Sgiacomo.travaglini@arm.com template <typename T, template <typename /* T */> class CombiningMatcher> 159613481Sgiacomo.travaglini@arm.com static Matcher<T> CreateMatcher(const ListType& matchers) { 159713481Sgiacomo.travaglini@arm.com return Matcher<T>(new CombiningMatcher<T>( 159813481Sgiacomo.travaglini@arm.com SafeMatcherCast<T>(matchers.first), 159913481Sgiacomo.travaglini@arm.com SafeMatcherCast<T>(matchers.second))); 160013481Sgiacomo.travaglini@arm.com } 160113481Sgiacomo.travaglini@arm.com}; 160213481Sgiacomo.travaglini@arm.com 160313481Sgiacomo.travaglini@arm.com// VariadicMatcher is used for the variadic implementation of 160413481Sgiacomo.travaglini@arm.com// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). 160513481Sgiacomo.travaglini@arm.com// CombiningMatcher<T> is used to recursively combine the provided matchers 160613481Sgiacomo.travaglini@arm.com// (of type Args...). 160713481Sgiacomo.travaglini@arm.comtemplate <template <typename T> class CombiningMatcher, typename... Args> 160813481Sgiacomo.travaglini@arm.comclass VariadicMatcher { 160913481Sgiacomo.travaglini@arm.com public: 161013481Sgiacomo.travaglini@arm.com VariadicMatcher(const Args&... matchers) // NOLINT 161113481Sgiacomo.travaglini@arm.com : matchers_(MatcherListType::BuildList(matchers...)) {} 161213481Sgiacomo.travaglini@arm.com 161313481Sgiacomo.travaglini@arm.com // This template type conversion operator allows an 161413481Sgiacomo.travaglini@arm.com // VariadicMatcher<Matcher1, Matcher2...> object to match any type that 161513481Sgiacomo.travaglini@arm.com // all of the provided matchers (Matcher1, Matcher2, ...) can match. 161613481Sgiacomo.travaglini@arm.com template <typename T> 161713481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 161813481Sgiacomo.travaglini@arm.com return MatcherListType::template CreateMatcher<T, CombiningMatcher>( 161913481Sgiacomo.travaglini@arm.com matchers_); 162013481Sgiacomo.travaglini@arm.com } 162113481Sgiacomo.travaglini@arm.com 162213481Sgiacomo.travaglini@arm.com private: 162313481Sgiacomo.travaglini@arm.com typedef MatcherList<sizeof...(Args), Args...> MatcherListType; 162413481Sgiacomo.travaglini@arm.com 162513481Sgiacomo.travaglini@arm.com const typename MatcherListType::ListType matchers_; 162613481Sgiacomo.travaglini@arm.com 162713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(VariadicMatcher); 162813481Sgiacomo.travaglini@arm.com}; 162913481Sgiacomo.travaglini@arm.com 163013481Sgiacomo.travaglini@arm.comtemplate <typename... Args> 163113481Sgiacomo.travaglini@arm.comusing AllOfMatcher = VariadicMatcher<BothOfMatcherImpl, Args...>; 163213481Sgiacomo.travaglini@arm.com 163313481Sgiacomo.travaglini@arm.com#endif // GTEST_LANG_CXX11 163413481Sgiacomo.travaglini@arm.com 163513481Sgiacomo.travaglini@arm.com// Used for implementing the AllOf(m_1, ..., m_n) matcher, which 163613481Sgiacomo.travaglini@arm.com// matches a value that matches all of the matchers m_1, ..., and m_n. 163713481Sgiacomo.travaglini@arm.comtemplate <typename Matcher1, typename Matcher2> 163813481Sgiacomo.travaglini@arm.comclass BothOfMatcher { 163913481Sgiacomo.travaglini@arm.com public: 164013481Sgiacomo.travaglini@arm.com BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2) 164113481Sgiacomo.travaglini@arm.com : matcher1_(matcher1), matcher2_(matcher2) {} 164213481Sgiacomo.travaglini@arm.com 164313481Sgiacomo.travaglini@arm.com // This template type conversion operator allows a 164413481Sgiacomo.travaglini@arm.com // BothOfMatcher<Matcher1, Matcher2> object to match any type that 164513481Sgiacomo.travaglini@arm.com // both Matcher1 and Matcher2 can match. 164613481Sgiacomo.travaglini@arm.com template <typename T> 164713481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 164813481Sgiacomo.travaglini@arm.com return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_), 164913481Sgiacomo.travaglini@arm.com SafeMatcherCast<T>(matcher2_))); 165013481Sgiacomo.travaglini@arm.com } 165113481Sgiacomo.travaglini@arm.com 165213481Sgiacomo.travaglini@arm.com private: 165313481Sgiacomo.travaglini@arm.com Matcher1 matcher1_; 165413481Sgiacomo.travaglini@arm.com Matcher2 matcher2_; 165513481Sgiacomo.travaglini@arm.com 165613481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(BothOfMatcher); 165713481Sgiacomo.travaglini@arm.com}; 165813481Sgiacomo.travaglini@arm.com 165913481Sgiacomo.travaglini@arm.com// Implements the AnyOf(m1, m2) matcher for a particular argument type 166013481Sgiacomo.travaglini@arm.com// T. We do not nest it inside the AnyOfMatcher class template, as 166113481Sgiacomo.travaglini@arm.com// that will prevent different instantiations of AnyOfMatcher from 166213481Sgiacomo.travaglini@arm.com// sharing the same EitherOfMatcherImpl<T> class. 166313481Sgiacomo.travaglini@arm.comtemplate <typename T> 166413481Sgiacomo.travaglini@arm.comclass EitherOfMatcherImpl : public MatcherInterface<T> { 166513481Sgiacomo.travaglini@arm.com public: 166613481Sgiacomo.travaglini@arm.com EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) 166713481Sgiacomo.travaglini@arm.com : matcher1_(matcher1), matcher2_(matcher2) {} 166813481Sgiacomo.travaglini@arm.com 166913481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 167013481Sgiacomo.travaglini@arm.com *os << "("; 167113481Sgiacomo.travaglini@arm.com matcher1_.DescribeTo(os); 167213481Sgiacomo.travaglini@arm.com *os << ") or ("; 167313481Sgiacomo.travaglini@arm.com matcher2_.DescribeTo(os); 167413481Sgiacomo.travaglini@arm.com *os << ")"; 167513481Sgiacomo.travaglini@arm.com } 167613481Sgiacomo.travaglini@arm.com 167713481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 167813481Sgiacomo.travaglini@arm.com *os << "("; 167913481Sgiacomo.travaglini@arm.com matcher1_.DescribeNegationTo(os); 168013481Sgiacomo.travaglini@arm.com *os << ") and ("; 168113481Sgiacomo.travaglini@arm.com matcher2_.DescribeNegationTo(os); 168213481Sgiacomo.travaglini@arm.com *os << ")"; 168313481Sgiacomo.travaglini@arm.com } 168413481Sgiacomo.travaglini@arm.com 168513481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { 168613481Sgiacomo.travaglini@arm.com // If either matcher1_ or matcher2_ matches x, we just need to 168713481Sgiacomo.travaglini@arm.com // explain why *one* of them matches. 168813481Sgiacomo.travaglini@arm.com StringMatchResultListener listener1; 168913481Sgiacomo.travaglini@arm.com if (matcher1_.MatchAndExplain(x, &listener1)) { 169013481Sgiacomo.travaglini@arm.com *listener << listener1.str(); 169113481Sgiacomo.travaglini@arm.com return true; 169213481Sgiacomo.travaglini@arm.com } 169313481Sgiacomo.travaglini@arm.com 169413481Sgiacomo.travaglini@arm.com StringMatchResultListener listener2; 169513481Sgiacomo.travaglini@arm.com if (matcher2_.MatchAndExplain(x, &listener2)) { 169613481Sgiacomo.travaglini@arm.com *listener << listener2.str(); 169713481Sgiacomo.travaglini@arm.com return true; 169813481Sgiacomo.travaglini@arm.com } 169913481Sgiacomo.travaglini@arm.com 170013481Sgiacomo.travaglini@arm.com // Otherwise we need to explain why *both* of them fail. 170113481Sgiacomo.travaglini@arm.com const internal::string s1 = listener1.str(); 170213481Sgiacomo.travaglini@arm.com const internal::string s2 = listener2.str(); 170313481Sgiacomo.travaglini@arm.com 170413481Sgiacomo.travaglini@arm.com if (s1 == "") { 170513481Sgiacomo.travaglini@arm.com *listener << s2; 170613481Sgiacomo.travaglini@arm.com } else { 170713481Sgiacomo.travaglini@arm.com *listener << s1; 170813481Sgiacomo.travaglini@arm.com if (s2 != "") { 170913481Sgiacomo.travaglini@arm.com *listener << ", and " << s2; 171013481Sgiacomo.travaglini@arm.com } 171113481Sgiacomo.travaglini@arm.com } 171213481Sgiacomo.travaglini@arm.com return false; 171313481Sgiacomo.travaglini@arm.com } 171413481Sgiacomo.travaglini@arm.com 171513481Sgiacomo.travaglini@arm.com private: 171613481Sgiacomo.travaglini@arm.com const Matcher<T> matcher1_; 171713481Sgiacomo.travaglini@arm.com const Matcher<T> matcher2_; 171813481Sgiacomo.travaglini@arm.com 171913481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl); 172013481Sgiacomo.travaglini@arm.com}; 172113481Sgiacomo.travaglini@arm.com 172213481Sgiacomo.travaglini@arm.com#if GTEST_LANG_CXX11 172313481Sgiacomo.travaglini@arm.com// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). 172413481Sgiacomo.travaglini@arm.comtemplate <typename... Args> 172513481Sgiacomo.travaglini@arm.comusing AnyOfMatcher = VariadicMatcher<EitherOfMatcherImpl, Args...>; 172613481Sgiacomo.travaglini@arm.com 172713481Sgiacomo.travaglini@arm.com#endif // GTEST_LANG_CXX11 172813481Sgiacomo.travaglini@arm.com 172913481Sgiacomo.travaglini@arm.com// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which 173013481Sgiacomo.travaglini@arm.com// matches a value that matches at least one of the matchers m_1, ..., 173113481Sgiacomo.travaglini@arm.com// and m_n. 173213481Sgiacomo.travaglini@arm.comtemplate <typename Matcher1, typename Matcher2> 173313481Sgiacomo.travaglini@arm.comclass EitherOfMatcher { 173413481Sgiacomo.travaglini@arm.com public: 173513481Sgiacomo.travaglini@arm.com EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2) 173613481Sgiacomo.travaglini@arm.com : matcher1_(matcher1), matcher2_(matcher2) {} 173713481Sgiacomo.travaglini@arm.com 173813481Sgiacomo.travaglini@arm.com // This template type conversion operator allows a 173913481Sgiacomo.travaglini@arm.com // EitherOfMatcher<Matcher1, Matcher2> object to match any type that 174013481Sgiacomo.travaglini@arm.com // both Matcher1 and Matcher2 can match. 174113481Sgiacomo.travaglini@arm.com template <typename T> 174213481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 174313481Sgiacomo.travaglini@arm.com return Matcher<T>(new EitherOfMatcherImpl<T>( 174413481Sgiacomo.travaglini@arm.com SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_))); 174513481Sgiacomo.travaglini@arm.com } 174613481Sgiacomo.travaglini@arm.com 174713481Sgiacomo.travaglini@arm.com private: 174813481Sgiacomo.travaglini@arm.com Matcher1 matcher1_; 174913481Sgiacomo.travaglini@arm.com Matcher2 matcher2_; 175013481Sgiacomo.travaglini@arm.com 175113481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(EitherOfMatcher); 175213481Sgiacomo.travaglini@arm.com}; 175313481Sgiacomo.travaglini@arm.com 175413481Sgiacomo.travaglini@arm.com// Used for implementing Truly(pred), which turns a predicate into a 175513481Sgiacomo.travaglini@arm.com// matcher. 175613481Sgiacomo.travaglini@arm.comtemplate <typename Predicate> 175713481Sgiacomo.travaglini@arm.comclass TrulyMatcher { 175813481Sgiacomo.travaglini@arm.com public: 175913481Sgiacomo.travaglini@arm.com explicit TrulyMatcher(Predicate pred) : predicate_(pred) {} 176013481Sgiacomo.travaglini@arm.com 176113481Sgiacomo.travaglini@arm.com // This method template allows Truly(pred) to be used as a matcher 176213481Sgiacomo.travaglini@arm.com // for type T where T is the argument type of predicate 'pred'. The 176313481Sgiacomo.travaglini@arm.com // argument is passed by reference as the predicate may be 176413481Sgiacomo.travaglini@arm.com // interested in the address of the argument. 176513481Sgiacomo.travaglini@arm.com template <typename T> 176613481Sgiacomo.travaglini@arm.com bool MatchAndExplain(T& x, // NOLINT 176713481Sgiacomo.travaglini@arm.com MatchResultListener* /* listener */) const { 176813481Sgiacomo.travaglini@arm.com // Without the if-statement, MSVC sometimes warns about converting 176913481Sgiacomo.travaglini@arm.com // a value to bool (warning 4800). 177013481Sgiacomo.travaglini@arm.com // 177113481Sgiacomo.travaglini@arm.com // We cannot write 'return !!predicate_(x);' as that doesn't work 177213481Sgiacomo.travaglini@arm.com // when predicate_(x) returns a class convertible to bool but 177313481Sgiacomo.travaglini@arm.com // having no operator!(). 177413481Sgiacomo.travaglini@arm.com if (predicate_(x)) 177513481Sgiacomo.travaglini@arm.com return true; 177613481Sgiacomo.travaglini@arm.com return false; 177713481Sgiacomo.travaglini@arm.com } 177813481Sgiacomo.travaglini@arm.com 177913481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 178013481Sgiacomo.travaglini@arm.com *os << "satisfies the given predicate"; 178113481Sgiacomo.travaglini@arm.com } 178213481Sgiacomo.travaglini@arm.com 178313481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 178413481Sgiacomo.travaglini@arm.com *os << "doesn't satisfy the given predicate"; 178513481Sgiacomo.travaglini@arm.com } 178613481Sgiacomo.travaglini@arm.com 178713481Sgiacomo.travaglini@arm.com private: 178813481Sgiacomo.travaglini@arm.com Predicate predicate_; 178913481Sgiacomo.travaglini@arm.com 179013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(TrulyMatcher); 179113481Sgiacomo.travaglini@arm.com}; 179213481Sgiacomo.travaglini@arm.com 179313481Sgiacomo.travaglini@arm.com// Used for implementing Matches(matcher), which turns a matcher into 179413481Sgiacomo.travaglini@arm.com// a predicate. 179513481Sgiacomo.travaglini@arm.comtemplate <typename M> 179613481Sgiacomo.travaglini@arm.comclass MatcherAsPredicate { 179713481Sgiacomo.travaglini@arm.com public: 179813481Sgiacomo.travaglini@arm.com explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {} 179913481Sgiacomo.travaglini@arm.com 180013481Sgiacomo.travaglini@arm.com // This template operator() allows Matches(m) to be used as a 180113481Sgiacomo.travaglini@arm.com // predicate on type T where m is a matcher on type T. 180213481Sgiacomo.travaglini@arm.com // 180313481Sgiacomo.travaglini@arm.com // The argument x is passed by reference instead of by value, as 180413481Sgiacomo.travaglini@arm.com // some matcher may be interested in its address (e.g. as in 180513481Sgiacomo.travaglini@arm.com // Matches(Ref(n))(x)). 180613481Sgiacomo.travaglini@arm.com template <typename T> 180713481Sgiacomo.travaglini@arm.com bool operator()(const T& x) const { 180813481Sgiacomo.travaglini@arm.com // We let matcher_ commit to a particular type here instead of 180913481Sgiacomo.travaglini@arm.com // when the MatcherAsPredicate object was constructed. This 181013481Sgiacomo.travaglini@arm.com // allows us to write Matches(m) where m is a polymorphic matcher 181113481Sgiacomo.travaglini@arm.com // (e.g. Eq(5)). 181213481Sgiacomo.travaglini@arm.com // 181313481Sgiacomo.travaglini@arm.com // If we write Matcher<T>(matcher_).Matches(x) here, it won't 181413481Sgiacomo.travaglini@arm.com // compile when matcher_ has type Matcher<const T&>; if we write 181513481Sgiacomo.travaglini@arm.com // Matcher<const T&>(matcher_).Matches(x) here, it won't compile 181613481Sgiacomo.travaglini@arm.com // when matcher_ has type Matcher<T>; if we just write 181713481Sgiacomo.travaglini@arm.com // matcher_.Matches(x), it won't compile when matcher_ is 181813481Sgiacomo.travaglini@arm.com // polymorphic, e.g. Eq(5). 181913481Sgiacomo.travaglini@arm.com // 182013481Sgiacomo.travaglini@arm.com // MatcherCast<const T&>() is necessary for making the code work 182113481Sgiacomo.travaglini@arm.com // in all of the above situations. 182213481Sgiacomo.travaglini@arm.com return MatcherCast<const T&>(matcher_).Matches(x); 182313481Sgiacomo.travaglini@arm.com } 182413481Sgiacomo.travaglini@arm.com 182513481Sgiacomo.travaglini@arm.com private: 182613481Sgiacomo.travaglini@arm.com M matcher_; 182713481Sgiacomo.travaglini@arm.com 182813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate); 182913481Sgiacomo.travaglini@arm.com}; 183013481Sgiacomo.travaglini@arm.com 183113481Sgiacomo.travaglini@arm.com// For implementing ASSERT_THAT() and EXPECT_THAT(). The template 183213481Sgiacomo.travaglini@arm.com// argument M must be a type that can be converted to a matcher. 183313481Sgiacomo.travaglini@arm.comtemplate <typename M> 183413481Sgiacomo.travaglini@arm.comclass PredicateFormatterFromMatcher { 183513481Sgiacomo.travaglini@arm.com public: 183613481Sgiacomo.travaglini@arm.com explicit PredicateFormatterFromMatcher(M m) : matcher_(internal::move(m)) {} 183713481Sgiacomo.travaglini@arm.com 183813481Sgiacomo.travaglini@arm.com // This template () operator allows a PredicateFormatterFromMatcher 183913481Sgiacomo.travaglini@arm.com // object to act as a predicate-formatter suitable for using with 184013481Sgiacomo.travaglini@arm.com // Google Test's EXPECT_PRED_FORMAT1() macro. 184113481Sgiacomo.travaglini@arm.com template <typename T> 184213481Sgiacomo.travaglini@arm.com AssertionResult operator()(const char* value_text, const T& x) const { 184313481Sgiacomo.travaglini@arm.com // We convert matcher_ to a Matcher<const T&> *now* instead of 184413481Sgiacomo.travaglini@arm.com // when the PredicateFormatterFromMatcher object was constructed, 184513481Sgiacomo.travaglini@arm.com // as matcher_ may be polymorphic (e.g. NotNull()) and we won't 184613481Sgiacomo.travaglini@arm.com // know which type to instantiate it to until we actually see the 184713481Sgiacomo.travaglini@arm.com // type of x here. 184813481Sgiacomo.travaglini@arm.com // 184913481Sgiacomo.travaglini@arm.com // We write SafeMatcherCast<const T&>(matcher_) instead of 185013481Sgiacomo.travaglini@arm.com // Matcher<const T&>(matcher_), as the latter won't compile when 185113481Sgiacomo.travaglini@arm.com // matcher_ has type Matcher<T> (e.g. An<int>()). 185213481Sgiacomo.travaglini@arm.com // We don't write MatcherCast<const T&> either, as that allows 185313481Sgiacomo.travaglini@arm.com // potentially unsafe downcasting of the matcher argument. 185413481Sgiacomo.travaglini@arm.com const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_); 185513481Sgiacomo.travaglini@arm.com StringMatchResultListener listener; 185613481Sgiacomo.travaglini@arm.com if (MatchPrintAndExplain(x, matcher, &listener)) 185713481Sgiacomo.travaglini@arm.com return AssertionSuccess(); 185813481Sgiacomo.travaglini@arm.com 185913481Sgiacomo.travaglini@arm.com ::std::stringstream ss; 186013481Sgiacomo.travaglini@arm.com ss << "Value of: " << value_text << "\n" 186113481Sgiacomo.travaglini@arm.com << "Expected: "; 186213481Sgiacomo.travaglini@arm.com matcher.DescribeTo(&ss); 186313481Sgiacomo.travaglini@arm.com ss << "\n Actual: " << listener.str(); 186413481Sgiacomo.travaglini@arm.com return AssertionFailure() << ss.str(); 186513481Sgiacomo.travaglini@arm.com } 186613481Sgiacomo.travaglini@arm.com 186713481Sgiacomo.travaglini@arm.com private: 186813481Sgiacomo.travaglini@arm.com const M matcher_; 186913481Sgiacomo.travaglini@arm.com 187013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher); 187113481Sgiacomo.travaglini@arm.com}; 187213481Sgiacomo.travaglini@arm.com 187313481Sgiacomo.travaglini@arm.com// A helper function for converting a matcher to a predicate-formatter 187413481Sgiacomo.travaglini@arm.com// without the user needing to explicitly write the type. This is 187513481Sgiacomo.travaglini@arm.com// used for implementing ASSERT_THAT() and EXPECT_THAT(). 187613481Sgiacomo.travaglini@arm.com// Implementation detail: 'matcher' is received by-value to force decaying. 187713481Sgiacomo.travaglini@arm.comtemplate <typename M> 187813481Sgiacomo.travaglini@arm.cominline PredicateFormatterFromMatcher<M> 187913481Sgiacomo.travaglini@arm.comMakePredicateFormatterFromMatcher(M matcher) { 188013481Sgiacomo.travaglini@arm.com return PredicateFormatterFromMatcher<M>(internal::move(matcher)); 188113481Sgiacomo.travaglini@arm.com} 188213481Sgiacomo.travaglini@arm.com 188313481Sgiacomo.travaglini@arm.com// Implements the polymorphic floating point equality matcher, which matches 188413481Sgiacomo.travaglini@arm.com// two float values using ULP-based approximation or, optionally, a 188513481Sgiacomo.travaglini@arm.com// user-specified epsilon. The template is meant to be instantiated with 188613481Sgiacomo.travaglini@arm.com// FloatType being either float or double. 188713481Sgiacomo.travaglini@arm.comtemplate <typename FloatType> 188813481Sgiacomo.travaglini@arm.comclass FloatingEqMatcher { 188913481Sgiacomo.travaglini@arm.com public: 189013481Sgiacomo.travaglini@arm.com // Constructor for FloatingEqMatcher. 189113481Sgiacomo.travaglini@arm.com // The matcher's input will be compared with expected. The matcher treats two 189213481Sgiacomo.travaglini@arm.com // NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards, 189313481Sgiacomo.travaglini@arm.com // equality comparisons between NANs will always return false. We specify a 189413481Sgiacomo.travaglini@arm.com // negative max_abs_error_ term to indicate that ULP-based approximation will 189513481Sgiacomo.travaglini@arm.com // be used for comparison. 189613481Sgiacomo.travaglini@arm.com FloatingEqMatcher(FloatType expected, bool nan_eq_nan) : 189713481Sgiacomo.travaglini@arm.com expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) { 189813481Sgiacomo.travaglini@arm.com } 189913481Sgiacomo.travaglini@arm.com 190013481Sgiacomo.travaglini@arm.com // Constructor that supports a user-specified max_abs_error that will be used 190113481Sgiacomo.travaglini@arm.com // for comparison instead of ULP-based approximation. The max absolute 190213481Sgiacomo.travaglini@arm.com // should be non-negative. 190313481Sgiacomo.travaglini@arm.com FloatingEqMatcher(FloatType expected, bool nan_eq_nan, 190413481Sgiacomo.travaglini@arm.com FloatType max_abs_error) 190513481Sgiacomo.travaglini@arm.com : expected_(expected), 190613481Sgiacomo.travaglini@arm.com nan_eq_nan_(nan_eq_nan), 190713481Sgiacomo.travaglini@arm.com max_abs_error_(max_abs_error) { 190813481Sgiacomo.travaglini@arm.com GTEST_CHECK_(max_abs_error >= 0) 190913481Sgiacomo.travaglini@arm.com << ", where max_abs_error is" << max_abs_error; 191013481Sgiacomo.travaglini@arm.com } 191113481Sgiacomo.travaglini@arm.com 191213481Sgiacomo.travaglini@arm.com // Implements floating point equality matcher as a Matcher<T>. 191313481Sgiacomo.travaglini@arm.com template <typename T> 191413481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<T> { 191513481Sgiacomo.travaglini@arm.com public: 191613481Sgiacomo.travaglini@arm.com Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error) 191713481Sgiacomo.travaglini@arm.com : expected_(expected), 191813481Sgiacomo.travaglini@arm.com nan_eq_nan_(nan_eq_nan), 191913481Sgiacomo.travaglini@arm.com max_abs_error_(max_abs_error) {} 192013481Sgiacomo.travaglini@arm.com 192113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T value, 192213481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 192313481Sgiacomo.travaglini@arm.com const FloatingPoint<FloatType> actual(value), expected(expected_); 192413481Sgiacomo.travaglini@arm.com 192513481Sgiacomo.travaglini@arm.com // Compares NaNs first, if nan_eq_nan_ is true. 192613481Sgiacomo.travaglini@arm.com if (actual.is_nan() || expected.is_nan()) { 192713481Sgiacomo.travaglini@arm.com if (actual.is_nan() && expected.is_nan()) { 192813481Sgiacomo.travaglini@arm.com return nan_eq_nan_; 192913481Sgiacomo.travaglini@arm.com } 193013481Sgiacomo.travaglini@arm.com // One is nan; the other is not nan. 193113481Sgiacomo.travaglini@arm.com return false; 193213481Sgiacomo.travaglini@arm.com } 193313481Sgiacomo.travaglini@arm.com if (HasMaxAbsError()) { 193413481Sgiacomo.travaglini@arm.com // We perform an equality check so that inf will match inf, regardless 193513481Sgiacomo.travaglini@arm.com // of error bounds. If the result of value - expected_ would result in 193613481Sgiacomo.travaglini@arm.com // overflow or if either value is inf, the default result is infinity, 193713481Sgiacomo.travaglini@arm.com // which should only match if max_abs_error_ is also infinity. 193813481Sgiacomo.travaglini@arm.com if (value == expected_) { 193913481Sgiacomo.travaglini@arm.com return true; 194013481Sgiacomo.travaglini@arm.com } 194113481Sgiacomo.travaglini@arm.com 194213481Sgiacomo.travaglini@arm.com const FloatType diff = value - expected_; 194313481Sgiacomo.travaglini@arm.com if (fabs(diff) <= max_abs_error_) { 194413481Sgiacomo.travaglini@arm.com return true; 194513481Sgiacomo.travaglini@arm.com } 194613481Sgiacomo.travaglini@arm.com 194713481Sgiacomo.travaglini@arm.com if (listener->IsInterested()) { 194813481Sgiacomo.travaglini@arm.com *listener << "which is " << diff << " from " << expected_; 194913481Sgiacomo.travaglini@arm.com } 195013481Sgiacomo.travaglini@arm.com return false; 195113481Sgiacomo.travaglini@arm.com } else { 195213481Sgiacomo.travaglini@arm.com return actual.AlmostEquals(expected); 195313481Sgiacomo.travaglini@arm.com } 195413481Sgiacomo.travaglini@arm.com } 195513481Sgiacomo.travaglini@arm.com 195613481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 195713481Sgiacomo.travaglini@arm.com // os->precision() returns the previously set precision, which we 195813481Sgiacomo.travaglini@arm.com // store to restore the ostream to its original configuration 195913481Sgiacomo.travaglini@arm.com // after outputting. 196013481Sgiacomo.travaglini@arm.com const ::std::streamsize old_precision = os->precision( 196113481Sgiacomo.travaglini@arm.com ::std::numeric_limits<FloatType>::digits10 + 2); 196213481Sgiacomo.travaglini@arm.com if (FloatingPoint<FloatType>(expected_).is_nan()) { 196313481Sgiacomo.travaglini@arm.com if (nan_eq_nan_) { 196413481Sgiacomo.travaglini@arm.com *os << "is NaN"; 196513481Sgiacomo.travaglini@arm.com } else { 196613481Sgiacomo.travaglini@arm.com *os << "never matches"; 196713481Sgiacomo.travaglini@arm.com } 196813481Sgiacomo.travaglini@arm.com } else { 196913481Sgiacomo.travaglini@arm.com *os << "is approximately " << expected_; 197013481Sgiacomo.travaglini@arm.com if (HasMaxAbsError()) { 197113481Sgiacomo.travaglini@arm.com *os << " (absolute error <= " << max_abs_error_ << ")"; 197213481Sgiacomo.travaglini@arm.com } 197313481Sgiacomo.travaglini@arm.com } 197413481Sgiacomo.travaglini@arm.com os->precision(old_precision); 197513481Sgiacomo.travaglini@arm.com } 197613481Sgiacomo.travaglini@arm.com 197713481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 197813481Sgiacomo.travaglini@arm.com // As before, get original precision. 197913481Sgiacomo.travaglini@arm.com const ::std::streamsize old_precision = os->precision( 198013481Sgiacomo.travaglini@arm.com ::std::numeric_limits<FloatType>::digits10 + 2); 198113481Sgiacomo.travaglini@arm.com if (FloatingPoint<FloatType>(expected_).is_nan()) { 198213481Sgiacomo.travaglini@arm.com if (nan_eq_nan_) { 198313481Sgiacomo.travaglini@arm.com *os << "isn't NaN"; 198413481Sgiacomo.travaglini@arm.com } else { 198513481Sgiacomo.travaglini@arm.com *os << "is anything"; 198613481Sgiacomo.travaglini@arm.com } 198713481Sgiacomo.travaglini@arm.com } else { 198813481Sgiacomo.travaglini@arm.com *os << "isn't approximately " << expected_; 198913481Sgiacomo.travaglini@arm.com if (HasMaxAbsError()) { 199013481Sgiacomo.travaglini@arm.com *os << " (absolute error > " << max_abs_error_ << ")"; 199113481Sgiacomo.travaglini@arm.com } 199213481Sgiacomo.travaglini@arm.com } 199313481Sgiacomo.travaglini@arm.com // Restore original precision. 199413481Sgiacomo.travaglini@arm.com os->precision(old_precision); 199513481Sgiacomo.travaglini@arm.com } 199613481Sgiacomo.travaglini@arm.com 199713481Sgiacomo.travaglini@arm.com private: 199813481Sgiacomo.travaglini@arm.com bool HasMaxAbsError() const { 199913481Sgiacomo.travaglini@arm.com return max_abs_error_ >= 0; 200013481Sgiacomo.travaglini@arm.com } 200113481Sgiacomo.travaglini@arm.com 200213481Sgiacomo.travaglini@arm.com const FloatType expected_; 200313481Sgiacomo.travaglini@arm.com const bool nan_eq_nan_; 200413481Sgiacomo.travaglini@arm.com // max_abs_error will be used for value comparison when >= 0. 200513481Sgiacomo.travaglini@arm.com const FloatType max_abs_error_; 200613481Sgiacomo.travaglini@arm.com 200713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 200813481Sgiacomo.travaglini@arm.com }; 200913481Sgiacomo.travaglini@arm.com 201013481Sgiacomo.travaglini@arm.com // The following 3 type conversion operators allow FloatEq(expected) and 201113481Sgiacomo.travaglini@arm.com // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a 201213481Sgiacomo.travaglini@arm.com // Matcher<const float&>, or a Matcher<float&>, but nothing else. 201313481Sgiacomo.travaglini@arm.com // (While Google's C++ coding style doesn't allow arguments passed 201413481Sgiacomo.travaglini@arm.com // by non-const reference, we may see them in code not conforming to 201513481Sgiacomo.travaglini@arm.com // the style. Therefore Google Mock needs to support them.) 201613481Sgiacomo.travaglini@arm.com operator Matcher<FloatType>() const { 201713481Sgiacomo.travaglini@arm.com return MakeMatcher( 201813481Sgiacomo.travaglini@arm.com new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); 201913481Sgiacomo.travaglini@arm.com } 202013481Sgiacomo.travaglini@arm.com 202113481Sgiacomo.travaglini@arm.com operator Matcher<const FloatType&>() const { 202213481Sgiacomo.travaglini@arm.com return MakeMatcher( 202313481Sgiacomo.travaglini@arm.com new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); 202413481Sgiacomo.travaglini@arm.com } 202513481Sgiacomo.travaglini@arm.com 202613481Sgiacomo.travaglini@arm.com operator Matcher<FloatType&>() const { 202713481Sgiacomo.travaglini@arm.com return MakeMatcher( 202813481Sgiacomo.travaglini@arm.com new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); 202913481Sgiacomo.travaglini@arm.com } 203013481Sgiacomo.travaglini@arm.com 203113481Sgiacomo.travaglini@arm.com private: 203213481Sgiacomo.travaglini@arm.com const FloatType expected_; 203313481Sgiacomo.travaglini@arm.com const bool nan_eq_nan_; 203413481Sgiacomo.travaglini@arm.com // max_abs_error will be used for value comparison when >= 0. 203513481Sgiacomo.travaglini@arm.com const FloatType max_abs_error_; 203613481Sgiacomo.travaglini@arm.com 203713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher); 203813481Sgiacomo.travaglini@arm.com}; 203913481Sgiacomo.travaglini@arm.com 204013481Sgiacomo.travaglini@arm.com// Implements the Pointee(m) matcher for matching a pointer whose 204113481Sgiacomo.travaglini@arm.com// pointee matches matcher m. The pointer can be either raw or smart. 204213481Sgiacomo.travaglini@arm.comtemplate <typename InnerMatcher> 204313481Sgiacomo.travaglini@arm.comclass PointeeMatcher { 204413481Sgiacomo.travaglini@arm.com public: 204513481Sgiacomo.travaglini@arm.com explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} 204613481Sgiacomo.travaglini@arm.com 204713481Sgiacomo.travaglini@arm.com // This type conversion operator template allows Pointee(m) to be 204813481Sgiacomo.travaglini@arm.com // used as a matcher for any pointer type whose pointee type is 204913481Sgiacomo.travaglini@arm.com // compatible with the inner matcher, where type Pointer can be 205013481Sgiacomo.travaglini@arm.com // either a raw pointer or a smart pointer. 205113481Sgiacomo.travaglini@arm.com // 205213481Sgiacomo.travaglini@arm.com // The reason we do this instead of relying on 205313481Sgiacomo.travaglini@arm.com // MakePolymorphicMatcher() is that the latter is not flexible 205413481Sgiacomo.travaglini@arm.com // enough for implementing the DescribeTo() method of Pointee(). 205513481Sgiacomo.travaglini@arm.com template <typename Pointer> 205613481Sgiacomo.travaglini@arm.com operator Matcher<Pointer>() const { 205713481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<Pointer>(matcher_)); 205813481Sgiacomo.travaglini@arm.com } 205913481Sgiacomo.travaglini@arm.com 206013481Sgiacomo.travaglini@arm.com private: 206113481Sgiacomo.travaglini@arm.com // The monomorphic implementation that works for a particular pointer type. 206213481Sgiacomo.travaglini@arm.com template <typename Pointer> 206313481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<Pointer> { 206413481Sgiacomo.travaglini@arm.com public: 206513481Sgiacomo.travaglini@arm.com typedef typename PointeeOf<GTEST_REMOVE_CONST_( // NOLINT 206613481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee; 206713481Sgiacomo.travaglini@arm.com 206813481Sgiacomo.travaglini@arm.com explicit Impl(const InnerMatcher& matcher) 206913481Sgiacomo.travaglini@arm.com : matcher_(MatcherCast<const Pointee&>(matcher)) {} 207013481Sgiacomo.travaglini@arm.com 207113481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 207213481Sgiacomo.travaglini@arm.com *os << "points to a value that "; 207313481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 207413481Sgiacomo.travaglini@arm.com } 207513481Sgiacomo.travaglini@arm.com 207613481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 207713481Sgiacomo.travaglini@arm.com *os << "does not point to a value that "; 207813481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 207913481Sgiacomo.travaglini@arm.com } 208013481Sgiacomo.travaglini@arm.com 208113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Pointer pointer, 208213481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 208313481Sgiacomo.travaglini@arm.com if (GetRawPointer(pointer) == NULL) 208413481Sgiacomo.travaglini@arm.com return false; 208513481Sgiacomo.travaglini@arm.com 208613481Sgiacomo.travaglini@arm.com *listener << "which points to "; 208713481Sgiacomo.travaglini@arm.com return MatchPrintAndExplain(*pointer, matcher_, listener); 208813481Sgiacomo.travaglini@arm.com } 208913481Sgiacomo.travaglini@arm.com 209013481Sgiacomo.travaglini@arm.com private: 209113481Sgiacomo.travaglini@arm.com const Matcher<const Pointee&> matcher_; 209213481Sgiacomo.travaglini@arm.com 209313481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 209413481Sgiacomo.travaglini@arm.com }; 209513481Sgiacomo.travaglini@arm.com 209613481Sgiacomo.travaglini@arm.com const InnerMatcher matcher_; 209713481Sgiacomo.travaglini@arm.com 209813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PointeeMatcher); 209913481Sgiacomo.travaglini@arm.com}; 210013481Sgiacomo.travaglini@arm.com 210113481Sgiacomo.travaglini@arm.com// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or 210213481Sgiacomo.travaglini@arm.com// reference that matches inner_matcher when dynamic_cast<T> is applied. 210313481Sgiacomo.travaglini@arm.com// The result of dynamic_cast<To> is forwarded to the inner matcher. 210413481Sgiacomo.travaglini@arm.com// If To is a pointer and the cast fails, the inner matcher will receive NULL. 210513481Sgiacomo.travaglini@arm.com// If To is a reference and the cast fails, this matcher returns false 210613481Sgiacomo.travaglini@arm.com// immediately. 210713481Sgiacomo.travaglini@arm.comtemplate <typename To> 210813481Sgiacomo.travaglini@arm.comclass WhenDynamicCastToMatcherBase { 210913481Sgiacomo.travaglini@arm.com public: 211013481Sgiacomo.travaglini@arm.com explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher) 211113481Sgiacomo.travaglini@arm.com : matcher_(matcher) {} 211213481Sgiacomo.travaglini@arm.com 211313481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 211413481Sgiacomo.travaglini@arm.com GetCastTypeDescription(os); 211513481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 211613481Sgiacomo.travaglini@arm.com } 211713481Sgiacomo.travaglini@arm.com 211813481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 211913481Sgiacomo.travaglini@arm.com GetCastTypeDescription(os); 212013481Sgiacomo.travaglini@arm.com matcher_.DescribeNegationTo(os); 212113481Sgiacomo.travaglini@arm.com } 212213481Sgiacomo.travaglini@arm.com 212313481Sgiacomo.travaglini@arm.com protected: 212413481Sgiacomo.travaglini@arm.com const Matcher<To> matcher_; 212513481Sgiacomo.travaglini@arm.com 212613481Sgiacomo.travaglini@arm.com static string GetToName() { 212713481Sgiacomo.travaglini@arm.com#if GTEST_HAS_RTTI 212813481Sgiacomo.travaglini@arm.com return GetTypeName<To>(); 212913481Sgiacomo.travaglini@arm.com#else // GTEST_HAS_RTTI 213013481Sgiacomo.travaglini@arm.com return "the target type"; 213113481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_RTTI 213213481Sgiacomo.travaglini@arm.com } 213313481Sgiacomo.travaglini@arm.com 213413481Sgiacomo.travaglini@arm.com private: 213513481Sgiacomo.travaglini@arm.com static void GetCastTypeDescription(::std::ostream* os) { 213613481Sgiacomo.travaglini@arm.com *os << "when dynamic_cast to " << GetToName() << ", "; 213713481Sgiacomo.travaglini@arm.com } 213813481Sgiacomo.travaglini@arm.com 213913481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase); 214013481Sgiacomo.travaglini@arm.com}; 214113481Sgiacomo.travaglini@arm.com 214213481Sgiacomo.travaglini@arm.com// Primary template. 214313481Sgiacomo.travaglini@arm.com// To is a pointer. Cast and forward the result. 214413481Sgiacomo.travaglini@arm.comtemplate <typename To> 214513481Sgiacomo.travaglini@arm.comclass WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { 214613481Sgiacomo.travaglini@arm.com public: 214713481Sgiacomo.travaglini@arm.com explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher) 214813481Sgiacomo.travaglini@arm.com : WhenDynamicCastToMatcherBase<To>(matcher) {} 214913481Sgiacomo.travaglini@arm.com 215013481Sgiacomo.travaglini@arm.com template <typename From> 215113481Sgiacomo.travaglini@arm.com bool MatchAndExplain(From from, MatchResultListener* listener) const { 215213481Sgiacomo.travaglini@arm.com // TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail? 215313481Sgiacomo.travaglini@arm.com To to = dynamic_cast<To>(from); 215413481Sgiacomo.travaglini@arm.com return MatchPrintAndExplain(to, this->matcher_, listener); 215513481Sgiacomo.travaglini@arm.com } 215613481Sgiacomo.travaglini@arm.com}; 215713481Sgiacomo.travaglini@arm.com 215813481Sgiacomo.travaglini@arm.com// Specialize for references. 215913481Sgiacomo.travaglini@arm.com// In this case we return false if the dynamic_cast fails. 216013481Sgiacomo.travaglini@arm.comtemplate <typename To> 216113481Sgiacomo.travaglini@arm.comclass WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { 216213481Sgiacomo.travaglini@arm.com public: 216313481Sgiacomo.travaglini@arm.com explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher) 216413481Sgiacomo.travaglini@arm.com : WhenDynamicCastToMatcherBase<To&>(matcher) {} 216513481Sgiacomo.travaglini@arm.com 216613481Sgiacomo.travaglini@arm.com template <typename From> 216713481Sgiacomo.travaglini@arm.com bool MatchAndExplain(From& from, MatchResultListener* listener) const { 216813481Sgiacomo.travaglini@arm.com // We don't want an std::bad_cast here, so do the cast with pointers. 216913481Sgiacomo.travaglini@arm.com To* to = dynamic_cast<To*>(&from); 217013481Sgiacomo.travaglini@arm.com if (to == NULL) { 217113481Sgiacomo.travaglini@arm.com *listener << "which cannot be dynamic_cast to " << this->GetToName(); 217213481Sgiacomo.travaglini@arm.com return false; 217313481Sgiacomo.travaglini@arm.com } 217413481Sgiacomo.travaglini@arm.com return MatchPrintAndExplain(*to, this->matcher_, listener); 217513481Sgiacomo.travaglini@arm.com } 217613481Sgiacomo.travaglini@arm.com}; 217713481Sgiacomo.travaglini@arm.com 217813481Sgiacomo.travaglini@arm.com// Implements the Field() matcher for matching a field (i.e. member 217913481Sgiacomo.travaglini@arm.com// variable) of an object. 218013481Sgiacomo.travaglini@arm.comtemplate <typename Class, typename FieldType> 218113481Sgiacomo.travaglini@arm.comclass FieldMatcher { 218213481Sgiacomo.travaglini@arm.com public: 218313481Sgiacomo.travaglini@arm.com FieldMatcher(FieldType Class::*field, 218413481Sgiacomo.travaglini@arm.com const Matcher<const FieldType&>& matcher) 218513481Sgiacomo.travaglini@arm.com : field_(field), matcher_(matcher) {} 218613481Sgiacomo.travaglini@arm.com 218713481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 218813481Sgiacomo.travaglini@arm.com *os << "is an object whose given field "; 218913481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 219013481Sgiacomo.travaglini@arm.com } 219113481Sgiacomo.travaglini@arm.com 219213481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 219313481Sgiacomo.travaglini@arm.com *os << "is an object whose given field "; 219413481Sgiacomo.travaglini@arm.com matcher_.DescribeNegationTo(os); 219513481Sgiacomo.travaglini@arm.com } 219613481Sgiacomo.travaglini@arm.com 219713481Sgiacomo.travaglini@arm.com template <typename T> 219813481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const T& value, MatchResultListener* listener) const { 219913481Sgiacomo.travaglini@arm.com return MatchAndExplainImpl( 220013481Sgiacomo.travaglini@arm.com typename ::testing::internal:: 220113481Sgiacomo.travaglini@arm.com is_pointer<GTEST_REMOVE_CONST_(T)>::type(), 220213481Sgiacomo.travaglini@arm.com value, listener); 220313481Sgiacomo.travaglini@arm.com } 220413481Sgiacomo.travaglini@arm.com 220513481Sgiacomo.travaglini@arm.com private: 220613481Sgiacomo.travaglini@arm.com // The first argument of MatchAndExplainImpl() is needed to help 220713481Sgiacomo.travaglini@arm.com // Symbian's C++ compiler choose which overload to use. Its type is 220813481Sgiacomo.travaglini@arm.com // true_type iff the Field() matcher is used to match a pointer. 220913481Sgiacomo.travaglini@arm.com bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, 221013481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 221113481Sgiacomo.travaglini@arm.com *listener << "whose given field is "; 221213481Sgiacomo.travaglini@arm.com return MatchPrintAndExplain(obj.*field_, matcher_, listener); 221313481Sgiacomo.travaglini@arm.com } 221413481Sgiacomo.travaglini@arm.com 221513481Sgiacomo.travaglini@arm.com bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, 221613481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 221713481Sgiacomo.travaglini@arm.com if (p == NULL) 221813481Sgiacomo.travaglini@arm.com return false; 221913481Sgiacomo.travaglini@arm.com 222013481Sgiacomo.travaglini@arm.com *listener << "which points to an object "; 222113481Sgiacomo.travaglini@arm.com // Since *p has a field, it must be a class/struct/union type and 222213481Sgiacomo.travaglini@arm.com // thus cannot be a pointer. Therefore we pass false_type() as 222313481Sgiacomo.travaglini@arm.com // the first argument. 222413481Sgiacomo.travaglini@arm.com return MatchAndExplainImpl(false_type(), *p, listener); 222513481Sgiacomo.travaglini@arm.com } 222613481Sgiacomo.travaglini@arm.com 222713481Sgiacomo.travaglini@arm.com const FieldType Class::*field_; 222813481Sgiacomo.travaglini@arm.com const Matcher<const FieldType&> matcher_; 222913481Sgiacomo.travaglini@arm.com 223013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(FieldMatcher); 223113481Sgiacomo.travaglini@arm.com}; 223213481Sgiacomo.travaglini@arm.com 223313481Sgiacomo.travaglini@arm.com// Implements the Property() matcher for matching a property 223413481Sgiacomo.travaglini@arm.com// (i.e. return value of a getter method) of an object. 223513481Sgiacomo.travaglini@arm.comtemplate <typename Class, typename PropertyType> 223613481Sgiacomo.travaglini@arm.comclass PropertyMatcher { 223713481Sgiacomo.travaglini@arm.com public: 223813481Sgiacomo.travaglini@arm.com // The property may have a reference type, so 'const PropertyType&' 223913481Sgiacomo.travaglini@arm.com // may cause double references and fail to compile. That's why we 224013481Sgiacomo.travaglini@arm.com // need GTEST_REFERENCE_TO_CONST, which works regardless of 224113481Sgiacomo.travaglini@arm.com // PropertyType being a reference or not. 224213481Sgiacomo.travaglini@arm.com typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; 224313481Sgiacomo.travaglini@arm.com 224413481Sgiacomo.travaglini@arm.com PropertyMatcher(PropertyType (Class::*property)() const, 224513481Sgiacomo.travaglini@arm.com const Matcher<RefToConstProperty>& matcher) 224613481Sgiacomo.travaglini@arm.com : property_(property), matcher_(matcher) {} 224713481Sgiacomo.travaglini@arm.com 224813481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 224913481Sgiacomo.travaglini@arm.com *os << "is an object whose given property "; 225013481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 225113481Sgiacomo.travaglini@arm.com } 225213481Sgiacomo.travaglini@arm.com 225313481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 225413481Sgiacomo.travaglini@arm.com *os << "is an object whose given property "; 225513481Sgiacomo.travaglini@arm.com matcher_.DescribeNegationTo(os); 225613481Sgiacomo.travaglini@arm.com } 225713481Sgiacomo.travaglini@arm.com 225813481Sgiacomo.travaglini@arm.com template <typename T> 225913481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const T&value, MatchResultListener* listener) const { 226013481Sgiacomo.travaglini@arm.com return MatchAndExplainImpl( 226113481Sgiacomo.travaglini@arm.com typename ::testing::internal:: 226213481Sgiacomo.travaglini@arm.com is_pointer<GTEST_REMOVE_CONST_(T)>::type(), 226313481Sgiacomo.travaglini@arm.com value, listener); 226413481Sgiacomo.travaglini@arm.com } 226513481Sgiacomo.travaglini@arm.com 226613481Sgiacomo.travaglini@arm.com private: 226713481Sgiacomo.travaglini@arm.com // The first argument of MatchAndExplainImpl() is needed to help 226813481Sgiacomo.travaglini@arm.com // Symbian's C++ compiler choose which overload to use. Its type is 226913481Sgiacomo.travaglini@arm.com // true_type iff the Property() matcher is used to match a pointer. 227013481Sgiacomo.travaglini@arm.com bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, 227113481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 227213481Sgiacomo.travaglini@arm.com *listener << "whose given property is "; 227313481Sgiacomo.travaglini@arm.com // Cannot pass the return value (for example, int) to MatchPrintAndExplain, 227413481Sgiacomo.travaglini@arm.com // which takes a non-const reference as argument. 227513481Sgiacomo.travaglini@arm.com#if defined(_PREFAST_ ) && _MSC_VER == 1800 227613481Sgiacomo.travaglini@arm.com // Workaround bug in VC++ 2013's /analyze parser. 227713481Sgiacomo.travaglini@arm.com // https://connect.microsoft.com/VisualStudio/feedback/details/1106363/internal-compiler-error-with-analyze-due-to-failure-to-infer-move 227813481Sgiacomo.travaglini@arm.com posix::Abort(); // To make sure it is never run. 227913481Sgiacomo.travaglini@arm.com return false; 228013481Sgiacomo.travaglini@arm.com#else 228113481Sgiacomo.travaglini@arm.com RefToConstProperty result = (obj.*property_)(); 228213481Sgiacomo.travaglini@arm.com return MatchPrintAndExplain(result, matcher_, listener); 228313481Sgiacomo.travaglini@arm.com#endif 228413481Sgiacomo.travaglini@arm.com } 228513481Sgiacomo.travaglini@arm.com 228613481Sgiacomo.travaglini@arm.com bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, 228713481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 228813481Sgiacomo.travaglini@arm.com if (p == NULL) 228913481Sgiacomo.travaglini@arm.com return false; 229013481Sgiacomo.travaglini@arm.com 229113481Sgiacomo.travaglini@arm.com *listener << "which points to an object "; 229213481Sgiacomo.travaglini@arm.com // Since *p has a property method, it must be a class/struct/union 229313481Sgiacomo.travaglini@arm.com // type and thus cannot be a pointer. Therefore we pass 229413481Sgiacomo.travaglini@arm.com // false_type() as the first argument. 229513481Sgiacomo.travaglini@arm.com return MatchAndExplainImpl(false_type(), *p, listener); 229613481Sgiacomo.travaglini@arm.com } 229713481Sgiacomo.travaglini@arm.com 229813481Sgiacomo.travaglini@arm.com PropertyType (Class::*property_)() const; 229913481Sgiacomo.travaglini@arm.com const Matcher<RefToConstProperty> matcher_; 230013481Sgiacomo.travaglini@arm.com 230113481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PropertyMatcher); 230213481Sgiacomo.travaglini@arm.com}; 230313481Sgiacomo.travaglini@arm.com 230413481Sgiacomo.travaglini@arm.com// Type traits specifying various features of different functors for ResultOf. 230513481Sgiacomo.travaglini@arm.com// The default template specifies features for functor objects. 230613481Sgiacomo.travaglini@arm.com// Functor classes have to typedef argument_type and result_type 230713481Sgiacomo.travaglini@arm.com// to be compatible with ResultOf. 230813481Sgiacomo.travaglini@arm.comtemplate <typename Functor> 230913481Sgiacomo.travaglini@arm.comstruct CallableTraits { 231013481Sgiacomo.travaglini@arm.com typedef typename Functor::result_type ResultType; 231113481Sgiacomo.travaglini@arm.com typedef Functor StorageType; 231213481Sgiacomo.travaglini@arm.com 231313481Sgiacomo.travaglini@arm.com static void CheckIsValid(Functor /* functor */) {} 231413481Sgiacomo.travaglini@arm.com template <typename T> 231513481Sgiacomo.travaglini@arm.com static ResultType Invoke(Functor f, T arg) { return f(arg); } 231613481Sgiacomo.travaglini@arm.com}; 231713481Sgiacomo.travaglini@arm.com 231813481Sgiacomo.travaglini@arm.com// Specialization for function pointers. 231913481Sgiacomo.travaglini@arm.comtemplate <typename ArgType, typename ResType> 232013481Sgiacomo.travaglini@arm.comstruct CallableTraits<ResType(*)(ArgType)> { 232113481Sgiacomo.travaglini@arm.com typedef ResType ResultType; 232213481Sgiacomo.travaglini@arm.com typedef ResType(*StorageType)(ArgType); 232313481Sgiacomo.travaglini@arm.com 232413481Sgiacomo.travaglini@arm.com static void CheckIsValid(ResType(*f)(ArgType)) { 232513481Sgiacomo.travaglini@arm.com GTEST_CHECK_(f != NULL) 232613481Sgiacomo.travaglini@arm.com << "NULL function pointer is passed into ResultOf()."; 232713481Sgiacomo.travaglini@arm.com } 232813481Sgiacomo.travaglini@arm.com template <typename T> 232913481Sgiacomo.travaglini@arm.com static ResType Invoke(ResType(*f)(ArgType), T arg) { 233013481Sgiacomo.travaglini@arm.com return (*f)(arg); 233113481Sgiacomo.travaglini@arm.com } 233213481Sgiacomo.travaglini@arm.com}; 233313481Sgiacomo.travaglini@arm.com 233413481Sgiacomo.travaglini@arm.com// Implements the ResultOf() matcher for matching a return value of a 233513481Sgiacomo.travaglini@arm.com// unary function of an object. 233613481Sgiacomo.travaglini@arm.comtemplate <typename Callable> 233713481Sgiacomo.travaglini@arm.comclass ResultOfMatcher { 233813481Sgiacomo.travaglini@arm.com public: 233913481Sgiacomo.travaglini@arm.com typedef typename CallableTraits<Callable>::ResultType ResultType; 234013481Sgiacomo.travaglini@arm.com 234113481Sgiacomo.travaglini@arm.com ResultOfMatcher(Callable callable, const Matcher<ResultType>& matcher) 234213481Sgiacomo.travaglini@arm.com : callable_(callable), matcher_(matcher) { 234313481Sgiacomo.travaglini@arm.com CallableTraits<Callable>::CheckIsValid(callable_); 234413481Sgiacomo.travaglini@arm.com } 234513481Sgiacomo.travaglini@arm.com 234613481Sgiacomo.travaglini@arm.com template <typename T> 234713481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 234813481Sgiacomo.travaglini@arm.com return Matcher<T>(new Impl<T>(callable_, matcher_)); 234913481Sgiacomo.travaglini@arm.com } 235013481Sgiacomo.travaglini@arm.com 235113481Sgiacomo.travaglini@arm.com private: 235213481Sgiacomo.travaglini@arm.com typedef typename CallableTraits<Callable>::StorageType CallableStorageType; 235313481Sgiacomo.travaglini@arm.com 235413481Sgiacomo.travaglini@arm.com template <typename T> 235513481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<T> { 235613481Sgiacomo.travaglini@arm.com public: 235713481Sgiacomo.travaglini@arm.com Impl(CallableStorageType callable, const Matcher<ResultType>& matcher) 235813481Sgiacomo.travaglini@arm.com : callable_(callable), matcher_(matcher) {} 235913481Sgiacomo.travaglini@arm.com 236013481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 236113481Sgiacomo.travaglini@arm.com *os << "is mapped by the given callable to a value that "; 236213481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 236313481Sgiacomo.travaglini@arm.com } 236413481Sgiacomo.travaglini@arm.com 236513481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 236613481Sgiacomo.travaglini@arm.com *os << "is mapped by the given callable to a value that "; 236713481Sgiacomo.travaglini@arm.com matcher_.DescribeNegationTo(os); 236813481Sgiacomo.travaglini@arm.com } 236913481Sgiacomo.travaglini@arm.com 237013481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T obj, MatchResultListener* listener) const { 237113481Sgiacomo.travaglini@arm.com *listener << "which is mapped by the given callable to "; 237213481Sgiacomo.travaglini@arm.com // Cannot pass the return value (for example, int) to 237313481Sgiacomo.travaglini@arm.com // MatchPrintAndExplain, which takes a non-const reference as argument. 237413481Sgiacomo.travaglini@arm.com ResultType result = 237513481Sgiacomo.travaglini@arm.com CallableTraits<Callable>::template Invoke<T>(callable_, obj); 237613481Sgiacomo.travaglini@arm.com return MatchPrintAndExplain(result, matcher_, listener); 237713481Sgiacomo.travaglini@arm.com } 237813481Sgiacomo.travaglini@arm.com 237913481Sgiacomo.travaglini@arm.com private: 238013481Sgiacomo.travaglini@arm.com // Functors often define operator() as non-const method even though 238113481Sgiacomo.travaglini@arm.com // they are actualy stateless. But we need to use them even when 238213481Sgiacomo.travaglini@arm.com // 'this' is a const pointer. It's the user's responsibility not to 238313481Sgiacomo.travaglini@arm.com // use stateful callables with ResultOf(), which does't guarantee 238413481Sgiacomo.travaglini@arm.com // how many times the callable will be invoked. 238513481Sgiacomo.travaglini@arm.com mutable CallableStorageType callable_; 238613481Sgiacomo.travaglini@arm.com const Matcher<ResultType> matcher_; 238713481Sgiacomo.travaglini@arm.com 238813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 238913481Sgiacomo.travaglini@arm.com }; // class Impl 239013481Sgiacomo.travaglini@arm.com 239113481Sgiacomo.travaglini@arm.com const CallableStorageType callable_; 239213481Sgiacomo.travaglini@arm.com const Matcher<ResultType> matcher_; 239313481Sgiacomo.travaglini@arm.com 239413481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ResultOfMatcher); 239513481Sgiacomo.travaglini@arm.com}; 239613481Sgiacomo.travaglini@arm.com 239713481Sgiacomo.travaglini@arm.com// Implements a matcher that checks the size of an STL-style container. 239813481Sgiacomo.travaglini@arm.comtemplate <typename SizeMatcher> 239913481Sgiacomo.travaglini@arm.comclass SizeIsMatcher { 240013481Sgiacomo.travaglini@arm.com public: 240113481Sgiacomo.travaglini@arm.com explicit SizeIsMatcher(const SizeMatcher& size_matcher) 240213481Sgiacomo.travaglini@arm.com : size_matcher_(size_matcher) { 240313481Sgiacomo.travaglini@arm.com } 240413481Sgiacomo.travaglini@arm.com 240513481Sgiacomo.travaglini@arm.com template <typename Container> 240613481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 240713481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<Container>(size_matcher_)); 240813481Sgiacomo.travaglini@arm.com } 240913481Sgiacomo.travaglini@arm.com 241013481Sgiacomo.travaglini@arm.com template <typename Container> 241113481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<Container> { 241213481Sgiacomo.travaglini@arm.com public: 241313481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView< 241413481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; 241513481Sgiacomo.travaglini@arm.com typedef typename ContainerView::type::size_type SizeType; 241613481Sgiacomo.travaglini@arm.com explicit Impl(const SizeMatcher& size_matcher) 241713481Sgiacomo.travaglini@arm.com : size_matcher_(MatcherCast<SizeType>(size_matcher)) {} 241813481Sgiacomo.travaglini@arm.com 241913481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 242013481Sgiacomo.travaglini@arm.com *os << "size "; 242113481Sgiacomo.travaglini@arm.com size_matcher_.DescribeTo(os); 242213481Sgiacomo.travaglini@arm.com } 242313481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 242413481Sgiacomo.travaglini@arm.com *os << "size "; 242513481Sgiacomo.travaglini@arm.com size_matcher_.DescribeNegationTo(os); 242613481Sgiacomo.travaglini@arm.com } 242713481Sgiacomo.travaglini@arm.com 242813481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Container container, 242913481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 243013481Sgiacomo.travaglini@arm.com SizeType size = container.size(); 243113481Sgiacomo.travaglini@arm.com StringMatchResultListener size_listener; 243213481Sgiacomo.travaglini@arm.com const bool result = size_matcher_.MatchAndExplain(size, &size_listener); 243313481Sgiacomo.travaglini@arm.com *listener 243413481Sgiacomo.travaglini@arm.com << "whose size " << size << (result ? " matches" : " doesn't match"); 243513481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(size_listener.str(), listener->stream()); 243613481Sgiacomo.travaglini@arm.com return result; 243713481Sgiacomo.travaglini@arm.com } 243813481Sgiacomo.travaglini@arm.com 243913481Sgiacomo.travaglini@arm.com private: 244013481Sgiacomo.travaglini@arm.com const Matcher<SizeType> size_matcher_; 244113481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 244213481Sgiacomo.travaglini@arm.com }; 244313481Sgiacomo.travaglini@arm.com 244413481Sgiacomo.travaglini@arm.com private: 244513481Sgiacomo.travaglini@arm.com const SizeMatcher size_matcher_; 244613481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(SizeIsMatcher); 244713481Sgiacomo.travaglini@arm.com}; 244813481Sgiacomo.travaglini@arm.com 244913481Sgiacomo.travaglini@arm.com// Implements a matcher that checks the begin()..end() distance of an STL-style 245013481Sgiacomo.travaglini@arm.com// container. 245113481Sgiacomo.travaglini@arm.comtemplate <typename DistanceMatcher> 245213481Sgiacomo.travaglini@arm.comclass BeginEndDistanceIsMatcher { 245313481Sgiacomo.travaglini@arm.com public: 245413481Sgiacomo.travaglini@arm.com explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher) 245513481Sgiacomo.travaglini@arm.com : distance_matcher_(distance_matcher) {} 245613481Sgiacomo.travaglini@arm.com 245713481Sgiacomo.travaglini@arm.com template <typename Container> 245813481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 245913481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<Container>(distance_matcher_)); 246013481Sgiacomo.travaglini@arm.com } 246113481Sgiacomo.travaglini@arm.com 246213481Sgiacomo.travaglini@arm.com template <typename Container> 246313481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<Container> { 246413481Sgiacomo.travaglini@arm.com public: 246513481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView< 246613481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; 246713481Sgiacomo.travaglini@arm.com typedef typename std::iterator_traits< 246813481Sgiacomo.travaglini@arm.com typename ContainerView::type::const_iterator>::difference_type 246913481Sgiacomo.travaglini@arm.com DistanceType; 247013481Sgiacomo.travaglini@arm.com explicit Impl(const DistanceMatcher& distance_matcher) 247113481Sgiacomo.travaglini@arm.com : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {} 247213481Sgiacomo.travaglini@arm.com 247313481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 247413481Sgiacomo.travaglini@arm.com *os << "distance between begin() and end() "; 247513481Sgiacomo.travaglini@arm.com distance_matcher_.DescribeTo(os); 247613481Sgiacomo.travaglini@arm.com } 247713481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 247813481Sgiacomo.travaglini@arm.com *os << "distance between begin() and end() "; 247913481Sgiacomo.travaglini@arm.com distance_matcher_.DescribeNegationTo(os); 248013481Sgiacomo.travaglini@arm.com } 248113481Sgiacomo.travaglini@arm.com 248213481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Container container, 248313481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 248413481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_BEGIN_AND_END_ 248513481Sgiacomo.travaglini@arm.com using std::begin; 248613481Sgiacomo.travaglini@arm.com using std::end; 248713481Sgiacomo.travaglini@arm.com DistanceType distance = std::distance(begin(container), end(container)); 248813481Sgiacomo.travaglini@arm.com#else 248913481Sgiacomo.travaglini@arm.com DistanceType distance = std::distance(container.begin(), container.end()); 249013481Sgiacomo.travaglini@arm.com#endif 249113481Sgiacomo.travaglini@arm.com StringMatchResultListener distance_listener; 249213481Sgiacomo.travaglini@arm.com const bool result = 249313481Sgiacomo.travaglini@arm.com distance_matcher_.MatchAndExplain(distance, &distance_listener); 249413481Sgiacomo.travaglini@arm.com *listener << "whose distance between begin() and end() " << distance 249513481Sgiacomo.travaglini@arm.com << (result ? " matches" : " doesn't match"); 249613481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(distance_listener.str(), listener->stream()); 249713481Sgiacomo.travaglini@arm.com return result; 249813481Sgiacomo.travaglini@arm.com } 249913481Sgiacomo.travaglini@arm.com 250013481Sgiacomo.travaglini@arm.com private: 250113481Sgiacomo.travaglini@arm.com const Matcher<DistanceType> distance_matcher_; 250213481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 250313481Sgiacomo.travaglini@arm.com }; 250413481Sgiacomo.travaglini@arm.com 250513481Sgiacomo.travaglini@arm.com private: 250613481Sgiacomo.travaglini@arm.com const DistanceMatcher distance_matcher_; 250713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher); 250813481Sgiacomo.travaglini@arm.com}; 250913481Sgiacomo.travaglini@arm.com 251013481Sgiacomo.travaglini@arm.com// Implements an equality matcher for any STL-style container whose elements 251113481Sgiacomo.travaglini@arm.com// support ==. This matcher is like Eq(), but its failure explanations provide 251213481Sgiacomo.travaglini@arm.com// more detailed information that is useful when the container is used as a set. 251313481Sgiacomo.travaglini@arm.com// The failure message reports elements that are in one of the operands but not 251413481Sgiacomo.travaglini@arm.com// the other. The failure messages do not report duplicate or out-of-order 251513481Sgiacomo.travaglini@arm.com// elements in the containers (which don't properly matter to sets, but can 251613481Sgiacomo.travaglini@arm.com// occur if the containers are vectors or lists, for example). 251713481Sgiacomo.travaglini@arm.com// 251813481Sgiacomo.travaglini@arm.com// Uses the container's const_iterator, value_type, operator ==, 251913481Sgiacomo.travaglini@arm.com// begin(), and end(). 252013481Sgiacomo.travaglini@arm.comtemplate <typename Container> 252113481Sgiacomo.travaglini@arm.comclass ContainerEqMatcher { 252213481Sgiacomo.travaglini@arm.com public: 252313481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView<Container> View; 252413481Sgiacomo.travaglini@arm.com typedef typename View::type StlContainer; 252513481Sgiacomo.travaglini@arm.com typedef typename View::const_reference StlContainerReference; 252613481Sgiacomo.travaglini@arm.com 252713481Sgiacomo.travaglini@arm.com // We make a copy of expected in case the elements in it are modified 252813481Sgiacomo.travaglini@arm.com // after this matcher is created. 252913481Sgiacomo.travaglini@arm.com explicit ContainerEqMatcher(const Container& expected) 253013481Sgiacomo.travaglini@arm.com : expected_(View::Copy(expected)) { 253113481Sgiacomo.travaglini@arm.com // Makes sure the user doesn't instantiate this class template 253213481Sgiacomo.travaglini@arm.com // with a const or reference type. 253313481Sgiacomo.travaglini@arm.com (void)testing::StaticAssertTypeEq<Container, 253413481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>(); 253513481Sgiacomo.travaglini@arm.com } 253613481Sgiacomo.travaglini@arm.com 253713481Sgiacomo.travaglini@arm.com void DescribeTo(::std::ostream* os) const { 253813481Sgiacomo.travaglini@arm.com *os << "equals "; 253913481Sgiacomo.travaglini@arm.com UniversalPrint(expected_, os); 254013481Sgiacomo.travaglini@arm.com } 254113481Sgiacomo.travaglini@arm.com void DescribeNegationTo(::std::ostream* os) const { 254213481Sgiacomo.travaglini@arm.com *os << "does not equal "; 254313481Sgiacomo.travaglini@arm.com UniversalPrint(expected_, os); 254413481Sgiacomo.travaglini@arm.com } 254513481Sgiacomo.travaglini@arm.com 254613481Sgiacomo.travaglini@arm.com template <typename LhsContainer> 254713481Sgiacomo.travaglini@arm.com bool MatchAndExplain(const LhsContainer& lhs, 254813481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 254913481Sgiacomo.travaglini@arm.com // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug 255013481Sgiacomo.travaglini@arm.com // that causes LhsContainer to be a const type sometimes. 255113481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)> 255213481Sgiacomo.travaglini@arm.com LhsView; 255313481Sgiacomo.travaglini@arm.com typedef typename LhsView::type LhsStlContainer; 255413481Sgiacomo.travaglini@arm.com StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); 255513481Sgiacomo.travaglini@arm.com if (lhs_stl_container == expected_) 255613481Sgiacomo.travaglini@arm.com return true; 255713481Sgiacomo.travaglini@arm.com 255813481Sgiacomo.travaglini@arm.com ::std::ostream* const os = listener->stream(); 255913481Sgiacomo.travaglini@arm.com if (os != NULL) { 256013481Sgiacomo.travaglini@arm.com // Something is different. Check for extra values first. 256113481Sgiacomo.travaglini@arm.com bool printed_header = false; 256213481Sgiacomo.travaglini@arm.com for (typename LhsStlContainer::const_iterator it = 256313481Sgiacomo.travaglini@arm.com lhs_stl_container.begin(); 256413481Sgiacomo.travaglini@arm.com it != lhs_stl_container.end(); ++it) { 256513481Sgiacomo.travaglini@arm.com if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) == 256613481Sgiacomo.travaglini@arm.com expected_.end()) { 256713481Sgiacomo.travaglini@arm.com if (printed_header) { 256813481Sgiacomo.travaglini@arm.com *os << ", "; 256913481Sgiacomo.travaglini@arm.com } else { 257013481Sgiacomo.travaglini@arm.com *os << "which has these unexpected elements: "; 257113481Sgiacomo.travaglini@arm.com printed_header = true; 257213481Sgiacomo.travaglini@arm.com } 257313481Sgiacomo.travaglini@arm.com UniversalPrint(*it, os); 257413481Sgiacomo.travaglini@arm.com } 257513481Sgiacomo.travaglini@arm.com } 257613481Sgiacomo.travaglini@arm.com 257713481Sgiacomo.travaglini@arm.com // Now check for missing values. 257813481Sgiacomo.travaglini@arm.com bool printed_header2 = false; 257913481Sgiacomo.travaglini@arm.com for (typename StlContainer::const_iterator it = expected_.begin(); 258013481Sgiacomo.travaglini@arm.com it != expected_.end(); ++it) { 258113481Sgiacomo.travaglini@arm.com if (internal::ArrayAwareFind( 258213481Sgiacomo.travaglini@arm.com lhs_stl_container.begin(), lhs_stl_container.end(), *it) == 258313481Sgiacomo.travaglini@arm.com lhs_stl_container.end()) { 258413481Sgiacomo.travaglini@arm.com if (printed_header2) { 258513481Sgiacomo.travaglini@arm.com *os << ", "; 258613481Sgiacomo.travaglini@arm.com } else { 258713481Sgiacomo.travaglini@arm.com *os << (printed_header ? ",\nand" : "which") 258813481Sgiacomo.travaglini@arm.com << " doesn't have these expected elements: "; 258913481Sgiacomo.travaglini@arm.com printed_header2 = true; 259013481Sgiacomo.travaglini@arm.com } 259113481Sgiacomo.travaglini@arm.com UniversalPrint(*it, os); 259213481Sgiacomo.travaglini@arm.com } 259313481Sgiacomo.travaglini@arm.com } 259413481Sgiacomo.travaglini@arm.com } 259513481Sgiacomo.travaglini@arm.com 259613481Sgiacomo.travaglini@arm.com return false; 259713481Sgiacomo.travaglini@arm.com } 259813481Sgiacomo.travaglini@arm.com 259913481Sgiacomo.travaglini@arm.com private: 260013481Sgiacomo.travaglini@arm.com const StlContainer expected_; 260113481Sgiacomo.travaglini@arm.com 260213481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher); 260313481Sgiacomo.travaglini@arm.com}; 260413481Sgiacomo.travaglini@arm.com 260513481Sgiacomo.travaglini@arm.com// A comparator functor that uses the < operator to compare two values. 260613481Sgiacomo.travaglini@arm.comstruct LessComparator { 260713481Sgiacomo.travaglini@arm.com template <typename T, typename U> 260813481Sgiacomo.travaglini@arm.com bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; } 260913481Sgiacomo.travaglini@arm.com}; 261013481Sgiacomo.travaglini@arm.com 261113481Sgiacomo.travaglini@arm.com// Implements WhenSortedBy(comparator, container_matcher). 261213481Sgiacomo.travaglini@arm.comtemplate <typename Comparator, typename ContainerMatcher> 261313481Sgiacomo.travaglini@arm.comclass WhenSortedByMatcher { 261413481Sgiacomo.travaglini@arm.com public: 261513481Sgiacomo.travaglini@arm.com WhenSortedByMatcher(const Comparator& comparator, 261613481Sgiacomo.travaglini@arm.com const ContainerMatcher& matcher) 261713481Sgiacomo.travaglini@arm.com : comparator_(comparator), matcher_(matcher) {} 261813481Sgiacomo.travaglini@arm.com 261913481Sgiacomo.travaglini@arm.com template <typename LhsContainer> 262013481Sgiacomo.travaglini@arm.com operator Matcher<LhsContainer>() const { 262113481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_)); 262213481Sgiacomo.travaglini@arm.com } 262313481Sgiacomo.travaglini@arm.com 262413481Sgiacomo.travaglini@arm.com template <typename LhsContainer> 262513481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<LhsContainer> { 262613481Sgiacomo.travaglini@arm.com public: 262713481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView< 262813481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; 262913481Sgiacomo.travaglini@arm.com typedef typename LhsView::type LhsStlContainer; 263013481Sgiacomo.travaglini@arm.com typedef typename LhsView::const_reference LhsStlContainerReference; 263113481Sgiacomo.travaglini@arm.com // Transforms std::pair<const Key, Value> into std::pair<Key, Value> 263213481Sgiacomo.travaglini@arm.com // so that we can match associative containers. 263313481Sgiacomo.travaglini@arm.com typedef typename RemoveConstFromKey< 263413481Sgiacomo.travaglini@arm.com typename LhsStlContainer::value_type>::type LhsValue; 263513481Sgiacomo.travaglini@arm.com 263613481Sgiacomo.travaglini@arm.com Impl(const Comparator& comparator, const ContainerMatcher& matcher) 263713481Sgiacomo.travaglini@arm.com : comparator_(comparator), matcher_(matcher) {} 263813481Sgiacomo.travaglini@arm.com 263913481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 264013481Sgiacomo.travaglini@arm.com *os << "(when sorted) "; 264113481Sgiacomo.travaglini@arm.com matcher_.DescribeTo(os); 264213481Sgiacomo.travaglini@arm.com } 264313481Sgiacomo.travaglini@arm.com 264413481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 264513481Sgiacomo.travaglini@arm.com *os << "(when sorted) "; 264613481Sgiacomo.travaglini@arm.com matcher_.DescribeNegationTo(os); 264713481Sgiacomo.travaglini@arm.com } 264813481Sgiacomo.travaglini@arm.com 264913481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(LhsContainer lhs, 265013481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 265113481Sgiacomo.travaglini@arm.com LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); 265213481Sgiacomo.travaglini@arm.com ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(), 265313481Sgiacomo.travaglini@arm.com lhs_stl_container.end()); 265413481Sgiacomo.travaglini@arm.com ::std::sort( 265513481Sgiacomo.travaglini@arm.com sorted_container.begin(), sorted_container.end(), comparator_); 265613481Sgiacomo.travaglini@arm.com 265713481Sgiacomo.travaglini@arm.com if (!listener->IsInterested()) { 265813481Sgiacomo.travaglini@arm.com // If the listener is not interested, we do not need to 265913481Sgiacomo.travaglini@arm.com // construct the inner explanation. 266013481Sgiacomo.travaglini@arm.com return matcher_.Matches(sorted_container); 266113481Sgiacomo.travaglini@arm.com } 266213481Sgiacomo.travaglini@arm.com 266313481Sgiacomo.travaglini@arm.com *listener << "which is "; 266413481Sgiacomo.travaglini@arm.com UniversalPrint(sorted_container, listener->stream()); 266513481Sgiacomo.travaglini@arm.com *listener << " when sorted"; 266613481Sgiacomo.travaglini@arm.com 266713481Sgiacomo.travaglini@arm.com StringMatchResultListener inner_listener; 266813481Sgiacomo.travaglini@arm.com const bool match = matcher_.MatchAndExplain(sorted_container, 266913481Sgiacomo.travaglini@arm.com &inner_listener); 267013481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(inner_listener.str(), listener->stream()); 267113481Sgiacomo.travaglini@arm.com return match; 267213481Sgiacomo.travaglini@arm.com } 267313481Sgiacomo.travaglini@arm.com 267413481Sgiacomo.travaglini@arm.com private: 267513481Sgiacomo.travaglini@arm.com const Comparator comparator_; 267613481Sgiacomo.travaglini@arm.com const Matcher<const ::std::vector<LhsValue>&> matcher_; 267713481Sgiacomo.travaglini@arm.com 267813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); 267913481Sgiacomo.travaglini@arm.com }; 268013481Sgiacomo.travaglini@arm.com 268113481Sgiacomo.travaglini@arm.com private: 268213481Sgiacomo.travaglini@arm.com const Comparator comparator_; 268313481Sgiacomo.travaglini@arm.com const ContainerMatcher matcher_; 268413481Sgiacomo.travaglini@arm.com 268513481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher); 268613481Sgiacomo.travaglini@arm.com}; 268713481Sgiacomo.travaglini@arm.com 268813481Sgiacomo.travaglini@arm.com// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher 268913481Sgiacomo.travaglini@arm.com// must be able to be safely cast to Matcher<tuple<const T1&, const 269013481Sgiacomo.travaglini@arm.com// T2&> >, where T1 and T2 are the types of elements in the LHS 269113481Sgiacomo.travaglini@arm.com// container and the RHS container respectively. 269213481Sgiacomo.travaglini@arm.comtemplate <typename TupleMatcher, typename RhsContainer> 269313481Sgiacomo.travaglini@arm.comclass PointwiseMatcher { 269413481Sgiacomo.travaglini@arm.com public: 269513481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView<RhsContainer> RhsView; 269613481Sgiacomo.travaglini@arm.com typedef typename RhsView::type RhsStlContainer; 269713481Sgiacomo.travaglini@arm.com typedef typename RhsStlContainer::value_type RhsValue; 269813481Sgiacomo.travaglini@arm.com 269913481Sgiacomo.travaglini@arm.com // Like ContainerEq, we make a copy of rhs in case the elements in 270013481Sgiacomo.travaglini@arm.com // it are modified after this matcher is created. 270113481Sgiacomo.travaglini@arm.com PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs) 270213481Sgiacomo.travaglini@arm.com : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) { 270313481Sgiacomo.travaglini@arm.com // Makes sure the user doesn't instantiate this class template 270413481Sgiacomo.travaglini@arm.com // with a const or reference type. 270513481Sgiacomo.travaglini@arm.com (void)testing::StaticAssertTypeEq<RhsContainer, 270613481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>(); 270713481Sgiacomo.travaglini@arm.com } 270813481Sgiacomo.travaglini@arm.com 270913481Sgiacomo.travaglini@arm.com template <typename LhsContainer> 271013481Sgiacomo.travaglini@arm.com operator Matcher<LhsContainer>() const { 271113481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_)); 271213481Sgiacomo.travaglini@arm.com } 271313481Sgiacomo.travaglini@arm.com 271413481Sgiacomo.travaglini@arm.com template <typename LhsContainer> 271513481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<LhsContainer> { 271613481Sgiacomo.travaglini@arm.com public: 271713481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView< 271813481Sgiacomo.travaglini@arm.com GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; 271913481Sgiacomo.travaglini@arm.com typedef typename LhsView::type LhsStlContainer; 272013481Sgiacomo.travaglini@arm.com typedef typename LhsView::const_reference LhsStlContainerReference; 272113481Sgiacomo.travaglini@arm.com typedef typename LhsStlContainer::value_type LhsValue; 272213481Sgiacomo.travaglini@arm.com // We pass the LHS value and the RHS value to the inner matcher by 272313481Sgiacomo.travaglini@arm.com // reference, as they may be expensive to copy. We must use tuple 272413481Sgiacomo.travaglini@arm.com // instead of pair here, as a pair cannot hold references (C++ 98, 272513481Sgiacomo.travaglini@arm.com // 20.2.2 [lib.pairs]). 272613481Sgiacomo.travaglini@arm.com typedef ::testing::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg; 272713481Sgiacomo.travaglini@arm.com 272813481Sgiacomo.travaglini@arm.com Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs) 272913481Sgiacomo.travaglini@arm.com // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher. 273013481Sgiacomo.travaglini@arm.com : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)), 273113481Sgiacomo.travaglini@arm.com rhs_(rhs) {} 273213481Sgiacomo.travaglini@arm.com 273313481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 273413481Sgiacomo.travaglini@arm.com *os << "contains " << rhs_.size() 273513481Sgiacomo.travaglini@arm.com << " values, where each value and its corresponding value in "; 273613481Sgiacomo.travaglini@arm.com UniversalPrinter<RhsStlContainer>::Print(rhs_, os); 273713481Sgiacomo.travaglini@arm.com *os << " "; 273813481Sgiacomo.travaglini@arm.com mono_tuple_matcher_.DescribeTo(os); 273913481Sgiacomo.travaglini@arm.com } 274013481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 274113481Sgiacomo.travaglini@arm.com *os << "doesn't contain exactly " << rhs_.size() 274213481Sgiacomo.travaglini@arm.com << " values, or contains a value x at some index i" 274313481Sgiacomo.travaglini@arm.com << " where x and the i-th value of "; 274413481Sgiacomo.travaglini@arm.com UniversalPrint(rhs_, os); 274513481Sgiacomo.travaglini@arm.com *os << " "; 274613481Sgiacomo.travaglini@arm.com mono_tuple_matcher_.DescribeNegationTo(os); 274713481Sgiacomo.travaglini@arm.com } 274813481Sgiacomo.travaglini@arm.com 274913481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(LhsContainer lhs, 275013481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 275113481Sgiacomo.travaglini@arm.com LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); 275213481Sgiacomo.travaglini@arm.com const size_t actual_size = lhs_stl_container.size(); 275313481Sgiacomo.travaglini@arm.com if (actual_size != rhs_.size()) { 275413481Sgiacomo.travaglini@arm.com *listener << "which contains " << actual_size << " values"; 275513481Sgiacomo.travaglini@arm.com return false; 275613481Sgiacomo.travaglini@arm.com } 275713481Sgiacomo.travaglini@arm.com 275813481Sgiacomo.travaglini@arm.com typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); 275913481Sgiacomo.travaglini@arm.com typename RhsStlContainer::const_iterator right = rhs_.begin(); 276013481Sgiacomo.travaglini@arm.com for (size_t i = 0; i != actual_size; ++i, ++left, ++right) { 276113481Sgiacomo.travaglini@arm.com const InnerMatcherArg value_pair(*left, *right); 276213481Sgiacomo.travaglini@arm.com 276313481Sgiacomo.travaglini@arm.com if (listener->IsInterested()) { 276413481Sgiacomo.travaglini@arm.com StringMatchResultListener inner_listener; 276513481Sgiacomo.travaglini@arm.com if (!mono_tuple_matcher_.MatchAndExplain( 276613481Sgiacomo.travaglini@arm.com value_pair, &inner_listener)) { 276713481Sgiacomo.travaglini@arm.com *listener << "where the value pair ("; 276813481Sgiacomo.travaglini@arm.com UniversalPrint(*left, listener->stream()); 276913481Sgiacomo.travaglini@arm.com *listener << ", "; 277013481Sgiacomo.travaglini@arm.com UniversalPrint(*right, listener->stream()); 277113481Sgiacomo.travaglini@arm.com *listener << ") at index #" << i << " don't match"; 277213481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(inner_listener.str(), listener->stream()); 277313481Sgiacomo.travaglini@arm.com return false; 277413481Sgiacomo.travaglini@arm.com } 277513481Sgiacomo.travaglini@arm.com } else { 277613481Sgiacomo.travaglini@arm.com if (!mono_tuple_matcher_.Matches(value_pair)) 277713481Sgiacomo.travaglini@arm.com return false; 277813481Sgiacomo.travaglini@arm.com } 277913481Sgiacomo.travaglini@arm.com } 278013481Sgiacomo.travaglini@arm.com 278113481Sgiacomo.travaglini@arm.com return true; 278213481Sgiacomo.travaglini@arm.com } 278313481Sgiacomo.travaglini@arm.com 278413481Sgiacomo.travaglini@arm.com private: 278513481Sgiacomo.travaglini@arm.com const Matcher<InnerMatcherArg> mono_tuple_matcher_; 278613481Sgiacomo.travaglini@arm.com const RhsStlContainer rhs_; 278713481Sgiacomo.travaglini@arm.com 278813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 278913481Sgiacomo.travaglini@arm.com }; 279013481Sgiacomo.travaglini@arm.com 279113481Sgiacomo.travaglini@arm.com private: 279213481Sgiacomo.travaglini@arm.com const TupleMatcher tuple_matcher_; 279313481Sgiacomo.travaglini@arm.com const RhsStlContainer rhs_; 279413481Sgiacomo.travaglini@arm.com 279513481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PointwiseMatcher); 279613481Sgiacomo.travaglini@arm.com}; 279713481Sgiacomo.travaglini@arm.com 279813481Sgiacomo.travaglini@arm.com// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl. 279913481Sgiacomo.travaglini@arm.comtemplate <typename Container> 280013481Sgiacomo.travaglini@arm.comclass QuantifierMatcherImpl : public MatcherInterface<Container> { 280113481Sgiacomo.travaglini@arm.com public: 280213481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; 280313481Sgiacomo.travaglini@arm.com typedef StlContainerView<RawContainer> View; 280413481Sgiacomo.travaglini@arm.com typedef typename View::type StlContainer; 280513481Sgiacomo.travaglini@arm.com typedef typename View::const_reference StlContainerReference; 280613481Sgiacomo.travaglini@arm.com typedef typename StlContainer::value_type Element; 280713481Sgiacomo.travaglini@arm.com 280813481Sgiacomo.travaglini@arm.com template <typename InnerMatcher> 280913481Sgiacomo.travaglini@arm.com explicit QuantifierMatcherImpl(InnerMatcher inner_matcher) 281013481Sgiacomo.travaglini@arm.com : inner_matcher_( 281113481Sgiacomo.travaglini@arm.com testing::SafeMatcherCast<const Element&>(inner_matcher)) {} 281213481Sgiacomo.travaglini@arm.com 281313481Sgiacomo.travaglini@arm.com // Checks whether: 281413481Sgiacomo.travaglini@arm.com // * All elements in the container match, if all_elements_should_match. 281513481Sgiacomo.travaglini@arm.com // * Any element in the container matches, if !all_elements_should_match. 281613481Sgiacomo.travaglini@arm.com bool MatchAndExplainImpl(bool all_elements_should_match, 281713481Sgiacomo.travaglini@arm.com Container container, 281813481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 281913481Sgiacomo.travaglini@arm.com StlContainerReference stl_container = View::ConstReference(container); 282013481Sgiacomo.travaglini@arm.com size_t i = 0; 282113481Sgiacomo.travaglini@arm.com for (typename StlContainer::const_iterator it = stl_container.begin(); 282213481Sgiacomo.travaglini@arm.com it != stl_container.end(); ++it, ++i) { 282313481Sgiacomo.travaglini@arm.com StringMatchResultListener inner_listener; 282413481Sgiacomo.travaglini@arm.com const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener); 282513481Sgiacomo.travaglini@arm.com 282613481Sgiacomo.travaglini@arm.com if (matches != all_elements_should_match) { 282713481Sgiacomo.travaglini@arm.com *listener << "whose element #" << i 282813481Sgiacomo.travaglini@arm.com << (matches ? " matches" : " doesn't match"); 282913481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(inner_listener.str(), listener->stream()); 283013481Sgiacomo.travaglini@arm.com return !all_elements_should_match; 283113481Sgiacomo.travaglini@arm.com } 283213481Sgiacomo.travaglini@arm.com } 283313481Sgiacomo.travaglini@arm.com return all_elements_should_match; 283413481Sgiacomo.travaglini@arm.com } 283513481Sgiacomo.travaglini@arm.com 283613481Sgiacomo.travaglini@arm.com protected: 283713481Sgiacomo.travaglini@arm.com const Matcher<const Element&> inner_matcher_; 283813481Sgiacomo.travaglini@arm.com 283913481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl); 284013481Sgiacomo.travaglini@arm.com}; 284113481Sgiacomo.travaglini@arm.com 284213481Sgiacomo.travaglini@arm.com// Implements Contains(element_matcher) for the given argument type Container. 284313481Sgiacomo.travaglini@arm.com// Symmetric to EachMatcherImpl. 284413481Sgiacomo.travaglini@arm.comtemplate <typename Container> 284513481Sgiacomo.travaglini@arm.comclass ContainsMatcherImpl : public QuantifierMatcherImpl<Container> { 284613481Sgiacomo.travaglini@arm.com public: 284713481Sgiacomo.travaglini@arm.com template <typename InnerMatcher> 284813481Sgiacomo.travaglini@arm.com explicit ContainsMatcherImpl(InnerMatcher inner_matcher) 284913481Sgiacomo.travaglini@arm.com : QuantifierMatcherImpl<Container>(inner_matcher) {} 285013481Sgiacomo.travaglini@arm.com 285113481Sgiacomo.travaglini@arm.com // Describes what this matcher does. 285213481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 285313481Sgiacomo.travaglini@arm.com *os << "contains at least one element that "; 285413481Sgiacomo.travaglini@arm.com this->inner_matcher_.DescribeTo(os); 285513481Sgiacomo.travaglini@arm.com } 285613481Sgiacomo.travaglini@arm.com 285713481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 285813481Sgiacomo.travaglini@arm.com *os << "doesn't contain any element that "; 285913481Sgiacomo.travaglini@arm.com this->inner_matcher_.DescribeTo(os); 286013481Sgiacomo.travaglini@arm.com } 286113481Sgiacomo.travaglini@arm.com 286213481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Container container, 286313481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 286413481Sgiacomo.travaglini@arm.com return this->MatchAndExplainImpl(false, container, listener); 286513481Sgiacomo.travaglini@arm.com } 286613481Sgiacomo.travaglini@arm.com 286713481Sgiacomo.travaglini@arm.com private: 286813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl); 286913481Sgiacomo.travaglini@arm.com}; 287013481Sgiacomo.travaglini@arm.com 287113481Sgiacomo.travaglini@arm.com// Implements Each(element_matcher) for the given argument type Container. 287213481Sgiacomo.travaglini@arm.com// Symmetric to ContainsMatcherImpl. 287313481Sgiacomo.travaglini@arm.comtemplate <typename Container> 287413481Sgiacomo.travaglini@arm.comclass EachMatcherImpl : public QuantifierMatcherImpl<Container> { 287513481Sgiacomo.travaglini@arm.com public: 287613481Sgiacomo.travaglini@arm.com template <typename InnerMatcher> 287713481Sgiacomo.travaglini@arm.com explicit EachMatcherImpl(InnerMatcher inner_matcher) 287813481Sgiacomo.travaglini@arm.com : QuantifierMatcherImpl<Container>(inner_matcher) {} 287913481Sgiacomo.travaglini@arm.com 288013481Sgiacomo.travaglini@arm.com // Describes what this matcher does. 288113481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 288213481Sgiacomo.travaglini@arm.com *os << "only contains elements that "; 288313481Sgiacomo.travaglini@arm.com this->inner_matcher_.DescribeTo(os); 288413481Sgiacomo.travaglini@arm.com } 288513481Sgiacomo.travaglini@arm.com 288613481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 288713481Sgiacomo.travaglini@arm.com *os << "contains some element that "; 288813481Sgiacomo.travaglini@arm.com this->inner_matcher_.DescribeNegationTo(os); 288913481Sgiacomo.travaglini@arm.com } 289013481Sgiacomo.travaglini@arm.com 289113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Container container, 289213481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 289313481Sgiacomo.travaglini@arm.com return this->MatchAndExplainImpl(true, container, listener); 289413481Sgiacomo.travaglini@arm.com } 289513481Sgiacomo.travaglini@arm.com 289613481Sgiacomo.travaglini@arm.com private: 289713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(EachMatcherImpl); 289813481Sgiacomo.travaglini@arm.com}; 289913481Sgiacomo.travaglini@arm.com 290013481Sgiacomo.travaglini@arm.com// Implements polymorphic Contains(element_matcher). 290113481Sgiacomo.travaglini@arm.comtemplate <typename M> 290213481Sgiacomo.travaglini@arm.comclass ContainsMatcher { 290313481Sgiacomo.travaglini@arm.com public: 290413481Sgiacomo.travaglini@arm.com explicit ContainsMatcher(M m) : inner_matcher_(m) {} 290513481Sgiacomo.travaglini@arm.com 290613481Sgiacomo.travaglini@arm.com template <typename Container> 290713481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 290813481Sgiacomo.travaglini@arm.com return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_)); 290913481Sgiacomo.travaglini@arm.com } 291013481Sgiacomo.travaglini@arm.com 291113481Sgiacomo.travaglini@arm.com private: 291213481Sgiacomo.travaglini@arm.com const M inner_matcher_; 291313481Sgiacomo.travaglini@arm.com 291413481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ContainsMatcher); 291513481Sgiacomo.travaglini@arm.com}; 291613481Sgiacomo.travaglini@arm.com 291713481Sgiacomo.travaglini@arm.com// Implements polymorphic Each(element_matcher). 291813481Sgiacomo.travaglini@arm.comtemplate <typename M> 291913481Sgiacomo.travaglini@arm.comclass EachMatcher { 292013481Sgiacomo.travaglini@arm.com public: 292113481Sgiacomo.travaglini@arm.com explicit EachMatcher(M m) : inner_matcher_(m) {} 292213481Sgiacomo.travaglini@arm.com 292313481Sgiacomo.travaglini@arm.com template <typename Container> 292413481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 292513481Sgiacomo.travaglini@arm.com return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_)); 292613481Sgiacomo.travaglini@arm.com } 292713481Sgiacomo.travaglini@arm.com 292813481Sgiacomo.travaglini@arm.com private: 292913481Sgiacomo.travaglini@arm.com const M inner_matcher_; 293013481Sgiacomo.travaglini@arm.com 293113481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(EachMatcher); 293213481Sgiacomo.travaglini@arm.com}; 293313481Sgiacomo.travaglini@arm.com 293413481Sgiacomo.travaglini@arm.com// Implements Key(inner_matcher) for the given argument pair type. 293513481Sgiacomo.travaglini@arm.com// Key(inner_matcher) matches an std::pair whose 'first' field matches 293613481Sgiacomo.travaglini@arm.com// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an 293713481Sgiacomo.travaglini@arm.com// std::map that contains at least one element whose key is >= 5. 293813481Sgiacomo.travaglini@arm.comtemplate <typename PairType> 293913481Sgiacomo.travaglini@arm.comclass KeyMatcherImpl : public MatcherInterface<PairType> { 294013481Sgiacomo.travaglini@arm.com public: 294113481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; 294213481Sgiacomo.travaglini@arm.com typedef typename RawPairType::first_type KeyType; 294313481Sgiacomo.travaglini@arm.com 294413481Sgiacomo.travaglini@arm.com template <typename InnerMatcher> 294513481Sgiacomo.travaglini@arm.com explicit KeyMatcherImpl(InnerMatcher inner_matcher) 294613481Sgiacomo.travaglini@arm.com : inner_matcher_( 294713481Sgiacomo.travaglini@arm.com testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { 294813481Sgiacomo.travaglini@arm.com } 294913481Sgiacomo.travaglini@arm.com 295013481Sgiacomo.travaglini@arm.com // Returns true iff 'key_value.first' (the key) matches the inner matcher. 295113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(PairType key_value, 295213481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 295313481Sgiacomo.travaglini@arm.com StringMatchResultListener inner_listener; 295413481Sgiacomo.travaglini@arm.com const bool match = inner_matcher_.MatchAndExplain(key_value.first, 295513481Sgiacomo.travaglini@arm.com &inner_listener); 295613481Sgiacomo.travaglini@arm.com const internal::string explanation = inner_listener.str(); 295713481Sgiacomo.travaglini@arm.com if (explanation != "") { 295813481Sgiacomo.travaglini@arm.com *listener << "whose first field is a value " << explanation; 295913481Sgiacomo.travaglini@arm.com } 296013481Sgiacomo.travaglini@arm.com return match; 296113481Sgiacomo.travaglini@arm.com } 296213481Sgiacomo.travaglini@arm.com 296313481Sgiacomo.travaglini@arm.com // Describes what this matcher does. 296413481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 296513481Sgiacomo.travaglini@arm.com *os << "has a key that "; 296613481Sgiacomo.travaglini@arm.com inner_matcher_.DescribeTo(os); 296713481Sgiacomo.travaglini@arm.com } 296813481Sgiacomo.travaglini@arm.com 296913481Sgiacomo.travaglini@arm.com // Describes what the negation of this matcher does. 297013481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 297113481Sgiacomo.travaglini@arm.com *os << "doesn't have a key that "; 297213481Sgiacomo.travaglini@arm.com inner_matcher_.DescribeTo(os); 297313481Sgiacomo.travaglini@arm.com } 297413481Sgiacomo.travaglini@arm.com 297513481Sgiacomo.travaglini@arm.com private: 297613481Sgiacomo.travaglini@arm.com const Matcher<const KeyType&> inner_matcher_; 297713481Sgiacomo.travaglini@arm.com 297813481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl); 297913481Sgiacomo.travaglini@arm.com}; 298013481Sgiacomo.travaglini@arm.com 298113481Sgiacomo.travaglini@arm.com// Implements polymorphic Key(matcher_for_key). 298213481Sgiacomo.travaglini@arm.comtemplate <typename M> 298313481Sgiacomo.travaglini@arm.comclass KeyMatcher { 298413481Sgiacomo.travaglini@arm.com public: 298513481Sgiacomo.travaglini@arm.com explicit KeyMatcher(M m) : matcher_for_key_(m) {} 298613481Sgiacomo.travaglini@arm.com 298713481Sgiacomo.travaglini@arm.com template <typename PairType> 298813481Sgiacomo.travaglini@arm.com operator Matcher<PairType>() const { 298913481Sgiacomo.travaglini@arm.com return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_)); 299013481Sgiacomo.travaglini@arm.com } 299113481Sgiacomo.travaglini@arm.com 299213481Sgiacomo.travaglini@arm.com private: 299313481Sgiacomo.travaglini@arm.com const M matcher_for_key_; 299413481Sgiacomo.travaglini@arm.com 299513481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(KeyMatcher); 299613481Sgiacomo.travaglini@arm.com}; 299713481Sgiacomo.travaglini@arm.com 299813481Sgiacomo.travaglini@arm.com// Implements Pair(first_matcher, second_matcher) for the given argument pair 299913481Sgiacomo.travaglini@arm.com// type with its two matchers. See Pair() function below. 300013481Sgiacomo.travaglini@arm.comtemplate <typename PairType> 300113481Sgiacomo.travaglini@arm.comclass PairMatcherImpl : public MatcherInterface<PairType> { 300213481Sgiacomo.travaglini@arm.com public: 300313481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; 300413481Sgiacomo.travaglini@arm.com typedef typename RawPairType::first_type FirstType; 300513481Sgiacomo.travaglini@arm.com typedef typename RawPairType::second_type SecondType; 300613481Sgiacomo.travaglini@arm.com 300713481Sgiacomo.travaglini@arm.com template <typename FirstMatcher, typename SecondMatcher> 300813481Sgiacomo.travaglini@arm.com PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher) 300913481Sgiacomo.travaglini@arm.com : first_matcher_( 301013481Sgiacomo.travaglini@arm.com testing::SafeMatcherCast<const FirstType&>(first_matcher)), 301113481Sgiacomo.travaglini@arm.com second_matcher_( 301213481Sgiacomo.travaglini@arm.com testing::SafeMatcherCast<const SecondType&>(second_matcher)) { 301313481Sgiacomo.travaglini@arm.com } 301413481Sgiacomo.travaglini@arm.com 301513481Sgiacomo.travaglini@arm.com // Describes what this matcher does. 301613481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 301713481Sgiacomo.travaglini@arm.com *os << "has a first field that "; 301813481Sgiacomo.travaglini@arm.com first_matcher_.DescribeTo(os); 301913481Sgiacomo.travaglini@arm.com *os << ", and has a second field that "; 302013481Sgiacomo.travaglini@arm.com second_matcher_.DescribeTo(os); 302113481Sgiacomo.travaglini@arm.com } 302213481Sgiacomo.travaglini@arm.com 302313481Sgiacomo.travaglini@arm.com // Describes what the negation of this matcher does. 302413481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 302513481Sgiacomo.travaglini@arm.com *os << "has a first field that "; 302613481Sgiacomo.travaglini@arm.com first_matcher_.DescribeNegationTo(os); 302713481Sgiacomo.travaglini@arm.com *os << ", or has a second field that "; 302813481Sgiacomo.travaglini@arm.com second_matcher_.DescribeNegationTo(os); 302913481Sgiacomo.travaglini@arm.com } 303013481Sgiacomo.travaglini@arm.com 303113481Sgiacomo.travaglini@arm.com // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second' 303213481Sgiacomo.travaglini@arm.com // matches second_matcher. 303313481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(PairType a_pair, 303413481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 303513481Sgiacomo.travaglini@arm.com if (!listener->IsInterested()) { 303613481Sgiacomo.travaglini@arm.com // If the listener is not interested, we don't need to construct the 303713481Sgiacomo.travaglini@arm.com // explanation. 303813481Sgiacomo.travaglini@arm.com return first_matcher_.Matches(a_pair.first) && 303913481Sgiacomo.travaglini@arm.com second_matcher_.Matches(a_pair.second); 304013481Sgiacomo.travaglini@arm.com } 304113481Sgiacomo.travaglini@arm.com StringMatchResultListener first_inner_listener; 304213481Sgiacomo.travaglini@arm.com if (!first_matcher_.MatchAndExplain(a_pair.first, 304313481Sgiacomo.travaglini@arm.com &first_inner_listener)) { 304413481Sgiacomo.travaglini@arm.com *listener << "whose first field does not match"; 304513481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(first_inner_listener.str(), listener->stream()); 304613481Sgiacomo.travaglini@arm.com return false; 304713481Sgiacomo.travaglini@arm.com } 304813481Sgiacomo.travaglini@arm.com StringMatchResultListener second_inner_listener; 304913481Sgiacomo.travaglini@arm.com if (!second_matcher_.MatchAndExplain(a_pair.second, 305013481Sgiacomo.travaglini@arm.com &second_inner_listener)) { 305113481Sgiacomo.travaglini@arm.com *listener << "whose second field does not match"; 305213481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(second_inner_listener.str(), listener->stream()); 305313481Sgiacomo.travaglini@arm.com return false; 305413481Sgiacomo.travaglini@arm.com } 305513481Sgiacomo.travaglini@arm.com ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(), 305613481Sgiacomo.travaglini@arm.com listener); 305713481Sgiacomo.travaglini@arm.com return true; 305813481Sgiacomo.travaglini@arm.com } 305913481Sgiacomo.travaglini@arm.com 306013481Sgiacomo.travaglini@arm.com private: 306113481Sgiacomo.travaglini@arm.com void ExplainSuccess(const internal::string& first_explanation, 306213481Sgiacomo.travaglini@arm.com const internal::string& second_explanation, 306313481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 306413481Sgiacomo.travaglini@arm.com *listener << "whose both fields match"; 306513481Sgiacomo.travaglini@arm.com if (first_explanation != "") { 306613481Sgiacomo.travaglini@arm.com *listener << ", where the first field is a value " << first_explanation; 306713481Sgiacomo.travaglini@arm.com } 306813481Sgiacomo.travaglini@arm.com if (second_explanation != "") { 306913481Sgiacomo.travaglini@arm.com *listener << ", "; 307013481Sgiacomo.travaglini@arm.com if (first_explanation != "") { 307113481Sgiacomo.travaglini@arm.com *listener << "and "; 307213481Sgiacomo.travaglini@arm.com } else { 307313481Sgiacomo.travaglini@arm.com *listener << "where "; 307413481Sgiacomo.travaglini@arm.com } 307513481Sgiacomo.travaglini@arm.com *listener << "the second field is a value " << second_explanation; 307613481Sgiacomo.travaglini@arm.com } 307713481Sgiacomo.travaglini@arm.com } 307813481Sgiacomo.travaglini@arm.com 307913481Sgiacomo.travaglini@arm.com const Matcher<const FirstType&> first_matcher_; 308013481Sgiacomo.travaglini@arm.com const Matcher<const SecondType&> second_matcher_; 308113481Sgiacomo.travaglini@arm.com 308213481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PairMatcherImpl); 308313481Sgiacomo.travaglini@arm.com}; 308413481Sgiacomo.travaglini@arm.com 308513481Sgiacomo.travaglini@arm.com// Implements polymorphic Pair(first_matcher, second_matcher). 308613481Sgiacomo.travaglini@arm.comtemplate <typename FirstMatcher, typename SecondMatcher> 308713481Sgiacomo.travaglini@arm.comclass PairMatcher { 308813481Sgiacomo.travaglini@arm.com public: 308913481Sgiacomo.travaglini@arm.com PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher) 309013481Sgiacomo.travaglini@arm.com : first_matcher_(first_matcher), second_matcher_(second_matcher) {} 309113481Sgiacomo.travaglini@arm.com 309213481Sgiacomo.travaglini@arm.com template <typename PairType> 309313481Sgiacomo.travaglini@arm.com operator Matcher<PairType> () const { 309413481Sgiacomo.travaglini@arm.com return MakeMatcher( 309513481Sgiacomo.travaglini@arm.com new PairMatcherImpl<PairType>( 309613481Sgiacomo.travaglini@arm.com first_matcher_, second_matcher_)); 309713481Sgiacomo.travaglini@arm.com } 309813481Sgiacomo.travaglini@arm.com 309913481Sgiacomo.travaglini@arm.com private: 310013481Sgiacomo.travaglini@arm.com const FirstMatcher first_matcher_; 310113481Sgiacomo.travaglini@arm.com const SecondMatcher second_matcher_; 310213481Sgiacomo.travaglini@arm.com 310313481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(PairMatcher); 310413481Sgiacomo.travaglini@arm.com}; 310513481Sgiacomo.travaglini@arm.com 310613481Sgiacomo.travaglini@arm.com// Implements ElementsAre() and ElementsAreArray(). 310713481Sgiacomo.travaglini@arm.comtemplate <typename Container> 310813481Sgiacomo.travaglini@arm.comclass ElementsAreMatcherImpl : public MatcherInterface<Container> { 310913481Sgiacomo.travaglini@arm.com public: 311013481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; 311113481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView<RawContainer> View; 311213481Sgiacomo.travaglini@arm.com typedef typename View::type StlContainer; 311313481Sgiacomo.travaglini@arm.com typedef typename View::const_reference StlContainerReference; 311413481Sgiacomo.travaglini@arm.com typedef typename StlContainer::value_type Element; 311513481Sgiacomo.travaglini@arm.com 311613481Sgiacomo.travaglini@arm.com // Constructs the matcher from a sequence of element values or 311713481Sgiacomo.travaglini@arm.com // element matchers. 311813481Sgiacomo.travaglini@arm.com template <typename InputIter> 311913481Sgiacomo.travaglini@arm.com ElementsAreMatcherImpl(InputIter first, InputIter last) { 312013481Sgiacomo.travaglini@arm.com while (first != last) { 312113481Sgiacomo.travaglini@arm.com matchers_.push_back(MatcherCast<const Element&>(*first++)); 312213481Sgiacomo.travaglini@arm.com } 312313481Sgiacomo.travaglini@arm.com } 312413481Sgiacomo.travaglini@arm.com 312513481Sgiacomo.travaglini@arm.com // Describes what this matcher does. 312613481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 312713481Sgiacomo.travaglini@arm.com if (count() == 0) { 312813481Sgiacomo.travaglini@arm.com *os << "is empty"; 312913481Sgiacomo.travaglini@arm.com } else if (count() == 1) { 313013481Sgiacomo.travaglini@arm.com *os << "has 1 element that "; 313113481Sgiacomo.travaglini@arm.com matchers_[0].DescribeTo(os); 313213481Sgiacomo.travaglini@arm.com } else { 313313481Sgiacomo.travaglini@arm.com *os << "has " << Elements(count()) << " where\n"; 313413481Sgiacomo.travaglini@arm.com for (size_t i = 0; i != count(); ++i) { 313513481Sgiacomo.travaglini@arm.com *os << "element #" << i << " "; 313613481Sgiacomo.travaglini@arm.com matchers_[i].DescribeTo(os); 313713481Sgiacomo.travaglini@arm.com if (i + 1 < count()) { 313813481Sgiacomo.travaglini@arm.com *os << ",\n"; 313913481Sgiacomo.travaglini@arm.com } 314013481Sgiacomo.travaglini@arm.com } 314113481Sgiacomo.travaglini@arm.com } 314213481Sgiacomo.travaglini@arm.com } 314313481Sgiacomo.travaglini@arm.com 314413481Sgiacomo.travaglini@arm.com // Describes what the negation of this matcher does. 314513481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 314613481Sgiacomo.travaglini@arm.com if (count() == 0) { 314713481Sgiacomo.travaglini@arm.com *os << "isn't empty"; 314813481Sgiacomo.travaglini@arm.com return; 314913481Sgiacomo.travaglini@arm.com } 315013481Sgiacomo.travaglini@arm.com 315113481Sgiacomo.travaglini@arm.com *os << "doesn't have " << Elements(count()) << ", or\n"; 315213481Sgiacomo.travaglini@arm.com for (size_t i = 0; i != count(); ++i) { 315313481Sgiacomo.travaglini@arm.com *os << "element #" << i << " "; 315413481Sgiacomo.travaglini@arm.com matchers_[i].DescribeNegationTo(os); 315513481Sgiacomo.travaglini@arm.com if (i + 1 < count()) { 315613481Sgiacomo.travaglini@arm.com *os << ", or\n"; 315713481Sgiacomo.travaglini@arm.com } 315813481Sgiacomo.travaglini@arm.com } 315913481Sgiacomo.travaglini@arm.com } 316013481Sgiacomo.travaglini@arm.com 316113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Container container, 316213481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 316313481Sgiacomo.travaglini@arm.com // To work with stream-like "containers", we must only walk 316413481Sgiacomo.travaglini@arm.com // through the elements in one pass. 316513481Sgiacomo.travaglini@arm.com 316613481Sgiacomo.travaglini@arm.com const bool listener_interested = listener->IsInterested(); 316713481Sgiacomo.travaglini@arm.com 316813481Sgiacomo.travaglini@arm.com // explanations[i] is the explanation of the element at index i. 316913481Sgiacomo.travaglini@arm.com ::std::vector<internal::string> explanations(count()); 317013481Sgiacomo.travaglini@arm.com StlContainerReference stl_container = View::ConstReference(container); 317113481Sgiacomo.travaglini@arm.com typename StlContainer::const_iterator it = stl_container.begin(); 317213481Sgiacomo.travaglini@arm.com size_t exam_pos = 0; 317313481Sgiacomo.travaglini@arm.com bool mismatch_found = false; // Have we found a mismatched element yet? 317413481Sgiacomo.travaglini@arm.com 317513481Sgiacomo.travaglini@arm.com // Go through the elements and matchers in pairs, until we reach 317613481Sgiacomo.travaglini@arm.com // the end of either the elements or the matchers, or until we find a 317713481Sgiacomo.travaglini@arm.com // mismatch. 317813481Sgiacomo.travaglini@arm.com for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) { 317913481Sgiacomo.travaglini@arm.com bool match; // Does the current element match the current matcher? 318013481Sgiacomo.travaglini@arm.com if (listener_interested) { 318113481Sgiacomo.travaglini@arm.com StringMatchResultListener s; 318213481Sgiacomo.travaglini@arm.com match = matchers_[exam_pos].MatchAndExplain(*it, &s); 318313481Sgiacomo.travaglini@arm.com explanations[exam_pos] = s.str(); 318413481Sgiacomo.travaglini@arm.com } else { 318513481Sgiacomo.travaglini@arm.com match = matchers_[exam_pos].Matches(*it); 318613481Sgiacomo.travaglini@arm.com } 318713481Sgiacomo.travaglini@arm.com 318813481Sgiacomo.travaglini@arm.com if (!match) { 318913481Sgiacomo.travaglini@arm.com mismatch_found = true; 319013481Sgiacomo.travaglini@arm.com break; 319113481Sgiacomo.travaglini@arm.com } 319213481Sgiacomo.travaglini@arm.com } 319313481Sgiacomo.travaglini@arm.com // If mismatch_found is true, 'exam_pos' is the index of the mismatch. 319413481Sgiacomo.travaglini@arm.com 319513481Sgiacomo.travaglini@arm.com // Find how many elements the actual container has. We avoid 319613481Sgiacomo.travaglini@arm.com // calling size() s.t. this code works for stream-like "containers" 319713481Sgiacomo.travaglini@arm.com // that don't define size(). 319813481Sgiacomo.travaglini@arm.com size_t actual_count = exam_pos; 319913481Sgiacomo.travaglini@arm.com for (; it != stl_container.end(); ++it) { 320013481Sgiacomo.travaglini@arm.com ++actual_count; 320113481Sgiacomo.travaglini@arm.com } 320213481Sgiacomo.travaglini@arm.com 320313481Sgiacomo.travaglini@arm.com if (actual_count != count()) { 320413481Sgiacomo.travaglini@arm.com // The element count doesn't match. If the container is empty, 320513481Sgiacomo.travaglini@arm.com // there's no need to explain anything as Google Mock already 320613481Sgiacomo.travaglini@arm.com // prints the empty container. Otherwise we just need to show 320713481Sgiacomo.travaglini@arm.com // how many elements there actually are. 320813481Sgiacomo.travaglini@arm.com if (listener_interested && (actual_count != 0)) { 320913481Sgiacomo.travaglini@arm.com *listener << "which has " << Elements(actual_count); 321013481Sgiacomo.travaglini@arm.com } 321113481Sgiacomo.travaglini@arm.com return false; 321213481Sgiacomo.travaglini@arm.com } 321313481Sgiacomo.travaglini@arm.com 321413481Sgiacomo.travaglini@arm.com if (mismatch_found) { 321513481Sgiacomo.travaglini@arm.com // The element count matches, but the exam_pos-th element doesn't match. 321613481Sgiacomo.travaglini@arm.com if (listener_interested) { 321713481Sgiacomo.travaglini@arm.com *listener << "whose element #" << exam_pos << " doesn't match"; 321813481Sgiacomo.travaglini@arm.com PrintIfNotEmpty(explanations[exam_pos], listener->stream()); 321913481Sgiacomo.travaglini@arm.com } 322013481Sgiacomo.travaglini@arm.com return false; 322113481Sgiacomo.travaglini@arm.com } 322213481Sgiacomo.travaglini@arm.com 322313481Sgiacomo.travaglini@arm.com // Every element matches its expectation. We need to explain why 322413481Sgiacomo.travaglini@arm.com // (the obvious ones can be skipped). 322513481Sgiacomo.travaglini@arm.com if (listener_interested) { 322613481Sgiacomo.travaglini@arm.com bool reason_printed = false; 322713481Sgiacomo.travaglini@arm.com for (size_t i = 0; i != count(); ++i) { 322813481Sgiacomo.travaglini@arm.com const internal::string& s = explanations[i]; 322913481Sgiacomo.travaglini@arm.com if (!s.empty()) { 323013481Sgiacomo.travaglini@arm.com if (reason_printed) { 323113481Sgiacomo.travaglini@arm.com *listener << ",\nand "; 323213481Sgiacomo.travaglini@arm.com } 323313481Sgiacomo.travaglini@arm.com *listener << "whose element #" << i << " matches, " << s; 323413481Sgiacomo.travaglini@arm.com reason_printed = true; 323513481Sgiacomo.travaglini@arm.com } 323613481Sgiacomo.travaglini@arm.com } 323713481Sgiacomo.travaglini@arm.com } 323813481Sgiacomo.travaglini@arm.com return true; 323913481Sgiacomo.travaglini@arm.com } 324013481Sgiacomo.travaglini@arm.com 324113481Sgiacomo.travaglini@arm.com private: 324213481Sgiacomo.travaglini@arm.com static Message Elements(size_t count) { 324313481Sgiacomo.travaglini@arm.com return Message() << count << (count == 1 ? " element" : " elements"); 324413481Sgiacomo.travaglini@arm.com } 324513481Sgiacomo.travaglini@arm.com 324613481Sgiacomo.travaglini@arm.com size_t count() const { return matchers_.size(); } 324713481Sgiacomo.travaglini@arm.com 324813481Sgiacomo.travaglini@arm.com ::std::vector<Matcher<const Element&> > matchers_; 324913481Sgiacomo.travaglini@arm.com 325013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl); 325113481Sgiacomo.travaglini@arm.com}; 325213481Sgiacomo.travaglini@arm.com 325313481Sgiacomo.travaglini@arm.com// Connectivity matrix of (elements X matchers), in element-major order. 325413481Sgiacomo.travaglini@arm.com// Initially, there are no edges. 325513481Sgiacomo.travaglini@arm.com// Use NextGraph() to iterate over all possible edge configurations. 325613481Sgiacomo.travaglini@arm.com// Use Randomize() to generate a random edge configuration. 325713481Sgiacomo.travaglini@arm.comclass GTEST_API_ MatchMatrix { 325813481Sgiacomo.travaglini@arm.com public: 325913481Sgiacomo.travaglini@arm.com MatchMatrix(size_t num_elements, size_t num_matchers) 326013481Sgiacomo.travaglini@arm.com : num_elements_(num_elements), 326113481Sgiacomo.travaglini@arm.com num_matchers_(num_matchers), 326213481Sgiacomo.travaglini@arm.com matched_(num_elements_* num_matchers_, 0) { 326313481Sgiacomo.travaglini@arm.com } 326413481Sgiacomo.travaglini@arm.com 326513481Sgiacomo.travaglini@arm.com size_t LhsSize() const { return num_elements_; } 326613481Sgiacomo.travaglini@arm.com size_t RhsSize() const { return num_matchers_; } 326713481Sgiacomo.travaglini@arm.com bool HasEdge(size_t ilhs, size_t irhs) const { 326813481Sgiacomo.travaglini@arm.com return matched_[SpaceIndex(ilhs, irhs)] == 1; 326913481Sgiacomo.travaglini@arm.com } 327013481Sgiacomo.travaglini@arm.com void SetEdge(size_t ilhs, size_t irhs, bool b) { 327113481Sgiacomo.travaglini@arm.com matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0; 327213481Sgiacomo.travaglini@arm.com } 327313481Sgiacomo.travaglini@arm.com 327413481Sgiacomo.travaglini@arm.com // Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number, 327513481Sgiacomo.travaglini@arm.com // adds 1 to that number; returns false if incrementing the graph left it 327613481Sgiacomo.travaglini@arm.com // empty. 327713481Sgiacomo.travaglini@arm.com bool NextGraph(); 327813481Sgiacomo.travaglini@arm.com 327913481Sgiacomo.travaglini@arm.com void Randomize(); 328013481Sgiacomo.travaglini@arm.com 328113481Sgiacomo.travaglini@arm.com string DebugString() const; 328213481Sgiacomo.travaglini@arm.com 328313481Sgiacomo.travaglini@arm.com private: 328413481Sgiacomo.travaglini@arm.com size_t SpaceIndex(size_t ilhs, size_t irhs) const { 328513481Sgiacomo.travaglini@arm.com return ilhs * num_matchers_ + irhs; 328613481Sgiacomo.travaglini@arm.com } 328713481Sgiacomo.travaglini@arm.com 328813481Sgiacomo.travaglini@arm.com size_t num_elements_; 328913481Sgiacomo.travaglini@arm.com size_t num_matchers_; 329013481Sgiacomo.travaglini@arm.com 329113481Sgiacomo.travaglini@arm.com // Each element is a char interpreted as bool. They are stored as a 329213481Sgiacomo.travaglini@arm.com // flattened array in lhs-major order, use 'SpaceIndex()' to translate 329313481Sgiacomo.travaglini@arm.com // a (ilhs, irhs) matrix coordinate into an offset. 329413481Sgiacomo.travaglini@arm.com ::std::vector<char> matched_; 329513481Sgiacomo.travaglini@arm.com}; 329613481Sgiacomo.travaglini@arm.com 329713481Sgiacomo.travaglini@arm.comtypedef ::std::pair<size_t, size_t> ElementMatcherPair; 329813481Sgiacomo.travaglini@arm.comtypedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; 329913481Sgiacomo.travaglini@arm.com 330013481Sgiacomo.travaglini@arm.com// Returns a maximum bipartite matching for the specified graph 'g'. 330113481Sgiacomo.travaglini@arm.com// The matching is represented as a vector of {element, matcher} pairs. 330213481Sgiacomo.travaglini@arm.comGTEST_API_ ElementMatcherPairs 330313481Sgiacomo.travaglini@arm.comFindMaxBipartiteMatching(const MatchMatrix& g); 330413481Sgiacomo.travaglini@arm.com 330513481Sgiacomo.travaglini@arm.comGTEST_API_ bool FindPairing(const MatchMatrix& matrix, 330613481Sgiacomo.travaglini@arm.com MatchResultListener* listener); 330713481Sgiacomo.travaglini@arm.com 330813481Sgiacomo.travaglini@arm.com// Untyped base class for implementing UnorderedElementsAre. By 330913481Sgiacomo.travaglini@arm.com// putting logic that's not specific to the element type here, we 331013481Sgiacomo.travaglini@arm.com// reduce binary bloat and increase compilation speed. 331113481Sgiacomo.travaglini@arm.comclass GTEST_API_ UnorderedElementsAreMatcherImplBase { 331213481Sgiacomo.travaglini@arm.com protected: 331313481Sgiacomo.travaglini@arm.com // A vector of matcher describers, one for each element matcher. 331413481Sgiacomo.travaglini@arm.com // Does not own the describers (and thus can be used only when the 331513481Sgiacomo.travaglini@arm.com // element matchers are alive). 331613481Sgiacomo.travaglini@arm.com typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec; 331713481Sgiacomo.travaglini@arm.com 331813481Sgiacomo.travaglini@arm.com // Describes this UnorderedElementsAre matcher. 331913481Sgiacomo.travaglini@arm.com void DescribeToImpl(::std::ostream* os) const; 332013481Sgiacomo.travaglini@arm.com 332113481Sgiacomo.travaglini@arm.com // Describes the negation of this UnorderedElementsAre matcher. 332213481Sgiacomo.travaglini@arm.com void DescribeNegationToImpl(::std::ostream* os) const; 332313481Sgiacomo.travaglini@arm.com 332413481Sgiacomo.travaglini@arm.com bool VerifyAllElementsAndMatchersAreMatched( 332513481Sgiacomo.travaglini@arm.com const ::std::vector<string>& element_printouts, 332613481Sgiacomo.travaglini@arm.com const MatchMatrix& matrix, 332713481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const; 332813481Sgiacomo.travaglini@arm.com 332913481Sgiacomo.travaglini@arm.com MatcherDescriberVec& matcher_describers() { 333013481Sgiacomo.travaglini@arm.com return matcher_describers_; 333113481Sgiacomo.travaglini@arm.com } 333213481Sgiacomo.travaglini@arm.com 333313481Sgiacomo.travaglini@arm.com static Message Elements(size_t n) { 333413481Sgiacomo.travaglini@arm.com return Message() << n << " element" << (n == 1 ? "" : "s"); 333513481Sgiacomo.travaglini@arm.com } 333613481Sgiacomo.travaglini@arm.com 333713481Sgiacomo.travaglini@arm.com private: 333813481Sgiacomo.travaglini@arm.com MatcherDescriberVec matcher_describers_; 333913481Sgiacomo.travaglini@arm.com 334013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase); 334113481Sgiacomo.travaglini@arm.com}; 334213481Sgiacomo.travaglini@arm.com 334313481Sgiacomo.travaglini@arm.com// Implements unordered ElementsAre and unordered ElementsAreArray. 334413481Sgiacomo.travaglini@arm.comtemplate <typename Container> 334513481Sgiacomo.travaglini@arm.comclass UnorderedElementsAreMatcherImpl 334613481Sgiacomo.travaglini@arm.com : public MatcherInterface<Container>, 334713481Sgiacomo.travaglini@arm.com public UnorderedElementsAreMatcherImplBase { 334813481Sgiacomo.travaglini@arm.com public: 334913481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; 335013481Sgiacomo.travaglini@arm.com typedef internal::StlContainerView<RawContainer> View; 335113481Sgiacomo.travaglini@arm.com typedef typename View::type StlContainer; 335213481Sgiacomo.travaglini@arm.com typedef typename View::const_reference StlContainerReference; 335313481Sgiacomo.travaglini@arm.com typedef typename StlContainer::const_iterator StlContainerConstIterator; 335413481Sgiacomo.travaglini@arm.com typedef typename StlContainer::value_type Element; 335513481Sgiacomo.travaglini@arm.com 335613481Sgiacomo.travaglini@arm.com // Constructs the matcher from a sequence of element values or 335713481Sgiacomo.travaglini@arm.com // element matchers. 335813481Sgiacomo.travaglini@arm.com template <typename InputIter> 335913481Sgiacomo.travaglini@arm.com UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) { 336013481Sgiacomo.travaglini@arm.com for (; first != last; ++first) { 336113481Sgiacomo.travaglini@arm.com matchers_.push_back(MatcherCast<const Element&>(*first)); 336213481Sgiacomo.travaglini@arm.com matcher_describers().push_back(matchers_.back().GetDescriber()); 336313481Sgiacomo.travaglini@arm.com } 336413481Sgiacomo.travaglini@arm.com } 336513481Sgiacomo.travaglini@arm.com 336613481Sgiacomo.travaglini@arm.com // Describes what this matcher does. 336713481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 336813481Sgiacomo.travaglini@arm.com return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os); 336913481Sgiacomo.travaglini@arm.com } 337013481Sgiacomo.travaglini@arm.com 337113481Sgiacomo.travaglini@arm.com // Describes what the negation of this matcher does. 337213481Sgiacomo.travaglini@arm.com virtual void DescribeNegationTo(::std::ostream* os) const { 337313481Sgiacomo.travaglini@arm.com return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os); 337413481Sgiacomo.travaglini@arm.com } 337513481Sgiacomo.travaglini@arm.com 337613481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(Container container, 337713481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 337813481Sgiacomo.travaglini@arm.com StlContainerReference stl_container = View::ConstReference(container); 337913481Sgiacomo.travaglini@arm.com ::std::vector<string> element_printouts; 338013481Sgiacomo.travaglini@arm.com MatchMatrix matrix = AnalyzeElements(stl_container.begin(), 338113481Sgiacomo.travaglini@arm.com stl_container.end(), 338213481Sgiacomo.travaglini@arm.com &element_printouts, 338313481Sgiacomo.travaglini@arm.com listener); 338413481Sgiacomo.travaglini@arm.com 338513481Sgiacomo.travaglini@arm.com const size_t actual_count = matrix.LhsSize(); 338613481Sgiacomo.travaglini@arm.com if (actual_count == 0 && matchers_.empty()) { 338713481Sgiacomo.travaglini@arm.com return true; 338813481Sgiacomo.travaglini@arm.com } 338913481Sgiacomo.travaglini@arm.com if (actual_count != matchers_.size()) { 339013481Sgiacomo.travaglini@arm.com // The element count doesn't match. If the container is empty, 339113481Sgiacomo.travaglini@arm.com // there's no need to explain anything as Google Mock already 339213481Sgiacomo.travaglini@arm.com // prints the empty container. Otherwise we just need to show 339313481Sgiacomo.travaglini@arm.com // how many elements there actually are. 339413481Sgiacomo.travaglini@arm.com if (actual_count != 0 && listener->IsInterested()) { 339513481Sgiacomo.travaglini@arm.com *listener << "which has " << Elements(actual_count); 339613481Sgiacomo.travaglini@arm.com } 339713481Sgiacomo.travaglini@arm.com return false; 339813481Sgiacomo.travaglini@arm.com } 339913481Sgiacomo.travaglini@arm.com 340013481Sgiacomo.travaglini@arm.com return VerifyAllElementsAndMatchersAreMatched(element_printouts, 340113481Sgiacomo.travaglini@arm.com matrix, listener) && 340213481Sgiacomo.travaglini@arm.com FindPairing(matrix, listener); 340313481Sgiacomo.travaglini@arm.com } 340413481Sgiacomo.travaglini@arm.com 340513481Sgiacomo.travaglini@arm.com private: 340613481Sgiacomo.travaglini@arm.com typedef ::std::vector<Matcher<const Element&> > MatcherVec; 340713481Sgiacomo.travaglini@arm.com 340813481Sgiacomo.travaglini@arm.com template <typename ElementIter> 340913481Sgiacomo.travaglini@arm.com MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, 341013481Sgiacomo.travaglini@arm.com ::std::vector<string>* element_printouts, 341113481Sgiacomo.travaglini@arm.com MatchResultListener* listener) const { 341213481Sgiacomo.travaglini@arm.com element_printouts->clear(); 341313481Sgiacomo.travaglini@arm.com ::std::vector<char> did_match; 341413481Sgiacomo.travaglini@arm.com size_t num_elements = 0; 341513481Sgiacomo.travaglini@arm.com for (; elem_first != elem_last; ++num_elements, ++elem_first) { 341613481Sgiacomo.travaglini@arm.com if (listener->IsInterested()) { 341713481Sgiacomo.travaglini@arm.com element_printouts->push_back(PrintToString(*elem_first)); 341813481Sgiacomo.travaglini@arm.com } 341913481Sgiacomo.travaglini@arm.com for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { 342013481Sgiacomo.travaglini@arm.com did_match.push_back(Matches(matchers_[irhs])(*elem_first)); 342113481Sgiacomo.travaglini@arm.com } 342213481Sgiacomo.travaglini@arm.com } 342313481Sgiacomo.travaglini@arm.com 342413481Sgiacomo.travaglini@arm.com MatchMatrix matrix(num_elements, matchers_.size()); 342513481Sgiacomo.travaglini@arm.com ::std::vector<char>::const_iterator did_match_iter = did_match.begin(); 342613481Sgiacomo.travaglini@arm.com for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) { 342713481Sgiacomo.travaglini@arm.com for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { 342813481Sgiacomo.travaglini@arm.com matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0); 342913481Sgiacomo.travaglini@arm.com } 343013481Sgiacomo.travaglini@arm.com } 343113481Sgiacomo.travaglini@arm.com return matrix; 343213481Sgiacomo.travaglini@arm.com } 343313481Sgiacomo.travaglini@arm.com 343413481Sgiacomo.travaglini@arm.com MatcherVec matchers_; 343513481Sgiacomo.travaglini@arm.com 343613481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl); 343713481Sgiacomo.travaglini@arm.com}; 343813481Sgiacomo.travaglini@arm.com 343913481Sgiacomo.travaglini@arm.com// Functor for use in TransformTuple. 344013481Sgiacomo.travaglini@arm.com// Performs MatcherCast<Target> on an input argument of any type. 344113481Sgiacomo.travaglini@arm.comtemplate <typename Target> 344213481Sgiacomo.travaglini@arm.comstruct CastAndAppendTransform { 344313481Sgiacomo.travaglini@arm.com template <typename Arg> 344413481Sgiacomo.travaglini@arm.com Matcher<Target> operator()(const Arg& a) const { 344513481Sgiacomo.travaglini@arm.com return MatcherCast<Target>(a); 344613481Sgiacomo.travaglini@arm.com } 344713481Sgiacomo.travaglini@arm.com}; 344813481Sgiacomo.travaglini@arm.com 344913481Sgiacomo.travaglini@arm.com// Implements UnorderedElementsAre. 345013481Sgiacomo.travaglini@arm.comtemplate <typename MatcherTuple> 345113481Sgiacomo.travaglini@arm.comclass UnorderedElementsAreMatcher { 345213481Sgiacomo.travaglini@arm.com public: 345313481Sgiacomo.travaglini@arm.com explicit UnorderedElementsAreMatcher(const MatcherTuple& args) 345413481Sgiacomo.travaglini@arm.com : matchers_(args) {} 345513481Sgiacomo.travaglini@arm.com 345613481Sgiacomo.travaglini@arm.com template <typename Container> 345713481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 345813481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; 345913481Sgiacomo.travaglini@arm.com typedef typename internal::StlContainerView<RawContainer>::type View; 346013481Sgiacomo.travaglini@arm.com typedef typename View::value_type Element; 346113481Sgiacomo.travaglini@arm.com typedef ::std::vector<Matcher<const Element&> > MatcherVec; 346213481Sgiacomo.travaglini@arm.com MatcherVec matchers; 346313481Sgiacomo.travaglini@arm.com matchers.reserve(::testing::tuple_size<MatcherTuple>::value); 346413481Sgiacomo.travaglini@arm.com TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, 346513481Sgiacomo.travaglini@arm.com ::std::back_inserter(matchers)); 346613481Sgiacomo.travaglini@arm.com return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( 346713481Sgiacomo.travaglini@arm.com matchers.begin(), matchers.end())); 346813481Sgiacomo.travaglini@arm.com } 346913481Sgiacomo.travaglini@arm.com 347013481Sgiacomo.travaglini@arm.com private: 347113481Sgiacomo.travaglini@arm.com const MatcherTuple matchers_; 347213481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher); 347313481Sgiacomo.travaglini@arm.com}; 347413481Sgiacomo.travaglini@arm.com 347513481Sgiacomo.travaglini@arm.com// Implements ElementsAre. 347613481Sgiacomo.travaglini@arm.comtemplate <typename MatcherTuple> 347713481Sgiacomo.travaglini@arm.comclass ElementsAreMatcher { 347813481Sgiacomo.travaglini@arm.com public: 347913481Sgiacomo.travaglini@arm.com explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {} 348013481Sgiacomo.travaglini@arm.com 348113481Sgiacomo.travaglini@arm.com template <typename Container> 348213481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 348313481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; 348413481Sgiacomo.travaglini@arm.com typedef typename internal::StlContainerView<RawContainer>::type View; 348513481Sgiacomo.travaglini@arm.com typedef typename View::value_type Element; 348613481Sgiacomo.travaglini@arm.com typedef ::std::vector<Matcher<const Element&> > MatcherVec; 348713481Sgiacomo.travaglini@arm.com MatcherVec matchers; 348813481Sgiacomo.travaglini@arm.com matchers.reserve(::testing::tuple_size<MatcherTuple>::value); 348913481Sgiacomo.travaglini@arm.com TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, 349013481Sgiacomo.travaglini@arm.com ::std::back_inserter(matchers)); 349113481Sgiacomo.travaglini@arm.com return MakeMatcher(new ElementsAreMatcherImpl<Container>( 349213481Sgiacomo.travaglini@arm.com matchers.begin(), matchers.end())); 349313481Sgiacomo.travaglini@arm.com } 349413481Sgiacomo.travaglini@arm.com 349513481Sgiacomo.travaglini@arm.com private: 349613481Sgiacomo.travaglini@arm.com const MatcherTuple matchers_; 349713481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher); 349813481Sgiacomo.travaglini@arm.com}; 349913481Sgiacomo.travaglini@arm.com 350013481Sgiacomo.travaglini@arm.com// Implements UnorderedElementsAreArray(). 350113481Sgiacomo.travaglini@arm.comtemplate <typename T> 350213481Sgiacomo.travaglini@arm.comclass UnorderedElementsAreArrayMatcher { 350313481Sgiacomo.travaglini@arm.com public: 350413481Sgiacomo.travaglini@arm.com UnorderedElementsAreArrayMatcher() {} 350513481Sgiacomo.travaglini@arm.com 350613481Sgiacomo.travaglini@arm.com template <typename Iter> 350713481Sgiacomo.travaglini@arm.com UnorderedElementsAreArrayMatcher(Iter first, Iter last) 350813481Sgiacomo.travaglini@arm.com : matchers_(first, last) {} 350913481Sgiacomo.travaglini@arm.com 351013481Sgiacomo.travaglini@arm.com template <typename Container> 351113481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 351213481Sgiacomo.travaglini@arm.com return MakeMatcher( 351313481Sgiacomo.travaglini@arm.com new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(), 351413481Sgiacomo.travaglini@arm.com matchers_.end())); 351513481Sgiacomo.travaglini@arm.com } 351613481Sgiacomo.travaglini@arm.com 351713481Sgiacomo.travaglini@arm.com private: 351813481Sgiacomo.travaglini@arm.com ::std::vector<T> matchers_; 351913481Sgiacomo.travaglini@arm.com 352013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher); 352113481Sgiacomo.travaglini@arm.com}; 352213481Sgiacomo.travaglini@arm.com 352313481Sgiacomo.travaglini@arm.com// Implements ElementsAreArray(). 352413481Sgiacomo.travaglini@arm.comtemplate <typename T> 352513481Sgiacomo.travaglini@arm.comclass ElementsAreArrayMatcher { 352613481Sgiacomo.travaglini@arm.com public: 352713481Sgiacomo.travaglini@arm.com template <typename Iter> 352813481Sgiacomo.travaglini@arm.com ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} 352913481Sgiacomo.travaglini@arm.com 353013481Sgiacomo.travaglini@arm.com template <typename Container> 353113481Sgiacomo.travaglini@arm.com operator Matcher<Container>() const { 353213481Sgiacomo.travaglini@arm.com return MakeMatcher(new ElementsAreMatcherImpl<Container>( 353313481Sgiacomo.travaglini@arm.com matchers_.begin(), matchers_.end())); 353413481Sgiacomo.travaglini@arm.com } 353513481Sgiacomo.travaglini@arm.com 353613481Sgiacomo.travaglini@arm.com private: 353713481Sgiacomo.travaglini@arm.com const ::std::vector<T> matchers_; 353813481Sgiacomo.travaglini@arm.com 353913481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher); 354013481Sgiacomo.travaglini@arm.com}; 354113481Sgiacomo.travaglini@arm.com 354213481Sgiacomo.travaglini@arm.com// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second 354313481Sgiacomo.travaglini@arm.com// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm, 354413481Sgiacomo.travaglini@arm.com// second) is a polymorphic matcher that matches a value x iff tm 354513481Sgiacomo.travaglini@arm.com// matches tuple (x, second). Useful for implementing 354613481Sgiacomo.travaglini@arm.com// UnorderedPointwise() in terms of UnorderedElementsAreArray(). 354713481Sgiacomo.travaglini@arm.com// 354813481Sgiacomo.travaglini@arm.com// BoundSecondMatcher is copyable and assignable, as we need to put 354913481Sgiacomo.travaglini@arm.com// instances of this class in a vector when implementing 355013481Sgiacomo.travaglini@arm.com// UnorderedPointwise(). 355113481Sgiacomo.travaglini@arm.comtemplate <typename Tuple2Matcher, typename Second> 355213481Sgiacomo.travaglini@arm.comclass BoundSecondMatcher { 355313481Sgiacomo.travaglini@arm.com public: 355413481Sgiacomo.travaglini@arm.com BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) 355513481Sgiacomo.travaglini@arm.com : tuple2_matcher_(tm), second_value_(second) {} 355613481Sgiacomo.travaglini@arm.com 355713481Sgiacomo.travaglini@arm.com template <typename T> 355813481Sgiacomo.travaglini@arm.com operator Matcher<T>() const { 355913481Sgiacomo.travaglini@arm.com return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); 356013481Sgiacomo.travaglini@arm.com } 356113481Sgiacomo.travaglini@arm.com 356213481Sgiacomo.travaglini@arm.com // We have to define this for UnorderedPointwise() to compile in 356313481Sgiacomo.travaglini@arm.com // C++98 mode, as it puts BoundSecondMatcher instances in a vector, 356413481Sgiacomo.travaglini@arm.com // which requires the elements to be assignable in C++98. The 356513481Sgiacomo.travaglini@arm.com // compiler cannot generate the operator= for us, as Tuple2Matcher 356613481Sgiacomo.travaglini@arm.com // and Second may not be assignable. 356713481Sgiacomo.travaglini@arm.com // 356813481Sgiacomo.travaglini@arm.com // However, this should never be called, so the implementation just 356913481Sgiacomo.travaglini@arm.com // need to assert. 357013481Sgiacomo.travaglini@arm.com void operator=(const BoundSecondMatcher& /*rhs*/) { 357113481Sgiacomo.travaglini@arm.com GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned."; 357213481Sgiacomo.travaglini@arm.com } 357313481Sgiacomo.travaglini@arm.com 357413481Sgiacomo.travaglini@arm.com private: 357513481Sgiacomo.travaglini@arm.com template <typename T> 357613481Sgiacomo.travaglini@arm.com class Impl : public MatcherInterface<T> { 357713481Sgiacomo.travaglini@arm.com public: 357813481Sgiacomo.travaglini@arm.com typedef ::testing::tuple<T, Second> ArgTuple; 357913481Sgiacomo.travaglini@arm.com 358013481Sgiacomo.travaglini@arm.com Impl(const Tuple2Matcher& tm, const Second& second) 358113481Sgiacomo.travaglini@arm.com : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)), 358213481Sgiacomo.travaglini@arm.com second_value_(second) {} 358313481Sgiacomo.travaglini@arm.com 358413481Sgiacomo.travaglini@arm.com virtual void DescribeTo(::std::ostream* os) const { 358513481Sgiacomo.travaglini@arm.com *os << "and "; 358613481Sgiacomo.travaglini@arm.com UniversalPrint(second_value_, os); 358713481Sgiacomo.travaglini@arm.com *os << " "; 358813481Sgiacomo.travaglini@arm.com mono_tuple2_matcher_.DescribeTo(os); 358913481Sgiacomo.travaglini@arm.com } 359013481Sgiacomo.travaglini@arm.com 359113481Sgiacomo.travaglini@arm.com virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { 359213481Sgiacomo.travaglini@arm.com return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_), 359313481Sgiacomo.travaglini@arm.com listener); 359413481Sgiacomo.travaglini@arm.com } 359513481Sgiacomo.travaglini@arm.com 359613481Sgiacomo.travaglini@arm.com private: 359713481Sgiacomo.travaglini@arm.com const Matcher<const ArgTuple&> mono_tuple2_matcher_; 359813481Sgiacomo.travaglini@arm.com const Second second_value_; 359913481Sgiacomo.travaglini@arm.com 360013481Sgiacomo.travaglini@arm.com GTEST_DISALLOW_ASSIGN_(Impl); 360113481Sgiacomo.travaglini@arm.com }; 360213481Sgiacomo.travaglini@arm.com 360313481Sgiacomo.travaglini@arm.com const Tuple2Matcher tuple2_matcher_; 360413481Sgiacomo.travaglini@arm.com const Second second_value_; 360513481Sgiacomo.travaglini@arm.com}; 360613481Sgiacomo.travaglini@arm.com 360713481Sgiacomo.travaglini@arm.com// Given a 2-tuple matcher tm and a value second, 360813481Sgiacomo.travaglini@arm.com// MatcherBindSecond(tm, second) returns a matcher that matches a 360913481Sgiacomo.travaglini@arm.com// value x iff tm matches tuple (x, second). Useful for implementing 361013481Sgiacomo.travaglini@arm.com// UnorderedPointwise() in terms of UnorderedElementsAreArray(). 361113481Sgiacomo.travaglini@arm.comtemplate <typename Tuple2Matcher, typename Second> 361213481Sgiacomo.travaglini@arm.comBoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( 361313481Sgiacomo.travaglini@arm.com const Tuple2Matcher& tm, const Second& second) { 361413481Sgiacomo.travaglini@arm.com return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second); 361513481Sgiacomo.travaglini@arm.com} 361613481Sgiacomo.travaglini@arm.com 361713481Sgiacomo.travaglini@arm.com// Returns the description for a matcher defined using the MATCHER*() 361813481Sgiacomo.travaglini@arm.com// macro where the user-supplied description string is "", if 361913481Sgiacomo.travaglini@arm.com// 'negation' is false; otherwise returns the description of the 362013481Sgiacomo.travaglini@arm.com// negation of the matcher. 'param_values' contains a list of strings 362113481Sgiacomo.travaglini@arm.com// that are the print-out of the matcher's parameters. 362213481Sgiacomo.travaglini@arm.comGTEST_API_ string FormatMatcherDescription(bool negation, 362313481Sgiacomo.travaglini@arm.com const char* matcher_name, 362413481Sgiacomo.travaglini@arm.com const Strings& param_values); 362513481Sgiacomo.travaglini@arm.com 362613481Sgiacomo.travaglini@arm.com} // namespace internal 362713481Sgiacomo.travaglini@arm.com 362813481Sgiacomo.travaglini@arm.com// ElementsAreArray(first, last) 362913481Sgiacomo.travaglini@arm.com// ElementsAreArray(pointer, count) 363013481Sgiacomo.travaglini@arm.com// ElementsAreArray(array) 363113481Sgiacomo.travaglini@arm.com// ElementsAreArray(container) 363213481Sgiacomo.travaglini@arm.com// ElementsAreArray({ e1, e2, ..., en }) 363313481Sgiacomo.travaglini@arm.com// 363413481Sgiacomo.travaglini@arm.com// The ElementsAreArray() functions are like ElementsAre(...), except 363513481Sgiacomo.travaglini@arm.com// that they are given a homogeneous sequence rather than taking each 363613481Sgiacomo.travaglini@arm.com// element as a function argument. The sequence can be specified as an 363713481Sgiacomo.travaglini@arm.com// array, a pointer and count, a vector, an initializer list, or an 363813481Sgiacomo.travaglini@arm.com// STL iterator range. In each of these cases, the underlying sequence 363913481Sgiacomo.travaglini@arm.com// can be either a sequence of values or a sequence of matchers. 364013481Sgiacomo.travaglini@arm.com// 364113481Sgiacomo.travaglini@arm.com// All forms of ElementsAreArray() make a copy of the input matcher sequence. 364213481Sgiacomo.travaglini@arm.com 364313481Sgiacomo.travaglini@arm.comtemplate <typename Iter> 364413481Sgiacomo.travaglini@arm.cominline internal::ElementsAreArrayMatcher< 364513481Sgiacomo.travaglini@arm.com typename ::std::iterator_traits<Iter>::value_type> 364613481Sgiacomo.travaglini@arm.comElementsAreArray(Iter first, Iter last) { 364713481Sgiacomo.travaglini@arm.com typedef typename ::std::iterator_traits<Iter>::value_type T; 364813481Sgiacomo.travaglini@arm.com return internal::ElementsAreArrayMatcher<T>(first, last); 364913481Sgiacomo.travaglini@arm.com} 365013481Sgiacomo.travaglini@arm.com 365113481Sgiacomo.travaglini@arm.comtemplate <typename T> 365213481Sgiacomo.travaglini@arm.cominline internal::ElementsAreArrayMatcher<T> ElementsAreArray( 365313481Sgiacomo.travaglini@arm.com const T* pointer, size_t count) { 365413481Sgiacomo.travaglini@arm.com return ElementsAreArray(pointer, pointer + count); 365513481Sgiacomo.travaglini@arm.com} 365613481Sgiacomo.travaglini@arm.com 365713481Sgiacomo.travaglini@arm.comtemplate <typename T, size_t N> 365813481Sgiacomo.travaglini@arm.cominline internal::ElementsAreArrayMatcher<T> ElementsAreArray( 365913481Sgiacomo.travaglini@arm.com const T (&array)[N]) { 366013481Sgiacomo.travaglini@arm.com return ElementsAreArray(array, N); 366113481Sgiacomo.travaglini@arm.com} 366213481Sgiacomo.travaglini@arm.com 366313481Sgiacomo.travaglini@arm.comtemplate <typename Container> 366413481Sgiacomo.travaglini@arm.cominline internal::ElementsAreArrayMatcher<typename Container::value_type> 366513481Sgiacomo.travaglini@arm.comElementsAreArray(const Container& container) { 366613481Sgiacomo.travaglini@arm.com return ElementsAreArray(container.begin(), container.end()); 366713481Sgiacomo.travaglini@arm.com} 366813481Sgiacomo.travaglini@arm.com 366913481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_INITIALIZER_LIST_ 367013481Sgiacomo.travaglini@arm.comtemplate <typename T> 367113481Sgiacomo.travaglini@arm.cominline internal::ElementsAreArrayMatcher<T> 367213481Sgiacomo.travaglini@arm.comElementsAreArray(::std::initializer_list<T> xs) { 367313481Sgiacomo.travaglini@arm.com return ElementsAreArray(xs.begin(), xs.end()); 367413481Sgiacomo.travaglini@arm.com} 367513481Sgiacomo.travaglini@arm.com#endif 367613481Sgiacomo.travaglini@arm.com 367713481Sgiacomo.travaglini@arm.com// UnorderedElementsAreArray(first, last) 367813481Sgiacomo.travaglini@arm.com// UnorderedElementsAreArray(pointer, count) 367913481Sgiacomo.travaglini@arm.com// UnorderedElementsAreArray(array) 368013481Sgiacomo.travaglini@arm.com// UnorderedElementsAreArray(container) 368113481Sgiacomo.travaglini@arm.com// UnorderedElementsAreArray({ e1, e2, ..., en }) 368213481Sgiacomo.travaglini@arm.com// 368313481Sgiacomo.travaglini@arm.com// The UnorderedElementsAreArray() functions are like 368413481Sgiacomo.travaglini@arm.com// ElementsAreArray(...), but allow matching the elements in any order. 368513481Sgiacomo.travaglini@arm.comtemplate <typename Iter> 368613481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher< 368713481Sgiacomo.travaglini@arm.com typename ::std::iterator_traits<Iter>::value_type> 368813481Sgiacomo.travaglini@arm.comUnorderedElementsAreArray(Iter first, Iter last) { 368913481Sgiacomo.travaglini@arm.com typedef typename ::std::iterator_traits<Iter>::value_type T; 369013481Sgiacomo.travaglini@arm.com return internal::UnorderedElementsAreArrayMatcher<T>(first, last); 369113481Sgiacomo.travaglini@arm.com} 369213481Sgiacomo.travaglini@arm.com 369313481Sgiacomo.travaglini@arm.comtemplate <typename T> 369413481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher<T> 369513481Sgiacomo.travaglini@arm.comUnorderedElementsAreArray(const T* pointer, size_t count) { 369613481Sgiacomo.travaglini@arm.com return UnorderedElementsAreArray(pointer, pointer + count); 369713481Sgiacomo.travaglini@arm.com} 369813481Sgiacomo.travaglini@arm.com 369913481Sgiacomo.travaglini@arm.comtemplate <typename T, size_t N> 370013481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher<T> 370113481Sgiacomo.travaglini@arm.comUnorderedElementsAreArray(const T (&array)[N]) { 370213481Sgiacomo.travaglini@arm.com return UnorderedElementsAreArray(array, N); 370313481Sgiacomo.travaglini@arm.com} 370413481Sgiacomo.travaglini@arm.com 370513481Sgiacomo.travaglini@arm.comtemplate <typename Container> 370613481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher< 370713481Sgiacomo.travaglini@arm.com typename Container::value_type> 370813481Sgiacomo.travaglini@arm.comUnorderedElementsAreArray(const Container& container) { 370913481Sgiacomo.travaglini@arm.com return UnorderedElementsAreArray(container.begin(), container.end()); 371013481Sgiacomo.travaglini@arm.com} 371113481Sgiacomo.travaglini@arm.com 371213481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_INITIALIZER_LIST_ 371313481Sgiacomo.travaglini@arm.comtemplate <typename T> 371413481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher<T> 371513481Sgiacomo.travaglini@arm.comUnorderedElementsAreArray(::std::initializer_list<T> xs) { 371613481Sgiacomo.travaglini@arm.com return UnorderedElementsAreArray(xs.begin(), xs.end()); 371713481Sgiacomo.travaglini@arm.com} 371813481Sgiacomo.travaglini@arm.com#endif 371913481Sgiacomo.travaglini@arm.com 372013481Sgiacomo.travaglini@arm.com// _ is a matcher that matches anything of any type. 372113481Sgiacomo.travaglini@arm.com// 372213481Sgiacomo.travaglini@arm.com// This definition is fine as: 372313481Sgiacomo.travaglini@arm.com// 372413481Sgiacomo.travaglini@arm.com// 1. The C++ standard permits using the name _ in a namespace that 372513481Sgiacomo.travaglini@arm.com// is not the global namespace or ::std. 372613481Sgiacomo.travaglini@arm.com// 2. The AnythingMatcher class has no data member or constructor, 372713481Sgiacomo.travaglini@arm.com// so it's OK to create global variables of this type. 372813481Sgiacomo.travaglini@arm.com// 3. c-style has approved of using _ in this case. 372913481Sgiacomo.travaglini@arm.comconst internal::AnythingMatcher _ = {}; 373013481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any value of the given type T. 373113481Sgiacomo.travaglini@arm.comtemplate <typename T> 373213481Sgiacomo.travaglini@arm.cominline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); } 373313481Sgiacomo.travaglini@arm.com 373413481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any value of the given type T. 373513481Sgiacomo.travaglini@arm.comtemplate <typename T> 373613481Sgiacomo.travaglini@arm.cominline Matcher<T> An() { return A<T>(); } 373713481Sgiacomo.travaglini@arm.com 373813481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches anything equal to x. 373913481Sgiacomo.travaglini@arm.com// Note: if the parameter of Eq() were declared as const T&, Eq("foo") 374013481Sgiacomo.travaglini@arm.com// wouldn't compile. 374113481Sgiacomo.travaglini@arm.comtemplate <typename T> 374213481Sgiacomo.travaglini@arm.cominline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); } 374313481Sgiacomo.travaglini@arm.com 374413481Sgiacomo.travaglini@arm.com// Constructs a Matcher<T> from a 'value' of type T. The constructed 374513481Sgiacomo.travaglini@arm.com// matcher matches any value that's equal to 'value'. 374613481Sgiacomo.travaglini@arm.comtemplate <typename T> 374713481Sgiacomo.travaglini@arm.comMatcher<T>::Matcher(T value) { *this = Eq(value); } 374813481Sgiacomo.travaglini@arm.com 374913481Sgiacomo.travaglini@arm.com// Creates a monomorphic matcher that matches anything with type Lhs 375013481Sgiacomo.travaglini@arm.com// and equal to rhs. A user may need to use this instead of Eq(...) 375113481Sgiacomo.travaglini@arm.com// in order to resolve an overloading ambiguity. 375213481Sgiacomo.travaglini@arm.com// 375313481Sgiacomo.travaglini@arm.com// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x)) 375413481Sgiacomo.travaglini@arm.com// or Matcher<T>(x), but more readable than the latter. 375513481Sgiacomo.travaglini@arm.com// 375613481Sgiacomo.travaglini@arm.com// We could define similar monomorphic matchers for other comparison 375713481Sgiacomo.travaglini@arm.com// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do 375813481Sgiacomo.travaglini@arm.com// it yet as those are used much less than Eq() in practice. A user 375913481Sgiacomo.travaglini@arm.com// can always write Matcher<T>(Lt(5)) to be explicit about the type, 376013481Sgiacomo.travaglini@arm.com// for example. 376113481Sgiacomo.travaglini@arm.comtemplate <typename Lhs, typename Rhs> 376213481Sgiacomo.travaglini@arm.cominline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); } 376313481Sgiacomo.travaglini@arm.com 376413481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches anything >= x. 376513481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 376613481Sgiacomo.travaglini@arm.cominline internal::GeMatcher<Rhs> Ge(Rhs x) { 376713481Sgiacomo.travaglini@arm.com return internal::GeMatcher<Rhs>(x); 376813481Sgiacomo.travaglini@arm.com} 376913481Sgiacomo.travaglini@arm.com 377013481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches anything > x. 377113481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 377213481Sgiacomo.travaglini@arm.cominline internal::GtMatcher<Rhs> Gt(Rhs x) { 377313481Sgiacomo.travaglini@arm.com return internal::GtMatcher<Rhs>(x); 377413481Sgiacomo.travaglini@arm.com} 377513481Sgiacomo.travaglini@arm.com 377613481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches anything <= x. 377713481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 377813481Sgiacomo.travaglini@arm.cominline internal::LeMatcher<Rhs> Le(Rhs x) { 377913481Sgiacomo.travaglini@arm.com return internal::LeMatcher<Rhs>(x); 378013481Sgiacomo.travaglini@arm.com} 378113481Sgiacomo.travaglini@arm.com 378213481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches anything < x. 378313481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 378413481Sgiacomo.travaglini@arm.cominline internal::LtMatcher<Rhs> Lt(Rhs x) { 378513481Sgiacomo.travaglini@arm.com return internal::LtMatcher<Rhs>(x); 378613481Sgiacomo.travaglini@arm.com} 378713481Sgiacomo.travaglini@arm.com 378813481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches anything != x. 378913481Sgiacomo.travaglini@arm.comtemplate <typename Rhs> 379013481Sgiacomo.travaglini@arm.cominline internal::NeMatcher<Rhs> Ne(Rhs x) { 379113481Sgiacomo.travaglini@arm.com return internal::NeMatcher<Rhs>(x); 379213481Sgiacomo.travaglini@arm.com} 379313481Sgiacomo.travaglini@arm.com 379413481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches any NULL pointer. 379513481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { 379613481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::IsNullMatcher()); 379713481Sgiacomo.travaglini@arm.com} 379813481Sgiacomo.travaglini@arm.com 379913481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches any non-NULL pointer. 380013481Sgiacomo.travaglini@arm.com// This is convenient as Not(NULL) doesn't compile (the compiler 380113481Sgiacomo.travaglini@arm.com// thinks that that expression is comparing a pointer with an integer). 380213481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::NotNullMatcher > NotNull() { 380313481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::NotNullMatcher()); 380413481Sgiacomo.travaglini@arm.com} 380513481Sgiacomo.travaglini@arm.com 380613481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches any argument that 380713481Sgiacomo.travaglini@arm.com// references variable x. 380813481Sgiacomo.travaglini@arm.comtemplate <typename T> 380913481Sgiacomo.travaglini@arm.cominline internal::RefMatcher<T&> Ref(T& x) { // NOLINT 381013481Sgiacomo.travaglini@arm.com return internal::RefMatcher<T&>(x); 381113481Sgiacomo.travaglini@arm.com} 381213481Sgiacomo.travaglini@arm.com 381313481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any double argument approximately 381413481Sgiacomo.travaglini@arm.com// equal to rhs, where two NANs are considered unequal. 381513481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { 381613481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<double>(rhs, false); 381713481Sgiacomo.travaglini@arm.com} 381813481Sgiacomo.travaglini@arm.com 381913481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any double argument approximately 382013481Sgiacomo.travaglini@arm.com// equal to rhs, including NaN values when rhs is NaN. 382113481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { 382213481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<double>(rhs, true); 382313481Sgiacomo.travaglini@arm.com} 382413481Sgiacomo.travaglini@arm.com 382513481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any double argument approximately equal to 382613481Sgiacomo.travaglini@arm.com// rhs, up to the specified max absolute error bound, where two NANs are 382713481Sgiacomo.travaglini@arm.com// considered unequal. The max absolute error bound must be non-negative. 382813481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<double> DoubleNear( 382913481Sgiacomo.travaglini@arm.com double rhs, double max_abs_error) { 383013481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error); 383113481Sgiacomo.travaglini@arm.com} 383213481Sgiacomo.travaglini@arm.com 383313481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any double argument approximately equal to 383413481Sgiacomo.travaglini@arm.com// rhs, up to the specified max absolute error bound, including NaN values when 383513481Sgiacomo.travaglini@arm.com// rhs is NaN. The max absolute error bound must be non-negative. 383613481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear( 383713481Sgiacomo.travaglini@arm.com double rhs, double max_abs_error) { 383813481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error); 383913481Sgiacomo.travaglini@arm.com} 384013481Sgiacomo.travaglini@arm.com 384113481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any float argument approximately 384213481Sgiacomo.travaglini@arm.com// equal to rhs, where two NANs are considered unequal. 384313481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<float> FloatEq(float rhs) { 384413481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<float>(rhs, false); 384513481Sgiacomo.travaglini@arm.com} 384613481Sgiacomo.travaglini@arm.com 384713481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any float argument approximately 384813481Sgiacomo.travaglini@arm.com// equal to rhs, including NaN values when rhs is NaN. 384913481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) { 385013481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<float>(rhs, true); 385113481Sgiacomo.travaglini@arm.com} 385213481Sgiacomo.travaglini@arm.com 385313481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any float argument approximately equal to 385413481Sgiacomo.travaglini@arm.com// rhs, up to the specified max absolute error bound, where two NANs are 385513481Sgiacomo.travaglini@arm.com// considered unequal. The max absolute error bound must be non-negative. 385613481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<float> FloatNear( 385713481Sgiacomo.travaglini@arm.com float rhs, float max_abs_error) { 385813481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error); 385913481Sgiacomo.travaglini@arm.com} 386013481Sgiacomo.travaglini@arm.com 386113481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any float argument approximately equal to 386213481Sgiacomo.travaglini@arm.com// rhs, up to the specified max absolute error bound, including NaN values when 386313481Sgiacomo.travaglini@arm.com// rhs is NaN. The max absolute error bound must be non-negative. 386413481Sgiacomo.travaglini@arm.cominline internal::FloatingEqMatcher<float> NanSensitiveFloatNear( 386513481Sgiacomo.travaglini@arm.com float rhs, float max_abs_error) { 386613481Sgiacomo.travaglini@arm.com return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error); 386713481Sgiacomo.travaglini@arm.com} 386813481Sgiacomo.travaglini@arm.com 386913481Sgiacomo.travaglini@arm.com// Creates a matcher that matches a pointer (raw or smart) that points 387013481Sgiacomo.travaglini@arm.com// to a value that matches inner_matcher. 387113481Sgiacomo.travaglini@arm.comtemplate <typename InnerMatcher> 387213481Sgiacomo.travaglini@arm.cominline internal::PointeeMatcher<InnerMatcher> Pointee( 387313481Sgiacomo.travaglini@arm.com const InnerMatcher& inner_matcher) { 387413481Sgiacomo.travaglini@arm.com return internal::PointeeMatcher<InnerMatcher>(inner_matcher); 387513481Sgiacomo.travaglini@arm.com} 387613481Sgiacomo.travaglini@arm.com 387713481Sgiacomo.travaglini@arm.com// Creates a matcher that matches a pointer or reference that matches 387813481Sgiacomo.travaglini@arm.com// inner_matcher when dynamic_cast<To> is applied. 387913481Sgiacomo.travaglini@arm.com// The result of dynamic_cast<To> is forwarded to the inner matcher. 388013481Sgiacomo.travaglini@arm.com// If To is a pointer and the cast fails, the inner matcher will receive NULL. 388113481Sgiacomo.travaglini@arm.com// If To is a reference and the cast fails, this matcher returns false 388213481Sgiacomo.travaglini@arm.com// immediately. 388313481Sgiacomo.travaglini@arm.comtemplate <typename To> 388413481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> > 388513481Sgiacomo.travaglini@arm.comWhenDynamicCastTo(const Matcher<To>& inner_matcher) { 388613481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher( 388713481Sgiacomo.travaglini@arm.com internal::WhenDynamicCastToMatcher<To>(inner_matcher)); 388813481Sgiacomo.travaglini@arm.com} 388913481Sgiacomo.travaglini@arm.com 389013481Sgiacomo.travaglini@arm.com// Creates a matcher that matches an object whose given field matches 389113481Sgiacomo.travaglini@arm.com// 'matcher'. For example, 389213481Sgiacomo.travaglini@arm.com// Field(&Foo::number, Ge(5)) 389313481Sgiacomo.travaglini@arm.com// matches a Foo object x iff x.number >= 5. 389413481Sgiacomo.travaglini@arm.comtemplate <typename Class, typename FieldType, typename FieldMatcher> 389513481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher< 389613481Sgiacomo.travaglini@arm.com internal::FieldMatcher<Class, FieldType> > Field( 389713481Sgiacomo.travaglini@arm.com FieldType Class::*field, const FieldMatcher& matcher) { 389813481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher( 389913481Sgiacomo.travaglini@arm.com internal::FieldMatcher<Class, FieldType>( 390013481Sgiacomo.travaglini@arm.com field, MatcherCast<const FieldType&>(matcher))); 390113481Sgiacomo.travaglini@arm.com // The call to MatcherCast() is required for supporting inner 390213481Sgiacomo.travaglini@arm.com // matchers of compatible types. For example, it allows 390313481Sgiacomo.travaglini@arm.com // Field(&Foo::bar, m) 390413481Sgiacomo.travaglini@arm.com // to compile where bar is an int32 and m is a matcher for int64. 390513481Sgiacomo.travaglini@arm.com} 390613481Sgiacomo.travaglini@arm.com 390713481Sgiacomo.travaglini@arm.com// Creates a matcher that matches an object whose given property 390813481Sgiacomo.travaglini@arm.com// matches 'matcher'. For example, 390913481Sgiacomo.travaglini@arm.com// Property(&Foo::str, StartsWith("hi")) 391013481Sgiacomo.travaglini@arm.com// matches a Foo object x iff x.str() starts with "hi". 391113481Sgiacomo.travaglini@arm.comtemplate <typename Class, typename PropertyType, typename PropertyMatcher> 391213481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher< 391313481Sgiacomo.travaglini@arm.com internal::PropertyMatcher<Class, PropertyType> > Property( 391413481Sgiacomo.travaglini@arm.com PropertyType (Class::*property)() const, const PropertyMatcher& matcher) { 391513481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher( 391613481Sgiacomo.travaglini@arm.com internal::PropertyMatcher<Class, PropertyType>( 391713481Sgiacomo.travaglini@arm.com property, 391813481Sgiacomo.travaglini@arm.com MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); 391913481Sgiacomo.travaglini@arm.com // The call to MatcherCast() is required for supporting inner 392013481Sgiacomo.travaglini@arm.com // matchers of compatible types. For example, it allows 392113481Sgiacomo.travaglini@arm.com // Property(&Foo::bar, m) 392213481Sgiacomo.travaglini@arm.com // to compile where bar() returns an int32 and m is a matcher for int64. 392313481Sgiacomo.travaglini@arm.com} 392413481Sgiacomo.travaglini@arm.com 392513481Sgiacomo.travaglini@arm.com// Creates a matcher that matches an object iff the result of applying 392613481Sgiacomo.travaglini@arm.com// a callable to x matches 'matcher'. 392713481Sgiacomo.travaglini@arm.com// For example, 392813481Sgiacomo.travaglini@arm.com// ResultOf(f, StartsWith("hi")) 392913481Sgiacomo.travaglini@arm.com// matches a Foo object x iff f(x) starts with "hi". 393013481Sgiacomo.travaglini@arm.com// callable parameter can be a function, function pointer, or a functor. 393113481Sgiacomo.travaglini@arm.com// Callable has to satisfy the following conditions: 393213481Sgiacomo.travaglini@arm.com// * It is required to keep no state affecting the results of 393313481Sgiacomo.travaglini@arm.com// the calls on it and make no assumptions about how many calls 393413481Sgiacomo.travaglini@arm.com// will be made. Any state it keeps must be protected from the 393513481Sgiacomo.travaglini@arm.com// concurrent access. 393613481Sgiacomo.travaglini@arm.com// * If it is a function object, it has to define type result_type. 393713481Sgiacomo.travaglini@arm.com// We recommend deriving your functor classes from std::unary_function. 393813481Sgiacomo.travaglini@arm.comtemplate <typename Callable, typename ResultOfMatcher> 393913481Sgiacomo.travaglini@arm.cominternal::ResultOfMatcher<Callable> ResultOf( 394013481Sgiacomo.travaglini@arm.com Callable callable, const ResultOfMatcher& matcher) { 394113481Sgiacomo.travaglini@arm.com return internal::ResultOfMatcher<Callable>( 394213481Sgiacomo.travaglini@arm.com callable, 394313481Sgiacomo.travaglini@arm.com MatcherCast<typename internal::CallableTraits<Callable>::ResultType>( 394413481Sgiacomo.travaglini@arm.com matcher)); 394513481Sgiacomo.travaglini@arm.com // The call to MatcherCast() is required for supporting inner 394613481Sgiacomo.travaglini@arm.com // matchers of compatible types. For example, it allows 394713481Sgiacomo.travaglini@arm.com // ResultOf(Function, m) 394813481Sgiacomo.travaglini@arm.com // to compile where Function() returns an int32 and m is a matcher for int64. 394913481Sgiacomo.travaglini@arm.com} 395013481Sgiacomo.travaglini@arm.com 395113481Sgiacomo.travaglini@arm.com// String matchers. 395213481Sgiacomo.travaglini@arm.com 395313481Sgiacomo.travaglini@arm.com// Matches a string equal to str. 395413481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > 395513481Sgiacomo.travaglini@arm.com StrEq(const internal::string& str) { 395613481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( 395713481Sgiacomo.travaglini@arm.com str, true, true)); 395813481Sgiacomo.travaglini@arm.com} 395913481Sgiacomo.travaglini@arm.com 396013481Sgiacomo.travaglini@arm.com// Matches a string not equal to str. 396113481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > 396213481Sgiacomo.travaglini@arm.com StrNe(const internal::string& str) { 396313481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( 396413481Sgiacomo.travaglini@arm.com str, false, true)); 396513481Sgiacomo.travaglini@arm.com} 396613481Sgiacomo.travaglini@arm.com 396713481Sgiacomo.travaglini@arm.com// Matches a string equal to str, ignoring case. 396813481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > 396913481Sgiacomo.travaglini@arm.com StrCaseEq(const internal::string& str) { 397013481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( 397113481Sgiacomo.travaglini@arm.com str, true, false)); 397213481Sgiacomo.travaglini@arm.com} 397313481Sgiacomo.travaglini@arm.com 397413481Sgiacomo.travaglini@arm.com// Matches a string not equal to str, ignoring case. 397513481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > 397613481Sgiacomo.travaglini@arm.com StrCaseNe(const internal::string& str) { 397713481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( 397813481Sgiacomo.travaglini@arm.com str, false, false)); 397913481Sgiacomo.travaglini@arm.com} 398013481Sgiacomo.travaglini@arm.com 398113481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any string, std::string, or C string 398213481Sgiacomo.travaglini@arm.com// that contains the given substring. 398313481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::HasSubstrMatcher<internal::string> > 398413481Sgiacomo.travaglini@arm.com HasSubstr(const internal::string& substring) { 398513481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::string>( 398613481Sgiacomo.travaglini@arm.com substring)); 398713481Sgiacomo.travaglini@arm.com} 398813481Sgiacomo.travaglini@arm.com 398913481Sgiacomo.travaglini@arm.com// Matches a string that starts with 'prefix' (case-sensitive). 399013481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StartsWithMatcher<internal::string> > 399113481Sgiacomo.travaglini@arm.com StartsWith(const internal::string& prefix) { 399213481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::string>( 399313481Sgiacomo.travaglini@arm.com prefix)); 399413481Sgiacomo.travaglini@arm.com} 399513481Sgiacomo.travaglini@arm.com 399613481Sgiacomo.travaglini@arm.com// Matches a string that ends with 'suffix' (case-sensitive). 399713481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::EndsWithMatcher<internal::string> > 399813481Sgiacomo.travaglini@arm.com EndsWith(const internal::string& suffix) { 399913481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::string>( 400013481Sgiacomo.travaglini@arm.com suffix)); 400113481Sgiacomo.travaglini@arm.com} 400213481Sgiacomo.travaglini@arm.com 400313481Sgiacomo.travaglini@arm.com// Matches a string that fully matches regular expression 'regex'. 400413481Sgiacomo.travaglini@arm.com// The matcher takes ownership of 'regex'. 400513481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( 400613481Sgiacomo.travaglini@arm.com const internal::RE* regex) { 400713481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); 400813481Sgiacomo.travaglini@arm.com} 400913481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( 401013481Sgiacomo.travaglini@arm.com const internal::string& regex) { 401113481Sgiacomo.travaglini@arm.com return MatchesRegex(new internal::RE(regex)); 401213481Sgiacomo.travaglini@arm.com} 401313481Sgiacomo.travaglini@arm.com 401413481Sgiacomo.travaglini@arm.com// Matches a string that contains regular expression 'regex'. 401513481Sgiacomo.travaglini@arm.com// The matcher takes ownership of 'regex'. 401613481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( 401713481Sgiacomo.travaglini@arm.com const internal::RE* regex) { 401813481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); 401913481Sgiacomo.travaglini@arm.com} 402013481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( 402113481Sgiacomo.travaglini@arm.com const internal::string& regex) { 402213481Sgiacomo.travaglini@arm.com return ContainsRegex(new internal::RE(regex)); 402313481Sgiacomo.travaglini@arm.com} 402413481Sgiacomo.travaglini@arm.com 402513481Sgiacomo.travaglini@arm.com#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING 402613481Sgiacomo.travaglini@arm.com// Wide string matchers. 402713481Sgiacomo.travaglini@arm.com 402813481Sgiacomo.travaglini@arm.com// Matches a string equal to str. 402913481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > 403013481Sgiacomo.travaglini@arm.com StrEq(const internal::wstring& str) { 403113481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( 403213481Sgiacomo.travaglini@arm.com str, true, true)); 403313481Sgiacomo.travaglini@arm.com} 403413481Sgiacomo.travaglini@arm.com 403513481Sgiacomo.travaglini@arm.com// Matches a string not equal to str. 403613481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > 403713481Sgiacomo.travaglini@arm.com StrNe(const internal::wstring& str) { 403813481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( 403913481Sgiacomo.travaglini@arm.com str, false, true)); 404013481Sgiacomo.travaglini@arm.com} 404113481Sgiacomo.travaglini@arm.com 404213481Sgiacomo.travaglini@arm.com// Matches a string equal to str, ignoring case. 404313481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > 404413481Sgiacomo.travaglini@arm.com StrCaseEq(const internal::wstring& str) { 404513481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( 404613481Sgiacomo.travaglini@arm.com str, true, false)); 404713481Sgiacomo.travaglini@arm.com} 404813481Sgiacomo.travaglini@arm.com 404913481Sgiacomo.travaglini@arm.com// Matches a string not equal to str, ignoring case. 405013481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > 405113481Sgiacomo.travaglini@arm.com StrCaseNe(const internal::wstring& str) { 405213481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( 405313481Sgiacomo.travaglini@arm.com str, false, false)); 405413481Sgiacomo.travaglini@arm.com} 405513481Sgiacomo.travaglini@arm.com 405613481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any wstring, std::wstring, or C wide string 405713481Sgiacomo.travaglini@arm.com// that contains the given substring. 405813481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> > 405913481Sgiacomo.travaglini@arm.com HasSubstr(const internal::wstring& substring) { 406013481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>( 406113481Sgiacomo.travaglini@arm.com substring)); 406213481Sgiacomo.travaglini@arm.com} 406313481Sgiacomo.travaglini@arm.com 406413481Sgiacomo.travaglini@arm.com// Matches a string that starts with 'prefix' (case-sensitive). 406513481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> > 406613481Sgiacomo.travaglini@arm.com StartsWith(const internal::wstring& prefix) { 406713481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>( 406813481Sgiacomo.travaglini@arm.com prefix)); 406913481Sgiacomo.travaglini@arm.com} 407013481Sgiacomo.travaglini@arm.com 407113481Sgiacomo.travaglini@arm.com// Matches a string that ends with 'suffix' (case-sensitive). 407213481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> > 407313481Sgiacomo.travaglini@arm.com EndsWith(const internal::wstring& suffix) { 407413481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>( 407513481Sgiacomo.travaglini@arm.com suffix)); 407613481Sgiacomo.travaglini@arm.com} 407713481Sgiacomo.travaglini@arm.com 407813481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING 407913481Sgiacomo.travaglini@arm.com 408013481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches a 2-tuple where the 408113481Sgiacomo.travaglini@arm.com// first field == the second field. 408213481Sgiacomo.travaglini@arm.cominline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); } 408313481Sgiacomo.travaglini@arm.com 408413481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches a 2-tuple where the 408513481Sgiacomo.travaglini@arm.com// first field >= the second field. 408613481Sgiacomo.travaglini@arm.cominline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); } 408713481Sgiacomo.travaglini@arm.com 408813481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches a 2-tuple where the 408913481Sgiacomo.travaglini@arm.com// first field > the second field. 409013481Sgiacomo.travaglini@arm.cominline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); } 409113481Sgiacomo.travaglini@arm.com 409213481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches a 2-tuple where the 409313481Sgiacomo.travaglini@arm.com// first field <= the second field. 409413481Sgiacomo.travaglini@arm.cominline internal::Le2Matcher Le() { return internal::Le2Matcher(); } 409513481Sgiacomo.travaglini@arm.com 409613481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches a 2-tuple where the 409713481Sgiacomo.travaglini@arm.com// first field < the second field. 409813481Sgiacomo.travaglini@arm.cominline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); } 409913481Sgiacomo.travaglini@arm.com 410013481Sgiacomo.travaglini@arm.com// Creates a polymorphic matcher that matches a 2-tuple where the 410113481Sgiacomo.travaglini@arm.com// first field != the second field. 410213481Sgiacomo.travaglini@arm.cominline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } 410313481Sgiacomo.travaglini@arm.com 410413481Sgiacomo.travaglini@arm.com// Creates a matcher that matches any value of type T that m doesn't 410513481Sgiacomo.travaglini@arm.com// match. 410613481Sgiacomo.travaglini@arm.comtemplate <typename InnerMatcher> 410713481Sgiacomo.travaglini@arm.cominline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) { 410813481Sgiacomo.travaglini@arm.com return internal::NotMatcher<InnerMatcher>(m); 410913481Sgiacomo.travaglini@arm.com} 411013481Sgiacomo.travaglini@arm.com 411113481Sgiacomo.travaglini@arm.com// Returns a matcher that matches anything that satisfies the given 411213481Sgiacomo.travaglini@arm.com// predicate. The predicate can be any unary function or functor 411313481Sgiacomo.travaglini@arm.com// whose return type can be implicitly converted to bool. 411413481Sgiacomo.travaglini@arm.comtemplate <typename Predicate> 411513481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::TrulyMatcher<Predicate> > 411613481Sgiacomo.travaglini@arm.comTruly(Predicate pred) { 411713481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred)); 411813481Sgiacomo.travaglini@arm.com} 411913481Sgiacomo.travaglini@arm.com 412013481Sgiacomo.travaglini@arm.com// Returns a matcher that matches the container size. The container must 412113481Sgiacomo.travaglini@arm.com// support both size() and size_type which all STL-like containers provide. 412213481Sgiacomo.travaglini@arm.com// Note that the parameter 'size' can be a value of type size_type as well as 412313481Sgiacomo.travaglini@arm.com// matcher. For instance: 412413481Sgiacomo.travaglini@arm.com// EXPECT_THAT(container, SizeIs(2)); // Checks container has 2 elements. 412513481Sgiacomo.travaglini@arm.com// EXPECT_THAT(container, SizeIs(Le(2)); // Checks container has at most 2. 412613481Sgiacomo.travaglini@arm.comtemplate <typename SizeMatcher> 412713481Sgiacomo.travaglini@arm.cominline internal::SizeIsMatcher<SizeMatcher> 412813481Sgiacomo.travaglini@arm.comSizeIs(const SizeMatcher& size_matcher) { 412913481Sgiacomo.travaglini@arm.com return internal::SizeIsMatcher<SizeMatcher>(size_matcher); 413013481Sgiacomo.travaglini@arm.com} 413113481Sgiacomo.travaglini@arm.com 413213481Sgiacomo.travaglini@arm.com// Returns a matcher that matches the distance between the container's begin() 413313481Sgiacomo.travaglini@arm.com// iterator and its end() iterator, i.e. the size of the container. This matcher 413413481Sgiacomo.travaglini@arm.com// can be used instead of SizeIs with containers such as std::forward_list which 413513481Sgiacomo.travaglini@arm.com// do not implement size(). The container must provide const_iterator (with 413613481Sgiacomo.travaglini@arm.com// valid iterator_traits), begin() and end(). 413713481Sgiacomo.travaglini@arm.comtemplate <typename DistanceMatcher> 413813481Sgiacomo.travaglini@arm.cominline internal::BeginEndDistanceIsMatcher<DistanceMatcher> 413913481Sgiacomo.travaglini@arm.comBeginEndDistanceIs(const DistanceMatcher& distance_matcher) { 414013481Sgiacomo.travaglini@arm.com return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher); 414113481Sgiacomo.travaglini@arm.com} 414213481Sgiacomo.travaglini@arm.com 414313481Sgiacomo.travaglini@arm.com// Returns a matcher that matches an equal container. 414413481Sgiacomo.travaglini@arm.com// This matcher behaves like Eq(), but in the event of mismatch lists the 414513481Sgiacomo.travaglini@arm.com// values that are included in one container but not the other. (Duplicate 414613481Sgiacomo.travaglini@arm.com// values and order differences are not explained.) 414713481Sgiacomo.travaglini@arm.comtemplate <typename Container> 414813481Sgiacomo.travaglini@arm.cominline PolymorphicMatcher<internal::ContainerEqMatcher< // NOLINT 414913481Sgiacomo.travaglini@arm.com GTEST_REMOVE_CONST_(Container)> > 415013481Sgiacomo.travaglini@arm.com ContainerEq(const Container& rhs) { 415113481Sgiacomo.travaglini@arm.com // This following line is for working around a bug in MSVC 8.0, 415213481Sgiacomo.travaglini@arm.com // which causes Container to be a const type sometimes. 415313481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_CONST_(Container) RawContainer; 415413481Sgiacomo.travaglini@arm.com return MakePolymorphicMatcher( 415513481Sgiacomo.travaglini@arm.com internal::ContainerEqMatcher<RawContainer>(rhs)); 415613481Sgiacomo.travaglini@arm.com} 415713481Sgiacomo.travaglini@arm.com 415813481Sgiacomo.travaglini@arm.com// Returns a matcher that matches a container that, when sorted using 415913481Sgiacomo.travaglini@arm.com// the given comparator, matches container_matcher. 416013481Sgiacomo.travaglini@arm.comtemplate <typename Comparator, typename ContainerMatcher> 416113481Sgiacomo.travaglini@arm.cominline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> 416213481Sgiacomo.travaglini@arm.comWhenSortedBy(const Comparator& comparator, 416313481Sgiacomo.travaglini@arm.com const ContainerMatcher& container_matcher) { 416413481Sgiacomo.travaglini@arm.com return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>( 416513481Sgiacomo.travaglini@arm.com comparator, container_matcher); 416613481Sgiacomo.travaglini@arm.com} 416713481Sgiacomo.travaglini@arm.com 416813481Sgiacomo.travaglini@arm.com// Returns a matcher that matches a container that, when sorted using 416913481Sgiacomo.travaglini@arm.com// the < operator, matches container_matcher. 417013481Sgiacomo.travaglini@arm.comtemplate <typename ContainerMatcher> 417113481Sgiacomo.travaglini@arm.cominline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher> 417213481Sgiacomo.travaglini@arm.comWhenSorted(const ContainerMatcher& container_matcher) { 417313481Sgiacomo.travaglini@arm.com return 417413481Sgiacomo.travaglini@arm.com internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>( 417513481Sgiacomo.travaglini@arm.com internal::LessComparator(), container_matcher); 417613481Sgiacomo.travaglini@arm.com} 417713481Sgiacomo.travaglini@arm.com 417813481Sgiacomo.travaglini@arm.com// Matches an STL-style container or a native array that contains the 417913481Sgiacomo.travaglini@arm.com// same number of elements as in rhs, where its i-th element and rhs's 418013481Sgiacomo.travaglini@arm.com// i-th element (as a pair) satisfy the given pair matcher, for all i. 418113481Sgiacomo.travaglini@arm.com// TupleMatcher must be able to be safely cast to Matcher<tuple<const 418213481Sgiacomo.travaglini@arm.com// T1&, const T2&> >, where T1 and T2 are the types of elements in the 418313481Sgiacomo.travaglini@arm.com// LHS container and the RHS container respectively. 418413481Sgiacomo.travaglini@arm.comtemplate <typename TupleMatcher, typename Container> 418513481Sgiacomo.travaglini@arm.cominline internal::PointwiseMatcher<TupleMatcher, 418613481Sgiacomo.travaglini@arm.com GTEST_REMOVE_CONST_(Container)> 418713481Sgiacomo.travaglini@arm.comPointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { 418813481Sgiacomo.travaglini@arm.com // This following line is for working around a bug in MSVC 8.0, 418913481Sgiacomo.travaglini@arm.com // which causes Container to be a const type sometimes (e.g. when 419013481Sgiacomo.travaglini@arm.com // rhs is a const int[]).. 419113481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_CONST_(Container) RawContainer; 419213481Sgiacomo.travaglini@arm.com return internal::PointwiseMatcher<TupleMatcher, RawContainer>( 419313481Sgiacomo.travaglini@arm.com tuple_matcher, rhs); 419413481Sgiacomo.travaglini@arm.com} 419513481Sgiacomo.travaglini@arm.com 419613481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_INITIALIZER_LIST_ 419713481Sgiacomo.travaglini@arm.com 419813481Sgiacomo.travaglini@arm.com// Supports the Pointwise(m, {a, b, c}) syntax. 419913481Sgiacomo.travaglini@arm.comtemplate <typename TupleMatcher, typename T> 420013481Sgiacomo.travaglini@arm.cominline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( 420113481Sgiacomo.travaglini@arm.com const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) { 420213481Sgiacomo.travaglini@arm.com return Pointwise(tuple_matcher, std::vector<T>(rhs)); 420313481Sgiacomo.travaglini@arm.com} 420413481Sgiacomo.travaglini@arm.com 420513481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_STD_INITIALIZER_LIST_ 420613481Sgiacomo.travaglini@arm.com 420713481Sgiacomo.travaglini@arm.com// UnorderedPointwise(pair_matcher, rhs) matches an STL-style 420813481Sgiacomo.travaglini@arm.com// container or a native array that contains the same number of 420913481Sgiacomo.travaglini@arm.com// elements as in rhs, where in some permutation of the container, its 421013481Sgiacomo.travaglini@arm.com// i-th element and rhs's i-th element (as a pair) satisfy the given 421113481Sgiacomo.travaglini@arm.com// pair matcher, for all i. Tuple2Matcher must be able to be safely 421213481Sgiacomo.travaglini@arm.com// cast to Matcher<tuple<const T1&, const T2&> >, where T1 and T2 are 421313481Sgiacomo.travaglini@arm.com// the types of elements in the LHS container and the RHS container 421413481Sgiacomo.travaglini@arm.com// respectively. 421513481Sgiacomo.travaglini@arm.com// 421613481Sgiacomo.travaglini@arm.com// This is like Pointwise(pair_matcher, rhs), except that the element 421713481Sgiacomo.travaglini@arm.com// order doesn't matter. 421813481Sgiacomo.travaglini@arm.comtemplate <typename Tuple2Matcher, typename RhsContainer> 421913481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher< 422013481Sgiacomo.travaglini@arm.com typename internal::BoundSecondMatcher< 422113481Sgiacomo.travaglini@arm.com Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_( 422213481Sgiacomo.travaglini@arm.com RhsContainer)>::type::value_type> > 422313481Sgiacomo.travaglini@arm.comUnorderedPointwise(const Tuple2Matcher& tuple2_matcher, 422413481Sgiacomo.travaglini@arm.com const RhsContainer& rhs_container) { 422513481Sgiacomo.travaglini@arm.com // This following line is for working around a bug in MSVC 8.0, 422613481Sgiacomo.travaglini@arm.com // which causes RhsContainer to be a const type sometimes (e.g. when 422713481Sgiacomo.travaglini@arm.com // rhs_container is a const int[]). 422813481Sgiacomo.travaglini@arm.com typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer; 422913481Sgiacomo.travaglini@arm.com 423013481Sgiacomo.travaglini@arm.com // RhsView allows the same code to handle RhsContainer being a 423113481Sgiacomo.travaglini@arm.com // STL-style container and it being a native C-style array. 423213481Sgiacomo.travaglini@arm.com typedef typename internal::StlContainerView<RawRhsContainer> RhsView; 423313481Sgiacomo.travaglini@arm.com typedef typename RhsView::type RhsStlContainer; 423413481Sgiacomo.travaglini@arm.com typedef typename RhsStlContainer::value_type Second; 423513481Sgiacomo.travaglini@arm.com const RhsStlContainer& rhs_stl_container = 423613481Sgiacomo.travaglini@arm.com RhsView::ConstReference(rhs_container); 423713481Sgiacomo.travaglini@arm.com 423813481Sgiacomo.travaglini@arm.com // Create a matcher for each element in rhs_container. 423913481Sgiacomo.travaglini@arm.com ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers; 424013481Sgiacomo.travaglini@arm.com for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin(); 424113481Sgiacomo.travaglini@arm.com it != rhs_stl_container.end(); ++it) { 424213481Sgiacomo.travaglini@arm.com matchers.push_back( 424313481Sgiacomo.travaglini@arm.com internal::MatcherBindSecond(tuple2_matcher, *it)); 424413481Sgiacomo.travaglini@arm.com } 424513481Sgiacomo.travaglini@arm.com 424613481Sgiacomo.travaglini@arm.com // Delegate the work to UnorderedElementsAreArray(). 424713481Sgiacomo.travaglini@arm.com return UnorderedElementsAreArray(matchers); 424813481Sgiacomo.travaglini@arm.com} 424913481Sgiacomo.travaglini@arm.com 425013481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_INITIALIZER_LIST_ 425113481Sgiacomo.travaglini@arm.com 425213481Sgiacomo.travaglini@arm.com// Supports the UnorderedPointwise(m, {a, b, c}) syntax. 425313481Sgiacomo.travaglini@arm.comtemplate <typename Tuple2Matcher, typename T> 425413481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreArrayMatcher< 425513481Sgiacomo.travaglini@arm.com typename internal::BoundSecondMatcher<Tuple2Matcher, T> > 425613481Sgiacomo.travaglini@arm.comUnorderedPointwise(const Tuple2Matcher& tuple2_matcher, 425713481Sgiacomo.travaglini@arm.com std::initializer_list<T> rhs) { 425813481Sgiacomo.travaglini@arm.com return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); 425913481Sgiacomo.travaglini@arm.com} 426013481Sgiacomo.travaglini@arm.com 426113481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_STD_INITIALIZER_LIST_ 426213481Sgiacomo.travaglini@arm.com 426313481Sgiacomo.travaglini@arm.com// Matches an STL-style container or a native array that contains at 426413481Sgiacomo.travaglini@arm.com// least one element matching the given value or matcher. 426513481Sgiacomo.travaglini@arm.com// 426613481Sgiacomo.travaglini@arm.com// Examples: 426713481Sgiacomo.travaglini@arm.com// ::std::set<int> page_ids; 426813481Sgiacomo.travaglini@arm.com// page_ids.insert(3); 426913481Sgiacomo.travaglini@arm.com// page_ids.insert(1); 427013481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Contains(1)); 427113481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Contains(Gt(2))); 427213481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Not(Contains(4))); 427313481Sgiacomo.travaglini@arm.com// 427413481Sgiacomo.travaglini@arm.com// ::std::map<int, size_t> page_lengths; 427513481Sgiacomo.travaglini@arm.com// page_lengths[1] = 100; 427613481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_lengths, 427713481Sgiacomo.travaglini@arm.com// Contains(::std::pair<const int, size_t>(1, 100))); 427813481Sgiacomo.travaglini@arm.com// 427913481Sgiacomo.travaglini@arm.com// const char* user_ids[] = { "joe", "mike", "tom" }; 428013481Sgiacomo.travaglini@arm.com// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom")))); 428113481Sgiacomo.travaglini@arm.comtemplate <typename M> 428213481Sgiacomo.travaglini@arm.cominline internal::ContainsMatcher<M> Contains(M matcher) { 428313481Sgiacomo.travaglini@arm.com return internal::ContainsMatcher<M>(matcher); 428413481Sgiacomo.travaglini@arm.com} 428513481Sgiacomo.travaglini@arm.com 428613481Sgiacomo.travaglini@arm.com// Matches an STL-style container or a native array that contains only 428713481Sgiacomo.travaglini@arm.com// elements matching the given value or matcher. 428813481Sgiacomo.travaglini@arm.com// 428913481Sgiacomo.travaglini@arm.com// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only 429013481Sgiacomo.travaglini@arm.com// the messages are different. 429113481Sgiacomo.travaglini@arm.com// 429213481Sgiacomo.travaglini@arm.com// Examples: 429313481Sgiacomo.travaglini@arm.com// ::std::set<int> page_ids; 429413481Sgiacomo.travaglini@arm.com// // Each(m) matches an empty container, regardless of what m is. 429513481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Each(Eq(1))); 429613481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Each(Eq(77))); 429713481Sgiacomo.travaglini@arm.com// 429813481Sgiacomo.travaglini@arm.com// page_ids.insert(3); 429913481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Each(Gt(0))); 430013481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Not(Each(Gt(4)))); 430113481Sgiacomo.travaglini@arm.com// page_ids.insert(1); 430213481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_ids, Not(Each(Lt(2)))); 430313481Sgiacomo.travaglini@arm.com// 430413481Sgiacomo.travaglini@arm.com// ::std::map<int, size_t> page_lengths; 430513481Sgiacomo.travaglini@arm.com// page_lengths[1] = 100; 430613481Sgiacomo.travaglini@arm.com// page_lengths[2] = 200; 430713481Sgiacomo.travaglini@arm.com// page_lengths[3] = 300; 430813481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100)))); 430913481Sgiacomo.travaglini@arm.com// EXPECT_THAT(page_lengths, Each(Key(Le(3)))); 431013481Sgiacomo.travaglini@arm.com// 431113481Sgiacomo.travaglini@arm.com// const char* user_ids[] = { "joe", "mike", "tom" }; 431213481Sgiacomo.travaglini@arm.com// EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom"))))); 431313481Sgiacomo.travaglini@arm.comtemplate <typename M> 431413481Sgiacomo.travaglini@arm.cominline internal::EachMatcher<M> Each(M matcher) { 431513481Sgiacomo.travaglini@arm.com return internal::EachMatcher<M>(matcher); 431613481Sgiacomo.travaglini@arm.com} 431713481Sgiacomo.travaglini@arm.com 431813481Sgiacomo.travaglini@arm.com// Key(inner_matcher) matches an std::pair whose 'first' field matches 431913481Sgiacomo.travaglini@arm.com// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an 432013481Sgiacomo.travaglini@arm.com// std::map that contains at least one element whose key is >= 5. 432113481Sgiacomo.travaglini@arm.comtemplate <typename M> 432213481Sgiacomo.travaglini@arm.cominline internal::KeyMatcher<M> Key(M inner_matcher) { 432313481Sgiacomo.travaglini@arm.com return internal::KeyMatcher<M>(inner_matcher); 432413481Sgiacomo.travaglini@arm.com} 432513481Sgiacomo.travaglini@arm.com 432613481Sgiacomo.travaglini@arm.com// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field 432713481Sgiacomo.travaglini@arm.com// matches first_matcher and whose 'second' field matches second_matcher. For 432813481Sgiacomo.travaglini@arm.com// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used 432913481Sgiacomo.travaglini@arm.com// to match a std::map<int, string> that contains exactly one element whose key 433013481Sgiacomo.travaglini@arm.com// is >= 5 and whose value equals "foo". 433113481Sgiacomo.travaglini@arm.comtemplate <typename FirstMatcher, typename SecondMatcher> 433213481Sgiacomo.travaglini@arm.cominline internal::PairMatcher<FirstMatcher, SecondMatcher> 433313481Sgiacomo.travaglini@arm.comPair(FirstMatcher first_matcher, SecondMatcher second_matcher) { 433413481Sgiacomo.travaglini@arm.com return internal::PairMatcher<FirstMatcher, SecondMatcher>( 433513481Sgiacomo.travaglini@arm.com first_matcher, second_matcher); 433613481Sgiacomo.travaglini@arm.com} 433713481Sgiacomo.travaglini@arm.com 433813481Sgiacomo.travaglini@arm.com// Returns a predicate that is satisfied by anything that matches the 433913481Sgiacomo.travaglini@arm.com// given matcher. 434013481Sgiacomo.travaglini@arm.comtemplate <typename M> 434113481Sgiacomo.travaglini@arm.cominline internal::MatcherAsPredicate<M> Matches(M matcher) { 434213481Sgiacomo.travaglini@arm.com return internal::MatcherAsPredicate<M>(matcher); 434313481Sgiacomo.travaglini@arm.com} 434413481Sgiacomo.travaglini@arm.com 434513481Sgiacomo.travaglini@arm.com// Returns true iff the value matches the matcher. 434613481Sgiacomo.travaglini@arm.comtemplate <typename T, typename M> 434713481Sgiacomo.travaglini@arm.cominline bool Value(const T& value, M matcher) { 434813481Sgiacomo.travaglini@arm.com return testing::Matches(matcher)(value); 434913481Sgiacomo.travaglini@arm.com} 435013481Sgiacomo.travaglini@arm.com 435113481Sgiacomo.travaglini@arm.com// Matches the value against the given matcher and explains the match 435213481Sgiacomo.travaglini@arm.com// result to listener. 435313481Sgiacomo.travaglini@arm.comtemplate <typename T, typename M> 435413481Sgiacomo.travaglini@arm.cominline bool ExplainMatchResult( 435513481Sgiacomo.travaglini@arm.com M matcher, const T& value, MatchResultListener* listener) { 435613481Sgiacomo.travaglini@arm.com return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); 435713481Sgiacomo.travaglini@arm.com} 435813481Sgiacomo.travaglini@arm.com 435913481Sgiacomo.travaglini@arm.com#if GTEST_LANG_CXX11 436013481Sgiacomo.travaglini@arm.com// Define variadic matcher versions. They are overloaded in 436113481Sgiacomo.travaglini@arm.com// gmock-generated-matchers.h for the cases supported by pre C++11 compilers. 436213481Sgiacomo.travaglini@arm.comtemplate <typename... Args> 436313481Sgiacomo.travaglini@arm.cominline internal::AllOfMatcher<Args...> AllOf(const Args&... matchers) { 436413481Sgiacomo.travaglini@arm.com return internal::AllOfMatcher<Args...>(matchers...); 436513481Sgiacomo.travaglini@arm.com} 436613481Sgiacomo.travaglini@arm.com 436713481Sgiacomo.travaglini@arm.comtemplate <typename... Args> 436813481Sgiacomo.travaglini@arm.cominline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) { 436913481Sgiacomo.travaglini@arm.com return internal::AnyOfMatcher<Args...>(matchers...); 437013481Sgiacomo.travaglini@arm.com} 437113481Sgiacomo.travaglini@arm.com 437213481Sgiacomo.travaglini@arm.com#endif // GTEST_LANG_CXX11 437313481Sgiacomo.travaglini@arm.com 437413481Sgiacomo.travaglini@arm.com// AllArgs(m) is a synonym of m. This is useful in 437513481Sgiacomo.travaglini@arm.com// 437613481Sgiacomo.travaglini@arm.com// EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq())); 437713481Sgiacomo.travaglini@arm.com// 437813481Sgiacomo.travaglini@arm.com// which is easier to read than 437913481Sgiacomo.travaglini@arm.com// 438013481Sgiacomo.travaglini@arm.com// EXPECT_CALL(foo, Bar(_, _)).With(Eq()); 438113481Sgiacomo.travaglini@arm.comtemplate <typename InnerMatcher> 438213481Sgiacomo.travaglini@arm.cominline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } 438313481Sgiacomo.travaglini@arm.com 438413481Sgiacomo.travaglini@arm.com// These macros allow using matchers to check values in Google Test 438513481Sgiacomo.travaglini@arm.com// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) 438613481Sgiacomo.travaglini@arm.com// succeed iff the value matches the matcher. If the assertion fails, 438713481Sgiacomo.travaglini@arm.com// the value and the description of the matcher will be printed. 438813481Sgiacomo.travaglini@arm.com#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ 438913481Sgiacomo.travaglini@arm.com ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) 439013481Sgiacomo.travaglini@arm.com#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ 439113481Sgiacomo.travaglini@arm.com ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) 439213481Sgiacomo.travaglini@arm.com 439313481Sgiacomo.travaglini@arm.com} // namespace testing 439413481Sgiacomo.travaglini@arm.com 439513481Sgiacomo.travaglini@arm.com// Include any custom callback matchers added by the local installation. 439613481Sgiacomo.travaglini@arm.com// We must include this header at the end to make sure it can use the 439713481Sgiacomo.travaglini@arm.com// declarations from this file. 439813481Sgiacomo.travaglini@arm.com#include "gmock/internal/custom/gmock-matchers.h" 439913481Sgiacomo.travaglini@arm.com#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ 4400