gmock-generated-matchers.h revision dd1c93d5709e32713961cfd95fe30489a4ad2d26
1// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
2
3// Copyright 2008, Google Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10//     * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12//     * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16//     * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32// Google Mock - a framework for writing C++ mock classes.
33//
34// This file implements some commonly used variadic matchers.
35
36#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
37#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
38
39#include <sstream>
40#include <string>
41#include <vector>
42#include <gmock/gmock-matchers.h>
43#include <gmock/gmock-printers.h>
44
45namespace testing {
46namespace internal {
47
48// The type of the i-th (0-based) field of Tuple.
49#define GMOCK_FIELD_TYPE_(Tuple, i) \
50    typename ::std::tr1::tuple_element<i, Tuple>::type
51
52// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
53// tuple of type Tuple.  It has two members:
54//
55//   type: a tuple type whose i-th field is the ki-th field of Tuple.
56//   GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
57//
58// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
59//
60//   type is tuple<int, bool>, and
61//   GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
62
63template <class Tuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
64    int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
65    int k9 = -1>
66class TupleFields;
67
68// This generic version is used when there are 10 selectors.
69template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
70    int k7, int k8, int k9>
71class TupleFields {
72 public:
73  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
74      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
75      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
76      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
77      GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8),
78      GMOCK_FIELD_TYPE_(Tuple, k9)> type;
79  static type GetSelectedFields(const Tuple& t) {
80    using ::std::tr1::get;
81    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
82        get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t), get<k9>(t));
83  }
84};
85
86// The following specialization is used for 0 ~ 9 selectors.
87
88template <class Tuple>
89class TupleFields<Tuple, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
90 public:
91  typedef ::std::tr1::tuple<> type;
92  static type GetSelectedFields(const Tuple& t) {
93    using ::std::tr1::get;
94    return type();
95  }
96};
97
98template <class Tuple, int k0>
99class TupleFields<Tuple, k0, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
100 public:
101  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type;
102  static type GetSelectedFields(const Tuple& t) {
103    using ::std::tr1::get;
104    return type(get<k0>(t));
105  }
106};
107
108template <class Tuple, int k0, int k1>
109class TupleFields<Tuple, k0, k1, -1, -1, -1, -1, -1, -1, -1, -1> {
110 public:
111  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
112      GMOCK_FIELD_TYPE_(Tuple, k1)> type;
113  static type GetSelectedFields(const Tuple& t) {
114    using ::std::tr1::get;
115    return type(get<k0>(t), get<k1>(t));
116  }
117};
118
119template <class Tuple, int k0, int k1, int k2>
120class TupleFields<Tuple, k0, k1, k2, -1, -1, -1, -1, -1, -1, -1> {
121 public:
122  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
123      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2)> type;
124  static type GetSelectedFields(const Tuple& t) {
125    using ::std::tr1::get;
126    return type(get<k0>(t), get<k1>(t), get<k2>(t));
127  }
128};
129
130template <class Tuple, int k0, int k1, int k2, int k3>
131class TupleFields<Tuple, k0, k1, k2, k3, -1, -1, -1, -1, -1, -1> {
132 public:
133  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
134      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
135      GMOCK_FIELD_TYPE_(Tuple, k3)> type;
136  static type GetSelectedFields(const Tuple& t) {
137    using ::std::tr1::get;
138    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t));
139  }
140};
141
142template <class Tuple, int k0, int k1, int k2, int k3, int k4>
143class TupleFields<Tuple, k0, k1, k2, k3, k4, -1, -1, -1, -1, -1> {
144 public:
145  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
146      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
147      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4)> type;
148  static type GetSelectedFields(const Tuple& t) {
149    using ::std::tr1::get;
150    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t));
151  }
152};
153
154template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5>
155class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, -1, -1, -1, -1> {
156 public:
157  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
158      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
159      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
160      GMOCK_FIELD_TYPE_(Tuple, k5)> type;
161  static type GetSelectedFields(const Tuple& t) {
162    using ::std::tr1::get;
163    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
164        get<k5>(t));
165  }
166};
167
168template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6>
169class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, -1, -1, -1> {
170 public:
171  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
172      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
173      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
174      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6)> type;
175  static type GetSelectedFields(const Tuple& t) {
176    using ::std::tr1::get;
177    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
178        get<k5>(t), get<k6>(t));
179  }
180};
181
182template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
183    int k7>
184class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, -1, -1> {
185 public:
186  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
187      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
188      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
189      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
190      GMOCK_FIELD_TYPE_(Tuple, k7)> type;
191  static type GetSelectedFields(const Tuple& t) {
192    using ::std::tr1::get;
193    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
194        get<k5>(t), get<k6>(t), get<k7>(t));
195  }
196};
197
198template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
199    int k7, int k8>
200class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, -1> {
201 public:
202  typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
203      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
204      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
205      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
206      GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8)> type;
207  static type GetSelectedFields(const Tuple& t) {
208    using ::std::tr1::get;
209    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
210        get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t));
211  }
212};
213
214#undef GMOCK_FIELD_TYPE_
215
216// Implements the Args() matcher.
217template <class ArgsTuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
218    int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
219    int k9 = -1>
220class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
221 public:
222  // ArgsTuple may have top-level const or reference modifiers.
223  typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(ArgsTuple)) RawArgsTuple;
224  typedef typename internal::TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5,
225      k6, k7, k8, k9>::type SelectedArgs;
226  typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
227
228  template <typename InnerMatcher>
229  explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
230      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
231
232  virtual bool Matches(ArgsTuple args) const {
233    return inner_matcher_.Matches(GetSelectedArgs(args));
234  }
235
236  virtual void DescribeTo(::std::ostream* os) const {
237    PrintIndices(os);
238    inner_matcher_.DescribeTo(os);
239  }
240
241  virtual void DescribeNegationTo(::std::ostream* os) const {
242    PrintIndices(os);
243    inner_matcher_.DescribeNegationTo(os);
244  }
245
246  virtual void ExplainMatchResultTo(ArgsTuple args,
247                                    ::std::ostream* os) const {
248    inner_matcher_.ExplainMatchResultTo(GetSelectedArgs(args), os);
249  }
250
251 private:
252  static SelectedArgs GetSelectedArgs(ArgsTuple args) {
253    return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8,
254        k9>::GetSelectedFields(args);
255  }
256
257  // Prints the indices of the selected fields.
258  static void PrintIndices(::std::ostream* os) {
259    *os << "are a tuple whose fields (";
260    const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 };
261    for (int i = 0; i < 10; i++) {
262      if (indices[i] < 0)
263        break;
264
265      if (i >= 1)
266        *os << ", ";
267
268      *os << "#" << indices[i];
269    }
270    *os << ") ";
271  }
272
273  const MonomorphicInnerMatcher inner_matcher_;
274};
275
276template <class InnerMatcher, int k0 = -1, int k1 = -1, int k2 = -1,
277    int k3 = -1, int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1,
278    int k8 = -1, int k9 = -1>
279class ArgsMatcher {
280 public:
281  explicit ArgsMatcher(const InnerMatcher& inner_matcher)
282      : inner_matcher_(inner_matcher) {}
283
284  template <typename ArgsTuple>
285  operator Matcher<ArgsTuple>() const {
286    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k0, k1, k2, k3, k4, k5,
287        k6, k7, k8, k9>(inner_matcher_));
288  }
289
290  const InnerMatcher inner_matcher_;
291};
292
293// Implements ElementsAre() and ElementsAreArray().
294template <typename Container>
295class ElementsAreMatcherImpl : public MatcherInterface<Container> {
296 public:
297  typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
298  typedef internal::StlContainerView<RawContainer> View;
299  typedef typename View::type StlContainer;
300  typedef typename View::const_reference StlContainerReference;
301  typedef typename StlContainer::value_type Element;
302
303  // Constructs the matcher from a sequence of element values or
304  // element matchers.
305  template <typename InputIter>
306  ElementsAreMatcherImpl(InputIter first, size_t count) {
307    matchers_.reserve(count);
308    InputIter it = first;
309    for (size_t i = 0; i != count; ++i, ++it) {
310      matchers_.push_back(MatcherCast<const Element&>(*it));
311    }
312  }
313
314  // Returns true iff 'container' matches.
315  virtual bool Matches(Container container) const {
316    StlContainerReference stl_container = View::ConstReference(container);
317    if (stl_container.size() != count())
318      return false;
319
320    typename StlContainer::const_iterator it = stl_container.begin();
321    for (size_t i = 0; i != count();  ++it, ++i) {
322      if (!matchers_[i].Matches(*it))
323        return false;
324    }
325
326    return true;
327  }
328
329  // Describes what this matcher does.
330  virtual void DescribeTo(::std::ostream* os) const {
331    if (count() == 0) {
332      *os << "is empty";
333    } else if (count() == 1) {
334      *os << "has 1 element that ";
335      matchers_[0].DescribeTo(os);
336    } else {
337      *os << "has " << Elements(count()) << " where\n";
338      for (size_t i = 0; i != count(); ++i) {
339        *os << "element " << i << " ";
340        matchers_[i].DescribeTo(os);
341        if (i + 1 < count()) {
342          *os << ",\n";
343        }
344      }
345    }
346  }
347
348  // Describes what the negation of this matcher does.
349  virtual void DescribeNegationTo(::std::ostream* os) const {
350    if (count() == 0) {
351      *os << "is not empty";
352      return;
353    }
354
355    *os << "does not have " << Elements(count()) << ", or\n";
356    for (size_t i = 0; i != count(); ++i) {
357      *os << "element " << i << " ";
358      matchers_[i].DescribeNegationTo(os);
359      if (i + 1 < count()) {
360        *os << ", or\n";
361      }
362    }
363  }
364
365  // Explains why 'container' matches, or doesn't match, this matcher.
366  virtual void ExplainMatchResultTo(Container container,
367                                    ::std::ostream* os) const {
368    StlContainerReference stl_container = View::ConstReference(container);
369    if (Matches(container)) {
370      // We need to explain why *each* element matches (the obvious
371      // ones can be skipped).
372
373      bool reason_printed = false;
374      typename StlContainer::const_iterator it = stl_container.begin();
375      for (size_t i = 0; i != count(); ++it, ++i) {
376        ::std::stringstream ss;
377        matchers_[i].ExplainMatchResultTo(*it, &ss);
378
379        const string s = ss.str();
380        if (!s.empty()) {
381          if (reason_printed) {
382            *os << ",\n";
383          }
384          *os << "element " << i << " " << s;
385          reason_printed = true;
386        }
387      }
388    } else {
389      // We need to explain why the container doesn't match.
390      const size_t actual_count = stl_container.size();
391      if (actual_count != count()) {
392        // The element count doesn't match.  If the container is
393        // empty, there's no need to explain anything as Google Mock
394        // already prints the empty container.  Otherwise we just need
395        // to show how many elements there actually are.
396        if (actual_count != 0) {
397          *os << "has " << Elements(actual_count);
398        }
399        return;
400      }
401
402      // The container has the right size but at least one element
403      // doesn't match expectation.  We need to find this element and
404      // explain why it doesn't match.
405      typename StlContainer::const_iterator it = stl_container.begin();
406      for (size_t i = 0; i != count(); ++it, ++i) {
407        if (matchers_[i].Matches(*it)) {
408          continue;
409        }
410
411        *os << "element " << i << " doesn't match";
412
413        ::std::stringstream ss;
414        matchers_[i].ExplainMatchResultTo(*it, &ss);
415        const string s = ss.str();
416        if (!s.empty()) {
417          *os << " (" << s << ")";
418        }
419        return;
420      }
421    }
422  }
423
424 private:
425  static Message Elements(size_t count) {
426    return Message() << count << (count == 1 ? " element" : " elements");
427  }
428
429  size_t count() const { return matchers_.size(); }
430  std::vector<Matcher<const Element&> > matchers_;
431};
432
433// Implements ElementsAre() of 0-10 arguments.
434
435class ElementsAreMatcher0 {
436 public:
437  ElementsAreMatcher0() {}
438
439  template <typename Container>
440  operator Matcher<Container>() const {
441    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
442        RawContainer;
443    typedef typename internal::StlContainerView<RawContainer>::type::value_type
444        Element;
445
446    const Matcher<const Element&>* const matchers = NULL;
447    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
448  }
449};
450
451template <typename T1>
452class ElementsAreMatcher1 {
453 public:
454  explicit ElementsAreMatcher1(const T1& e1) : e1_(e1) {}
455
456  template <typename Container>
457  operator Matcher<Container>() const {
458    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
459        RawContainer;
460    typedef typename internal::StlContainerView<RawContainer>::type::value_type
461        Element;
462
463    const Matcher<const Element&> matchers[] = {
464      MatcherCast<const Element&>(e1_),
465    };
466
467    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 1));
468  }
469
470 private:
471  const T1& e1_;
472};
473
474template <typename T1, typename T2>
475class ElementsAreMatcher2 {
476 public:
477  ElementsAreMatcher2(const T1& e1, const T2& e2) : e1_(e1), e2_(e2) {}
478
479  template <typename Container>
480  operator Matcher<Container>() const {
481    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
482        RawContainer;
483    typedef typename internal::StlContainerView<RawContainer>::type::value_type
484        Element;
485
486    const Matcher<const Element&> matchers[] = {
487      MatcherCast<const Element&>(e1_),
488      MatcherCast<const Element&>(e2_),
489    };
490
491    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 2));
492  }
493
494 private:
495  const T1& e1_;
496  const T2& e2_;
497};
498
499template <typename T1, typename T2, typename T3>
500class ElementsAreMatcher3 {
501 public:
502  ElementsAreMatcher3(const T1& e1, const T2& e2, const T3& e3) : e1_(e1),
503      e2_(e2), e3_(e3) {}
504
505  template <typename Container>
506  operator Matcher<Container>() const {
507    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
508        RawContainer;
509    typedef typename internal::StlContainerView<RawContainer>::type::value_type
510        Element;
511
512    const Matcher<const Element&> matchers[] = {
513      MatcherCast<const Element&>(e1_),
514      MatcherCast<const Element&>(e2_),
515      MatcherCast<const Element&>(e3_),
516    };
517
518    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 3));
519  }
520
521 private:
522  const T1& e1_;
523  const T2& e2_;
524  const T3& e3_;
525};
526
527template <typename T1, typename T2, typename T3, typename T4>
528class ElementsAreMatcher4 {
529 public:
530  ElementsAreMatcher4(const T1& e1, const T2& e2, const T3& e3,
531      const T4& e4) : e1_(e1), e2_(e2), e3_(e3), e4_(e4) {}
532
533  template <typename Container>
534  operator Matcher<Container>() const {
535    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
536        RawContainer;
537    typedef typename internal::StlContainerView<RawContainer>::type::value_type
538        Element;
539
540    const Matcher<const Element&> matchers[] = {
541      MatcherCast<const Element&>(e1_),
542      MatcherCast<const Element&>(e2_),
543      MatcherCast<const Element&>(e3_),
544      MatcherCast<const Element&>(e4_),
545    };
546
547    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 4));
548  }
549
550 private:
551  const T1& e1_;
552  const T2& e2_;
553  const T3& e3_;
554  const T4& e4_;
555};
556
557template <typename T1, typename T2, typename T3, typename T4, typename T5>
558class ElementsAreMatcher5 {
559 public:
560  ElementsAreMatcher5(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
561      const T5& e5) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5) {}
562
563  template <typename Container>
564  operator Matcher<Container>() const {
565    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
566        RawContainer;
567    typedef typename internal::StlContainerView<RawContainer>::type::value_type
568        Element;
569
570    const Matcher<const Element&> matchers[] = {
571      MatcherCast<const Element&>(e1_),
572      MatcherCast<const Element&>(e2_),
573      MatcherCast<const Element&>(e3_),
574      MatcherCast<const Element&>(e4_),
575      MatcherCast<const Element&>(e5_),
576    };
577
578    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 5));
579  }
580
581 private:
582  const T1& e1_;
583  const T2& e2_;
584  const T3& e3_;
585  const T4& e4_;
586  const T5& e5_;
587};
588
589template <typename T1, typename T2, typename T3, typename T4, typename T5,
590    typename T6>
591class ElementsAreMatcher6 {
592 public:
593  ElementsAreMatcher6(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
594      const T5& e5, const T6& e6) : e1_(e1), e2_(e2), e3_(e3), e4_(e4),
595      e5_(e5), e6_(e6) {}
596
597  template <typename Container>
598  operator Matcher<Container>() const {
599    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
600        RawContainer;
601    typedef typename internal::StlContainerView<RawContainer>::type::value_type
602        Element;
603
604    const Matcher<const Element&> matchers[] = {
605      MatcherCast<const Element&>(e1_),
606      MatcherCast<const Element&>(e2_),
607      MatcherCast<const Element&>(e3_),
608      MatcherCast<const Element&>(e4_),
609      MatcherCast<const Element&>(e5_),
610      MatcherCast<const Element&>(e6_),
611    };
612
613    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 6));
614  }
615
616 private:
617  const T1& e1_;
618  const T2& e2_;
619  const T3& e3_;
620  const T4& e4_;
621  const T5& e5_;
622  const T6& e6_;
623};
624
625template <typename T1, typename T2, typename T3, typename T4, typename T5,
626    typename T6, typename T7>
627class ElementsAreMatcher7 {
628 public:
629  ElementsAreMatcher7(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
630      const T5& e5, const T6& e6, const T7& e7) : e1_(e1), e2_(e2), e3_(e3),
631      e4_(e4), e5_(e5), e6_(e6), e7_(e7) {}
632
633  template <typename Container>
634  operator Matcher<Container>() const {
635    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
636        RawContainer;
637    typedef typename internal::StlContainerView<RawContainer>::type::value_type
638        Element;
639
640    const Matcher<const Element&> matchers[] = {
641      MatcherCast<const Element&>(e1_),
642      MatcherCast<const Element&>(e2_),
643      MatcherCast<const Element&>(e3_),
644      MatcherCast<const Element&>(e4_),
645      MatcherCast<const Element&>(e5_),
646      MatcherCast<const Element&>(e6_),
647      MatcherCast<const Element&>(e7_),
648    };
649
650    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 7));
651  }
652
653 private:
654  const T1& e1_;
655  const T2& e2_;
656  const T3& e3_;
657  const T4& e4_;
658  const T5& e5_;
659  const T6& e6_;
660  const T7& e7_;
661};
662
663template <typename T1, typename T2, typename T3, typename T4, typename T5,
664    typename T6, typename T7, typename T8>
665class ElementsAreMatcher8 {
666 public:
667  ElementsAreMatcher8(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
668      const T5& e5, const T6& e6, const T7& e7, const T8& e8) : e1_(e1),
669      e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6), e7_(e7), e8_(e8) {}
670
671  template <typename Container>
672  operator Matcher<Container>() const {
673    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
674        RawContainer;
675    typedef typename internal::StlContainerView<RawContainer>::type::value_type
676        Element;
677
678    const Matcher<const Element&> matchers[] = {
679      MatcherCast<const Element&>(e1_),
680      MatcherCast<const Element&>(e2_),
681      MatcherCast<const Element&>(e3_),
682      MatcherCast<const Element&>(e4_),
683      MatcherCast<const Element&>(e5_),
684      MatcherCast<const Element&>(e6_),
685      MatcherCast<const Element&>(e7_),
686      MatcherCast<const Element&>(e8_),
687    };
688
689    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 8));
690  }
691
692 private:
693  const T1& e1_;
694  const T2& e2_;
695  const T3& e3_;
696  const T4& e4_;
697  const T5& e5_;
698  const T6& e6_;
699  const T7& e7_;
700  const T8& e8_;
701};
702
703template <typename T1, typename T2, typename T3, typename T4, typename T5,
704    typename T6, typename T7, typename T8, typename T9>
705class ElementsAreMatcher9 {
706 public:
707  ElementsAreMatcher9(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
708      const T5& e5, const T6& e6, const T7& e7, const T8& e8,
709      const T9& e9) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6),
710      e7_(e7), e8_(e8), e9_(e9) {}
711
712  template <typename Container>
713  operator Matcher<Container>() const {
714    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
715        RawContainer;
716    typedef typename internal::StlContainerView<RawContainer>::type::value_type
717        Element;
718
719    const Matcher<const Element&> matchers[] = {
720      MatcherCast<const Element&>(e1_),
721      MatcherCast<const Element&>(e2_),
722      MatcherCast<const Element&>(e3_),
723      MatcherCast<const Element&>(e4_),
724      MatcherCast<const Element&>(e5_),
725      MatcherCast<const Element&>(e6_),
726      MatcherCast<const Element&>(e7_),
727      MatcherCast<const Element&>(e8_),
728      MatcherCast<const Element&>(e9_),
729    };
730
731    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 9));
732  }
733
734 private:
735  const T1& e1_;
736  const T2& e2_;
737  const T3& e3_;
738  const T4& e4_;
739  const T5& e5_;
740  const T6& e6_;
741  const T7& e7_;
742  const T8& e8_;
743  const T9& e9_;
744};
745
746template <typename T1, typename T2, typename T3, typename T4, typename T5,
747    typename T6, typename T7, typename T8, typename T9, typename T10>
748class ElementsAreMatcher10 {
749 public:
750  ElementsAreMatcher10(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
751      const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
752      const T10& e10) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6),
753      e7_(e7), e8_(e8), e9_(e9), e10_(e10) {}
754
755  template <typename Container>
756  operator Matcher<Container>() const {
757    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
758        RawContainer;
759    typedef typename internal::StlContainerView<RawContainer>::type::value_type
760        Element;
761
762    const Matcher<const Element&> matchers[] = {
763      MatcherCast<const Element&>(e1_),
764      MatcherCast<const Element&>(e2_),
765      MatcherCast<const Element&>(e3_),
766      MatcherCast<const Element&>(e4_),
767      MatcherCast<const Element&>(e5_),
768      MatcherCast<const Element&>(e6_),
769      MatcherCast<const Element&>(e7_),
770      MatcherCast<const Element&>(e8_),
771      MatcherCast<const Element&>(e9_),
772      MatcherCast<const Element&>(e10_),
773    };
774
775    return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 10));
776  }
777
778 private:
779  const T1& e1_;
780  const T2& e2_;
781  const T3& e3_;
782  const T4& e4_;
783  const T5& e5_;
784  const T6& e6_;
785  const T7& e7_;
786  const T8& e8_;
787  const T9& e9_;
788  const T10& e10_;
789};
790
791// Implements ElementsAreArray().
792template <typename T>
793class ElementsAreArrayMatcher {
794 public:
795  ElementsAreArrayMatcher(const T* first, size_t count) :
796      first_(first), count_(count) {}
797
798  template <typename Container>
799  operator Matcher<Container>() const {
800    typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
801        RawContainer;
802    typedef typename internal::StlContainerView<RawContainer>::type::value_type
803        Element;
804
805    return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
806  }
807
808 private:
809  const T* const first_;
810  const size_t count_;
811};
812
813}  // namespace internal
814
815// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
816// fields of it matches a_matcher.  C++ doesn't support default
817// arguments for function templates, so we have to overload it.
818template <typename InnerMatcher>
819inline internal::ArgsMatcher<InnerMatcher>
820Args(const InnerMatcher& matcher) {
821  return internal::ArgsMatcher<InnerMatcher>(matcher);
822}
823
824template <int k1, typename InnerMatcher>
825inline internal::ArgsMatcher<InnerMatcher, k1>
826Args(const InnerMatcher& matcher) {
827  return internal::ArgsMatcher<InnerMatcher, k1>(matcher);
828}
829
830template <int k1, int k2, typename InnerMatcher>
831inline internal::ArgsMatcher<InnerMatcher, k1, k2>
832Args(const InnerMatcher& matcher) {
833  return internal::ArgsMatcher<InnerMatcher, k1, k2>(matcher);
834}
835
836template <int k1, int k2, int k3, typename InnerMatcher>
837inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3>
838Args(const InnerMatcher& matcher) {
839  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3>(matcher);
840}
841
842template <int k1, int k2, int k3, int k4, typename InnerMatcher>
843inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>
844Args(const InnerMatcher& matcher) {
845  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>(matcher);
846}
847
848template <int k1, int k2, int k3, int k4, int k5, typename InnerMatcher>
849inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>
850Args(const InnerMatcher& matcher) {
851  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>(matcher);
852}
853
854template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerMatcher>
855inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>
856Args(const InnerMatcher& matcher) {
857  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>(matcher);
858}
859
860template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
861    typename InnerMatcher>
862inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7>
863Args(const InnerMatcher& matcher) {
864  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6,
865      k7>(matcher);
866}
867
868template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
869    typename InnerMatcher>
870inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8>
871Args(const InnerMatcher& matcher) {
872  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7,
873      k8>(matcher);
874}
875
876template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
877    int k9, typename InnerMatcher>
878inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9>
879Args(const InnerMatcher& matcher) {
880  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
881      k9>(matcher);
882}
883
884template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
885    int k9, int k10, typename InnerMatcher>
886inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9,
887    k10>
888Args(const InnerMatcher& matcher) {
889  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
890      k9, k10>(matcher);
891}
892
893// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with
894// (n + 1) elements, where the i-th element in the container must
895// match the i-th argument in the list.  Each argument of
896// ElementsAre() can be either a value or a matcher.  We support up to
897// 10 arguments.
898//
899// NOTE: Since ElementsAre() cares about the order of the elements, it
900// must not be used with containers whose elements's order is
901// undefined (e.g. hash_map).
902
903inline internal::ElementsAreMatcher0 ElementsAre() {
904  return internal::ElementsAreMatcher0();
905}
906
907template <typename T1>
908inline internal::ElementsAreMatcher1<T1> ElementsAre(const T1& e1) {
909  return internal::ElementsAreMatcher1<T1>(e1);
910}
911
912template <typename T1, typename T2>
913inline internal::ElementsAreMatcher2<T1, T2> ElementsAre(const T1& e1,
914    const T2& e2) {
915  return internal::ElementsAreMatcher2<T1, T2>(e1, e2);
916}
917
918template <typename T1, typename T2, typename T3>
919inline internal::ElementsAreMatcher3<T1, T2, T3> ElementsAre(const T1& e1,
920    const T2& e2, const T3& e3) {
921  return internal::ElementsAreMatcher3<T1, T2, T3>(e1, e2, e3);
922}
923
924template <typename T1, typename T2, typename T3, typename T4>
925inline internal::ElementsAreMatcher4<T1, T2, T3, T4> ElementsAre(const T1& e1,
926    const T2& e2, const T3& e3, const T4& e4) {
927  return internal::ElementsAreMatcher4<T1, T2, T3, T4>(e1, e2, e3, e4);
928}
929
930template <typename T1, typename T2, typename T3, typename T4, typename T5>
931inline internal::ElementsAreMatcher5<T1, T2, T3, T4,
932    T5> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
933    const T5& e5) {
934  return internal::ElementsAreMatcher5<T1, T2, T3, T4, T5>(e1, e2, e3, e4, e5);
935}
936
937template <typename T1, typename T2, typename T3, typename T4, typename T5,
938    typename T6>
939inline internal::ElementsAreMatcher6<T1, T2, T3, T4, T5,
940    T6> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
941    const T5& e5, const T6& e6) {
942  return internal::ElementsAreMatcher6<T1, T2, T3, T4, T5, T6>(e1, e2, e3, e4,
943      e5, e6);
944}
945
946template <typename T1, typename T2, typename T3, typename T4, typename T5,
947    typename T6, typename T7>
948inline internal::ElementsAreMatcher7<T1, T2, T3, T4, T5, T6,
949    T7> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
950    const T5& e5, const T6& e6, const T7& e7) {
951  return internal::ElementsAreMatcher7<T1, T2, T3, T4, T5, T6, T7>(e1, e2, e3,
952      e4, e5, e6, e7);
953}
954
955template <typename T1, typename T2, typename T3, typename T4, typename T5,
956    typename T6, typename T7, typename T8>
957inline internal::ElementsAreMatcher8<T1, T2, T3, T4, T5, T6, T7,
958    T8> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
959    const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
960  return internal::ElementsAreMatcher8<T1, T2, T3, T4, T5, T6, T7, T8>(e1, e2,
961      e3, e4, e5, e6, e7, e8);
962}
963
964template <typename T1, typename T2, typename T3, typename T4, typename T5,
965    typename T6, typename T7, typename T8, typename T9>
966inline internal::ElementsAreMatcher9<T1, T2, T3, T4, T5, T6, T7, T8,
967    T9> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
968    const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
969  return internal::ElementsAreMatcher9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(e1,
970      e2, e3, e4, e5, e6, e7, e8, e9);
971}
972
973template <typename T1, typename T2, typename T3, typename T4, typename T5,
974    typename T6, typename T7, typename T8, typename T9, typename T10>
975inline internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
976    T10> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
977    const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
978    const T10& e10) {
979  return internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
980      T10>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
981}
982
983// ElementsAreArray(array) and ElementAreArray(array, count) are like
984// ElementsAre(), except that they take an array of values or
985// matchers.  The former form infers the size of 'array', which must
986// be a static C-style array.  In the latter form, 'array' can either
987// be a static array or a pointer to a dynamically created array.
988
989template <typename T>
990inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
991    const T* first, size_t count) {
992  return internal::ElementsAreArrayMatcher<T>(first, count);
993}
994
995template <typename T, size_t N>
996inline internal::ElementsAreArrayMatcher<T>
997ElementsAreArray(const T (&array)[N]) {
998  return internal::ElementsAreArrayMatcher<T>(array, N);
999}
1000
1001}  // namespace testing
1002
1003// The MATCHER* family of macros can be used in a namespace scope to
1004// define custom matchers easily.  The syntax:
1005//
1006//   MATCHER(name, description_string) { statements; }
1007//
1008// will define a matcher with the given name that executes the
1009// statements, which must return a bool to indicate if the match
1010// succeeds.  Inside the statements, you can refer to the value being
1011// matched by 'arg', and refer to its type by 'arg_type'.
1012//
1013// The description string documents what the matcher does, and is used
1014// to generate the failure message when the match fails.  Since a
1015// MATCHER() is usually defined in a header file shared by multiple
1016// C++ source files, we require the description to be a C-string
1017// literal to avoid possible side effects.  It can be empty, in which
1018// case we'll use the sequence of words in the matcher name as the
1019// description.
1020//
1021// For example:
1022//
1023//   MATCHER(IsEven, "") { return (arg % 2) == 0; }
1024//
1025// allows you to write
1026//
1027//   // Expects mock_foo.Bar(n) to be called where n is even.
1028//   EXPECT_CALL(mock_foo, Bar(IsEven()));
1029//
1030// or,
1031//
1032//   // Verifies that the value of some_expression is even.
1033//   EXPECT_THAT(some_expression, IsEven());
1034//
1035// If the above assertion fails, it will print something like:
1036//
1037//   Value of: some_expression
1038//   Expected: is even
1039//     Actual: 7
1040//
1041// where the description "is even" is automatically calculated from the
1042// matcher name IsEven.
1043//
1044// Note that the type of the value being matched (arg_type) is
1045// determined by the context in which you use the matcher and is
1046// supplied to you by the compiler, so you don't need to worry about
1047// declaring it (nor can you).  This allows the matcher to be
1048// polymorphic.  For example, IsEven() can be used to match any type
1049// where the value of "(arg % 2) == 0" can be implicitly converted to
1050// a bool.  In the "Bar(IsEven())" example above, if method Bar()
1051// takes an int, 'arg_type' will be int; if it takes an unsigned long,
1052// 'arg_type' will be unsigned long; and so on.
1053//
1054// Sometimes you'll want to parameterize the matcher.  For that you
1055// can use another macro:
1056//
1057//   MATCHER_P(name, param_name, description_string) { statements; }
1058//
1059// For example:
1060//
1061//   MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
1062//
1063// will allow you to write:
1064//
1065//   EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
1066//
1067// which may lead to this message (assuming n is 10):
1068//
1069//   Value of: Blah("a")
1070//   Expected: has absolute value 10
1071//     Actual: -9
1072//
1073// Note that both the matcher description and its parameter are
1074// printed, making the message human-friendly.
1075//
1076// In the matcher definition body, you can write 'foo_type' to
1077// reference the type of a parameter named 'foo'.  For example, in the
1078// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
1079// 'value_type' to refer to the type of 'value'.
1080//
1081// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to
1082// support multi-parameter matchers.
1083//
1084// When defining a parameterized matcher, you can use Python-style
1085// interpolations in the description string to refer to the parameter
1086// values.  We support the following syntax currently:
1087//
1088//   %%       a single '%' character
1089//   %(*)s    all parameters of the matcher printed as a tuple
1090//   %(foo)s  value of the matcher parameter named 'foo'
1091//
1092// For example,
1093//
1094//   MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") {
1095//     return low <= arg && arg <= hi;
1096//   }
1097//   ...
1098//   EXPECT_THAT(3, InClosedRange(4, 6));
1099//
1100// would generate a failure that contains the message:
1101//
1102//   Expected: is in range [4, 6]
1103//
1104// If you specify "" as the description, the failure message will
1105// contain the sequence of words in the matcher name followed by the
1106// parameter values printed as a tuple.  For example,
1107//
1108//   MATCHER_P2(InClosedRange, low, hi, "") { ... }
1109//   ...
1110//   EXPECT_THAT(3, InClosedRange(4, 6));
1111//
1112// would generate a failure that contains the text:
1113//
1114//   Expected: in closed range (4, 6)
1115//
1116// For the purpose of typing, you can view
1117//
1118//   MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
1119//
1120// as shorthand for
1121//
1122//   template <typename p1_type, ..., typename pk_type>
1123//   FooMatcherPk<p1_type, ..., pk_type>
1124//   Foo(p1_type p1, ..., pk_type pk) { ... }
1125//
1126// When you write Foo(v1, ..., vk), the compiler infers the types of
1127// the parameters v1, ..., and vk for you.  If you are not happy with
1128// the result of the type inference, you can specify the types by
1129// explicitly instantiating the template, as in Foo<long, bool>(5,
1130// false).  As said earlier, you don't get to (or need to) specify
1131// 'arg_type' as that's determined by the context in which the matcher
1132// is used.  You can assign the result of expression Foo(p1, ..., pk)
1133// to a variable of type FooMatcherPk<p1_type, ..., pk_type>.  This
1134// can be useful when composing matchers.
1135//
1136// While you can instantiate a matcher template with reference types,
1137// passing the parameters by pointer usually makes your code more
1138// readable.  If, however, you still want to pass a parameter by
1139// reference, be aware that in the failure message generated by the
1140// matcher you will see the value of the referenced object but not its
1141// address.
1142//
1143// You can overload matchers with different numbers of parameters:
1144//
1145//   MATCHER_P(Blah, a, description_string1) { ... }
1146//   MATCHER_P2(Blah, a, b, description_string2) { ... }
1147//
1148// While it's tempting to always use the MATCHER* macros when defining
1149// a new matcher, you should also consider implementing
1150// MatcherInterface or using MakePolymorphicMatcher() instead,
1151// especially if you need to use the matcher a lot.  While these
1152// approaches require more work, they give you more control on the
1153// types of the value being matched and the matcher parameters, which
1154// in general leads to better compiler error messages that pay off in
1155// the long run.  They also allow overloading matchers based on
1156// parameter types (as opposed to just based on the number of
1157// parameters).
1158//
1159// CAVEAT:
1160//
1161// MATCHER*() can only be used in a namespace scope.  The reason is
1162// that C++ doesn't yet allow function-local types to be used to
1163// instantiate templates.  The up-coming C++0x standard will fix this.
1164// Once that's done, we'll consider supporting using MATCHER*() inside
1165// a function.
1166//
1167// MORE INFORMATION:
1168//
1169// To learn more about using these macros, please search for 'MATCHER'
1170// on http://code.google.com/p/googlemock/wiki/CookBook.
1171
1172namespace testing {
1173namespace internal {
1174
1175// Constants denoting interpolations in a matcher description string.
1176const int kTupleInterpolation = -1;    // "%(*)s"
1177const int kPercentInterpolation = -2;  // "%%"
1178const int kInvalidInterpolation = -3;  // "%" followed by invalid text
1179
1180// Records the location and content of an interpolation.
1181struct Interpolation {
1182  Interpolation(const char* start, const char* end, int param)
1183      : start_pos(start), end_pos(end), param_index(param) {}
1184
1185  // Points to the start of the interpolation (the '%' character).
1186  const char* start_pos;
1187  // Points to the first character after the interpolation.
1188  const char* end_pos;
1189  // 0-based index of the interpolated matcher parameter;
1190  // kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
1191  int param_index;
1192};
1193
1194typedef ::std::vector<Interpolation> Interpolations;
1195
1196// Parses a matcher description string and returns a vector of
1197// interpolations that appear in the string; generates non-fatal
1198// failures iff 'description' is an invalid matcher description.
1199// 'param_names' is a NULL-terminated array of parameter names in the
1200// order they appear in the MATCHER_P*() parameter list.
1201Interpolations ValidateMatcherDescription(
1202    const char* param_names[], const char* description);
1203
1204// Returns the actual matcher description, given the matcher name,
1205// user-supplied description template string, interpolations in the
1206// string, and the printed values of the matcher parameters.
1207string FormatMatcherDescription(
1208    const char* matcher_name, const char* description,
1209    const Interpolations& interp, const Strings& param_values);
1210
1211}  // namespace internal
1212}  // namespace testing
1213
1214#define MATCHER(name, description)\
1215  class name##Matcher {\
1216   public:\
1217    template <typename arg_type>\
1218    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1219     public:\
1220      gmock_Impl(const ::testing::internal::Interpolations& gmock_interp)\
1221           : gmock_interp_(gmock_interp) {}\
1222      virtual bool Matches(arg_type arg) const;\
1223      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1224        const ::testing::internal::Strings& gmock_printed_params = \
1225            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1226                ::std::tr1::tuple<>());\
1227        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1228                     #name, description, gmock_interp_, gmock_printed_params);\
1229      }\
1230      const ::testing::internal::Interpolations gmock_interp_;\
1231    };\
1232    template <typename arg_type>\
1233    operator ::testing::Matcher<arg_type>() const {\
1234      return ::testing::Matcher<arg_type>(\
1235          new gmock_Impl<arg_type>(gmock_interp_));\
1236    }\
1237    name##Matcher() {\
1238      const char* gmock_param_names[] = { NULL };\
1239      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1240          gmock_param_names, ("" description ""));\
1241    }\
1242    ::testing::internal::Interpolations gmock_interp_;\
1243  };\
1244  inline name##Matcher name() {\
1245    return name##Matcher();\
1246  }\
1247  template <typename arg_type>\
1248  bool name##Matcher::\
1249      gmock_Impl<arg_type>::Matches(arg_type arg) const
1250
1251#define MATCHER_P(name, p0, description)\
1252  template <typename p0##_type>\
1253  class name##MatcherP {\
1254   public:\
1255    template <typename arg_type>\
1256    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1257     public:\
1258      explicit gmock_Impl(p0##_type gmock_p0, \
1259          const ::testing::internal::Interpolations& gmock_interp)\
1260           : p0(gmock_p0), gmock_interp_(gmock_interp) {}\
1261      virtual bool Matches(arg_type arg) const;\
1262      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1263        const ::testing::internal::Strings& gmock_printed_params = \
1264            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1265                ::std::tr1::tuple<p0##_type>(p0));\
1266        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1267                     #name, description, gmock_interp_, gmock_printed_params);\
1268      }\
1269      p0##_type p0;\
1270      const ::testing::internal::Interpolations gmock_interp_;\
1271    };\
1272    template <typename arg_type>\
1273    operator ::testing::Matcher<arg_type>() const {\
1274      return ::testing::Matcher<arg_type>(\
1275          new gmock_Impl<arg_type>(p0, gmock_interp_));\
1276    }\
1277    name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
1278      const char* gmock_param_names[] = { #p0, NULL };\
1279      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1280          gmock_param_names, ("" description ""));\
1281    }\
1282    p0##_type p0;\
1283    ::testing::internal::Interpolations gmock_interp_;\
1284  };\
1285  template <typename p0##_type>\
1286  inline name##MatcherP<p0##_type> name(p0##_type p0) {\
1287    return name##MatcherP<p0##_type>(p0);\
1288  }\
1289  template <typename p0##_type>\
1290  template <typename arg_type>\
1291  bool name##MatcherP<p0##_type>::\
1292      gmock_Impl<arg_type>::Matches(arg_type arg) const
1293
1294#define MATCHER_P2(name, p0, p1, description)\
1295  template <typename p0##_type, typename p1##_type>\
1296  class name##MatcherP2 {\
1297   public:\
1298    template <typename arg_type>\
1299    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1300     public:\
1301      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
1302          const ::testing::internal::Interpolations& gmock_interp)\
1303           : p0(gmock_p0), p1(gmock_p1), gmock_interp_(gmock_interp) {}\
1304      virtual bool Matches(arg_type arg) const;\
1305      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1306        const ::testing::internal::Strings& gmock_printed_params = \
1307            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1308                ::std::tr1::tuple<p0##_type, p1##_type>(p0, p1));\
1309        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1310                     #name, description, gmock_interp_, gmock_printed_params);\
1311      }\
1312      p0##_type p0;\
1313      p1##_type p1;\
1314      const ::testing::internal::Interpolations gmock_interp_;\
1315    };\
1316    template <typename arg_type>\
1317    operator ::testing::Matcher<arg_type>() const {\
1318      return ::testing::Matcher<arg_type>(\
1319          new gmock_Impl<arg_type>(p0, p1, gmock_interp_));\
1320    }\
1321    name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
1322        p1(gmock_p1) {\
1323      const char* gmock_param_names[] = { #p0, #p1, NULL };\
1324      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1325          gmock_param_names, ("" description ""));\
1326    }\
1327    p0##_type p0;\
1328    p1##_type p1;\
1329    ::testing::internal::Interpolations gmock_interp_;\
1330  };\
1331  template <typename p0##_type, typename p1##_type>\
1332  inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \
1333      p1##_type p1) {\
1334    return name##MatcherP2<p0##_type, p1##_type>(p0, p1);\
1335  }\
1336  template <typename p0##_type, typename p1##_type>\
1337  template <typename arg_type>\
1338  bool name##MatcherP2<p0##_type, p1##_type>::\
1339      gmock_Impl<arg_type>::Matches(arg_type arg) const
1340
1341#define MATCHER_P3(name, p0, p1, p2, description)\
1342  template <typename p0##_type, typename p1##_type, typename p2##_type>\
1343  class name##MatcherP3 {\
1344   public:\
1345    template <typename arg_type>\
1346    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1347     public:\
1348      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1349          const ::testing::internal::Interpolations& gmock_interp)\
1350           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
1351               gmock_interp_(gmock_interp) {}\
1352      virtual bool Matches(arg_type arg) const;\
1353      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1354        const ::testing::internal::Strings& gmock_printed_params = \
1355            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1356                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \
1357                    p2));\
1358        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1359                     #name, description, gmock_interp_, gmock_printed_params);\
1360      }\
1361      p0##_type p0;\
1362      p1##_type p1;\
1363      p2##_type p2;\
1364      const ::testing::internal::Interpolations gmock_interp_;\
1365    };\
1366    template <typename arg_type>\
1367    operator ::testing::Matcher<arg_type>() const {\
1368      return ::testing::Matcher<arg_type>(\
1369          new gmock_Impl<arg_type>(p0, p1, p2, gmock_interp_));\
1370    }\
1371    name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \
1372        p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\
1373      const char* gmock_param_names[] = { #p0, #p1, #p2, NULL };\
1374      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1375          gmock_param_names, ("" description ""));\
1376    }\
1377    p0##_type p0;\
1378    p1##_type p1;\
1379    p2##_type p2;\
1380    ::testing::internal::Interpolations gmock_interp_;\
1381  };\
1382  template <typename p0##_type, typename p1##_type, typename p2##_type>\
1383  inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \
1384      p1##_type p1, p2##_type p2) {\
1385    return name##MatcherP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\
1386  }\
1387  template <typename p0##_type, typename p1##_type, typename p2##_type>\
1388  template <typename arg_type>\
1389  bool name##MatcherP3<p0##_type, p1##_type, p2##_type>::\
1390      gmock_Impl<arg_type>::Matches(arg_type arg) const
1391
1392#define MATCHER_P4(name, p0, p1, p2, p3, description)\
1393  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1394      typename p3##_type>\
1395  class name##MatcherP4 {\
1396   public:\
1397    template <typename arg_type>\
1398    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1399     public:\
1400      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1401          p3##_type gmock_p3, \
1402          const ::testing::internal::Interpolations& gmock_interp)\
1403           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1404               gmock_interp_(gmock_interp) {}\
1405      virtual bool Matches(arg_type arg) const;\
1406      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1407        const ::testing::internal::Strings& gmock_printed_params = \
1408            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1409                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, \
1410                    p3##_type>(p0, p1, p2, p3));\
1411        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1412                     #name, description, gmock_interp_, gmock_printed_params);\
1413      }\
1414      p0##_type p0;\
1415      p1##_type p1;\
1416      p2##_type p2;\
1417      p3##_type p3;\
1418      const ::testing::internal::Interpolations gmock_interp_;\
1419    };\
1420    template <typename arg_type>\
1421    operator ::testing::Matcher<arg_type>() const {\
1422      return ::testing::Matcher<arg_type>(\
1423          new gmock_Impl<arg_type>(p0, p1, p2, p3, gmock_interp_));\
1424    }\
1425    name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \
1426        p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
1427        p2(gmock_p2), p3(gmock_p3) {\
1428      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, NULL };\
1429      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1430          gmock_param_names, ("" description ""));\
1431    }\
1432    p0##_type p0;\
1433    p1##_type p1;\
1434    p2##_type p2;\
1435    p3##_type p3;\
1436    ::testing::internal::Interpolations gmock_interp_;\
1437  };\
1438  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1439      typename p3##_type>\
1440  inline name##MatcherP4<p0##_type, p1##_type, p2##_type, \
1441      p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \
1442      p3##_type p3) {\
1443    return name##MatcherP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, \
1444        p1, p2, p3);\
1445  }\
1446  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1447      typename p3##_type>\
1448  template <typename arg_type>\
1449  bool name##MatcherP4<p0##_type, p1##_type, p2##_type, p3##_type>::\
1450      gmock_Impl<arg_type>::Matches(arg_type arg) const
1451
1452#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\
1453  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1454      typename p3##_type, typename p4##_type>\
1455  class name##MatcherP5 {\
1456   public:\
1457    template <typename arg_type>\
1458    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1459     public:\
1460      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1461          p3##_type gmock_p3, p4##_type gmock_p4, \
1462          const ::testing::internal::Interpolations& gmock_interp)\
1463           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1464               p4(gmock_p4), gmock_interp_(gmock_interp) {}\
1465      virtual bool Matches(arg_type arg) const;\
1466      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1467        const ::testing::internal::Strings& gmock_printed_params = \
1468            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1469                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
1470                    p4##_type>(p0, p1, p2, p3, p4));\
1471        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1472                     #name, description, gmock_interp_, gmock_printed_params);\
1473      }\
1474      p0##_type p0;\
1475      p1##_type p1;\
1476      p2##_type p2;\
1477      p3##_type p3;\
1478      p4##_type p4;\
1479      const ::testing::internal::Interpolations gmock_interp_;\
1480    };\
1481    template <typename arg_type>\
1482    operator ::testing::Matcher<arg_type>() const {\
1483      return ::testing::Matcher<arg_type>(\
1484          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, gmock_interp_));\
1485    }\
1486    name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \
1487        p2##_type gmock_p2, p3##_type gmock_p3, \
1488        p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
1489        p3(gmock_p3), p4(gmock_p4) {\
1490      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, NULL };\
1491      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1492          gmock_param_names, ("" description ""));\
1493    }\
1494    p0##_type p0;\
1495    p1##_type p1;\
1496    p2##_type p2;\
1497    p3##_type p3;\
1498    p4##_type p4;\
1499    ::testing::internal::Interpolations gmock_interp_;\
1500  };\
1501  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1502      typename p3##_type, typename p4##_type>\
1503  inline name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \
1504      p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
1505      p4##_type p4) {\
1506    return name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \
1507        p4##_type>(p0, p1, p2, p3, p4);\
1508  }\
1509  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1510      typename p3##_type, typename p4##_type>\
1511  template <typename arg_type>\
1512  bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type>::\
1513      gmock_Impl<arg_type>::Matches(arg_type arg) const
1514
1515#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\
1516  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1517      typename p3##_type, typename p4##_type, typename p5##_type>\
1518  class name##MatcherP6 {\
1519   public:\
1520    template <typename arg_type>\
1521    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1522     public:\
1523      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1524          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1525          const ::testing::internal::Interpolations& gmock_interp)\
1526           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1527               p4(gmock_p4), p5(gmock_p5), gmock_interp_(gmock_interp) {}\
1528      virtual bool Matches(arg_type arg) const;\
1529      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1530        const ::testing::internal::Strings& gmock_printed_params = \
1531            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1532                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
1533                    p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5));\
1534        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1535                     #name, description, gmock_interp_, gmock_printed_params);\
1536      }\
1537      p0##_type p0;\
1538      p1##_type p1;\
1539      p2##_type p2;\
1540      p3##_type p3;\
1541      p4##_type p4;\
1542      p5##_type p5;\
1543      const ::testing::internal::Interpolations gmock_interp_;\
1544    };\
1545    template <typename arg_type>\
1546    operator ::testing::Matcher<arg_type>() const {\
1547      return ::testing::Matcher<arg_type>(\
1548          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, gmock_interp_));\
1549    }\
1550    name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \
1551        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1552        p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
1553        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\
1554      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, NULL };\
1555      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1556          gmock_param_names, ("" description ""));\
1557    }\
1558    p0##_type p0;\
1559    p1##_type p1;\
1560    p2##_type p2;\
1561    p3##_type p3;\
1562    p4##_type p4;\
1563    p5##_type p5;\
1564    ::testing::internal::Interpolations gmock_interp_;\
1565  };\
1566  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1567      typename p3##_type, typename p4##_type, typename p5##_type>\
1568  inline name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, \
1569      p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \
1570      p3##_type p3, p4##_type p4, p5##_type p5) {\
1571    return name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, \
1572        p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\
1573  }\
1574  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1575      typename p3##_type, typename p4##_type, typename p5##_type>\
1576  template <typename arg_type>\
1577  bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1578      p5##_type>::\
1579      gmock_Impl<arg_type>::Matches(arg_type arg) const
1580
1581#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\
1582  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1583      typename p3##_type, typename p4##_type, typename p5##_type, \
1584      typename p6##_type>\
1585  class name##MatcherP7 {\
1586   public:\
1587    template <typename arg_type>\
1588    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1589     public:\
1590      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1591          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1592          p6##_type gmock_p6, \
1593          const ::testing::internal::Interpolations& gmock_interp)\
1594           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1595               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
1596               gmock_interp_(gmock_interp) {}\
1597      virtual bool Matches(arg_type arg) const;\
1598      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1599        const ::testing::internal::Strings& gmock_printed_params = \
1600            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1601                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
1602                    p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \
1603                    p6));\
1604        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1605                     #name, description, gmock_interp_, gmock_printed_params);\
1606      }\
1607      p0##_type p0;\
1608      p1##_type p1;\
1609      p2##_type p2;\
1610      p3##_type p3;\
1611      p4##_type p4;\
1612      p5##_type p5;\
1613      p6##_type p6;\
1614      const ::testing::internal::Interpolations gmock_interp_;\
1615    };\
1616    template <typename arg_type>\
1617    operator ::testing::Matcher<arg_type>() const {\
1618      return ::testing::Matcher<arg_type>(\
1619          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, gmock_interp_));\
1620    }\
1621    name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \
1622        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1623        p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
1624        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
1625        p6(gmock_p6) {\
1626      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
1627          NULL };\
1628      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1629          gmock_param_names, ("" description ""));\
1630    }\
1631    p0##_type p0;\
1632    p1##_type p1;\
1633    p2##_type p2;\
1634    p3##_type p3;\
1635    p4##_type p4;\
1636    p5##_type p5;\
1637    p6##_type p6;\
1638    ::testing::internal::Interpolations gmock_interp_;\
1639  };\
1640  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1641      typename p3##_type, typename p4##_type, typename p5##_type, \
1642      typename p6##_type>\
1643  inline name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, \
1644      p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \
1645      p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \
1646      p6##_type p6) {\
1647    return name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, \
1648        p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\
1649  }\
1650  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1651      typename p3##_type, typename p4##_type, typename p5##_type, \
1652      typename p6##_type>\
1653  template <typename arg_type>\
1654  bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1655      p5##_type, p6##_type>::\
1656      gmock_Impl<arg_type>::Matches(arg_type arg) const
1657
1658#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\
1659  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1660      typename p3##_type, typename p4##_type, typename p5##_type, \
1661      typename p6##_type, typename p7##_type>\
1662  class name##MatcherP8 {\
1663   public:\
1664    template <typename arg_type>\
1665    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1666     public:\
1667      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1668          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1669          p6##_type gmock_p6, p7##_type gmock_p7, \
1670          const ::testing::internal::Interpolations& gmock_interp)\
1671           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1672               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
1673               gmock_interp_(gmock_interp) {}\
1674      virtual bool Matches(arg_type arg) const;\
1675      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1676        const ::testing::internal::Strings& gmock_printed_params = \
1677            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1678                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
1679                    p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \
1680                    p3, p4, p5, p6, p7));\
1681        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1682                     #name, description, gmock_interp_, gmock_printed_params);\
1683      }\
1684      p0##_type p0;\
1685      p1##_type p1;\
1686      p2##_type p2;\
1687      p3##_type p3;\
1688      p4##_type p4;\
1689      p5##_type p5;\
1690      p6##_type p6;\
1691      p7##_type p7;\
1692      const ::testing::internal::Interpolations gmock_interp_;\
1693    };\
1694    template <typename arg_type>\
1695    operator ::testing::Matcher<arg_type>() const {\
1696      return ::testing::Matcher<arg_type>(\
1697          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, \
1698              gmock_interp_));\
1699    }\
1700    name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \
1701        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1702        p5##_type gmock_p5, p6##_type gmock_p6, \
1703        p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
1704        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
1705        p7(gmock_p7) {\
1706      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
1707          #p7, NULL };\
1708      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1709          gmock_param_names, ("" description ""));\
1710    }\
1711    p0##_type p0;\
1712    p1##_type p1;\
1713    p2##_type p2;\
1714    p3##_type p3;\
1715    p4##_type p4;\
1716    p5##_type p5;\
1717    p6##_type p6;\
1718    p7##_type p7;\
1719    ::testing::internal::Interpolations gmock_interp_;\
1720  };\
1721  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1722      typename p3##_type, typename p4##_type, typename p5##_type, \
1723      typename p6##_type, typename p7##_type>\
1724  inline name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, \
1725      p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \
1726      p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \
1727      p6##_type p6, p7##_type p7) {\
1728    return name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, \
1729        p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \
1730        p6, p7);\
1731  }\
1732  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1733      typename p3##_type, typename p4##_type, typename p5##_type, \
1734      typename p6##_type, typename p7##_type>\
1735  template <typename arg_type>\
1736  bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1737      p5##_type, p6##_type, p7##_type>::\
1738      gmock_Impl<arg_type>::Matches(arg_type arg) const
1739
1740#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\
1741  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1742      typename p3##_type, typename p4##_type, typename p5##_type, \
1743      typename p6##_type, typename p7##_type, typename p8##_type>\
1744  class name##MatcherP9 {\
1745   public:\
1746    template <typename arg_type>\
1747    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1748     public:\
1749      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1750          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1751          p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
1752          const ::testing::internal::Interpolations& gmock_interp)\
1753           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1754               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
1755               p8(gmock_p8), gmock_interp_(gmock_interp) {}\
1756      virtual bool Matches(arg_type arg) const;\
1757      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1758        const ::testing::internal::Strings& gmock_printed_params = \
1759            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1760                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
1761                    p4##_type, p5##_type, p6##_type, p7##_type, \
1762                    p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8));\
1763        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1764                     #name, description, gmock_interp_, gmock_printed_params);\
1765      }\
1766      p0##_type p0;\
1767      p1##_type p1;\
1768      p2##_type p2;\
1769      p3##_type p3;\
1770      p4##_type p4;\
1771      p5##_type p5;\
1772      p6##_type p6;\
1773      p7##_type p7;\
1774      p8##_type p8;\
1775      const ::testing::internal::Interpolations gmock_interp_;\
1776    };\
1777    template <typename arg_type>\
1778    operator ::testing::Matcher<arg_type>() const {\
1779      return ::testing::Matcher<arg_type>(\
1780          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, \
1781              gmock_interp_));\
1782    }\
1783    name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \
1784        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1785        p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
1786        p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
1787        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
1788        p8(gmock_p8) {\
1789      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
1790          #p7, #p8, NULL };\
1791      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1792          gmock_param_names, ("" description ""));\
1793    }\
1794    p0##_type p0;\
1795    p1##_type p1;\
1796    p2##_type p2;\
1797    p3##_type p3;\
1798    p4##_type p4;\
1799    p5##_type p5;\
1800    p6##_type p6;\
1801    p7##_type p7;\
1802    p8##_type p8;\
1803    ::testing::internal::Interpolations gmock_interp_;\
1804  };\
1805  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1806      typename p3##_type, typename p4##_type, typename p5##_type, \
1807      typename p6##_type, typename p7##_type, typename p8##_type>\
1808  inline name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, \
1809      p4##_type, p5##_type, p6##_type, p7##_type, \
1810      p8##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
1811      p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \
1812      p8##_type p8) {\
1813    return name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, \
1814        p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \
1815        p3, p4, p5, p6, p7, p8);\
1816  }\
1817  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1818      typename p3##_type, typename p4##_type, typename p5##_type, \
1819      typename p6##_type, typename p7##_type, typename p8##_type>\
1820  template <typename arg_type>\
1821  bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1822      p5##_type, p6##_type, p7##_type, p8##_type>::\
1823      gmock_Impl<arg_type>::Matches(arg_type arg) const
1824
1825#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\
1826  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1827      typename p3##_type, typename p4##_type, typename p5##_type, \
1828      typename p6##_type, typename p7##_type, typename p8##_type, \
1829      typename p9##_type>\
1830  class name##MatcherP10 {\
1831   public:\
1832    template <typename arg_type>\
1833    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
1834     public:\
1835      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1836          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1837          p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
1838          p9##_type gmock_p9, \
1839          const ::testing::internal::Interpolations& gmock_interp)\
1840           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
1841               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
1842               p8(gmock_p8), p9(gmock_p9), gmock_interp_(gmock_interp) {}\
1843      virtual bool Matches(arg_type arg) const;\
1844      virtual void DescribeTo(::std::ostream* gmock_os) const {\
1845        const ::testing::internal::Strings& gmock_printed_params = \
1846            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
1847                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
1848                    p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
1849                    p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\
1850        *gmock_os << ::testing::internal::FormatMatcherDescription(\
1851                     #name, description, gmock_interp_, gmock_printed_params);\
1852      }\
1853      p0##_type p0;\
1854      p1##_type p1;\
1855      p2##_type p2;\
1856      p3##_type p3;\
1857      p4##_type p4;\
1858      p5##_type p5;\
1859      p6##_type p6;\
1860      p7##_type p7;\
1861      p8##_type p8;\
1862      p9##_type p9;\
1863      const ::testing::internal::Interpolations gmock_interp_;\
1864    };\
1865    template <typename arg_type>\
1866    operator ::testing::Matcher<arg_type>() const {\
1867      return ::testing::Matcher<arg_type>(\
1868          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, \
1869              gmock_interp_));\
1870    }\
1871    name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \
1872        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1873        p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
1874        p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
1875        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
1876        p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\
1877      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
1878          #p7, #p8, #p9, NULL };\
1879      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
1880          gmock_param_names, ("" description ""));\
1881    }\
1882    p0##_type p0;\
1883    p1##_type p1;\
1884    p2##_type p2;\
1885    p3##_type p3;\
1886    p4##_type p4;\
1887    p5##_type p5;\
1888    p6##_type p6;\
1889    p7##_type p7;\
1890    p8##_type p8;\
1891    p9##_type p9;\
1892    ::testing::internal::Interpolations gmock_interp_;\
1893  };\
1894  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1895      typename p3##_type, typename p4##_type, typename p5##_type, \
1896      typename p6##_type, typename p7##_type, typename p8##_type, \
1897      typename p9##_type>\
1898  inline name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
1899      p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
1900      p9##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
1901      p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \
1902      p9##_type p9) {\
1903    return name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
1904        p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \
1905        p1, p2, p3, p4, p5, p6, p7, p8, p9);\
1906  }\
1907  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1908      typename p3##_type, typename p4##_type, typename p5##_type, \
1909      typename p6##_type, typename p7##_type, typename p8##_type, \
1910      typename p9##_type>\
1911  template <typename arg_type>\
1912  bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
1913      p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>::\
1914      gmock_Impl<arg_type>::Matches(arg_type arg) const
1915
1916#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
1917