1// This file was GENERATED by command:
2//     pump.py gmock-generated-actions.h.pump
3// DO NOT EDIT BY HAND!!!
4
5// Copyright 2007, Google Inc.
6// All rights reserved.
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11//
12//     * Redistributions of source code must retain the above copyright
13// notice, this list of conditions and the following disclaimer.
14//     * Redistributions in binary form must reproduce the above
15// copyright notice, this list of conditions and the following disclaimer
16// in the documentation and/or other materials provided with the
17// distribution.
18//     * Neither the name of Google Inc. nor the names of its
19// contributors may be used to endorse or promote products derived from
20// this software without specific prior written permission.
21//
22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34
35// Google Mock - a framework for writing C++ mock classes.
36//
37// This file implements some commonly used variadic actions.
38
39// GOOGLETEST_CM0002 DO NOT DELETE
40
41#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
42#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
43
44#include "gmock/gmock-actions.h"
45#include "gmock/internal/gmock-port.h"
46
47namespace testing {
48namespace internal {
49
50// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
51// function, method, or callback with the unpacked values, where F is
52// a function type that takes N arguments.
53template <typename Result, typename ArgumentTuple>
54class InvokeHelper;
55
56template <typename R>
57class InvokeHelper<R, ::testing::tuple<> > {
58 public:
59  template <typename Function>
60  static R Invoke(Function function, const ::testing::tuple<>&) {
61           return function();
62  }
63
64  template <class Class, typename MethodPtr>
65  static R InvokeMethod(Class* obj_ptr,
66                        MethodPtr method_ptr,
67                        const ::testing::tuple<>&) {
68           return (obj_ptr->*method_ptr)();
69  }
70
71  template <typename CallbackType>
72  static R InvokeCallback(CallbackType* callback,
73                          const ::testing::tuple<>&) {
74           return callback->Run();
75  }
76};
77
78template <typename R, typename A1>
79class InvokeHelper<R, ::testing::tuple<A1> > {
80 public:
81  template <typename Function>
82  static R Invoke(Function function, const ::testing::tuple<A1>& args) {
83           return function(get<0>(args));
84  }
85
86  template <class Class, typename MethodPtr>
87  static R InvokeMethod(Class* obj_ptr,
88                        MethodPtr method_ptr,
89                        const ::testing::tuple<A1>& args) {
90           return (obj_ptr->*method_ptr)(get<0>(args));
91  }
92
93  template <typename CallbackType>
94  static R InvokeCallback(CallbackType* callback,
95                          const ::testing::tuple<A1>& args) {
96           return callback->Run(get<0>(args));
97  }
98};
99
100template <typename R, typename A1, typename A2>
101class InvokeHelper<R, ::testing::tuple<A1, A2> > {
102 public:
103  template <typename Function>
104  static R Invoke(Function function, const ::testing::tuple<A1, A2>& args) {
105           return function(get<0>(args), get<1>(args));
106  }
107
108  template <class Class, typename MethodPtr>
109  static R InvokeMethod(Class* obj_ptr,
110                        MethodPtr method_ptr,
111                        const ::testing::tuple<A1, A2>& args) {
112           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args));
113  }
114
115  template <typename CallbackType>
116  static R InvokeCallback(CallbackType* callback,
117                          const ::testing::tuple<A1, A2>& args) {
118           return callback->Run(get<0>(args), get<1>(args));
119  }
120};
121
122template <typename R, typename A1, typename A2, typename A3>
123class InvokeHelper<R, ::testing::tuple<A1, A2, A3> > {
124 public:
125  template <typename Function>
126  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3>& args) {
127           return function(get<0>(args), get<1>(args), get<2>(args));
128  }
129
130  template <class Class, typename MethodPtr>
131  static R InvokeMethod(Class* obj_ptr,
132                        MethodPtr method_ptr,
133                        const ::testing::tuple<A1, A2, A3>& args) {
134           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
135               get<2>(args));
136  }
137
138  template <typename CallbackType>
139  static R InvokeCallback(CallbackType* callback,
140                          const ::testing::tuple<A1, A2, A3>& args) {
141           return callback->Run(get<0>(args), get<1>(args), get<2>(args));
142  }
143};
144
145template <typename R, typename A1, typename A2, typename A3, typename A4>
146class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4> > {
147 public:
148  template <typename Function>
149  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3,
150      A4>& args) {
151           return function(get<0>(args), get<1>(args), get<2>(args),
152               get<3>(args));
153  }
154
155  template <class Class, typename MethodPtr>
156  static R InvokeMethod(Class* obj_ptr,
157                        MethodPtr method_ptr,
158                        const ::testing::tuple<A1, A2, A3, A4>& args) {
159           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
160               get<2>(args), get<3>(args));
161  }
162
163  template <typename CallbackType>
164  static R InvokeCallback(CallbackType* callback,
165                          const ::testing::tuple<A1, A2, A3, A4>& args) {
166           return callback->Run(get<0>(args), get<1>(args), get<2>(args),
167               get<3>(args));
168  }
169};
170
171template <typename R, typename A1, typename A2, typename A3, typename A4,
172    typename A5>
173class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5> > {
174 public:
175  template <typename Function>
176  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4,
177      A5>& args) {
178           return function(get<0>(args), get<1>(args), get<2>(args),
179               get<3>(args), get<4>(args));
180  }
181
182  template <class Class, typename MethodPtr>
183  static R InvokeMethod(Class* obj_ptr,
184                        MethodPtr method_ptr,
185                        const ::testing::tuple<A1, A2, A3, A4, A5>& args) {
186           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
187               get<2>(args), get<3>(args), get<4>(args));
188  }
189
190  template <typename CallbackType>
191  static R InvokeCallback(CallbackType* callback,
192                          const ::testing::tuple<A1, A2, A3, A4, A5>& args) {
193           return callback->Run(get<0>(args), get<1>(args), get<2>(args),
194               get<3>(args), get<4>(args));
195  }
196};
197
198template <typename R, typename A1, typename A2, typename A3, typename A4,
199    typename A5, typename A6>
200class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
201 public:
202  template <typename Function>
203  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
204      A6>& args) {
205           return function(get<0>(args), get<1>(args), get<2>(args),
206               get<3>(args), get<4>(args), get<5>(args));
207  }
208
209  template <class Class, typename MethodPtr>
210  static R InvokeMethod(Class* obj_ptr,
211                        MethodPtr method_ptr,
212                        const ::testing::tuple<A1, A2, A3, A4, A5, A6>& args) {
213           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
214               get<2>(args), get<3>(args), get<4>(args), get<5>(args));
215  }
216
217  // There is no InvokeCallback() for 6-tuples
218};
219
220template <typename R, typename A1, typename A2, typename A3, typename A4,
221    typename A5, typename A6, typename A7>
222class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
223 public:
224  template <typename Function>
225  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
226      A6, A7>& args) {
227           return function(get<0>(args), get<1>(args), get<2>(args),
228               get<3>(args), get<4>(args), get<5>(args), get<6>(args));
229  }
230
231  template <class Class, typename MethodPtr>
232  static R InvokeMethod(Class* obj_ptr,
233                        MethodPtr method_ptr,
234                        const ::testing::tuple<A1, A2, A3, A4, A5, A6,
235                            A7>& args) {
236           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
237               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
238               get<6>(args));
239  }
240
241  // There is no InvokeCallback() for 7-tuples
242};
243
244template <typename R, typename A1, typename A2, typename A3, typename A4,
245    typename A5, typename A6, typename A7, typename A8>
246class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
247 public:
248  template <typename Function>
249  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
250      A6, A7, A8>& args) {
251           return function(get<0>(args), get<1>(args), get<2>(args),
252               get<3>(args), get<4>(args), get<5>(args), get<6>(args),
253               get<7>(args));
254  }
255
256  template <class Class, typename MethodPtr>
257  static R InvokeMethod(Class* obj_ptr,
258                        MethodPtr method_ptr,
259                        const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7,
260                            A8>& args) {
261           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
262               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
263               get<6>(args), get<7>(args));
264  }
265
266  // There is no InvokeCallback() for 8-tuples
267};
268
269template <typename R, typename A1, typename A2, typename A3, typename A4,
270    typename A5, typename A6, typename A7, typename A8, typename A9>
271class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
272 public:
273  template <typename Function>
274  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
275      A6, A7, A8, A9>& args) {
276           return function(get<0>(args), get<1>(args), get<2>(args),
277               get<3>(args), get<4>(args), get<5>(args), get<6>(args),
278               get<7>(args), get<8>(args));
279  }
280
281  template <class Class, typename MethodPtr>
282  static R InvokeMethod(Class* obj_ptr,
283                        MethodPtr method_ptr,
284                        const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
285                            A9>& args) {
286           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
287               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
288               get<6>(args), get<7>(args), get<8>(args));
289  }
290
291  // There is no InvokeCallback() for 9-tuples
292};
293
294template <typename R, typename A1, typename A2, typename A3, typename A4,
295    typename A5, typename A6, typename A7, typename A8, typename A9,
296    typename A10>
297class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
298    A10> > {
299 public:
300  template <typename Function>
301  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
302      A6, A7, A8, A9, A10>& args) {
303           return function(get<0>(args), get<1>(args), get<2>(args),
304               get<3>(args), get<4>(args), get<5>(args), get<6>(args),
305               get<7>(args), get<8>(args), get<9>(args));
306  }
307
308  template <class Class, typename MethodPtr>
309  static R InvokeMethod(Class* obj_ptr,
310                        MethodPtr method_ptr,
311                        const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
312                            A9, A10>& args) {
313           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
314               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
315               get<6>(args), get<7>(args), get<8>(args), get<9>(args));
316  }
317
318  // There is no InvokeCallback() for 10-tuples
319};
320
321// Implements the Invoke(callback) action.
322template <typename CallbackType>
323class InvokeCallbackAction {
324 public:
325  // The c'tor takes ownership of the callback.
326  explicit InvokeCallbackAction(CallbackType* callback)
327      : callback_(callback) {
328    callback->CheckIsRepeatable();  // Makes sure the callback is permanent.
329  }
330
331  // This type conversion operator template allows Invoke(callback) to
332  // be used wherever the callback's type is compatible with that of
333  // the mock function, i.e. if the mock function's arguments can be
334  // implicitly converted to the callback's arguments and the
335  // callback's result can be implicitly converted to the mock
336  // function's result.
337  template <typename Result, typename ArgumentTuple>
338  Result Perform(const ArgumentTuple& args) const {
339    return InvokeHelper<Result, ArgumentTuple>::InvokeCallback(
340        callback_.get(), args);
341  }
342 private:
343  const linked_ptr<CallbackType> callback_;
344};
345
346// An INTERNAL macro for extracting the type of a tuple field.  It's
347// subject to change without notice - DO NOT USE IN USER CODE!
348#define GMOCK_FIELD_(Tuple, N) \
349    typename ::testing::tuple_element<N, Tuple>::type
350
351// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
352// type of an n-ary function whose i-th (1-based) argument type is the
353// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
354// type, and whose return type is Result.  For example,
355//   SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type
356// is int(bool, long).
357//
358// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
359// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
360// For example,
361//   SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select(
362//       ::testing::make_tuple(true, 'a', 2.5))
363// returns tuple (2.5, true).
364//
365// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
366// in the range [0, 10].  Duplicates are allowed and they don't have
367// to be in an ascending or descending order.
368
369template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
370    int k4, int k5, int k6, int k7, int k8, int k9, int k10>
371class SelectArgs {
372 public:
373  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
374      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
375      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
376      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
377      GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9),
378      GMOCK_FIELD_(ArgumentTuple, k10));
379  typedef typename Function<type>::ArgumentTuple SelectedArgs;
380  static SelectedArgs Select(const ArgumentTuple& args) {
381    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
382        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
383        get<k8>(args), get<k9>(args), get<k10>(args));
384  }
385};
386
387template <typename Result, typename ArgumentTuple>
388class SelectArgs<Result, ArgumentTuple,
389                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
390 public:
391  typedef Result type();
392  typedef typename Function<type>::ArgumentTuple SelectedArgs;
393  static SelectedArgs Select(const ArgumentTuple& /* args */) {
394    return SelectedArgs();
395  }
396};
397
398template <typename Result, typename ArgumentTuple, int k1>
399class SelectArgs<Result, ArgumentTuple,
400                 k1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
401 public:
402  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1));
403  typedef typename Function<type>::ArgumentTuple SelectedArgs;
404  static SelectedArgs Select(const ArgumentTuple& args) {
405    return SelectedArgs(get<k1>(args));
406  }
407};
408
409template <typename Result, typename ArgumentTuple, int k1, int k2>
410class SelectArgs<Result, ArgumentTuple,
411                 k1, k2, -1, -1, -1, -1, -1, -1, -1, -1> {
412 public:
413  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
414      GMOCK_FIELD_(ArgumentTuple, k2));
415  typedef typename Function<type>::ArgumentTuple SelectedArgs;
416  static SelectedArgs Select(const ArgumentTuple& args) {
417    return SelectedArgs(get<k1>(args), get<k2>(args));
418  }
419};
420
421template <typename Result, typename ArgumentTuple, int k1, int k2, int k3>
422class SelectArgs<Result, ArgumentTuple,
423                 k1, k2, k3, -1, -1, -1, -1, -1, -1, -1> {
424 public:
425  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
426      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3));
427  typedef typename Function<type>::ArgumentTuple SelectedArgs;
428  static SelectedArgs Select(const ArgumentTuple& args) {
429    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args));
430  }
431};
432
433template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
434    int k4>
435class SelectArgs<Result, ArgumentTuple,
436                 k1, k2, k3, k4, -1, -1, -1, -1, -1, -1> {
437 public:
438  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
439      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
440      GMOCK_FIELD_(ArgumentTuple, k4));
441  typedef typename Function<type>::ArgumentTuple SelectedArgs;
442  static SelectedArgs Select(const ArgumentTuple& args) {
443    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
444        get<k4>(args));
445  }
446};
447
448template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
449    int k4, int k5>
450class SelectArgs<Result, ArgumentTuple,
451                 k1, k2, k3, k4, k5, -1, -1, -1, -1, -1> {
452 public:
453  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
454      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
455      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5));
456  typedef typename Function<type>::ArgumentTuple SelectedArgs;
457  static SelectedArgs Select(const ArgumentTuple& args) {
458    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
459        get<k4>(args), get<k5>(args));
460  }
461};
462
463template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
464    int k4, int k5, int k6>
465class SelectArgs<Result, ArgumentTuple,
466                 k1, k2, k3, k4, k5, k6, -1, -1, -1, -1> {
467 public:
468  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
469      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
470      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
471      GMOCK_FIELD_(ArgumentTuple, k6));
472  typedef typename Function<type>::ArgumentTuple SelectedArgs;
473  static SelectedArgs Select(const ArgumentTuple& args) {
474    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
475        get<k4>(args), get<k5>(args), get<k6>(args));
476  }
477};
478
479template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
480    int k4, int k5, int k6, int k7>
481class SelectArgs<Result, ArgumentTuple,
482                 k1, k2, k3, k4, k5, k6, k7, -1, -1, -1> {
483 public:
484  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
485      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
486      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
487      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7));
488  typedef typename Function<type>::ArgumentTuple SelectedArgs;
489  static SelectedArgs Select(const ArgumentTuple& args) {
490    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
491        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args));
492  }
493};
494
495template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
496    int k4, int k5, int k6, int k7, int k8>
497class SelectArgs<Result, ArgumentTuple,
498                 k1, k2, k3, k4, k5, k6, k7, k8, -1, -1> {
499 public:
500  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
501      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
502      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
503      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
504      GMOCK_FIELD_(ArgumentTuple, k8));
505  typedef typename Function<type>::ArgumentTuple SelectedArgs;
506  static SelectedArgs Select(const ArgumentTuple& args) {
507    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
508        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
509        get<k8>(args));
510  }
511};
512
513template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
514    int k4, int k5, int k6, int k7, int k8, int k9>
515class SelectArgs<Result, ArgumentTuple,
516                 k1, k2, k3, k4, k5, k6, k7, k8, k9, -1> {
517 public:
518  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
519      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
520      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
521      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
522      GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9));
523  typedef typename Function<type>::ArgumentTuple SelectedArgs;
524  static SelectedArgs Select(const ArgumentTuple& args) {
525    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
526        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
527        get<k8>(args), get<k9>(args));
528  }
529};
530
531#undef GMOCK_FIELD_
532
533// Implements the WithArgs action.
534template <typename InnerAction, int k1 = -1, int k2 = -1, int k3 = -1,
535    int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
536    int k9 = -1, int k10 = -1>
537class WithArgsAction {
538 public:
539  explicit WithArgsAction(const InnerAction& action) : action_(action) {}
540
541  template <typename F>
542  operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
543
544 private:
545  template <typename F>
546  class Impl : public ActionInterface<F> {
547   public:
548    typedef typename Function<F>::Result Result;
549    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
550
551    explicit Impl(const InnerAction& action) : action_(action) {}
552
553    virtual Result Perform(const ArgumentTuple& args) {
554      return action_.Perform(SelectArgs<Result, ArgumentTuple, k1, k2, k3, k4,
555          k5, k6, k7, k8, k9, k10>::Select(args));
556    }
557
558   private:
559    typedef typename SelectArgs<Result, ArgumentTuple,
560        k1, k2, k3, k4, k5, k6, k7, k8, k9, k10>::type InnerFunctionType;
561
562    Action<InnerFunctionType> action_;
563  };
564
565  const InnerAction action_;
566
567  GTEST_DISALLOW_ASSIGN_(WithArgsAction);
568};
569
570// A macro from the ACTION* family (defined later in this file)
571// defines an action that can be used in a mock function.  Typically,
572// these actions only care about a subset of the arguments of the mock
573// function.  For example, if such an action only uses the second
574// argument, it can be used in any mock function that takes >= 2
575// arguments where the type of the second argument is compatible.
576//
577// Therefore, the action implementation must be prepared to take more
578// arguments than it needs.  The ExcessiveArg type is used to
579// represent those excessive arguments.  In order to keep the compiler
580// error messages tractable, we define it in the testing namespace
581// instead of testing::internal.  However, this is an INTERNAL TYPE
582// and subject to change without notice, so a user MUST NOT USE THIS
583// TYPE DIRECTLY.
584struct ExcessiveArg {};
585
586// A helper class needed for implementing the ACTION* macros.
587template <typename Result, class Impl>
588class ActionHelper {
589 public:
590  static Result Perform(Impl* impl, const ::testing::tuple<>& args) {
591    return impl->template gmock_PerformImpl<>(args, ExcessiveArg(),
592        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
593        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
594        ExcessiveArg());
595  }
596
597  template <typename A0>
598  static Result Perform(Impl* impl, const ::testing::tuple<A0>& args) {
599    return impl->template gmock_PerformImpl<A0>(args, get<0>(args),
600        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
601        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
602        ExcessiveArg());
603  }
604
605  template <typename A0, typename A1>
606  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1>& args) {
607    return impl->template gmock_PerformImpl<A0, A1>(args, get<0>(args),
608        get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
609        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
610        ExcessiveArg());
611  }
612
613  template <typename A0, typename A1, typename A2>
614  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2>& args) {
615    return impl->template gmock_PerformImpl<A0, A1, A2>(args, get<0>(args),
616        get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(),
617        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
618        ExcessiveArg());
619  }
620
621  template <typename A0, typename A1, typename A2, typename A3>
622  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2,
623      A3>& args) {
624    return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args, get<0>(args),
625        get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(),
626        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
627        ExcessiveArg());
628  }
629
630  template <typename A0, typename A1, typename A2, typename A3, typename A4>
631  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3,
632      A4>& args) {
633    return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4>(args,
634        get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
635        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
636        ExcessiveArg());
637  }
638
639  template <typename A0, typename A1, typename A2, typename A3, typename A4,
640      typename A5>
641  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
642      A5>& args) {
643    return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5>(args,
644        get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
645        get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
646        ExcessiveArg());
647  }
648
649  template <typename A0, typename A1, typename A2, typename A3, typename A4,
650      typename A5, typename A6>
651  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
652      A5, A6>& args) {
653    return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6>(args,
654        get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
655        get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(),
656        ExcessiveArg());
657  }
658
659  template <typename A0, typename A1, typename A2, typename A3, typename A4,
660      typename A5, typename A6, typename A7>
661  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
662      A5, A6, A7>& args) {
663    return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6,
664        A7>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
665        get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(),
666        ExcessiveArg());
667  }
668
669  template <typename A0, typename A1, typename A2, typename A3, typename A4,
670      typename A5, typename A6, typename A7, typename A8>
671  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
672      A5, A6, A7, A8>& args) {
673    return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7,
674        A8>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
675        get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
676        ExcessiveArg());
677  }
678
679  template <typename A0, typename A1, typename A2, typename A3, typename A4,
680      typename A5, typename A6, typename A7, typename A8, typename A9>
681  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
682      A5, A6, A7, A8, A9>& args) {
683    return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8,
684        A9>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
685        get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
686        get<9>(args));
687  }
688};
689
690}  // namespace internal
691
692// Various overloads for Invoke().
693
694// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
695// the selected arguments of the mock function to an_action and
696// performs it.  It serves as an adaptor between actions with
697// different argument lists.  C++ doesn't support default arguments for
698// function templates, so we have to overload it.
699template <int k1, typename InnerAction>
700inline internal::WithArgsAction<InnerAction, k1>
701WithArgs(const InnerAction& action) {
702  return internal::WithArgsAction<InnerAction, k1>(action);
703}
704
705template <int k1, int k2, typename InnerAction>
706inline internal::WithArgsAction<InnerAction, k1, k2>
707WithArgs(const InnerAction& action) {
708  return internal::WithArgsAction<InnerAction, k1, k2>(action);
709}
710
711template <int k1, int k2, int k3, typename InnerAction>
712inline internal::WithArgsAction<InnerAction, k1, k2, k3>
713WithArgs(const InnerAction& action) {
714  return internal::WithArgsAction<InnerAction, k1, k2, k3>(action);
715}
716
717template <int k1, int k2, int k3, int k4, typename InnerAction>
718inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4>
719WithArgs(const InnerAction& action) {
720  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4>(action);
721}
722
723template <int k1, int k2, int k3, int k4, int k5, typename InnerAction>
724inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>
725WithArgs(const InnerAction& action) {
726  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>(action);
727}
728
729template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerAction>
730inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>
731WithArgs(const InnerAction& action) {
732  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>(action);
733}
734
735template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
736    typename InnerAction>
737inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7>
738WithArgs(const InnerAction& action) {
739  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6,
740      k7>(action);
741}
742
743template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
744    typename InnerAction>
745inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8>
746WithArgs(const InnerAction& action) {
747  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7,
748      k8>(action);
749}
750
751template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
752    int k9, typename InnerAction>
753inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, k9>
754WithArgs(const InnerAction& action) {
755  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
756      k9>(action);
757}
758
759template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
760    int k9, int k10, typename InnerAction>
761inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
762    k9, k10>
763WithArgs(const InnerAction& action) {
764  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
765      k9, k10>(action);
766}
767
768// Creates an action that does actions a1, a2, ..., sequentially in
769// each invocation.
770template <typename Action1, typename Action2>
771inline internal::DoBothAction<Action1, Action2>
772DoAll(Action1 a1, Action2 a2) {
773  return internal::DoBothAction<Action1, Action2>(a1, a2);
774}
775
776template <typename Action1, typename Action2, typename Action3>
777inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
778    Action3> >
779DoAll(Action1 a1, Action2 a2, Action3 a3) {
780  return DoAll(a1, DoAll(a2, a3));
781}
782
783template <typename Action1, typename Action2, typename Action3,
784    typename Action4>
785inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
786    internal::DoBothAction<Action3, Action4> > >
787DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) {
788  return DoAll(a1, DoAll(a2, a3, a4));
789}
790
791template <typename Action1, typename Action2, typename Action3,
792    typename Action4, typename Action5>
793inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
794    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
795    Action5> > > >
796DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) {
797  return DoAll(a1, DoAll(a2, a3, a4, a5));
798}
799
800template <typename Action1, typename Action2, typename Action3,
801    typename Action4, typename Action5, typename Action6>
802inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
803    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
804    internal::DoBothAction<Action5, Action6> > > > >
805DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) {
806  return DoAll(a1, DoAll(a2, a3, a4, a5, a6));
807}
808
809template <typename Action1, typename Action2, typename Action3,
810    typename Action4, typename Action5, typename Action6, typename Action7>
811inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
812    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
813    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
814    Action7> > > > > >
815DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
816    Action7 a7) {
817  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7));
818}
819
820template <typename Action1, typename Action2, typename Action3,
821    typename Action4, typename Action5, typename Action6, typename Action7,
822    typename Action8>
823inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
824    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
825    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
826    internal::DoBothAction<Action7, Action8> > > > > > >
827DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
828    Action7 a7, Action8 a8) {
829  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8));
830}
831
832template <typename Action1, typename Action2, typename Action3,
833    typename Action4, typename Action5, typename Action6, typename Action7,
834    typename Action8, typename Action9>
835inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
836    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
837    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
838    internal::DoBothAction<Action7, internal::DoBothAction<Action8,
839    Action9> > > > > > > >
840DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
841    Action7 a7, Action8 a8, Action9 a9) {
842  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9));
843}
844
845template <typename Action1, typename Action2, typename Action3,
846    typename Action4, typename Action5, typename Action6, typename Action7,
847    typename Action8, typename Action9, typename Action10>
848inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
849    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
850    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
851    internal::DoBothAction<Action7, internal::DoBothAction<Action8,
852    internal::DoBothAction<Action9, Action10> > > > > > > > >
853DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
854    Action7 a7, Action8 a8, Action9 a9, Action10 a10) {
855  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10));
856}
857
858}  // namespace testing
859
860// The ACTION* family of macros can be used in a namespace scope to
861// define custom actions easily.  The syntax:
862//
863//   ACTION(name) { statements; }
864//
865// will define an action with the given name that executes the
866// statements.  The value returned by the statements will be used as
867// the return value of the action.  Inside the statements, you can
868// refer to the K-th (0-based) argument of the mock function by
869// 'argK', and refer to its type by 'argK_type'.  For example:
870//
871//   ACTION(IncrementArg1) {
872//     arg1_type temp = arg1;
873//     return ++(*temp);
874//   }
875//
876// allows you to write
877//
878//   ...WillOnce(IncrementArg1());
879//
880// You can also refer to the entire argument tuple and its type by
881// 'args' and 'args_type', and refer to the mock function type and its
882// return type by 'function_type' and 'return_type'.
883//
884// Note that you don't need to specify the types of the mock function
885// arguments.  However rest assured that your code is still type-safe:
886// you'll get a compiler error if *arg1 doesn't support the ++
887// operator, or if the type of ++(*arg1) isn't compatible with the
888// mock function's return type, for example.
889//
890// Sometimes you'll want to parameterize the action.   For that you can use
891// another macro:
892//
893//   ACTION_P(name, param_name) { statements; }
894//
895// For example:
896//
897//   ACTION_P(Add, n) { return arg0 + n; }
898//
899// will allow you to write:
900//
901//   ...WillOnce(Add(5));
902//
903// Note that you don't need to provide the type of the parameter
904// either.  If you need to reference the type of a parameter named
905// 'foo', you can write 'foo_type'.  For example, in the body of
906// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
907// of 'n'.
908//
909// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support
910// multi-parameter actions.
911//
912// For the purpose of typing, you can view
913//
914//   ACTION_Pk(Foo, p1, ..., pk) { ... }
915//
916// as shorthand for
917//
918//   template <typename p1_type, ..., typename pk_type>
919//   FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
920//
921// In particular, you can provide the template type arguments
922// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
923// although usually you can rely on the compiler to infer the types
924// for you automatically.  You can assign the result of expression
925// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
926// pk_type>.  This can be useful when composing actions.
927//
928// You can also overload actions with different numbers of parameters:
929//
930//   ACTION_P(Plus, a) { ... }
931//   ACTION_P2(Plus, a, b) { ... }
932//
933// While it's tempting to always use the ACTION* macros when defining
934// a new action, you should also consider implementing ActionInterface
935// or using MakePolymorphicAction() instead, especially if you need to
936// use the action a lot.  While these approaches require more work,
937// they give you more control on the types of the mock function
938// arguments and the action parameters, which in general leads to
939// better compiler error messages that pay off in the long run.  They
940// also allow overloading actions based on parameter types (as opposed
941// to just based on the number of parameters).
942//
943// CAVEAT:
944//
945// ACTION*() can only be used in a namespace scope.  The reason is
946// that C++ doesn't yet allow function-local types to be used to
947// instantiate templates.  The up-coming C++0x standard will fix this.
948// Once that's done, we'll consider supporting using ACTION*() inside
949// a function.
950//
951// MORE INFORMATION:
952//
953// To learn more about using these macros, please search for 'ACTION'
954// on https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
955
956// An internal macro needed for implementing ACTION*().
957#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
958    const args_type& args GTEST_ATTRIBUTE_UNUSED_, \
959    arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \
960    arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \
961    arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \
962    arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \
963    arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \
964    arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \
965    arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \
966    arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \
967    arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \
968    arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_
969
970// Sometimes you want to give an action explicit template parameters
971// that cannot be inferred from its value parameters.  ACTION() and
972// ACTION_P*() don't support that.  ACTION_TEMPLATE() remedies that
973// and can be viewed as an extension to ACTION() and ACTION_P*().
974//
975// The syntax:
976//
977//   ACTION_TEMPLATE(ActionName,
978//                   HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
979//                   AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
980//
981// defines an action template that takes m explicit template
982// parameters and n value parameters.  name_i is the name of the i-th
983// template parameter, and kind_i specifies whether it's a typename,
984// an integral constant, or a template.  p_i is the name of the i-th
985// value parameter.
986//
987// Example:
988//
989//   // DuplicateArg<k, T>(output) converts the k-th argument of the mock
990//   // function to type T and copies it to *output.
991//   ACTION_TEMPLATE(DuplicateArg,
992//                   HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
993//                   AND_1_VALUE_PARAMS(output)) {
994//     *output = T(::testing::get<k>(args));
995//   }
996//   ...
997//     int n;
998//     EXPECT_CALL(mock, Foo(_, _))
999//         .WillOnce(DuplicateArg<1, unsigned char>(&n));
1000//
1001// To create an instance of an action template, write:
1002//
1003//   ActionName<t1, ..., t_m>(v1, ..., v_n)
1004//
1005// where the ts are the template arguments and the vs are the value
1006// arguments.  The value argument types are inferred by the compiler.
1007// If you want to explicitly specify the value argument types, you can
1008// provide additional template arguments:
1009//
1010//   ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
1011//
1012// where u_i is the desired type of v_i.
1013//
1014// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
1015// number of value parameters, but not on the number of template
1016// parameters.  Without the restriction, the meaning of the following
1017// is unclear:
1018//
1019//   OverloadedAction<int, bool>(x);
1020//
1021// Are we using a single-template-parameter action where 'bool' refers
1022// to the type of x, or are we using a two-template-parameter action
1023// where the compiler is asked to infer the type of x?
1024//
1025// Implementation notes:
1026//
1027// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
1028// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
1029// implementing ACTION_TEMPLATE.  The main trick we use is to create
1030// new macro invocations when expanding a macro.  For example, we have
1031//
1032//   #define ACTION_TEMPLATE(name, template_params, value_params)
1033//       ... GMOCK_INTERNAL_DECL_##template_params ...
1034//
1035// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
1036// to expand to
1037//
1038//       ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
1039//
1040// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
1041// preprocessor will continue to expand it to
1042//
1043//       ... typename T ...
1044//
1045// This technique conforms to the C++ standard and is portable.  It
1046// allows us to implement action templates using O(N) code, where N is
1047// the maximum number of template/value parameters supported.  Without
1048// using it, we'd have to devote O(N^2) amount of code to implement all
1049// combinations of m and n.
1050
1051// Declares the template parameters.
1052#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
1053#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
1054    name1) kind0 name0, kind1 name1
1055#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1056    kind2, name2) kind0 name0, kind1 name1, kind2 name2
1057#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1058    kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \
1059    kind3 name3
1060#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1061    kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \
1062    kind2 name2, kind3 name3, kind4 name4
1063#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1064    kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \
1065    kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5
1066#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1067    kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
1068    name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
1069    kind5 name5, kind6 name6
1070#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1071    kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
1072    kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \
1073    kind4 name4, kind5 name5, kind6 name6, kind7 name7
1074#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1075    kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
1076    kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \
1077    kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \
1078    kind8 name8
1079#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
1080    name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
1081    name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \
1082    kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \
1083    kind6 name6, kind7 name7, kind8 name8, kind9 name9
1084
1085// Lists the template parameters.
1086#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
1087#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
1088    name1) name0, name1
1089#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1090    kind2, name2) name0, name1, name2
1091#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1092    kind2, name2, kind3, name3) name0, name1, name2, name3
1093#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1094    kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \
1095    name4
1096#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1097    kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \
1098    name2, name3, name4, name5
1099#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1100    kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
1101    name6) name0, name1, name2, name3, name4, name5, name6
1102#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1103    kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
1104    kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7
1105#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
1106    kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
1107    kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \
1108    name6, name7, name8
1109#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
1110    name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
1111    name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \
1112    name3, name4, name5, name6, name7, name8, name9
1113
1114// Declares the types of value parameters.
1115#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()
1116#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type
1117#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \
1118    typename p0##_type, typename p1##_type
1119#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \
1120    typename p0##_type, typename p1##_type, typename p2##_type
1121#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
1122    typename p0##_type, typename p1##_type, typename p2##_type, \
1123    typename p3##_type
1124#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
1125    typename p0##_type, typename p1##_type, typename p2##_type, \
1126    typename p3##_type, typename p4##_type
1127#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
1128    typename p0##_type, typename p1##_type, typename p2##_type, \
1129    typename p3##_type, typename p4##_type, typename p5##_type
1130#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1131    p6) , typename p0##_type, typename p1##_type, typename p2##_type, \
1132    typename p3##_type, typename p4##_type, typename p5##_type, \
1133    typename p6##_type
1134#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1135    p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \
1136    typename p3##_type, typename p4##_type, typename p5##_type, \
1137    typename p6##_type, typename p7##_type
1138#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1139    p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \
1140    typename p3##_type, typename p4##_type, typename p5##_type, \
1141    typename p6##_type, typename p7##_type, typename p8##_type
1142#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1143    p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \
1144    typename p2##_type, typename p3##_type, typename p4##_type, \
1145    typename p5##_type, typename p6##_type, typename p7##_type, \
1146    typename p8##_type, typename p9##_type
1147
1148// Initializes the value parameters.
1149#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
1150    ()
1151#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
1152    (p0##_type gmock_p0) : p0(::testing::internal::move(gmock_p0))
1153#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
1154    (p0##_type gmock_p0, \
1155        p1##_type gmock_p1) : p0(::testing::internal::move(gmock_p0)), \
1156        p1(::testing::internal::move(gmock_p1))
1157#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
1158    (p0##_type gmock_p0, p1##_type gmock_p1, \
1159        p2##_type gmock_p2) : p0(::testing::internal::move(gmock_p0)), \
1160        p1(::testing::internal::move(gmock_p1)), \
1161        p2(::testing::internal::move(gmock_p2))
1162#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
1163    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1164        p3##_type gmock_p3) : p0(::testing::internal::move(gmock_p0)), \
1165        p1(::testing::internal::move(gmock_p1)), \
1166        p2(::testing::internal::move(gmock_p2)), \
1167        p3(::testing::internal::move(gmock_p3))
1168#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
1169    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1170        p3##_type gmock_p3, \
1171        p4##_type gmock_p4) : p0(::testing::internal::move(gmock_p0)), \
1172        p1(::testing::internal::move(gmock_p1)), \
1173        p2(::testing::internal::move(gmock_p2)), \
1174        p3(::testing::internal::move(gmock_p3)), \
1175        p4(::testing::internal::move(gmock_p4))
1176#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
1177    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1178        p3##_type gmock_p3, p4##_type gmock_p4, \
1179        p5##_type gmock_p5) : p0(::testing::internal::move(gmock_p0)), \
1180        p1(::testing::internal::move(gmock_p1)), \
1181        p2(::testing::internal::move(gmock_p2)), \
1182        p3(::testing::internal::move(gmock_p3)), \
1183        p4(::testing::internal::move(gmock_p4)), \
1184        p5(::testing::internal::move(gmock_p5))
1185#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
1186    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1187        p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1188        p6##_type gmock_p6) : p0(::testing::internal::move(gmock_p0)), \
1189        p1(::testing::internal::move(gmock_p1)), \
1190        p2(::testing::internal::move(gmock_p2)), \
1191        p3(::testing::internal::move(gmock_p3)), \
1192        p4(::testing::internal::move(gmock_p4)), \
1193        p5(::testing::internal::move(gmock_p5)), \
1194        p6(::testing::internal::move(gmock_p6))
1195#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
1196    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1197        p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1198        p6##_type gmock_p6, \
1199        p7##_type gmock_p7) : p0(::testing::internal::move(gmock_p0)), \
1200        p1(::testing::internal::move(gmock_p1)), \
1201        p2(::testing::internal::move(gmock_p2)), \
1202        p3(::testing::internal::move(gmock_p3)), \
1203        p4(::testing::internal::move(gmock_p4)), \
1204        p5(::testing::internal::move(gmock_p5)), \
1205        p6(::testing::internal::move(gmock_p6)), \
1206        p7(::testing::internal::move(gmock_p7))
1207#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1208    p7, p8)\
1209    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1210        p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1211        p6##_type gmock_p6, p7##_type gmock_p7, \
1212        p8##_type gmock_p8) : p0(::testing::internal::move(gmock_p0)), \
1213        p1(::testing::internal::move(gmock_p1)), \
1214        p2(::testing::internal::move(gmock_p2)), \
1215        p3(::testing::internal::move(gmock_p3)), \
1216        p4(::testing::internal::move(gmock_p4)), \
1217        p5(::testing::internal::move(gmock_p5)), \
1218        p6(::testing::internal::move(gmock_p6)), \
1219        p7(::testing::internal::move(gmock_p7)), \
1220        p8(::testing::internal::move(gmock_p8))
1221#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1222    p7, p8, p9)\
1223    (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1224        p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1225        p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
1226        p9##_type gmock_p9) : p0(::testing::internal::move(gmock_p0)), \
1227        p1(::testing::internal::move(gmock_p1)), \
1228        p2(::testing::internal::move(gmock_p2)), \
1229        p3(::testing::internal::move(gmock_p3)), \
1230        p4(::testing::internal::move(gmock_p4)), \
1231        p5(::testing::internal::move(gmock_p5)), \
1232        p6(::testing::internal::move(gmock_p6)), \
1233        p7(::testing::internal::move(gmock_p7)), \
1234        p8(::testing::internal::move(gmock_p8)), \
1235        p9(::testing::internal::move(gmock_p9))
1236
1237// Declares the fields for storing the value parameters.
1238#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
1239#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;
1240#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \
1241    p1##_type p1;
1242#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \
1243    p1##_type p1; p2##_type p2;
1244#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \
1245    p1##_type p1; p2##_type p2; p3##_type p3;
1246#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \
1247    p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4;
1248#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \
1249    p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
1250    p5##_type p5;
1251#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1252    p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
1253    p5##_type p5; p6##_type p6;
1254#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1255    p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
1256    p5##_type p5; p6##_type p6; p7##_type p7;
1257#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1258    p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \
1259    p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8;
1260#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1261    p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \
1262    p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \
1263    p9##_type p9;
1264
1265// Lists the value parameters.
1266#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()
1267#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0
1268#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1
1269#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2
1270#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3
1271#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \
1272    p2, p3, p4
1273#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \
1274    p1, p2, p3, p4, p5
1275#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1276    p6) p0, p1, p2, p3, p4, p5, p6
1277#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1278    p7) p0, p1, p2, p3, p4, p5, p6, p7
1279#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1280    p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8
1281#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1282    p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9
1283
1284// Lists the value parameter types.
1285#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()
1286#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type
1287#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \
1288    p1##_type
1289#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \
1290    p1##_type, p2##_type
1291#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
1292    p0##_type, p1##_type, p2##_type, p3##_type
1293#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
1294    p0##_type, p1##_type, p2##_type, p3##_type, p4##_type
1295#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
1296    p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type
1297#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1298    p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \
1299    p6##_type
1300#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1301    p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1302    p5##_type, p6##_type, p7##_type
1303#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1304    p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1305    p5##_type, p6##_type, p7##_type, p8##_type
1306#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1307    p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1308    p5##_type, p6##_type, p7##_type, p8##_type, p9##_type
1309
1310// Declares the value parameters.
1311#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()
1312#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0
1313#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \
1314    p1##_type p1
1315#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \
1316    p1##_type p1, p2##_type p2
1317#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \
1318    p1##_type p1, p2##_type p2, p3##_type p3
1319#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \
1320    p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4
1321#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \
1322    p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
1323    p5##_type p5
1324#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
1325    p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
1326    p5##_type p5, p6##_type p6
1327#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1328    p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
1329    p5##_type p5, p6##_type p6, p7##_type p7
1330#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1331    p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
1332    p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8
1333#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1334    p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
1335    p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \
1336    p9##_type p9
1337
1338// The suffix of the class template implementing the action template.
1339#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()
1340#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P
1341#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2
1342#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3
1343#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4
1344#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5
1345#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6
1346#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7
1347#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1348    p7) P8
1349#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1350    p7, p8) P9
1351#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
1352    p7, p8, p9) P10
1353
1354// The name of the class template implementing the action template.
1355#define GMOCK_ACTION_CLASS_(name, value_params)\
1356    GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
1357
1358#define ACTION_TEMPLATE(name, template_params, value_params)\
1359  template <GMOCK_INTERNAL_DECL_##template_params\
1360            GMOCK_INTERNAL_DECL_TYPE_##value_params>\
1361  class GMOCK_ACTION_CLASS_(name, value_params) {\
1362   public:\
1363    explicit GMOCK_ACTION_CLASS_(name, value_params)\
1364        GMOCK_INTERNAL_INIT_##value_params {}\
1365    template <typename F>\
1366    class gmock_Impl : public ::testing::ActionInterface<F> {\
1367     public:\
1368      typedef F function_type;\
1369      typedef typename ::testing::internal::Function<F>::Result return_type;\
1370      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1371          args_type;\
1372      explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
1373      virtual return_type Perform(const args_type& args) {\
1374        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1375            Perform(this, args);\
1376      }\
1377      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1378          typename arg3_type, typename arg4_type, typename arg5_type, \
1379          typename arg6_type, typename arg7_type, typename arg8_type, \
1380          typename arg9_type>\
1381      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1382          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1383          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1384          arg9_type arg9) const;\
1385      GMOCK_INTERNAL_DEFN_##value_params\
1386     private:\
1387      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1388    };\
1389    template <typename F> operator ::testing::Action<F>() const {\
1390      return ::testing::Action<F>(\
1391          new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
1392    }\
1393    GMOCK_INTERNAL_DEFN_##value_params\
1394   private:\
1395    GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
1396  };\
1397  template <GMOCK_INTERNAL_DECL_##template_params\
1398            GMOCK_INTERNAL_DECL_TYPE_##value_params>\
1399  inline GMOCK_ACTION_CLASS_(name, value_params)<\
1400      GMOCK_INTERNAL_LIST_##template_params\
1401      GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
1402          GMOCK_INTERNAL_DECL_##value_params) {\
1403    return GMOCK_ACTION_CLASS_(name, value_params)<\
1404        GMOCK_INTERNAL_LIST_##template_params\
1405        GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
1406            GMOCK_INTERNAL_LIST_##value_params);\
1407  }\
1408  template <GMOCK_INTERNAL_DECL_##template_params\
1409            GMOCK_INTERNAL_DECL_TYPE_##value_params>\
1410  template <typename F>\
1411  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1412      typename arg3_type, typename arg4_type, typename arg5_type, \
1413      typename arg6_type, typename arg7_type, typename arg8_type, \
1414      typename arg9_type>\
1415  typename ::testing::internal::Function<F>::Result\
1416      GMOCK_ACTION_CLASS_(name, value_params)<\
1417          GMOCK_INTERNAL_LIST_##template_params\
1418          GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
1419              gmock_PerformImpl(\
1420          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1421
1422#define ACTION(name)\
1423  class name##Action {\
1424   public:\
1425    name##Action() {}\
1426    template <typename F>\
1427    class gmock_Impl : public ::testing::ActionInterface<F> {\
1428     public:\
1429      typedef F function_type;\
1430      typedef typename ::testing::internal::Function<F>::Result return_type;\
1431      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1432          args_type;\
1433      gmock_Impl() {}\
1434      virtual return_type Perform(const args_type& args) {\
1435        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1436            Perform(this, args);\
1437      }\
1438      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1439          typename arg3_type, typename arg4_type, typename arg5_type, \
1440          typename arg6_type, typename arg7_type, typename arg8_type, \
1441          typename arg9_type>\
1442      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1443          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1444          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1445          arg9_type arg9) const;\
1446     private:\
1447      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1448    };\
1449    template <typename F> operator ::testing::Action<F>() const {\
1450      return ::testing::Action<F>(new gmock_Impl<F>());\
1451    }\
1452   private:\
1453    GTEST_DISALLOW_ASSIGN_(name##Action);\
1454  };\
1455  inline name##Action name() {\
1456    return name##Action();\
1457  }\
1458  template <typename F>\
1459  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1460      typename arg3_type, typename arg4_type, typename arg5_type, \
1461      typename arg6_type, typename arg7_type, typename arg8_type, \
1462      typename arg9_type>\
1463  typename ::testing::internal::Function<F>::Result\
1464      name##Action::gmock_Impl<F>::gmock_PerformImpl(\
1465          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1466
1467#define ACTION_P(name, p0)\
1468  template <typename p0##_type>\
1469  class name##ActionP {\
1470   public:\
1471    explicit name##ActionP(p0##_type gmock_p0) : \
1472        p0(::testing::internal::forward<p0##_type>(gmock_p0)) {}\
1473    template <typename F>\
1474    class gmock_Impl : public ::testing::ActionInterface<F> {\
1475     public:\
1476      typedef F function_type;\
1477      typedef typename ::testing::internal::Function<F>::Result return_type;\
1478      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1479          args_type;\
1480      explicit gmock_Impl(p0##_type gmock_p0) : \
1481          p0(::testing::internal::forward<p0##_type>(gmock_p0)) {}\
1482      virtual return_type Perform(const args_type& args) {\
1483        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1484            Perform(this, args);\
1485      }\
1486      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1487          typename arg3_type, typename arg4_type, typename arg5_type, \
1488          typename arg6_type, typename arg7_type, typename arg8_type, \
1489          typename arg9_type>\
1490      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1491          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1492          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1493          arg9_type arg9) const;\
1494      p0##_type p0;\
1495     private:\
1496      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1497    };\
1498    template <typename F> operator ::testing::Action<F>() const {\
1499      return ::testing::Action<F>(new gmock_Impl<F>(p0));\
1500    }\
1501    p0##_type p0;\
1502   private:\
1503    GTEST_DISALLOW_ASSIGN_(name##ActionP);\
1504  };\
1505  template <typename p0##_type>\
1506  inline name##ActionP<p0##_type> name(p0##_type p0) {\
1507    return name##ActionP<p0##_type>(p0);\
1508  }\
1509  template <typename p0##_type>\
1510  template <typename F>\
1511  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1512      typename arg3_type, typename arg4_type, typename arg5_type, \
1513      typename arg6_type, typename arg7_type, typename arg8_type, \
1514      typename arg9_type>\
1515  typename ::testing::internal::Function<F>::Result\
1516      name##ActionP<p0##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1517          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1518
1519#define ACTION_P2(name, p0, p1)\
1520  template <typename p0##_type, typename p1##_type>\
1521  class name##ActionP2 {\
1522   public:\
1523    name##ActionP2(p0##_type gmock_p0, \
1524        p1##_type gmock_p1) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1525        p1(::testing::internal::forward<p1##_type>(gmock_p1)) {}\
1526    template <typename F>\
1527    class gmock_Impl : public ::testing::ActionInterface<F> {\
1528     public:\
1529      typedef F function_type;\
1530      typedef typename ::testing::internal::Function<F>::Result return_type;\
1531      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1532          args_type;\
1533      gmock_Impl(p0##_type gmock_p0, \
1534          p1##_type gmock_p1) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1535          p1(::testing::internal::forward<p1##_type>(gmock_p1)) {}\
1536      virtual return_type Perform(const args_type& args) {\
1537        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1538            Perform(this, args);\
1539      }\
1540      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1541          typename arg3_type, typename arg4_type, typename arg5_type, \
1542          typename arg6_type, typename arg7_type, typename arg8_type, \
1543          typename arg9_type>\
1544      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1545          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1546          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1547          arg9_type arg9) const;\
1548      p0##_type p0;\
1549      p1##_type p1;\
1550     private:\
1551      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1552    };\
1553    template <typename F> operator ::testing::Action<F>() const {\
1554      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1));\
1555    }\
1556    p0##_type p0;\
1557    p1##_type p1;\
1558   private:\
1559    GTEST_DISALLOW_ASSIGN_(name##ActionP2);\
1560  };\
1561  template <typename p0##_type, typename p1##_type>\
1562  inline name##ActionP2<p0##_type, p1##_type> name(p0##_type p0, \
1563      p1##_type p1) {\
1564    return name##ActionP2<p0##_type, p1##_type>(p0, p1);\
1565  }\
1566  template <typename p0##_type, typename p1##_type>\
1567  template <typename F>\
1568  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1569      typename arg3_type, typename arg4_type, typename arg5_type, \
1570      typename arg6_type, typename arg7_type, typename arg8_type, \
1571      typename arg9_type>\
1572  typename ::testing::internal::Function<F>::Result\
1573      name##ActionP2<p0##_type, p1##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1574          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1575
1576#define ACTION_P3(name, p0, p1, p2)\
1577  template <typename p0##_type, typename p1##_type, typename p2##_type>\
1578  class name##ActionP3 {\
1579   public:\
1580    name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \
1581        p2##_type gmock_p2) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1582        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1583        p2(::testing::internal::forward<p2##_type>(gmock_p2)) {}\
1584    template <typename F>\
1585    class gmock_Impl : public ::testing::ActionInterface<F> {\
1586     public:\
1587      typedef F function_type;\
1588      typedef typename ::testing::internal::Function<F>::Result return_type;\
1589      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1590          args_type;\
1591      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
1592          p2##_type gmock_p2) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1593          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1594          p2(::testing::internal::forward<p2##_type>(gmock_p2)) {}\
1595      virtual return_type Perform(const args_type& args) {\
1596        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1597            Perform(this, args);\
1598      }\
1599      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1600          typename arg3_type, typename arg4_type, typename arg5_type, \
1601          typename arg6_type, typename arg7_type, typename arg8_type, \
1602          typename arg9_type>\
1603      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1604          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1605          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1606          arg9_type arg9) const;\
1607      p0##_type p0;\
1608      p1##_type p1;\
1609      p2##_type p2;\
1610     private:\
1611      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1612    };\
1613    template <typename F> operator ::testing::Action<F>() const {\
1614      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2));\
1615    }\
1616    p0##_type p0;\
1617    p1##_type p1;\
1618    p2##_type p2;\
1619   private:\
1620    GTEST_DISALLOW_ASSIGN_(name##ActionP3);\
1621  };\
1622  template <typename p0##_type, typename p1##_type, typename p2##_type>\
1623  inline name##ActionP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \
1624      p1##_type p1, p2##_type p2) {\
1625    return name##ActionP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\
1626  }\
1627  template <typename p0##_type, typename p1##_type, typename p2##_type>\
1628  template <typename F>\
1629  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1630      typename arg3_type, typename arg4_type, typename arg5_type, \
1631      typename arg6_type, typename arg7_type, typename arg8_type, \
1632      typename arg9_type>\
1633  typename ::testing::internal::Function<F>::Result\
1634      name##ActionP3<p0##_type, p1##_type, \
1635          p2##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1636          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1637
1638#define ACTION_P4(name, p0, p1, p2, p3)\
1639  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1640      typename p3##_type>\
1641  class name##ActionP4 {\
1642   public:\
1643    name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \
1644        p2##_type gmock_p2, \
1645        p3##_type gmock_p3) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1646        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1647        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1648        p3(::testing::internal::forward<p3##_type>(gmock_p3)) {}\
1649    template <typename F>\
1650    class gmock_Impl : public ::testing::ActionInterface<F> {\
1651     public:\
1652      typedef F function_type;\
1653      typedef typename ::testing::internal::Function<F>::Result return_type;\
1654      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1655          args_type;\
1656      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1657          p3##_type gmock_p3) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1658          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1659          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1660          p3(::testing::internal::forward<p3##_type>(gmock_p3)) {}\
1661      virtual return_type Perform(const args_type& args) {\
1662        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1663            Perform(this, args);\
1664      }\
1665      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1666          typename arg3_type, typename arg4_type, typename arg5_type, \
1667          typename arg6_type, typename arg7_type, typename arg8_type, \
1668          typename arg9_type>\
1669      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1670          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1671          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1672          arg9_type arg9) const;\
1673      p0##_type p0;\
1674      p1##_type p1;\
1675      p2##_type p2;\
1676      p3##_type p3;\
1677     private:\
1678      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1679    };\
1680    template <typename F> operator ::testing::Action<F>() const {\
1681      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3));\
1682    }\
1683    p0##_type p0;\
1684    p1##_type p1;\
1685    p2##_type p2;\
1686    p3##_type p3;\
1687   private:\
1688    GTEST_DISALLOW_ASSIGN_(name##ActionP4);\
1689  };\
1690  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1691      typename p3##_type>\
1692  inline name##ActionP4<p0##_type, p1##_type, p2##_type, \
1693      p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \
1694      p3##_type p3) {\
1695    return name##ActionP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, p1, \
1696        p2, p3);\
1697  }\
1698  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1699      typename p3##_type>\
1700  template <typename F>\
1701  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1702      typename arg3_type, typename arg4_type, typename arg5_type, \
1703      typename arg6_type, typename arg7_type, typename arg8_type, \
1704      typename arg9_type>\
1705  typename ::testing::internal::Function<F>::Result\
1706      name##ActionP4<p0##_type, p1##_type, p2##_type, \
1707          p3##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1708          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1709
1710#define ACTION_P5(name, p0, p1, p2, p3, p4)\
1711  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1712      typename p3##_type, typename p4##_type>\
1713  class name##ActionP5 {\
1714   public:\
1715    name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \
1716        p2##_type gmock_p2, p3##_type gmock_p3, \
1717        p4##_type gmock_p4) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1718        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1719        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1720        p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1721        p4(::testing::internal::forward<p4##_type>(gmock_p4)) {}\
1722    template <typename F>\
1723    class gmock_Impl : public ::testing::ActionInterface<F> {\
1724     public:\
1725      typedef F function_type;\
1726      typedef typename ::testing::internal::Function<F>::Result return_type;\
1727      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1728          args_type;\
1729      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1730          p3##_type gmock_p3, \
1731          p4##_type gmock_p4) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1732          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1733          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1734          p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1735          p4(::testing::internal::forward<p4##_type>(gmock_p4)) {}\
1736      virtual return_type Perform(const args_type& args) {\
1737        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1738            Perform(this, args);\
1739      }\
1740      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1741          typename arg3_type, typename arg4_type, typename arg5_type, \
1742          typename arg6_type, typename arg7_type, typename arg8_type, \
1743          typename arg9_type>\
1744      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1745          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1746          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1747          arg9_type arg9) const;\
1748      p0##_type p0;\
1749      p1##_type p1;\
1750      p2##_type p2;\
1751      p3##_type p3;\
1752      p4##_type p4;\
1753     private:\
1754      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1755    };\
1756    template <typename F> operator ::testing::Action<F>() const {\
1757      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4));\
1758    }\
1759    p0##_type p0;\
1760    p1##_type p1;\
1761    p2##_type p2;\
1762    p3##_type p3;\
1763    p4##_type p4;\
1764   private:\
1765    GTEST_DISALLOW_ASSIGN_(name##ActionP5);\
1766  };\
1767  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1768      typename p3##_type, typename p4##_type>\
1769  inline name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \
1770      p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
1771      p4##_type p4) {\
1772    return name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \
1773        p4##_type>(p0, p1, p2, p3, p4);\
1774  }\
1775  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1776      typename p3##_type, typename p4##_type>\
1777  template <typename F>\
1778  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1779      typename arg3_type, typename arg4_type, typename arg5_type, \
1780      typename arg6_type, typename arg7_type, typename arg8_type, \
1781      typename arg9_type>\
1782  typename ::testing::internal::Function<F>::Result\
1783      name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \
1784          p4##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1785          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1786
1787#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\
1788  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1789      typename p3##_type, typename p4##_type, typename p5##_type>\
1790  class name##ActionP6 {\
1791   public:\
1792    name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \
1793        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1794        p5##_type gmock_p5) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1795        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1796        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1797        p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1798        p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
1799        p5(::testing::internal::forward<p5##_type>(gmock_p5)) {}\
1800    template <typename F>\
1801    class gmock_Impl : public ::testing::ActionInterface<F> {\
1802     public:\
1803      typedef F function_type;\
1804      typedef typename ::testing::internal::Function<F>::Result return_type;\
1805      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1806          args_type;\
1807      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1808          p3##_type gmock_p3, p4##_type gmock_p4, \
1809          p5##_type gmock_p5) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1810          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1811          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1812          p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1813          p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
1814          p5(::testing::internal::forward<p5##_type>(gmock_p5)) {}\
1815      virtual return_type Perform(const args_type& args) {\
1816        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1817            Perform(this, args);\
1818      }\
1819      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1820          typename arg3_type, typename arg4_type, typename arg5_type, \
1821          typename arg6_type, typename arg7_type, typename arg8_type, \
1822          typename arg9_type>\
1823      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1824          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1825          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1826          arg9_type arg9) const;\
1827      p0##_type p0;\
1828      p1##_type p1;\
1829      p2##_type p2;\
1830      p3##_type p3;\
1831      p4##_type p4;\
1832      p5##_type p5;\
1833     private:\
1834      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1835    };\
1836    template <typename F> operator ::testing::Action<F>() const {\
1837      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5));\
1838    }\
1839    p0##_type p0;\
1840    p1##_type p1;\
1841    p2##_type p2;\
1842    p3##_type p3;\
1843    p4##_type p4;\
1844    p5##_type p5;\
1845   private:\
1846    GTEST_DISALLOW_ASSIGN_(name##ActionP6);\
1847  };\
1848  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1849      typename p3##_type, typename p4##_type, typename p5##_type>\
1850  inline name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \
1851      p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \
1852      p3##_type p3, p4##_type p4, p5##_type p5) {\
1853    return name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \
1854        p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\
1855  }\
1856  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1857      typename p3##_type, typename p4##_type, typename p5##_type>\
1858  template <typename F>\
1859  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1860      typename arg3_type, typename arg4_type, typename arg5_type, \
1861      typename arg6_type, typename arg7_type, typename arg8_type, \
1862      typename arg9_type>\
1863  typename ::testing::internal::Function<F>::Result\
1864      name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1865          p5##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1866          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1867
1868#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\
1869  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1870      typename p3##_type, typename p4##_type, typename p5##_type, \
1871      typename p6##_type>\
1872  class name##ActionP7 {\
1873   public:\
1874    name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \
1875        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1876        p5##_type gmock_p5, \
1877        p6##_type gmock_p6) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1878        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1879        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1880        p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1881        p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
1882        p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
1883        p6(::testing::internal::forward<p6##_type>(gmock_p6)) {}\
1884    template <typename F>\
1885    class gmock_Impl : public ::testing::ActionInterface<F> {\
1886     public:\
1887      typedef F function_type;\
1888      typedef typename ::testing::internal::Function<F>::Result return_type;\
1889      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1890          args_type;\
1891      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1892          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1893          p6##_type gmock_p6) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1894          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1895          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1896          p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1897          p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
1898          p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
1899          p6(::testing::internal::forward<p6##_type>(gmock_p6)) {}\
1900      virtual return_type Perform(const args_type& args) {\
1901        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1902            Perform(this, args);\
1903      }\
1904      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1905          typename arg3_type, typename arg4_type, typename arg5_type, \
1906          typename arg6_type, typename arg7_type, typename arg8_type, \
1907          typename arg9_type>\
1908      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
1909          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
1910          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
1911          arg9_type arg9) const;\
1912      p0##_type p0;\
1913      p1##_type p1;\
1914      p2##_type p2;\
1915      p3##_type p3;\
1916      p4##_type p4;\
1917      p5##_type p5;\
1918      p6##_type p6;\
1919     private:\
1920      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
1921    };\
1922    template <typename F> operator ::testing::Action<F>() const {\
1923      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
1924          p6));\
1925    }\
1926    p0##_type p0;\
1927    p1##_type p1;\
1928    p2##_type p2;\
1929    p3##_type p3;\
1930    p4##_type p4;\
1931    p5##_type p5;\
1932    p6##_type p6;\
1933   private:\
1934    GTEST_DISALLOW_ASSIGN_(name##ActionP7);\
1935  };\
1936  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1937      typename p3##_type, typename p4##_type, typename p5##_type, \
1938      typename p6##_type>\
1939  inline name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \
1940      p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \
1941      p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \
1942      p6##_type p6) {\
1943    return name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \
1944        p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\
1945  }\
1946  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1947      typename p3##_type, typename p4##_type, typename p5##_type, \
1948      typename p6##_type>\
1949  template <typename F>\
1950  template <typename arg0_type, typename arg1_type, typename arg2_type, \
1951      typename arg3_type, typename arg4_type, typename arg5_type, \
1952      typename arg6_type, typename arg7_type, typename arg8_type, \
1953      typename arg9_type>\
1954  typename ::testing::internal::Function<F>::Result\
1955      name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
1956          p5##_type, p6##_type>::gmock_Impl<F>::gmock_PerformImpl(\
1957          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1958
1959#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\
1960  template <typename p0##_type, typename p1##_type, typename p2##_type, \
1961      typename p3##_type, typename p4##_type, typename p5##_type, \
1962      typename p6##_type, typename p7##_type>\
1963  class name##ActionP8 {\
1964   public:\
1965    name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \
1966        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
1967        p5##_type gmock_p5, p6##_type gmock_p6, \
1968        p7##_type gmock_p7) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1969        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1970        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1971        p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1972        p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
1973        p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
1974        p6(::testing::internal::forward<p6##_type>(gmock_p6)), \
1975        p7(::testing::internal::forward<p7##_type>(gmock_p7)) {}\
1976    template <typename F>\
1977    class gmock_Impl : public ::testing::ActionInterface<F> {\
1978     public:\
1979      typedef F function_type;\
1980      typedef typename ::testing::internal::Function<F>::Result return_type;\
1981      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
1982          args_type;\
1983      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
1984          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
1985          p6##_type gmock_p6, \
1986          p7##_type gmock_p7) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
1987          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
1988          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
1989          p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
1990          p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
1991          p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
1992          p6(::testing::internal::forward<p6##_type>(gmock_p6)), \
1993          p7(::testing::internal::forward<p7##_type>(gmock_p7)) {}\
1994      virtual return_type Perform(const args_type& args) {\
1995        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
1996            Perform(this, args);\
1997      }\
1998      template <typename arg0_type, typename arg1_type, typename arg2_type, \
1999          typename arg3_type, typename arg4_type, typename arg5_type, \
2000          typename arg6_type, typename arg7_type, typename arg8_type, \
2001          typename arg9_type>\
2002      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
2003          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
2004          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
2005          arg9_type arg9) const;\
2006      p0##_type p0;\
2007      p1##_type p1;\
2008      p2##_type p2;\
2009      p3##_type p3;\
2010      p4##_type p4;\
2011      p5##_type p5;\
2012      p6##_type p6;\
2013      p7##_type p7;\
2014     private:\
2015      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
2016    };\
2017    template <typename F> operator ::testing::Action<F>() const {\
2018      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
2019          p6, p7));\
2020    }\
2021    p0##_type p0;\
2022    p1##_type p1;\
2023    p2##_type p2;\
2024    p3##_type p3;\
2025    p4##_type p4;\
2026    p5##_type p5;\
2027    p6##_type p6;\
2028    p7##_type p7;\
2029   private:\
2030    GTEST_DISALLOW_ASSIGN_(name##ActionP8);\
2031  };\
2032  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2033      typename p3##_type, typename p4##_type, typename p5##_type, \
2034      typename p6##_type, typename p7##_type>\
2035  inline name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \
2036      p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \
2037      p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \
2038      p6##_type p6, p7##_type p7) {\
2039    return name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \
2040        p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \
2041        p6, p7);\
2042  }\
2043  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2044      typename p3##_type, typename p4##_type, typename p5##_type, \
2045      typename p6##_type, typename p7##_type>\
2046  template <typename F>\
2047  template <typename arg0_type, typename arg1_type, typename arg2_type, \
2048      typename arg3_type, typename arg4_type, typename arg5_type, \
2049      typename arg6_type, typename arg7_type, typename arg8_type, \
2050      typename arg9_type>\
2051  typename ::testing::internal::Function<F>::Result\
2052      name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
2053          p5##_type, p6##_type, \
2054          p7##_type>::gmock_Impl<F>::gmock_PerformImpl(\
2055          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
2056
2057#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\
2058  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2059      typename p3##_type, typename p4##_type, typename p5##_type, \
2060      typename p6##_type, typename p7##_type, typename p8##_type>\
2061  class name##ActionP9 {\
2062   public:\
2063    name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \
2064        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
2065        p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
2066        p8##_type gmock_p8) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
2067        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
2068        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
2069        p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
2070        p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
2071        p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
2072        p6(::testing::internal::forward<p6##_type>(gmock_p6)), \
2073        p7(::testing::internal::forward<p7##_type>(gmock_p7)), \
2074        p8(::testing::internal::forward<p8##_type>(gmock_p8)) {}\
2075    template <typename F>\
2076    class gmock_Impl : public ::testing::ActionInterface<F> {\
2077     public:\
2078      typedef F function_type;\
2079      typedef typename ::testing::internal::Function<F>::Result return_type;\
2080      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
2081          args_type;\
2082      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
2083          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
2084          p6##_type gmock_p6, p7##_type gmock_p7, \
2085          p8##_type gmock_p8) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
2086          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
2087          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
2088          p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
2089          p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
2090          p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
2091          p6(::testing::internal::forward<p6##_type>(gmock_p6)), \
2092          p7(::testing::internal::forward<p7##_type>(gmock_p7)), \
2093          p8(::testing::internal::forward<p8##_type>(gmock_p8)) {}\
2094      virtual return_type Perform(const args_type& args) {\
2095        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
2096            Perform(this, args);\
2097      }\
2098      template <typename arg0_type, typename arg1_type, typename arg2_type, \
2099          typename arg3_type, typename arg4_type, typename arg5_type, \
2100          typename arg6_type, typename arg7_type, typename arg8_type, \
2101          typename arg9_type>\
2102      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
2103          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
2104          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
2105          arg9_type arg9) const;\
2106      p0##_type p0;\
2107      p1##_type p1;\
2108      p2##_type p2;\
2109      p3##_type p3;\
2110      p4##_type p4;\
2111      p5##_type p5;\
2112      p6##_type p6;\
2113      p7##_type p7;\
2114      p8##_type p8;\
2115     private:\
2116      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
2117    };\
2118    template <typename F> operator ::testing::Action<F>() const {\
2119      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
2120          p6, p7, p8));\
2121    }\
2122    p0##_type p0;\
2123    p1##_type p1;\
2124    p2##_type p2;\
2125    p3##_type p3;\
2126    p4##_type p4;\
2127    p5##_type p5;\
2128    p6##_type p6;\
2129    p7##_type p7;\
2130    p8##_type p8;\
2131   private:\
2132    GTEST_DISALLOW_ASSIGN_(name##ActionP9);\
2133  };\
2134  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2135      typename p3##_type, typename p4##_type, typename p5##_type, \
2136      typename p6##_type, typename p7##_type, typename p8##_type>\
2137  inline name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \
2138      p4##_type, p5##_type, p6##_type, p7##_type, \
2139      p8##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
2140      p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \
2141      p8##_type p8) {\
2142    return name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \
2143        p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \
2144        p3, p4, p5, p6, p7, p8);\
2145  }\
2146  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2147      typename p3##_type, typename p4##_type, typename p5##_type, \
2148      typename p6##_type, typename p7##_type, typename p8##_type>\
2149  template <typename F>\
2150  template <typename arg0_type, typename arg1_type, typename arg2_type, \
2151      typename arg3_type, typename arg4_type, typename arg5_type, \
2152      typename arg6_type, typename arg7_type, typename arg8_type, \
2153      typename arg9_type>\
2154  typename ::testing::internal::Function<F>::Result\
2155      name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
2156          p5##_type, p6##_type, p7##_type, \
2157          p8##_type>::gmock_Impl<F>::gmock_PerformImpl(\
2158          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
2159
2160#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\
2161  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2162      typename p3##_type, typename p4##_type, typename p5##_type, \
2163      typename p6##_type, typename p7##_type, typename p8##_type, \
2164      typename p9##_type>\
2165  class name##ActionP10 {\
2166   public:\
2167    name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \
2168        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
2169        p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
2170        p8##_type gmock_p8, \
2171        p9##_type gmock_p9) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
2172        p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
2173        p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
2174        p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
2175        p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
2176        p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
2177        p6(::testing::internal::forward<p6##_type>(gmock_p6)), \
2178        p7(::testing::internal::forward<p7##_type>(gmock_p7)), \
2179        p8(::testing::internal::forward<p8##_type>(gmock_p8)), \
2180        p9(::testing::internal::forward<p9##_type>(gmock_p9)) {}\
2181    template <typename F>\
2182    class gmock_Impl : public ::testing::ActionInterface<F> {\
2183     public:\
2184      typedef F function_type;\
2185      typedef typename ::testing::internal::Function<F>::Result return_type;\
2186      typedef typename ::testing::internal::Function<F>::ArgumentTuple\
2187          args_type;\
2188      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
2189          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
2190          p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
2191          p9##_type gmock_p9) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \
2192          p1(::testing::internal::forward<p1##_type>(gmock_p1)), \
2193          p2(::testing::internal::forward<p2##_type>(gmock_p2)), \
2194          p3(::testing::internal::forward<p3##_type>(gmock_p3)), \
2195          p4(::testing::internal::forward<p4##_type>(gmock_p4)), \
2196          p5(::testing::internal::forward<p5##_type>(gmock_p5)), \
2197          p6(::testing::internal::forward<p6##_type>(gmock_p6)), \
2198          p7(::testing::internal::forward<p7##_type>(gmock_p7)), \
2199          p8(::testing::internal::forward<p8##_type>(gmock_p8)), \
2200          p9(::testing::internal::forward<p9##_type>(gmock_p9)) {}\
2201      virtual return_type Perform(const args_type& args) {\
2202        return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
2203            Perform(this, args);\
2204      }\
2205      template <typename arg0_type, typename arg1_type, typename arg2_type, \
2206          typename arg3_type, typename arg4_type, typename arg5_type, \
2207          typename arg6_type, typename arg7_type, typename arg8_type, \
2208          typename arg9_type>\
2209      return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
2210          arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
2211          arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
2212          arg9_type arg9) const;\
2213      p0##_type p0;\
2214      p1##_type p1;\
2215      p2##_type p2;\
2216      p3##_type p3;\
2217      p4##_type p4;\
2218      p5##_type p5;\
2219      p6##_type p6;\
2220      p7##_type p7;\
2221      p8##_type p8;\
2222      p9##_type p9;\
2223     private:\
2224      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
2225    };\
2226    template <typename F> operator ::testing::Action<F>() const {\
2227      return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
2228          p6, p7, p8, p9));\
2229    }\
2230    p0##_type p0;\
2231    p1##_type p1;\
2232    p2##_type p2;\
2233    p3##_type p3;\
2234    p4##_type p4;\
2235    p5##_type p5;\
2236    p6##_type p6;\
2237    p7##_type p7;\
2238    p8##_type p8;\
2239    p9##_type p9;\
2240   private:\
2241    GTEST_DISALLOW_ASSIGN_(name##ActionP10);\
2242  };\
2243  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2244      typename p3##_type, typename p4##_type, typename p5##_type, \
2245      typename p6##_type, typename p7##_type, typename p8##_type, \
2246      typename p9##_type>\
2247  inline name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \
2248      p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
2249      p9##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
2250      p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \
2251      p9##_type p9) {\
2252    return name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \
2253        p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \
2254        p1, p2, p3, p4, p5, p6, p7, p8, p9);\
2255  }\
2256  template <typename p0##_type, typename p1##_type, typename p2##_type, \
2257      typename p3##_type, typename p4##_type, typename p5##_type, \
2258      typename p6##_type, typename p7##_type, typename p8##_type, \
2259      typename p9##_type>\
2260  template <typename F>\
2261  template <typename arg0_type, typename arg1_type, typename arg2_type, \
2262      typename arg3_type, typename arg4_type, typename arg5_type, \
2263      typename arg6_type, typename arg7_type, typename arg8_type, \
2264      typename arg9_type>\
2265  typename ::testing::internal::Function<F>::Result\
2266      name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
2267          p5##_type, p6##_type, p7##_type, p8##_type, \
2268          p9##_type>::gmock_Impl<F>::gmock_PerformImpl(\
2269          GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
2270
2271namespace testing {
2272
2273
2274// The ACTION*() macros trigger warning C4100 (unreferenced formal
2275// parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in
2276// the macro definition, as the warnings are generated when the macro
2277// is expanded and macro expansion cannot contain #pragma.  Therefore
2278// we suppress them here.
2279#ifdef _MSC_VER
2280# pragma warning(push)
2281# pragma warning(disable:4100)
2282#endif
2283
2284// Various overloads for InvokeArgument<N>().
2285//
2286// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
2287// (0-based) argument, which must be a k-ary callable, of the mock
2288// function, with arguments a1, a2, ..., a_k.
2289//
2290// Notes:
2291//
2292//   1. The arguments are passed by value by default.  If you need to
2293//   pass an argument by reference, wrap it inside ByRef().  For
2294//   example,
2295//
2296//     InvokeArgument<1>(5, string("Hello"), ByRef(foo))
2297//
2298//   passes 5 and string("Hello") by value, and passes foo by
2299//   reference.
2300//
2301//   2. If the callable takes an argument by reference but ByRef() is
2302//   not used, it will receive the reference to a copy of the value,
2303//   instead of the original value.  For example, when the 0-th
2304//   argument of the mock function takes a const string&, the action
2305//
2306//     InvokeArgument<0>(string("Hello"))
2307//
2308//   makes a copy of the temporary string("Hello") object and passes a
2309//   reference of the copy, instead of the original temporary object,
2310//   to the callable.  This makes it easy for a user to define an
2311//   InvokeArgument action from temporary values and have it performed
2312//   later.
2313
2314namespace internal {
2315namespace invoke_argument {
2316
2317// Appears in InvokeArgumentAdl's argument list to help avoid
2318// accidental calls to user functions of the same name.
2319struct AdlTag {};
2320
2321// InvokeArgumentAdl - a helper for InvokeArgument.
2322// The basic overloads are provided here for generic functors.
2323// Overloads for other custom-callables are provided in the
2324// internal/custom/callback-actions.h header.
2325
2326template <typename R, typename F>
2327R InvokeArgumentAdl(AdlTag, F f) {
2328  return f();
2329}
2330template <typename R, typename F, typename A1>
2331R InvokeArgumentAdl(AdlTag, F f, A1 a1) {
2332  return f(a1);
2333}
2334template <typename R, typename F, typename A1, typename A2>
2335R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) {
2336  return f(a1, a2);
2337}
2338template <typename R, typename F, typename A1, typename A2, typename A3>
2339R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) {
2340  return f(a1, a2, a3);
2341}
2342template <typename R, typename F, typename A1, typename A2, typename A3,
2343    typename A4>
2344R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) {
2345  return f(a1, a2, a3, a4);
2346}
2347template <typename R, typename F, typename A1, typename A2, typename A3,
2348    typename A4, typename A5>
2349R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
2350  return f(a1, a2, a3, a4, a5);
2351}
2352template <typename R, typename F, typename A1, typename A2, typename A3,
2353    typename A4, typename A5, typename A6>
2354R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
2355  return f(a1, a2, a3, a4, a5, a6);
2356}
2357template <typename R, typename F, typename A1, typename A2, typename A3,
2358    typename A4, typename A5, typename A6, typename A7>
2359R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
2360    A7 a7) {
2361  return f(a1, a2, a3, a4, a5, a6, a7);
2362}
2363template <typename R, typename F, typename A1, typename A2, typename A3,
2364    typename A4, typename A5, typename A6, typename A7, typename A8>
2365R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
2366    A7 a7, A8 a8) {
2367  return f(a1, a2, a3, a4, a5, a6, a7, a8);
2368}
2369template <typename R, typename F, typename A1, typename A2, typename A3,
2370    typename A4, typename A5, typename A6, typename A7, typename A8,
2371    typename A9>
2372R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
2373    A7 a7, A8 a8, A9 a9) {
2374  return f(a1, a2, a3, a4, a5, a6, a7, a8, a9);
2375}
2376template <typename R, typename F, typename A1, typename A2, typename A3,
2377    typename A4, typename A5, typename A6, typename A7, typename A8,
2378    typename A9, typename A10>
2379R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
2380    A7 a7, A8 a8, A9 a9, A10 a10) {
2381  return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
2382}
2383}  // namespace invoke_argument
2384}  // namespace internal
2385
2386ACTION_TEMPLATE(InvokeArgument,
2387                HAS_1_TEMPLATE_PARAMS(int, k),
2388                AND_0_VALUE_PARAMS()) {
2389  using internal::invoke_argument::InvokeArgumentAdl;
2390  return InvokeArgumentAdl<return_type>(
2391      internal::invoke_argument::AdlTag(),
2392      ::testing::get<k>(args));
2393}
2394
2395ACTION_TEMPLATE(InvokeArgument,
2396                HAS_1_TEMPLATE_PARAMS(int, k),
2397                AND_1_VALUE_PARAMS(p0)) {
2398  using internal::invoke_argument::InvokeArgumentAdl;
2399  return InvokeArgumentAdl<return_type>(
2400      internal::invoke_argument::AdlTag(),
2401      ::testing::get<k>(args), p0);
2402}
2403
2404ACTION_TEMPLATE(InvokeArgument,
2405                HAS_1_TEMPLATE_PARAMS(int, k),
2406                AND_2_VALUE_PARAMS(p0, p1)) {
2407  using internal::invoke_argument::InvokeArgumentAdl;
2408  return InvokeArgumentAdl<return_type>(
2409      internal::invoke_argument::AdlTag(),
2410      ::testing::get<k>(args), p0, p1);
2411}
2412
2413ACTION_TEMPLATE(InvokeArgument,
2414                HAS_1_TEMPLATE_PARAMS(int, k),
2415                AND_3_VALUE_PARAMS(p0, p1, p2)) {
2416  using internal::invoke_argument::InvokeArgumentAdl;
2417  return InvokeArgumentAdl<return_type>(
2418      internal::invoke_argument::AdlTag(),
2419      ::testing::get<k>(args), p0, p1, p2);
2420}
2421
2422ACTION_TEMPLATE(InvokeArgument,
2423                HAS_1_TEMPLATE_PARAMS(int, k),
2424                AND_4_VALUE_PARAMS(p0, p1, p2, p3)) {
2425  using internal::invoke_argument::InvokeArgumentAdl;
2426  return InvokeArgumentAdl<return_type>(
2427      internal::invoke_argument::AdlTag(),
2428      ::testing::get<k>(args), p0, p1, p2, p3);
2429}
2430
2431ACTION_TEMPLATE(InvokeArgument,
2432                HAS_1_TEMPLATE_PARAMS(int, k),
2433                AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) {
2434  using internal::invoke_argument::InvokeArgumentAdl;
2435  return InvokeArgumentAdl<return_type>(
2436      internal::invoke_argument::AdlTag(),
2437      ::testing::get<k>(args), p0, p1, p2, p3, p4);
2438}
2439
2440ACTION_TEMPLATE(InvokeArgument,
2441                HAS_1_TEMPLATE_PARAMS(int, k),
2442                AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) {
2443  using internal::invoke_argument::InvokeArgumentAdl;
2444  return InvokeArgumentAdl<return_type>(
2445      internal::invoke_argument::AdlTag(),
2446      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5);
2447}
2448
2449ACTION_TEMPLATE(InvokeArgument,
2450                HAS_1_TEMPLATE_PARAMS(int, k),
2451                AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) {
2452  using internal::invoke_argument::InvokeArgumentAdl;
2453  return InvokeArgumentAdl<return_type>(
2454      internal::invoke_argument::AdlTag(),
2455      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6);
2456}
2457
2458ACTION_TEMPLATE(InvokeArgument,
2459                HAS_1_TEMPLATE_PARAMS(int, k),
2460                AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) {
2461  using internal::invoke_argument::InvokeArgumentAdl;
2462  return InvokeArgumentAdl<return_type>(
2463      internal::invoke_argument::AdlTag(),
2464      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7);
2465}
2466
2467ACTION_TEMPLATE(InvokeArgument,
2468                HAS_1_TEMPLATE_PARAMS(int, k),
2469                AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) {
2470  using internal::invoke_argument::InvokeArgumentAdl;
2471  return InvokeArgumentAdl<return_type>(
2472      internal::invoke_argument::AdlTag(),
2473      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8);
2474}
2475
2476ACTION_TEMPLATE(InvokeArgument,
2477                HAS_1_TEMPLATE_PARAMS(int, k),
2478                AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) {
2479  using internal::invoke_argument::InvokeArgumentAdl;
2480  return InvokeArgumentAdl<return_type>(
2481      internal::invoke_argument::AdlTag(),
2482      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
2483}
2484
2485// Various overloads for ReturnNew<T>().
2486//
2487// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
2488// instance of type T, constructed on the heap with constructor arguments
2489// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
2490ACTION_TEMPLATE(ReturnNew,
2491                HAS_1_TEMPLATE_PARAMS(typename, T),
2492                AND_0_VALUE_PARAMS()) {
2493  return new T();
2494}
2495
2496ACTION_TEMPLATE(ReturnNew,
2497                HAS_1_TEMPLATE_PARAMS(typename, T),
2498                AND_1_VALUE_PARAMS(p0)) {
2499  return new T(p0);
2500}
2501
2502ACTION_TEMPLATE(ReturnNew,
2503                HAS_1_TEMPLATE_PARAMS(typename, T),
2504                AND_2_VALUE_PARAMS(p0, p1)) {
2505  return new T(p0, p1);
2506}
2507
2508ACTION_TEMPLATE(ReturnNew,
2509                HAS_1_TEMPLATE_PARAMS(typename, T),
2510                AND_3_VALUE_PARAMS(p0, p1, p2)) {
2511  return new T(p0, p1, p2);
2512}
2513
2514ACTION_TEMPLATE(ReturnNew,
2515                HAS_1_TEMPLATE_PARAMS(typename, T),
2516                AND_4_VALUE_PARAMS(p0, p1, p2, p3)) {
2517  return new T(p0, p1, p2, p3);
2518}
2519
2520ACTION_TEMPLATE(ReturnNew,
2521                HAS_1_TEMPLATE_PARAMS(typename, T),
2522                AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) {
2523  return new T(p0, p1, p2, p3, p4);
2524}
2525
2526ACTION_TEMPLATE(ReturnNew,
2527                HAS_1_TEMPLATE_PARAMS(typename, T),
2528                AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) {
2529  return new T(p0, p1, p2, p3, p4, p5);
2530}
2531
2532ACTION_TEMPLATE(ReturnNew,
2533                HAS_1_TEMPLATE_PARAMS(typename, T),
2534                AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) {
2535  return new T(p0, p1, p2, p3, p4, p5, p6);
2536}
2537
2538ACTION_TEMPLATE(ReturnNew,
2539                HAS_1_TEMPLATE_PARAMS(typename, T),
2540                AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) {
2541  return new T(p0, p1, p2, p3, p4, p5, p6, p7);
2542}
2543
2544ACTION_TEMPLATE(ReturnNew,
2545                HAS_1_TEMPLATE_PARAMS(typename, T),
2546                AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) {
2547  return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8);
2548}
2549
2550ACTION_TEMPLATE(ReturnNew,
2551                HAS_1_TEMPLATE_PARAMS(typename, T),
2552                AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) {
2553  return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
2554}
2555
2556#ifdef _MSC_VER
2557# pragma warning(pop)
2558#endif
2559
2560}  // namespace testing
2561
2562// Include any custom callback actions added by the local installation.
2563// We must include this header at the end to make sure it can use the
2564// declarations from this file.
2565#include "gmock/internal/custom/gmock-generated-actions.h"
2566
2567#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
2568