113481Sgiacomo.travaglini@arm.com$$ -*- mode: c++; -*-
213481Sgiacomo.travaglini@arm.com$$ This is a Pump source file.  Please use Pump to convert it to
313481Sgiacomo.travaglini@arm.com$$ gmock-generated-actions.h.
413481Sgiacomo.travaglini@arm.com$$
513481Sgiacomo.travaglini@arm.com$var n = 10  $$ The maximum arity we support.
613481Sgiacomo.travaglini@arm.com$$ }} This line fixes auto-indentation of the following code in Emacs.
713481Sgiacomo.travaglini@arm.com// Copyright 2008, Google Inc.
813481Sgiacomo.travaglini@arm.com// All rights reserved.
913481Sgiacomo.travaglini@arm.com//
1013481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
1113481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
1213481Sgiacomo.travaglini@arm.com// met:
1313481Sgiacomo.travaglini@arm.com//
1413481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
1513481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1613481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1713481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1813481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1913481Sgiacomo.travaglini@arm.com// distribution.
2013481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
2113481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
2213481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
2313481Sgiacomo.travaglini@arm.com//
2413481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2513481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2613481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2713481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2813481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2913481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3013481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3113481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3213481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3313481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3413481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3513481Sgiacomo.travaglini@arm.com
3613481Sgiacomo.travaglini@arm.com// Google Mock - a framework for writing C++ mock classes.
3713481Sgiacomo.travaglini@arm.com//
3813481Sgiacomo.travaglini@arm.com// This file implements some commonly used variadic matchers.
3913481Sgiacomo.travaglini@arm.com
4013481Sgiacomo.travaglini@arm.com#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
4113481Sgiacomo.travaglini@arm.com#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
4213481Sgiacomo.travaglini@arm.com
4313481Sgiacomo.travaglini@arm.com#include <iterator>
4413481Sgiacomo.travaglini@arm.com#include <sstream>
4513481Sgiacomo.travaglini@arm.com#include <string>
4613481Sgiacomo.travaglini@arm.com#include <vector>
4713481Sgiacomo.travaglini@arm.com#include "gmock/gmock-matchers.h"
4813481Sgiacomo.travaglini@arm.com
4913481Sgiacomo.travaglini@arm.comnamespace testing {
5013481Sgiacomo.travaglini@arm.comnamespace internal {
5113481Sgiacomo.travaglini@arm.com
5213481Sgiacomo.travaglini@arm.com$range i 0..n-1
5313481Sgiacomo.travaglini@arm.com
5413481Sgiacomo.travaglini@arm.com// The type of the i-th (0-based) field of Tuple.
5513481Sgiacomo.travaglini@arm.com#define GMOCK_FIELD_TYPE_(Tuple, i) \
5613481Sgiacomo.travaglini@arm.com    typename ::testing::tuple_element<i, Tuple>::type
5713481Sgiacomo.travaglini@arm.com
5813481Sgiacomo.travaglini@arm.com// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
5913481Sgiacomo.travaglini@arm.com// tuple of type Tuple.  It has two members:
6013481Sgiacomo.travaglini@arm.com//
6113481Sgiacomo.travaglini@arm.com//   type: a tuple type whose i-th field is the ki-th field of Tuple.
6213481Sgiacomo.travaglini@arm.com//   GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
6313481Sgiacomo.travaglini@arm.com//
6413481Sgiacomo.travaglini@arm.com// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
6513481Sgiacomo.travaglini@arm.com//
6613481Sgiacomo.travaglini@arm.com//   type is tuple<int, bool>, and
6713481Sgiacomo.travaglini@arm.com//   GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
6813481Sgiacomo.travaglini@arm.com
6913481Sgiacomo.travaglini@arm.comtemplate <class Tuple$for i [[, int k$i = -1]]>
7013481Sgiacomo.travaglini@arm.comclass TupleFields;
7113481Sgiacomo.travaglini@arm.com
7213481Sgiacomo.travaglini@arm.com// This generic version is used when there are $n selectors.
7313481Sgiacomo.travaglini@arm.comtemplate <class Tuple$for i [[, int k$i]]>
7413481Sgiacomo.travaglini@arm.comclass TupleFields {
7513481Sgiacomo.travaglini@arm.com public:
7613481Sgiacomo.travaglini@arm.com  typedef ::testing::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
7713481Sgiacomo.travaglini@arm.com  static type GetSelectedFields(const Tuple& t) {
7813481Sgiacomo.travaglini@arm.com    return type($for i, [[get<k$i>(t)]]);
7913481Sgiacomo.travaglini@arm.com  }
8013481Sgiacomo.travaglini@arm.com};
8113481Sgiacomo.travaglini@arm.com
8213481Sgiacomo.travaglini@arm.com// The following specialization is used for 0 ~ $(n-1) selectors.
8313481Sgiacomo.travaglini@arm.com
8413481Sgiacomo.travaglini@arm.com$for i [[
8513481Sgiacomo.travaglini@arm.com$$ }}}
8613481Sgiacomo.travaglini@arm.com$range j 0..i-1
8713481Sgiacomo.travaglini@arm.com$range k 0..n-1
8813481Sgiacomo.travaglini@arm.com
8913481Sgiacomo.travaglini@arm.comtemplate <class Tuple$for j [[, int k$j]]>
9013481Sgiacomo.travaglini@arm.comclass TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
9113481Sgiacomo.travaglini@arm.com public:
9213481Sgiacomo.travaglini@arm.com  typedef ::testing::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
9313481Sgiacomo.travaglini@arm.com  static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) {
9413481Sgiacomo.travaglini@arm.com    return type($for j, [[get<k$j>(t)]]);
9513481Sgiacomo.travaglini@arm.com  }
9613481Sgiacomo.travaglini@arm.com};
9713481Sgiacomo.travaglini@arm.com
9813481Sgiacomo.travaglini@arm.com]]
9913481Sgiacomo.travaglini@arm.com
10013481Sgiacomo.travaglini@arm.com#undef GMOCK_FIELD_TYPE_
10113481Sgiacomo.travaglini@arm.com
10213481Sgiacomo.travaglini@arm.com// Implements the Args() matcher.
10313481Sgiacomo.travaglini@arm.com
10413481Sgiacomo.travaglini@arm.com$var ks = [[$for i, [[k$i]]]]
10513481Sgiacomo.travaglini@arm.comtemplate <class ArgsTuple$for i [[, int k$i = -1]]>
10613481Sgiacomo.travaglini@arm.comclass ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
10713481Sgiacomo.travaglini@arm.com public:
10813481Sgiacomo.travaglini@arm.com  // ArgsTuple may have top-level const or reference modifiers.
10913481Sgiacomo.travaglini@arm.com  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
11013481Sgiacomo.travaglini@arm.com  typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
11113481Sgiacomo.travaglini@arm.com  typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
11213481Sgiacomo.travaglini@arm.com
11313481Sgiacomo.travaglini@arm.com  template <typename InnerMatcher>
11413481Sgiacomo.travaglini@arm.com  explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
11513481Sgiacomo.travaglini@arm.com      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
11613481Sgiacomo.travaglini@arm.com
11713481Sgiacomo.travaglini@arm.com  virtual bool MatchAndExplain(ArgsTuple args,
11813481Sgiacomo.travaglini@arm.com                               MatchResultListener* listener) const {
11913481Sgiacomo.travaglini@arm.com    const SelectedArgs& selected_args = GetSelectedArgs(args);
12013481Sgiacomo.travaglini@arm.com    if (!listener->IsInterested())
12113481Sgiacomo.travaglini@arm.com      return inner_matcher_.Matches(selected_args);
12213481Sgiacomo.travaglini@arm.com
12313481Sgiacomo.travaglini@arm.com    PrintIndices(listener->stream());
12413481Sgiacomo.travaglini@arm.com    *listener << "are " << PrintToString(selected_args);
12513481Sgiacomo.travaglini@arm.com
12613481Sgiacomo.travaglini@arm.com    StringMatchResultListener inner_listener;
12713481Sgiacomo.travaglini@arm.com    const bool match = inner_matcher_.MatchAndExplain(selected_args,
12813481Sgiacomo.travaglini@arm.com                                                      &inner_listener);
12913481Sgiacomo.travaglini@arm.com    PrintIfNotEmpty(inner_listener.str(), listener->stream());
13013481Sgiacomo.travaglini@arm.com    return match;
13113481Sgiacomo.travaglini@arm.com  }
13213481Sgiacomo.travaglini@arm.com
13313481Sgiacomo.travaglini@arm.com  virtual void DescribeTo(::std::ostream* os) const {
13413481Sgiacomo.travaglini@arm.com    *os << "are a tuple ";
13513481Sgiacomo.travaglini@arm.com    PrintIndices(os);
13613481Sgiacomo.travaglini@arm.com    inner_matcher_.DescribeTo(os);
13713481Sgiacomo.travaglini@arm.com  }
13813481Sgiacomo.travaglini@arm.com
13913481Sgiacomo.travaglini@arm.com  virtual void DescribeNegationTo(::std::ostream* os) const {
14013481Sgiacomo.travaglini@arm.com    *os << "are a tuple ";
14113481Sgiacomo.travaglini@arm.com    PrintIndices(os);
14213481Sgiacomo.travaglini@arm.com    inner_matcher_.DescribeNegationTo(os);
14313481Sgiacomo.travaglini@arm.com  }
14413481Sgiacomo.travaglini@arm.com
14513481Sgiacomo.travaglini@arm.com private:
14613481Sgiacomo.travaglini@arm.com  static SelectedArgs GetSelectedArgs(ArgsTuple args) {
14713481Sgiacomo.travaglini@arm.com    return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
14813481Sgiacomo.travaglini@arm.com  }
14913481Sgiacomo.travaglini@arm.com
15013481Sgiacomo.travaglini@arm.com  // Prints the indices of the selected fields.
15113481Sgiacomo.travaglini@arm.com  static void PrintIndices(::std::ostream* os) {
15213481Sgiacomo.travaglini@arm.com    *os << "whose fields (";
15313481Sgiacomo.travaglini@arm.com    const int indices[$n] = { $ks };
15413481Sgiacomo.travaglini@arm.com    for (int i = 0; i < $n; i++) {
15513481Sgiacomo.travaglini@arm.com      if (indices[i] < 0)
15613481Sgiacomo.travaglini@arm.com        break;
15713481Sgiacomo.travaglini@arm.com
15813481Sgiacomo.travaglini@arm.com      if (i >= 1)
15913481Sgiacomo.travaglini@arm.com        *os << ", ";
16013481Sgiacomo.travaglini@arm.com
16113481Sgiacomo.travaglini@arm.com      *os << "#" << indices[i];
16213481Sgiacomo.travaglini@arm.com    }
16313481Sgiacomo.travaglini@arm.com    *os << ") ";
16413481Sgiacomo.travaglini@arm.com  }
16513481Sgiacomo.travaglini@arm.com
16613481Sgiacomo.travaglini@arm.com  const MonomorphicInnerMatcher inner_matcher_;
16713481Sgiacomo.travaglini@arm.com
16813481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
16913481Sgiacomo.travaglini@arm.com};
17013481Sgiacomo.travaglini@arm.com
17113481Sgiacomo.travaglini@arm.comtemplate <class InnerMatcher$for i [[, int k$i = -1]]>
17213481Sgiacomo.travaglini@arm.comclass ArgsMatcher {
17313481Sgiacomo.travaglini@arm.com public:
17413481Sgiacomo.travaglini@arm.com  explicit ArgsMatcher(const InnerMatcher& inner_matcher)
17513481Sgiacomo.travaglini@arm.com      : inner_matcher_(inner_matcher) {}
17613481Sgiacomo.travaglini@arm.com
17713481Sgiacomo.travaglini@arm.com  template <typename ArgsTuple>
17813481Sgiacomo.travaglini@arm.com  operator Matcher<ArgsTuple>() const {
17913481Sgiacomo.travaglini@arm.com    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
18013481Sgiacomo.travaglini@arm.com  }
18113481Sgiacomo.travaglini@arm.com
18213481Sgiacomo.travaglini@arm.com private:
18313481Sgiacomo.travaglini@arm.com  const InnerMatcher inner_matcher_;
18413481Sgiacomo.travaglini@arm.com
18513481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
18613481Sgiacomo.travaglini@arm.com};
18713481Sgiacomo.travaglini@arm.com
18813481Sgiacomo.travaglini@arm.com// A set of metafunctions for computing the result type of AllOf.
18913481Sgiacomo.travaglini@arm.com// AllOf(m1, ..., mN) returns
19013481Sgiacomo.travaglini@arm.com// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
19113481Sgiacomo.travaglini@arm.com
19213481Sgiacomo.travaglini@arm.com// Although AllOf isn't defined for one argument, AllOfResult1 is defined
19313481Sgiacomo.travaglini@arm.com// to simplify the implementation.
19413481Sgiacomo.travaglini@arm.comtemplate <typename M1>
19513481Sgiacomo.travaglini@arm.comstruct AllOfResult1 {
19613481Sgiacomo.travaglini@arm.com  typedef M1 type;
19713481Sgiacomo.travaglini@arm.com};
19813481Sgiacomo.travaglini@arm.com
19913481Sgiacomo.travaglini@arm.com$range i 1..n
20013481Sgiacomo.travaglini@arm.com
20113481Sgiacomo.travaglini@arm.com$range i 2..n
20213481Sgiacomo.travaglini@arm.com$for i [[
20313481Sgiacomo.travaglini@arm.com$range j 2..i
20413481Sgiacomo.travaglini@arm.com$var m = i/2
20513481Sgiacomo.travaglini@arm.com$range k 1..m
20613481Sgiacomo.travaglini@arm.com$range t m+1..i
20713481Sgiacomo.travaglini@arm.com
20813481Sgiacomo.travaglini@arm.comtemplate <typename M1$for j [[, typename M$j]]>
20913481Sgiacomo.travaglini@arm.comstruct AllOfResult$i {
21013481Sgiacomo.travaglini@arm.com  typedef BothOfMatcher<
21113481Sgiacomo.travaglini@arm.com      typename AllOfResult$m<$for k, [[M$k]]>::type,
21213481Sgiacomo.travaglini@arm.com      typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
21313481Sgiacomo.travaglini@arm.com  > type;
21413481Sgiacomo.travaglini@arm.com};
21513481Sgiacomo.travaglini@arm.com
21613481Sgiacomo.travaglini@arm.com]]
21713481Sgiacomo.travaglini@arm.com
21813481Sgiacomo.travaglini@arm.com// A set of metafunctions for computing the result type of AnyOf.
21913481Sgiacomo.travaglini@arm.com// AnyOf(m1, ..., mN) returns
22013481Sgiacomo.travaglini@arm.com// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
22113481Sgiacomo.travaglini@arm.com
22213481Sgiacomo.travaglini@arm.com// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
22313481Sgiacomo.travaglini@arm.com// to simplify the implementation.
22413481Sgiacomo.travaglini@arm.comtemplate <typename M1>
22513481Sgiacomo.travaglini@arm.comstruct AnyOfResult1 {
22613481Sgiacomo.travaglini@arm.com  typedef M1 type;
22713481Sgiacomo.travaglini@arm.com};
22813481Sgiacomo.travaglini@arm.com
22913481Sgiacomo.travaglini@arm.com$range i 1..n
23013481Sgiacomo.travaglini@arm.com
23113481Sgiacomo.travaglini@arm.com$range i 2..n
23213481Sgiacomo.travaglini@arm.com$for i [[
23313481Sgiacomo.travaglini@arm.com$range j 2..i
23413481Sgiacomo.travaglini@arm.com$var m = i/2
23513481Sgiacomo.travaglini@arm.com$range k 1..m
23613481Sgiacomo.travaglini@arm.com$range t m+1..i
23713481Sgiacomo.travaglini@arm.com
23813481Sgiacomo.travaglini@arm.comtemplate <typename M1$for j [[, typename M$j]]>
23913481Sgiacomo.travaglini@arm.comstruct AnyOfResult$i {
24013481Sgiacomo.travaglini@arm.com  typedef EitherOfMatcher<
24113481Sgiacomo.travaglini@arm.com      typename AnyOfResult$m<$for k, [[M$k]]>::type,
24213481Sgiacomo.travaglini@arm.com      typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
24313481Sgiacomo.travaglini@arm.com  > type;
24413481Sgiacomo.travaglini@arm.com};
24513481Sgiacomo.travaglini@arm.com
24613481Sgiacomo.travaglini@arm.com]]
24713481Sgiacomo.travaglini@arm.com
24813481Sgiacomo.travaglini@arm.com}  // namespace internal
24913481Sgiacomo.travaglini@arm.com
25013481Sgiacomo.travaglini@arm.com// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
25113481Sgiacomo.travaglini@arm.com// fields of it matches a_matcher.  C++ doesn't support default
25213481Sgiacomo.travaglini@arm.com// arguments for function templates, so we have to overload it.
25313481Sgiacomo.travaglini@arm.com
25413481Sgiacomo.travaglini@arm.com$range i 0..n
25513481Sgiacomo.travaglini@arm.com$for i [[
25613481Sgiacomo.travaglini@arm.com$range j 1..i
25713481Sgiacomo.travaglini@arm.comtemplate <$for j [[int k$j, ]]typename InnerMatcher>
25813481Sgiacomo.travaglini@arm.cominline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
25913481Sgiacomo.travaglini@arm.comArgs(const InnerMatcher& matcher) {
26013481Sgiacomo.travaglini@arm.com  return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
26113481Sgiacomo.travaglini@arm.com}
26213481Sgiacomo.travaglini@arm.com
26313481Sgiacomo.travaglini@arm.com
26413481Sgiacomo.travaglini@arm.com]]
26513481Sgiacomo.travaglini@arm.com// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
26613481Sgiacomo.travaglini@arm.com// n elements, where the i-th element in the container must
26713481Sgiacomo.travaglini@arm.com// match the i-th argument in the list.  Each argument of
26813481Sgiacomo.travaglini@arm.com// ElementsAre() can be either a value or a matcher.  We support up to
26913481Sgiacomo.travaglini@arm.com// $n arguments.
27013481Sgiacomo.travaglini@arm.com//
27113481Sgiacomo.travaglini@arm.com// The use of DecayArray in the implementation allows ElementsAre()
27213481Sgiacomo.travaglini@arm.com// to accept string literals, whose type is const char[N], but we
27313481Sgiacomo.travaglini@arm.com// want to treat them as const char*.
27413481Sgiacomo.travaglini@arm.com//
27513481Sgiacomo.travaglini@arm.com// NOTE: Since ElementsAre() cares about the order of the elements, it
27613481Sgiacomo.travaglini@arm.com// must not be used with containers whose elements's order is
27713481Sgiacomo.travaglini@arm.com// undefined (e.g. hash_map).
27813481Sgiacomo.travaglini@arm.com
27913481Sgiacomo.travaglini@arm.com$range i 0..n
28013481Sgiacomo.travaglini@arm.com$for i [[
28113481Sgiacomo.travaglini@arm.com
28213481Sgiacomo.travaglini@arm.com$range j 1..i
28313481Sgiacomo.travaglini@arm.com
28413481Sgiacomo.travaglini@arm.com$if i>0 [[
28513481Sgiacomo.travaglini@arm.com
28613481Sgiacomo.travaglini@arm.comtemplate <$for j, [[typename T$j]]>
28713481Sgiacomo.travaglini@arm.com]]
28813481Sgiacomo.travaglini@arm.com
28913481Sgiacomo.travaglini@arm.cominline internal::ElementsAreMatcher<
29013481Sgiacomo.travaglini@arm.com    ::testing::tuple<
29113481Sgiacomo.travaglini@arm.com$for j, [[
29213481Sgiacomo.travaglini@arm.com
29313481Sgiacomo.travaglini@arm.com        typename internal::DecayArray<T$j[[]]>::type]]> >
29413481Sgiacomo.travaglini@arm.comElementsAre($for j, [[const T$j& e$j]]) {
29513481Sgiacomo.travaglini@arm.com  typedef ::testing::tuple<
29613481Sgiacomo.travaglini@arm.com$for j, [[
29713481Sgiacomo.travaglini@arm.com
29813481Sgiacomo.travaglini@arm.com      typename internal::DecayArray<T$j[[]]>::type]]> Args;
29913481Sgiacomo.travaglini@arm.com  return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
30013481Sgiacomo.travaglini@arm.com}
30113481Sgiacomo.travaglini@arm.com
30213481Sgiacomo.travaglini@arm.com]]
30313481Sgiacomo.travaglini@arm.com
30413481Sgiacomo.travaglini@arm.com// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
30513481Sgiacomo.travaglini@arm.com// that matches n elements in any order.  We support up to n=$n arguments.
30613481Sgiacomo.travaglini@arm.com
30713481Sgiacomo.travaglini@arm.com$range i 0..n
30813481Sgiacomo.travaglini@arm.com$for i [[
30913481Sgiacomo.travaglini@arm.com
31013481Sgiacomo.travaglini@arm.com$range j 1..i
31113481Sgiacomo.travaglini@arm.com
31213481Sgiacomo.travaglini@arm.com$if i>0 [[
31313481Sgiacomo.travaglini@arm.com
31413481Sgiacomo.travaglini@arm.comtemplate <$for j, [[typename T$j]]>
31513481Sgiacomo.travaglini@arm.com]]
31613481Sgiacomo.travaglini@arm.com
31713481Sgiacomo.travaglini@arm.cominline internal::UnorderedElementsAreMatcher<
31813481Sgiacomo.travaglini@arm.com    ::testing::tuple<
31913481Sgiacomo.travaglini@arm.com$for j, [[
32013481Sgiacomo.travaglini@arm.com
32113481Sgiacomo.travaglini@arm.com        typename internal::DecayArray<T$j[[]]>::type]]> >
32213481Sgiacomo.travaglini@arm.comUnorderedElementsAre($for j, [[const T$j& e$j]]) {
32313481Sgiacomo.travaglini@arm.com  typedef ::testing::tuple<
32413481Sgiacomo.travaglini@arm.com$for j, [[
32513481Sgiacomo.travaglini@arm.com
32613481Sgiacomo.travaglini@arm.com      typename internal::DecayArray<T$j[[]]>::type]]> Args;
32713481Sgiacomo.travaglini@arm.com  return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
32813481Sgiacomo.travaglini@arm.com}
32913481Sgiacomo.travaglini@arm.com
33013481Sgiacomo.travaglini@arm.com]]
33113481Sgiacomo.travaglini@arm.com
33213481Sgiacomo.travaglini@arm.com// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
33313481Sgiacomo.travaglini@arm.com// sub-matchers.  AllOf is called fully qualified to prevent ADL from firing.
33413481Sgiacomo.travaglini@arm.com
33513481Sgiacomo.travaglini@arm.com$range i 2..n
33613481Sgiacomo.travaglini@arm.com$for i [[
33713481Sgiacomo.travaglini@arm.com$range j 1..i
33813481Sgiacomo.travaglini@arm.com$var m = i/2
33913481Sgiacomo.travaglini@arm.com$range k 1..m
34013481Sgiacomo.travaglini@arm.com$range t m+1..i
34113481Sgiacomo.travaglini@arm.com
34213481Sgiacomo.travaglini@arm.comtemplate <$for j, [[typename M$j]]>
34313481Sgiacomo.travaglini@arm.cominline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
34413481Sgiacomo.travaglini@arm.comAllOf($for j, [[M$j m$j]]) {
34513481Sgiacomo.travaglini@arm.com  return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
34613481Sgiacomo.travaglini@arm.com      $if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
34713481Sgiacomo.travaglini@arm.com      $if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
34813481Sgiacomo.travaglini@arm.com}
34913481Sgiacomo.travaglini@arm.com
35013481Sgiacomo.travaglini@arm.com]]
35113481Sgiacomo.travaglini@arm.com
35213481Sgiacomo.travaglini@arm.com// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
35313481Sgiacomo.travaglini@arm.com// sub-matchers.  AnyOf is called fully qualified to prevent ADL from firing.
35413481Sgiacomo.travaglini@arm.com
35513481Sgiacomo.travaglini@arm.com$range i 2..n
35613481Sgiacomo.travaglini@arm.com$for i [[
35713481Sgiacomo.travaglini@arm.com$range j 1..i
35813481Sgiacomo.travaglini@arm.com$var m = i/2
35913481Sgiacomo.travaglini@arm.com$range k 1..m
36013481Sgiacomo.travaglini@arm.com$range t m+1..i
36113481Sgiacomo.travaglini@arm.com
36213481Sgiacomo.travaglini@arm.comtemplate <$for j, [[typename M$j]]>
36313481Sgiacomo.travaglini@arm.cominline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
36413481Sgiacomo.travaglini@arm.comAnyOf($for j, [[M$j m$j]]) {
36513481Sgiacomo.travaglini@arm.com  return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
36613481Sgiacomo.travaglini@arm.com      $if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
36713481Sgiacomo.travaglini@arm.com      $if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
36813481Sgiacomo.travaglini@arm.com}
36913481Sgiacomo.travaglini@arm.com
37013481Sgiacomo.travaglini@arm.com]]
37113481Sgiacomo.travaglini@arm.com
37213481Sgiacomo.travaglini@arm.com}  // namespace testing
37313481Sgiacomo.travaglini@arm.com$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
37413481Sgiacomo.travaglini@arm.com$$   // show up in the generated code.
37513481Sgiacomo.travaglini@arm.com
37613481Sgiacomo.travaglini@arm.com
37713481Sgiacomo.travaglini@arm.com// The MATCHER* family of macros can be used in a namespace scope to
37813481Sgiacomo.travaglini@arm.com// define custom matchers easily.
37913481Sgiacomo.travaglini@arm.com//
38013481Sgiacomo.travaglini@arm.com// Basic Usage
38113481Sgiacomo.travaglini@arm.com// ===========
38213481Sgiacomo.travaglini@arm.com//
38313481Sgiacomo.travaglini@arm.com// The syntax
38413481Sgiacomo.travaglini@arm.com//
38513481Sgiacomo.travaglini@arm.com//   MATCHER(name, description_string) { statements; }
38613481Sgiacomo.travaglini@arm.com//
38713481Sgiacomo.travaglini@arm.com// defines a matcher with the given name that executes the statements,
38813481Sgiacomo.travaglini@arm.com// which must return a bool to indicate if the match succeeds.  Inside
38913481Sgiacomo.travaglini@arm.com// the statements, you can refer to the value being matched by 'arg',
39013481Sgiacomo.travaglini@arm.com// and refer to its type by 'arg_type'.
39113481Sgiacomo.travaglini@arm.com//
39213481Sgiacomo.travaglini@arm.com// The description string documents what the matcher does, and is used
39313481Sgiacomo.travaglini@arm.com// to generate the failure message when the match fails.  Since a
39413481Sgiacomo.travaglini@arm.com// MATCHER() is usually defined in a header file shared by multiple
39513481Sgiacomo.travaglini@arm.com// C++ source files, we require the description to be a C-string
39613481Sgiacomo.travaglini@arm.com// literal to avoid possible side effects.  It can be empty, in which
39713481Sgiacomo.travaglini@arm.com// case we'll use the sequence of words in the matcher name as the
39813481Sgiacomo.travaglini@arm.com// description.
39913481Sgiacomo.travaglini@arm.com//
40013481Sgiacomo.travaglini@arm.com// For example:
40113481Sgiacomo.travaglini@arm.com//
40213481Sgiacomo.travaglini@arm.com//   MATCHER(IsEven, "") { return (arg % 2) == 0; }
40313481Sgiacomo.travaglini@arm.com//
40413481Sgiacomo.travaglini@arm.com// allows you to write
40513481Sgiacomo.travaglini@arm.com//
40613481Sgiacomo.travaglini@arm.com//   // Expects mock_foo.Bar(n) to be called where n is even.
40713481Sgiacomo.travaglini@arm.com//   EXPECT_CALL(mock_foo, Bar(IsEven()));
40813481Sgiacomo.travaglini@arm.com//
40913481Sgiacomo.travaglini@arm.com// or,
41013481Sgiacomo.travaglini@arm.com//
41113481Sgiacomo.travaglini@arm.com//   // Verifies that the value of some_expression is even.
41213481Sgiacomo.travaglini@arm.com//   EXPECT_THAT(some_expression, IsEven());
41313481Sgiacomo.travaglini@arm.com//
41413481Sgiacomo.travaglini@arm.com// If the above assertion fails, it will print something like:
41513481Sgiacomo.travaglini@arm.com//
41613481Sgiacomo.travaglini@arm.com//   Value of: some_expression
41713481Sgiacomo.travaglini@arm.com//   Expected: is even
41813481Sgiacomo.travaglini@arm.com//     Actual: 7
41913481Sgiacomo.travaglini@arm.com//
42013481Sgiacomo.travaglini@arm.com// where the description "is even" is automatically calculated from the
42113481Sgiacomo.travaglini@arm.com// matcher name IsEven.
42213481Sgiacomo.travaglini@arm.com//
42313481Sgiacomo.travaglini@arm.com// Argument Type
42413481Sgiacomo.travaglini@arm.com// =============
42513481Sgiacomo.travaglini@arm.com//
42613481Sgiacomo.travaglini@arm.com// Note that the type of the value being matched (arg_type) is
42713481Sgiacomo.travaglini@arm.com// determined by the context in which you use the matcher and is
42813481Sgiacomo.travaglini@arm.com// supplied to you by the compiler, so you don't need to worry about
42913481Sgiacomo.travaglini@arm.com// declaring it (nor can you).  This allows the matcher to be
43013481Sgiacomo.travaglini@arm.com// polymorphic.  For example, IsEven() can be used to match any type
43113481Sgiacomo.travaglini@arm.com// where the value of "(arg % 2) == 0" can be implicitly converted to
43213481Sgiacomo.travaglini@arm.com// a bool.  In the "Bar(IsEven())" example above, if method Bar()
43313481Sgiacomo.travaglini@arm.com// takes an int, 'arg_type' will be int; if it takes an unsigned long,
43413481Sgiacomo.travaglini@arm.com// 'arg_type' will be unsigned long; and so on.
43513481Sgiacomo.travaglini@arm.com//
43613481Sgiacomo.travaglini@arm.com// Parameterizing Matchers
43713481Sgiacomo.travaglini@arm.com// =======================
43813481Sgiacomo.travaglini@arm.com//
43913481Sgiacomo.travaglini@arm.com// Sometimes you'll want to parameterize the matcher.  For that you
44013481Sgiacomo.travaglini@arm.com// can use another macro:
44113481Sgiacomo.travaglini@arm.com//
44213481Sgiacomo.travaglini@arm.com//   MATCHER_P(name, param_name, description_string) { statements; }
44313481Sgiacomo.travaglini@arm.com//
44413481Sgiacomo.travaglini@arm.com// For example:
44513481Sgiacomo.travaglini@arm.com//
44613481Sgiacomo.travaglini@arm.com//   MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
44713481Sgiacomo.travaglini@arm.com//
44813481Sgiacomo.travaglini@arm.com// will allow you to write:
44913481Sgiacomo.travaglini@arm.com//
45013481Sgiacomo.travaglini@arm.com//   EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
45113481Sgiacomo.travaglini@arm.com//
45213481Sgiacomo.travaglini@arm.com// which may lead to this message (assuming n is 10):
45313481Sgiacomo.travaglini@arm.com//
45413481Sgiacomo.travaglini@arm.com//   Value of: Blah("a")
45513481Sgiacomo.travaglini@arm.com//   Expected: has absolute value 10
45613481Sgiacomo.travaglini@arm.com//     Actual: -9
45713481Sgiacomo.travaglini@arm.com//
45813481Sgiacomo.travaglini@arm.com// Note that both the matcher description and its parameter are
45913481Sgiacomo.travaglini@arm.com// printed, making the message human-friendly.
46013481Sgiacomo.travaglini@arm.com//
46113481Sgiacomo.travaglini@arm.com// In the matcher definition body, you can write 'foo_type' to
46213481Sgiacomo.travaglini@arm.com// reference the type of a parameter named 'foo'.  For example, in the
46313481Sgiacomo.travaglini@arm.com// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
46413481Sgiacomo.travaglini@arm.com// 'value_type' to refer to the type of 'value'.
46513481Sgiacomo.travaglini@arm.com//
46613481Sgiacomo.travaglini@arm.com// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
46713481Sgiacomo.travaglini@arm.com// support multi-parameter matchers.
46813481Sgiacomo.travaglini@arm.com//
46913481Sgiacomo.travaglini@arm.com// Describing Parameterized Matchers
47013481Sgiacomo.travaglini@arm.com// =================================
47113481Sgiacomo.travaglini@arm.com//
47213481Sgiacomo.travaglini@arm.com// The last argument to MATCHER*() is a string-typed expression.  The
47313481Sgiacomo.travaglini@arm.com// expression can reference all of the matcher's parameters and a
47413481Sgiacomo.travaglini@arm.com// special bool-typed variable named 'negation'.  When 'negation' is
47513481Sgiacomo.travaglini@arm.com// false, the expression should evaluate to the matcher's description;
47613481Sgiacomo.travaglini@arm.com// otherwise it should evaluate to the description of the negation of
47713481Sgiacomo.travaglini@arm.com// the matcher.  For example,
47813481Sgiacomo.travaglini@arm.com//
47913481Sgiacomo.travaglini@arm.com//   using testing::PrintToString;
48013481Sgiacomo.travaglini@arm.com//
48113481Sgiacomo.travaglini@arm.com//   MATCHER_P2(InClosedRange, low, hi,
48213481Sgiacomo.travaglini@arm.com//       string(negation ? "is not" : "is") + " in range [" +
48313481Sgiacomo.travaglini@arm.com//       PrintToString(low) + ", " + PrintToString(hi) + "]") {
48413481Sgiacomo.travaglini@arm.com//     return low <= arg && arg <= hi;
48513481Sgiacomo.travaglini@arm.com//   }
48613481Sgiacomo.travaglini@arm.com//   ...
48713481Sgiacomo.travaglini@arm.com//   EXPECT_THAT(3, InClosedRange(4, 6));
48813481Sgiacomo.travaglini@arm.com//   EXPECT_THAT(3, Not(InClosedRange(2, 4)));
48913481Sgiacomo.travaglini@arm.com//
49013481Sgiacomo.travaglini@arm.com// would generate two failures that contain the text:
49113481Sgiacomo.travaglini@arm.com//
49213481Sgiacomo.travaglini@arm.com//   Expected: is in range [4, 6]
49313481Sgiacomo.travaglini@arm.com//   ...
49413481Sgiacomo.travaglini@arm.com//   Expected: is not in range [2, 4]
49513481Sgiacomo.travaglini@arm.com//
49613481Sgiacomo.travaglini@arm.com// If you specify "" as the description, the failure message will
49713481Sgiacomo.travaglini@arm.com// contain the sequence of words in the matcher name followed by the
49813481Sgiacomo.travaglini@arm.com// parameter values printed as a tuple.  For example,
49913481Sgiacomo.travaglini@arm.com//
50013481Sgiacomo.travaglini@arm.com//   MATCHER_P2(InClosedRange, low, hi, "") { ... }
50113481Sgiacomo.travaglini@arm.com//   ...
50213481Sgiacomo.travaglini@arm.com//   EXPECT_THAT(3, InClosedRange(4, 6));
50313481Sgiacomo.travaglini@arm.com//   EXPECT_THAT(3, Not(InClosedRange(2, 4)));
50413481Sgiacomo.travaglini@arm.com//
50513481Sgiacomo.travaglini@arm.com// would generate two failures that contain the text:
50613481Sgiacomo.travaglini@arm.com//
50713481Sgiacomo.travaglini@arm.com//   Expected: in closed range (4, 6)
50813481Sgiacomo.travaglini@arm.com//   ...
50913481Sgiacomo.travaglini@arm.com//   Expected: not (in closed range (2, 4))
51013481Sgiacomo.travaglini@arm.com//
51113481Sgiacomo.travaglini@arm.com// Types of Matcher Parameters
51213481Sgiacomo.travaglini@arm.com// ===========================
51313481Sgiacomo.travaglini@arm.com//
51413481Sgiacomo.travaglini@arm.com// For the purpose of typing, you can view
51513481Sgiacomo.travaglini@arm.com//
51613481Sgiacomo.travaglini@arm.com//   MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
51713481Sgiacomo.travaglini@arm.com//
51813481Sgiacomo.travaglini@arm.com// as shorthand for
51913481Sgiacomo.travaglini@arm.com//
52013481Sgiacomo.travaglini@arm.com//   template <typename p1_type, ..., typename pk_type>
52113481Sgiacomo.travaglini@arm.com//   FooMatcherPk<p1_type, ..., pk_type>
52213481Sgiacomo.travaglini@arm.com//   Foo(p1_type p1, ..., pk_type pk) { ... }
52313481Sgiacomo.travaglini@arm.com//
52413481Sgiacomo.travaglini@arm.com// When you write Foo(v1, ..., vk), the compiler infers the types of
52513481Sgiacomo.travaglini@arm.com// the parameters v1, ..., and vk for you.  If you are not happy with
52613481Sgiacomo.travaglini@arm.com// the result of the type inference, you can specify the types by
52713481Sgiacomo.travaglini@arm.com// explicitly instantiating the template, as in Foo<long, bool>(5,
52813481Sgiacomo.travaglini@arm.com// false).  As said earlier, you don't get to (or need to) specify
52913481Sgiacomo.travaglini@arm.com// 'arg_type' as that's determined by the context in which the matcher
53013481Sgiacomo.travaglini@arm.com// is used.  You can assign the result of expression Foo(p1, ..., pk)
53113481Sgiacomo.travaglini@arm.com// to a variable of type FooMatcherPk<p1_type, ..., pk_type>.  This
53213481Sgiacomo.travaglini@arm.com// can be useful when composing matchers.
53313481Sgiacomo.travaglini@arm.com//
53413481Sgiacomo.travaglini@arm.com// While you can instantiate a matcher template with reference types,
53513481Sgiacomo.travaglini@arm.com// passing the parameters by pointer usually makes your code more
53613481Sgiacomo.travaglini@arm.com// readable.  If, however, you still want to pass a parameter by
53713481Sgiacomo.travaglini@arm.com// reference, be aware that in the failure message generated by the
53813481Sgiacomo.travaglini@arm.com// matcher you will see the value of the referenced object but not its
53913481Sgiacomo.travaglini@arm.com// address.
54013481Sgiacomo.travaglini@arm.com//
54113481Sgiacomo.travaglini@arm.com// Explaining Match Results
54213481Sgiacomo.travaglini@arm.com// ========================
54313481Sgiacomo.travaglini@arm.com//
54413481Sgiacomo.travaglini@arm.com// Sometimes the matcher description alone isn't enough to explain why
54513481Sgiacomo.travaglini@arm.com// the match has failed or succeeded.  For example, when expecting a
54613481Sgiacomo.travaglini@arm.com// long string, it can be very helpful to also print the diff between
54713481Sgiacomo.travaglini@arm.com// the expected string and the actual one.  To achieve that, you can
54813481Sgiacomo.travaglini@arm.com// optionally stream additional information to a special variable
54913481Sgiacomo.travaglini@arm.com// named result_listener, whose type is a pointer to class
55013481Sgiacomo.travaglini@arm.com// MatchResultListener:
55113481Sgiacomo.travaglini@arm.com//
55213481Sgiacomo.travaglini@arm.com//   MATCHER_P(EqualsLongString, str, "") {
55313481Sgiacomo.travaglini@arm.com//     if (arg == str) return true;
55413481Sgiacomo.travaglini@arm.com//
55513481Sgiacomo.travaglini@arm.com//     *result_listener << "the difference: "
55613481Sgiacomo.travaglini@arm.com///                     << DiffStrings(str, arg);
55713481Sgiacomo.travaglini@arm.com//     return false;
55813481Sgiacomo.travaglini@arm.com//   }
55913481Sgiacomo.travaglini@arm.com//
56013481Sgiacomo.travaglini@arm.com// Overloading Matchers
56113481Sgiacomo.travaglini@arm.com// ====================
56213481Sgiacomo.travaglini@arm.com//
56313481Sgiacomo.travaglini@arm.com// You can overload matchers with different numbers of parameters:
56413481Sgiacomo.travaglini@arm.com//
56513481Sgiacomo.travaglini@arm.com//   MATCHER_P(Blah, a, description_string1) { ... }
56613481Sgiacomo.travaglini@arm.com//   MATCHER_P2(Blah, a, b, description_string2) { ... }
56713481Sgiacomo.travaglini@arm.com//
56813481Sgiacomo.travaglini@arm.com// Caveats
56913481Sgiacomo.travaglini@arm.com// =======
57013481Sgiacomo.travaglini@arm.com//
57113481Sgiacomo.travaglini@arm.com// When defining a new matcher, you should also consider implementing
57213481Sgiacomo.travaglini@arm.com// MatcherInterface or using MakePolymorphicMatcher().  These
57313481Sgiacomo.travaglini@arm.com// approaches require more work than the MATCHER* macros, but also
57413481Sgiacomo.travaglini@arm.com// give you more control on the types of the value being matched and
57513481Sgiacomo.travaglini@arm.com// the matcher parameters, which may leads to better compiler error
57613481Sgiacomo.travaglini@arm.com// messages when the matcher is used wrong.  They also allow
57713481Sgiacomo.travaglini@arm.com// overloading matchers based on parameter types (as opposed to just
57813481Sgiacomo.travaglini@arm.com// based on the number of parameters).
57913481Sgiacomo.travaglini@arm.com//
58013481Sgiacomo.travaglini@arm.com// MATCHER*() can only be used in a namespace scope.  The reason is
58113481Sgiacomo.travaglini@arm.com// that C++ doesn't yet allow function-local types to be used to
58213481Sgiacomo.travaglini@arm.com// instantiate templates.  The up-coming C++0x standard will fix this.
58313481Sgiacomo.travaglini@arm.com// Once that's done, we'll consider supporting using MATCHER*() inside
58413481Sgiacomo.travaglini@arm.com// a function.
58513481Sgiacomo.travaglini@arm.com//
58613481Sgiacomo.travaglini@arm.com// More Information
58713481Sgiacomo.travaglini@arm.com// ================
58813481Sgiacomo.travaglini@arm.com//
58913481Sgiacomo.travaglini@arm.com// To learn more about using these macros, please search for 'MATCHER'
59013481Sgiacomo.travaglini@arm.com// on http://code.google.com/p/googlemock/wiki/CookBook.
59113481Sgiacomo.travaglini@arm.com
59213481Sgiacomo.travaglini@arm.com$range i 0..n
59313481Sgiacomo.travaglini@arm.com$for i
59413481Sgiacomo.travaglini@arm.com
59513481Sgiacomo.travaglini@arm.com[[
59613481Sgiacomo.travaglini@arm.com$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
59713481Sgiacomo.travaglini@arm.com                                         $else [[MATCHER_P$i]]]]
59813481Sgiacomo.travaglini@arm.com$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
59913481Sgiacomo.travaglini@arm.com                                                 $else [[P$i]]]]]]
60013481Sgiacomo.travaglini@arm.com$range j 0..i-1
60113481Sgiacomo.travaglini@arm.com$var template = [[$if i==0 [[]] $else [[
60213481Sgiacomo.travaglini@arm.com
60313481Sgiacomo.travaglini@arm.com  template <$for j, [[typename p$j##_type]]>\
60413481Sgiacomo.travaglini@arm.com]]]]
60513481Sgiacomo.travaglini@arm.com$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
60613481Sgiacomo.travaglini@arm.com$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
60713481Sgiacomo.travaglini@arm.com$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
60813481Sgiacomo.travaglini@arm.com$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
60913481Sgiacomo.travaglini@arm.com$var params = [[$for j, [[p$j]]]]
61013481Sgiacomo.travaglini@arm.com$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
61113481Sgiacomo.travaglini@arm.com$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
61213481Sgiacomo.travaglini@arm.com$var param_field_decls = [[$for j
61313481Sgiacomo.travaglini@arm.com[[
61413481Sgiacomo.travaglini@arm.com
61513481Sgiacomo.travaglini@arm.com      p$j##_type p$j;\
61613481Sgiacomo.travaglini@arm.com]]]]
61713481Sgiacomo.travaglini@arm.com$var param_field_decls2 = [[$for j
61813481Sgiacomo.travaglini@arm.com[[
61913481Sgiacomo.travaglini@arm.com
62013481Sgiacomo.travaglini@arm.com    p$j##_type p$j;\
62113481Sgiacomo.travaglini@arm.com]]]]
62213481Sgiacomo.travaglini@arm.com
62313481Sgiacomo.travaglini@arm.com#define $macro_name(name$for j [[, p$j]], description)\$template
62413481Sgiacomo.travaglini@arm.com  class $class_name {\
62513481Sgiacomo.travaglini@arm.com   public:\
62613481Sgiacomo.travaglini@arm.com    template <typename arg_type>\
62713481Sgiacomo.travaglini@arm.com    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
62813481Sgiacomo.travaglini@arm.com     public:\
62913481Sgiacomo.travaglini@arm.com      [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
63013481Sgiacomo.travaglini@arm.com          $impl_inits {}\
63113481Sgiacomo.travaglini@arm.com      virtual bool MatchAndExplain(\
63213481Sgiacomo.travaglini@arm.com          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
63313481Sgiacomo.travaglini@arm.com      virtual void DescribeTo(::std::ostream* gmock_os) const {\
63413481Sgiacomo.travaglini@arm.com        *gmock_os << FormatDescription(false);\
63513481Sgiacomo.travaglini@arm.com      }\
63613481Sgiacomo.travaglini@arm.com      virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
63713481Sgiacomo.travaglini@arm.com        *gmock_os << FormatDescription(true);\
63813481Sgiacomo.travaglini@arm.com      }\$param_field_decls
63913481Sgiacomo.travaglini@arm.com     private:\
64013481Sgiacomo.travaglini@arm.com      ::testing::internal::string FormatDescription(bool negation) const {\
64113481Sgiacomo.travaglini@arm.com        const ::testing::internal::string gmock_description = (description);\
64213481Sgiacomo.travaglini@arm.com        if (!gmock_description.empty())\
64313481Sgiacomo.travaglini@arm.com          return gmock_description;\
64413481Sgiacomo.travaglini@arm.com        return ::testing::internal::FormatMatcherDescription(\
64513481Sgiacomo.travaglini@arm.com            negation, #name, \
64613481Sgiacomo.travaglini@arm.com            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
64713481Sgiacomo.travaglini@arm.com                ::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
64813481Sgiacomo.travaglini@arm.com      }\
64913481Sgiacomo.travaglini@arm.com      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
65013481Sgiacomo.travaglini@arm.com    };\
65113481Sgiacomo.travaglini@arm.com    template <typename arg_type>\
65213481Sgiacomo.travaglini@arm.com    operator ::testing::Matcher<arg_type>() const {\
65313481Sgiacomo.travaglini@arm.com      return ::testing::Matcher<arg_type>(\
65413481Sgiacomo.travaglini@arm.com          new gmock_Impl<arg_type>($params));\
65513481Sgiacomo.travaglini@arm.com    }\
65613481Sgiacomo.travaglini@arm.com    [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\
65713481Sgiacomo.travaglini@arm.com    }\$param_field_decls2
65813481Sgiacomo.travaglini@arm.com   private:\
65913481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_($class_name);\
66013481Sgiacomo.travaglini@arm.com  };\$template
66113481Sgiacomo.travaglini@arm.com  inline $class_name$param_types name($param_types_and_names) {\
66213481Sgiacomo.travaglini@arm.com    return $class_name$param_types($params);\
66313481Sgiacomo.travaglini@arm.com  }\$template
66413481Sgiacomo.travaglini@arm.com  template <typename arg_type>\
66513481Sgiacomo.travaglini@arm.com  bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
66613481Sgiacomo.travaglini@arm.com      arg_type arg, \
66713481Sgiacomo.travaglini@arm.com      ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
66813481Sgiacomo.travaglini@arm.com          const
66913481Sgiacomo.travaglini@arm.com]]
67013481Sgiacomo.travaglini@arm.com
67113481Sgiacomo.travaglini@arm.com
67213481Sgiacomo.travaglini@arm.com#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
673