blob: 3854279eb978cfef2f3ac9d080ba4b9d097e15a1 [file] [log] [blame]
shiqiane35fdd92008-12-10 05:08:54 +00001$$ -*- mode: c++; -*-
2$$ This is a Pump source file. Please use Pump to convert it to
3$$ gmock-generated-variadic-actions.h.
4$$
5$var n = 10 $$ The maximum arity we support.
6// Copyright 2007, Google Inc.
7// All rights reserved.
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// * Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15// * Redistributions in binary form must reproduce the above
16// copyright notice, this list of conditions and the following disclaimer
17// in the documentation and/or other materials provided with the
18// distribution.
19// * Neither the name of Google Inc. nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34//
35// Author: wan@google.com (Zhanyong Wan)
36
37// Google Mock - a framework for writing C++ mock classes.
38//
39// This file implements some commonly used variadic actions.
40
41#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
42#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
43
44#include <gmock/gmock-actions.h>
45#include <gmock/internal/gmock-port.h>
46
47namespace testing {
48namespace internal {
49
50// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
51// function or method with the unpacked values, where F is a function
52// type that takes N arguments.
53template <typename Result, typename ArgumentTuple>
54class InvokeHelper;
55
56
57$range i 0..n
58$for i [[
59$range j 1..i
60$var types = [[$for j [[, typename A$j]]]]
61$var as = [[$for j, [[A$j]]]]
62$var args = [[$if i==0 [[]] $else [[ args]]]]
63$var import = [[$if i==0 [[]] $else [[
64 using ::std::tr1::get;
65
66]]]]
67$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
68template <typename R$types>
69class InvokeHelper<R, ::std::tr1::tuple<$as> > {
70 public:
71 template <typename Function>
72 static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
73$import return function($gets);
74 }
75
76 template <class Class, typename MethodPtr>
77 static R InvokeMethod(Class* obj_ptr,
78 MethodPtr method_ptr,
79 const ::std::tr1::tuple<$as>&$args) {
80$import return (obj_ptr->*method_ptr)($gets);
81 }
82};
83
84
85]]
86
87// Implements the Invoke(f) action. The template argument
88// FunctionImpl is the implementation type of f, which can be either a
89// function pointer or a functor. Invoke(f) can be used as an
90// Action<F> as long as f's type is compatible with F (i.e. f can be
91// assigned to a tr1::function<F>).
92template <typename FunctionImpl>
93class InvokeAction {
94 public:
95 // The c'tor makes a copy of function_impl (either a function
96 // pointer or a functor).
97 explicit InvokeAction(FunctionImpl function_impl)
98 : function_impl_(function_impl) {}
99
100 template <typename Result, typename ArgumentTuple>
101 Result Perform(const ArgumentTuple& args) {
102 return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
103 }
104 private:
105 FunctionImpl function_impl_;
106};
107
108// Implements the Invoke(object_ptr, &Class::Method) action.
109template <class Class, typename MethodPtr>
110class InvokeMethodAction {
111 public:
112 InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
113 : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
114
115 template <typename Result, typename ArgumentTuple>
116 Result Perform(const ArgumentTuple& args) const {
117 return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
118 obj_ptr_, method_ptr_, args);
119 }
120 private:
121 Class* const obj_ptr_;
122 const MethodPtr method_ptr_;
123};
124
125// A ReferenceWrapper<T> object represents a reference to type T,
126// which can be either const or not. It can be explicitly converted
127// from, and implicitly converted to, a T&. Unlike a reference,
128// ReferenceWrapper<T> can be copied and can survive template type
129// inference. This is used to support by-reference arguments in the
130// InvokeArgument<N>(...) action. The idea was from "reference
131// wrappers" in tr1, which we don't have in our source tree yet.
132template <typename T>
133class ReferenceWrapper {
134 public:
135 // Constructs a ReferenceWrapper<T> object from a T&.
136 explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
137
138 // Allows a ReferenceWrapper<T> object to be implicitly converted to
139 // a T&.
140 operator T&() const { return *pointer_; }
141 private:
142 T* pointer_;
143};
144
145// CallableHelper has static methods for invoking "callables",
146// i.e. function pointers and functors. It uses overloading to
147// provide a uniform interface for invoking different kinds of
148// callables. In particular, you can use:
149//
150// CallableHelper<R>::Call(callable, a1, a2, ..., an)
151//
152// to invoke an n-ary callable, where R is its return type. If an
153// argument, say a2, needs to be passed by reference, you should write
154// ByRef(a2) instead of a2 in the above expression.
155template <typename R>
156class CallableHelper {
157 public:
158 // Calls a nullary callable.
159 template <typename Function>
160 static R Call(Function function) { return function(); }
161
162 // Calls a unary callable.
163
164 // We deliberately pass a1 by value instead of const reference here
165 // in case it is a C-string literal. If we had declared the
166 // parameter as 'const A1& a1' and write Call(function, "Hi"), the
167 // compiler would've thought A1 is 'char[3]', which causes trouble
168 // when you need to copy a value of type A1. By declaring the
169 // parameter as 'A1 a1', the compiler will correctly infer that A1
170 // is 'const char*' when it sees Call(function, "Hi").
171 //
172 // Since this function is defined inline, the compiler can get rid
173 // of the copying of the arguments. Therefore the performance won't
174 // be hurt.
175 template <typename Function, typename A1>
176 static R Call(Function function, A1 a1) { return function(a1); }
177
178$range i 2..n
179$for i
180[[
181$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
182
183 // Calls a $arity callable.
184
185$range j 1..i
186$var typename_As = [[$for j, [[typename A$j]]]]
187$var Aas = [[$for j, [[A$j a$j]]]]
188$var as = [[$for j, [[a$j]]]]
189$var typename_Ts = [[$for j, [[typename T$j]]]]
190$var Ts = [[$for j, [[T$j]]]]
191 template <typename Function, $typename_As>
192 static R Call(Function function, $Aas) {
193 return function($as);
194 }
195
196]]
197
198}; // class CallableHelper
199
200// Invokes a nullary callable argument.
201template <size_t N>
202class InvokeArgumentAction0 {
203 public:
204 template <typename Result, typename ArgumentTuple>
205 static Result Perform(const ArgumentTuple& args) {
206 return CallableHelper<Result>::Call(::std::tr1::get<N>(args));
207 }
208};
209
210// Invokes a unary callable argument with the given argument.
211template <size_t N, typename A1>
212class InvokeArgumentAction1 {
213 public:
214 // We deliberately pass a1 by value instead of const reference here
215 // in case it is a C-string literal.
216 //
217 // Since this function is defined inline, the compiler can get rid
218 // of the copying of the arguments. Therefore the performance won't
219 // be hurt.
220 explicit InvokeArgumentAction1(A1 a1) : arg1_(a1) {}
221
222 template <typename Result, typename ArgumentTuple>
223 Result Perform(const ArgumentTuple& args) {
224 return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_);
225 }
226 private:
227 const A1 arg1_;
228};
229
230$range i 2..n
231$for i [[
232$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
233$range j 1..i
234$var typename_As = [[$for j, [[typename A$j]]]]
235$var args_ = [[$for j, [[arg$j[[]]_]]]]
236
237// Invokes a $arity callable argument with the given arguments.
238template <size_t N, $typename_As>
239class InvokeArgumentAction$i {
240 public:
241 InvokeArgumentAction$i($for j, [[A$j a$j]]) :
242 $for j, [[arg$j[[]]_(a$j)]] {}
243
244 template <typename Result, typename ArgumentTuple>
245 Result Perform(const ArgumentTuple& args) {
246$if i <= 4 [[
247
248 return CallableHelper<Result>::Call(::std::tr1::get<N>(args), $args_);
249
250]] $else [[
251
252 // We extract the callable to a variable before invoking it, in
253 // case it is a functor passed by value and its operator() is not
254 // const.
255 typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
256 ::std::tr1::get<N>(args);
257 return function($args_);
258
259]]
260 }
261 private:
262$for j [[
263
264 const A$j arg$j[[]]_;
265]]
266
267};
268
269]]
270
271// An INTERNAL macro for extracting the type of a tuple field. It's
272// subject to change without notice - DO NOT USE IN USER CODE!
zhanyong.wane0d051e2009-02-19 00:33:37 +0000273#define GMOCK_FIELD_(Tuple, N) \
shiqiane35fdd92008-12-10 05:08:54 +0000274 typename ::std::tr1::tuple_element<N, Tuple>::type
275
276$range i 1..n
277
278// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
279// type of an n-ary function whose i-th (1-based) argument type is the
280// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
281// type, and whose return type is Result. For example,
282// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
283// is int(bool, long).
284//
285// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
286// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
287// For example,
288// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
289// ::std::tr1::make_tuple(true, 'a', 2.5))
290// returns ::std::tr1::tuple (2.5, true).
291//
292// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
293// in the range [0, $n]. Duplicates are allowed and they don't have
294// to be in an ascending or descending order.
295
296template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
297class SelectArgs {
298 public:
zhanyong.wane0d051e2009-02-19 00:33:37 +0000299 typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
shiqiane35fdd92008-12-10 05:08:54 +0000300 typedef typename Function<type>::ArgumentTuple SelectedArgs;
301 static SelectedArgs Select(const ArgumentTuple& args) {
302 using ::std::tr1::get;
303 return SelectedArgs($for i, [[get<k$i>(args)]]);
304 }
305};
306
307
308$for i [[
309$range j 1..n
310$range j1 1..i-1
311template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
312class SelectArgs<Result, ArgumentTuple,
313 $for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
314 public:
zhanyong.wane0d051e2009-02-19 00:33:37 +0000315 typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
shiqiane35fdd92008-12-10 05:08:54 +0000316 typedef typename Function<type>::ArgumentTuple SelectedArgs;
zhanyong.wan3fbd2dd2009-03-26 19:06:45 +0000317 static SelectedArgs Select(const ArgumentTuple& [[]]
318$if i == 1 [[/* args */]] $else [[args]]) {
shiqiane35fdd92008-12-10 05:08:54 +0000319 using ::std::tr1::get;
320 return SelectedArgs($for j1, [[get<k$j1>(args)]]);
321 }
322};
323
324
325]]
zhanyong.wane0d051e2009-02-19 00:33:37 +0000326#undef GMOCK_FIELD_
shiqiane35fdd92008-12-10 05:08:54 +0000327
328$var ks = [[$for i, [[k$i]]]]
329
330// Implements the WithArgs action.
331template <typename InnerAction, $for i, [[int k$i = -1]]>
332class WithArgsAction {
333 public:
334 explicit WithArgsAction(const InnerAction& action) : action_(action) {}
335
336 template <typename F>
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000337 operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
338
339 private:
340 template <typename F>
341 class Impl : public ActionInterface<F> {
342 public:
shiqiane35fdd92008-12-10 05:08:54 +0000343 typedef typename Function<F>::Result Result;
344 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000345
346 explicit Impl(const InnerAction& action) : action_(action) {}
347
348 virtual Result Perform(const ArgumentTuple& args) {
349 return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
350 }
351
352 private:
shiqiane35fdd92008-12-10 05:08:54 +0000353 typedef typename SelectArgs<Result, ArgumentTuple,
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000354 $ks>::type InnerFunctionType;
shiqiane35fdd92008-12-10 05:08:54 +0000355
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000356 Action<InnerFunctionType> action_;
357 };
shiqiane35fdd92008-12-10 05:08:54 +0000358
shiqiane35fdd92008-12-10 05:08:54 +0000359 const InnerAction action_;
360};
361
362// Does two actions sequentially. Used for implementing the DoAll(a1,
363// a2, ...) action.
364template <typename Action1, typename Action2>
365class DoBothAction {
366 public:
367 DoBothAction(Action1 action1, Action2 action2)
368 : action1_(action1), action2_(action2) {}
369
370 // This template type conversion operator allows DoAll(a1, ..., a_n)
371 // to be used in ANY function of compatible type.
372 template <typename F>
373 operator Action<F>() const {
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000374 return Action<F>(new Impl<F>(action1_, action2_));
375 }
376
377 private:
378 // Implements the DoAll(...) action for a particular function type F.
379 template <typename F>
380 class Impl : public ActionInterface<F> {
381 public:
shiqiane35fdd92008-12-10 05:08:54 +0000382 typedef typename Function<F>::Result Result;
383 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
384 typedef typename Function<F>::MakeResultVoid VoidResult;
385
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000386 Impl(const Action<VoidResult>& action1, const Action<F>& action2)
387 : action1_(action1), action2_(action2) {}
shiqiane35fdd92008-12-10 05:08:54 +0000388
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000389 virtual Result Perform(const ArgumentTuple& args) {
390 action1_.Perform(args);
391 return action2_.Perform(args);
392 }
shiqiane35fdd92008-12-10 05:08:54 +0000393
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000394 private:
395 const Action<VoidResult> action1_;
396 const Action<F> action2_;
397 };
398
shiqiane35fdd92008-12-10 05:08:54 +0000399 Action1 action1_;
400 Action2 action2_;
401};
402
shiqian326aa562009-01-09 21:43:57 +0000403// A macro from the ACTION* family (defined later in this file)
404// defines an action that can be used in a mock function. Typically,
405// these actions only care about a subset of the arguments of the mock
406// function. For example, if such an action only uses the second
407// argument, it can be used in any mock function that takes >= 2
408// arguments where the type of the second argument is compatible.
409//
410// Therefore, the action implementation must be prepared to take more
411// arguments than it needs. The ExcessiveArg type is used to
412// represent those excessive arguments. In order to keep the compiler
413// error messages tractable, we define it in the testing namespace
414// instead of testing::internal. However, this is an INTERNAL TYPE
415// and subject to change without notice, so a user MUST NOT USE THIS
416// TYPE DIRECTLY.
417struct ExcessiveArg {};
418
419// A helper class needed for implementing the ACTION* macros.
420template <typename Result, class Impl>
421class ActionHelper {
422 public:
423$range i 0..n
424$for i
425
426[[
427$var template = [[$if i==0 [[]] $else [[
428$range j 0..i-1
429 template <$for j, [[typename A$j]]>
430]]]]
431$range j 0..i-1
432$var As = [[$for j, [[A$j]]]]
433$var as = [[$for j, [[get<$j>(args)]]]]
434$range k 1..n-i
435$var eas = [[$for k, [[ExcessiveArg()]]]]
436$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
437$template
438 static Result Perform(Impl* impl, const ::std::tr1::tuple<$As>& args) {
439 using ::std::tr1::get;
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000440 return impl->template gmock_PerformImpl<$As>(args, $arg_list);
shiqian326aa562009-01-09 21:43:57 +0000441 }
442
443]]
444};
445
shiqiane35fdd92008-12-10 05:08:54 +0000446} // namespace internal
447
448// Various overloads for Invoke().
449
450// Creates an action that invokes 'function_impl' with the mock
451// function's arguments.
452template <typename FunctionImpl>
453PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
454 FunctionImpl function_impl) {
455 return MakePolymorphicAction(
456 internal::InvokeAction<FunctionImpl>(function_impl));
457}
458
459// Creates an action that invokes the given method on the given object
460// with the mock function's arguments.
461template <class Class, typename MethodPtr>
462PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
463 Class* obj_ptr, MethodPtr method_ptr) {
464 return MakePolymorphicAction(
465 internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
466}
467
468// Creates a reference wrapper for the given L-value. If necessary,
469// you can explicitly specify the type of the reference. For example,
470// suppose 'derived' is an object of type Derived, ByRef(derived)
471// would wrap a Derived&. If you want to wrap a const Base& instead,
472// where Base is a base class of Derived, just write:
473//
474// ByRef<const Base>(derived)
475template <typename T>
476inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
477 return internal::ReferenceWrapper<T>(l_value);
478}
479
480// Various overloads for InvokeArgument<N>().
481//
482// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
483// (0-based) argument, which must be a k-ary callable, of the mock
484// function, with arguments a1, a2, ..., a_k.
485//
486// Notes:
487//
488// 1. The arguments are passed by value by default. If you need to
489// pass an argument by reference, wrap it inside ByRef(). For
490// example,
491//
492// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
493//
494// passes 5 and string("Hello") by value, and passes foo by
495// reference.
496//
497// 2. If the callable takes an argument by reference but ByRef() is
498// not used, it will receive the reference to a copy of the value,
499// instead of the original value. For example, when the 0-th
500// argument of the mock function takes a const string&, the action
501//
502// InvokeArgument<0>(string("Hello"))
503//
504// makes a copy of the temporary string("Hello") object and passes a
505// reference of the copy, instead of the original temporary object,
506// to the callable. This makes it easy for a user to define an
507// InvokeArgument action from temporary values and have it performed
508// later.
509template <size_t N>
510inline PolymorphicAction<internal::InvokeArgumentAction0<N> > InvokeArgument() {
511 return MakePolymorphicAction(internal::InvokeArgumentAction0<N>());
512}
513
514// We deliberately pass a1 by value instead of const reference here in
515// case it is a C-string literal. If we had declared the parameter as
516// 'const A1& a1' and write InvokeArgument<0>("Hi"), the compiler
517// would've thought A1 is 'char[3]', which causes trouble as the
518// implementation needs to copy a value of type A1. By declaring the
519// parameter as 'A1 a1', the compiler will correctly infer that A1 is
520// 'const char*' when it sees InvokeArgument<0>("Hi").
521//
522// Since this function is defined inline, the compiler can get rid of
523// the copying of the arguments. Therefore the performance won't be
524// hurt.
525template <size_t N, typename A1>
526inline PolymorphicAction<internal::InvokeArgumentAction1<N, A1> >
527InvokeArgument(A1 a1) {
528 return MakePolymorphicAction(internal::InvokeArgumentAction1<N, A1>(a1));
529}
530
531$range i 2..n
532$for i [[
533$range j 1..i
534$var typename_As = [[$for j, [[typename A$j]]]]
535$var As = [[$for j, [[A$j]]]]
536$var Aas = [[$for j, [[A$j a$j]]]]
537$var as = [[$for j, [[a$j]]]]
538
539template <size_t N, $typename_As>
540inline PolymorphicAction<internal::InvokeArgumentAction$i<N, $As> >
541InvokeArgument($Aas) {
542 return MakePolymorphicAction(
543 internal::InvokeArgumentAction$i<N, $As>($as));
544}
545
546]]
547
548// WithoutArgs(inner_action) can be used in a mock function with a
549// non-empty argument list to perform inner_action, which takes no
550// argument. In other words, it adapts an action accepting no
551// argument to one that accepts (and ignores) arguments.
552template <typename InnerAction>
553inline internal::WithArgsAction<InnerAction>
554WithoutArgs(const InnerAction& action) {
555 return internal::WithArgsAction<InnerAction>(action);
556}
557
558// WithArg<k>(an_action) creates an action that passes the k-th
559// (0-based) argument of the mock function to an_action and performs
560// it. It adapts an action accepting one argument to one that accepts
561// multiple arguments. For convenience, we also provide
562// WithArgs<k>(an_action) (defined below) as a synonym.
563template <int k, typename InnerAction>
564inline internal::WithArgsAction<InnerAction, k>
565WithArg(const InnerAction& action) {
566 return internal::WithArgsAction<InnerAction, k>(action);
567}
568
569// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
570// the selected arguments of the mock function to an_action and
571// performs it. It serves as an adaptor between actions with
572// different argument lists. C++ doesn't support default arguments for
573// function templates, so we have to overload it.
574
575$range i 1..n
576$for i [[
577$range j 1..i
578template <$for j [[int k$j, ]]typename InnerAction>
579inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
580WithArgs(const InnerAction& action) {
581 return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
582}
583
584
585]]
586// Creates an action that does actions a1, a2, ..., sequentially in
587// each invocation.
588$range i 2..n
589$for i [[
590$range j 2..i
591$var types = [[$for j, [[typename Action$j]]]]
592$var Aas = [[$for j [[, Action$j a$j]]]]
593
594template <typename Action1, $types>
595$range k 1..i-1
596
597inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
598
599DoAll(Action1 a1$Aas) {
600$if i==2 [[
601
602 return internal::DoBothAction<Action1, Action2>(a1, a2);
603]] $else [[
604$range j2 2..i
605
606 return DoAll(a1, DoAll($for j2, [[a$j2]]));
607]]
608
609}
610
611]]
612
613} // namespace testing
614
shiqian326aa562009-01-09 21:43:57 +0000615// The ACTION* family of macros can be used in a namespace scope to
616// define custom actions easily. The syntax:
617//
618// ACTION(name) { statements; }
619//
620// will define an action with the given name that executes the
621// statements. The value returned by the statements will be used as
622// the return value of the action. Inside the statements, you can
623// refer to the K-th (0-based) argument of the mock function by
624// 'argK', and refer to its type by 'argK_type'. For example:
625//
626// ACTION(IncrementArg1) {
627// arg1_type temp = arg1;
628// return ++(*temp);
629// }
630//
631// allows you to write
632//
633// ...WillOnce(IncrementArg1());
634//
635// You can also refer to the entire argument tuple and its type by
636// 'args' and 'args_type', and refer to the mock function type and its
637// return type by 'function_type' and 'return_type'.
638//
639// Note that you don't need to specify the types of the mock function
640// arguments. However rest assured that your code is still type-safe:
641// you'll get a compiler error if *arg1 doesn't support the ++
642// operator, or if the type of ++(*arg1) isn't compatible with the
643// mock function's return type, for example.
644//
645// Sometimes you'll want to parameterize the action. For that you can use
646// another macro:
647//
648// ACTION_P(name, param_name) { statements; }
649//
650// For example:
651//
652// ACTION_P(Add, n) { return arg0 + n; }
653//
654// will allow you to write:
655//
656// ...WillOnce(Add(5));
657//
658// Note that you don't need to provide the type of the parameter
659// either. If you need to reference the type of a parameter named
660// 'foo', you can write 'foo_type'. For example, in the body of
661// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
662// of 'n'.
663//
664// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
665// multi-parameter actions.
666//
667// For the purpose of typing, you can view
668//
669// ACTION_Pk(Foo, p1, ..., pk) { ... }
670//
671// as shorthand for
672//
673// template <typename p1_type, ..., typename pk_type>
674// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
675//
676// In particular, you can provide the template type arguments
677// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
678// although usually you can rely on the compiler to infer the types
679// for you automatically. You can assign the result of expression
680// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
681// pk_type>. This can be useful when composing actions.
682//
683// You can also overload actions with different numbers of parameters:
684//
685// ACTION_P(Plus, a) { ... }
686// ACTION_P2(Plus, a, b) { ... }
687//
688// While it's tempting to always use the ACTION* macros when defining
689// a new action, you should also consider implementing ActionInterface
690// or using MakePolymorphicAction() instead, especially if you need to
691// use the action a lot. While these approaches require more work,
692// they give you more control on the types of the mock function
693// arguments and the action parameters, which in general leads to
694// better compiler error messages that pay off in the long run. They
695// also allow overloading actions based on parameter types (as opposed
696// to just based on the number of parameters).
697//
698// CAVEAT:
699//
700// ACTION*() can only be used in a namespace scope. The reason is
701// that C++ doesn't yet allow function-local types to be used to
702// instantiate templates. The up-coming C++0x standard will fix this.
703// Once that's done, we'll consider supporting using ACTION*() inside
704// a function.
705//
706// MORE INFORMATION:
707//
708// To learn more about using these macros, please search for 'ACTION'
709// on http://code.google.com/p/googlemock/wiki/CookBook.
710
711$range i 0..n
712$for i
713
714[[
715$var template = [[$if i==0 [[]] $else [[
716$range j 0..i-1
717
718 template <$for j, [[typename p$j##_type]]>\
719]]]]
720$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
721 $else [[P$i]]]]]]
722$range j 0..i-1
723$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
724$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
725$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000726$var param_field_decls = [[$for j
shiqian326aa562009-01-09 21:43:57 +0000727[[
728
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000729 p$j##_type p$j;\
shiqian326aa562009-01-09 21:43:57 +0000730]]]]
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000731$var param_field_decls2 = [[$for j
shiqian326aa562009-01-09 21:43:57 +0000732[[
733
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000734 p$j##_type p$j;\
shiqian326aa562009-01-09 21:43:57 +0000735]]]]
736$var params = [[$for j, [[p$j]]]]
737$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
738$range k 0..n-1
739$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
740$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
741$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
742 $else [[ACTION_P$i]]]]
743
744#define $macro_name(name$for j [[, p$j]])\$template
745 class $class_name {\
746 public:\
747 $class_name($ctor_param_list)$inits {}\
748 template <typename F>\
749 class gmock_Impl : public ::testing::ActionInterface<F> {\
750 public:\
751 typedef F function_type;\
752 typedef typename ::testing::internal::Function<F>::Result return_type;\
753 typedef typename ::testing::internal::Function<F>::ArgumentTuple\
754 args_type;\
755 [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
756 virtual return_type Perform(const args_type& args) {\
757 return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
758 Perform(this, args);\
759 }\
760 template <$typename_arg_types>\
761 return_type gmock_PerformImpl(const args_type& args, [[]]
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000762$arg_types_and_names) const;\$param_field_decls
shiqian326aa562009-01-09 21:43:57 +0000763 };\
764 template <typename F> operator ::testing::Action<F>() const {\
765 return ::testing::Action<F>(new gmock_Impl<F>($params));\
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000766 }\$param_field_decls2
shiqian326aa562009-01-09 21:43:57 +0000767 };\$template
768 inline $class_name$param_types name($param_types_and_names) {\
769 return $class_name$param_types($params);\
770 }\$template
771 template <typename F>\
772 template <$typename_arg_types>\
773 typename ::testing::internal::Function<F>::Result\
774 $class_name$param_types::\
775 gmock_Impl<F>::gmock_PerformImpl(const args_type& args, [[]]
776$arg_types_and_names) const
777]]
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000778$$ } // This meta comment fixes auto-indentation in Emacs. It won't
779$$ // show up in the generated code.
shiqian326aa562009-01-09 21:43:57 +0000780
781
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000782// TODO(wan@google.com): move the following to a different .h file
783// such that we don't have to run 'pump' every time the code is
784// updated.
zhanyong.wane1cdce52009-02-06 01:09:43 +0000785namespace testing {
786
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000787namespace internal {
788
789// Saves argument #0 to where the pointer points.
790ACTION_P(SaveArg0, pointer) { *pointer = arg0; }
791
792// Assigns 'value' to the variable referenced by argument #0.
793ACTION_P(SetArg0Referee, value) {
794 // Ensures that argument #0 is a reference. If you get a compiler
795 // error on the next line, you are using SetArgReferee<k>(value) in
796 // a mock function whose k-th (0-based) argument is not a reference.
797 GMOCK_COMPILE_ASSERT_(internal::is_reference<arg0_type>::value,
798 SetArgReferee_must_be_used_with_a_reference_argument);
799 arg0 = value;
800}
801
802} // namespace internal
803
804// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
805// mock function to *pointer.
806template <int k, typename Pointer>
807inline internal::WithArgsAction<internal::SaveArg0ActionP<Pointer>, k>
808SaveArg(const Pointer& pointer) {
809 return WithArg<k>(internal::SaveArg0(pointer));
810}
811
812// Action SetArgReferee<k>(value) assigns 'value' to the variable
813// referenced by the k-th (0-based) argument of the mock function.
814template <int k, typename Value>
815inline internal::WithArgsAction<internal::SetArg0RefereeActionP<Value>, k>
816SetArgReferee(const Value& value) {
817 return WithArg<k>(internal::SetArg0Referee(value));
818}
819
zhanyong.wane1cdce52009-02-06 01:09:43 +0000820// Action Throw(exception) can be used in a mock function of any type
821// to throw the given exception. Any copyable value can be thrown.
822#if GTEST_HAS_EXCEPTIONS
823ACTION_P(Throw, exception) { throw exception; }
824#endif // GTEST_HAS_EXCEPTIONS
825
826} // namespace testing
827
shiqiane35fdd92008-12-10 05:08:54 +0000828#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_