gmock-matchers.h revision 13481
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