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