blob: 2a7e4ffd545e2b0e7622ce2d20627855f375f72b [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.
zhanyong.wan18490652009-05-11 18:54:08 +00006$$}} This meta comment fixes auto-indentation in editors.
shiqiane35fdd92008-12-10 05:08:54 +00007// Copyright 2007, Google Inc.
8// All rights reserved.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// * Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16// * Redistributions in binary form must reproduce the above
17// copyright notice, this list of conditions and the following disclaimer
18// in the documentation and/or other materials provided with the
19// distribution.
20// * Neither the name of Google Inc. nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Author: wan@google.com (Zhanyong Wan)
37
38// Google Mock - a framework for writing C++ mock classes.
39//
40// This file implements some commonly used variadic actions.
41
42#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
43#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
44
45#include <gmock/gmock-actions.h>
zhanyong.wan387bdd52009-07-20 21:16:35 +000046#include <gmock/gmock-printers.h>
shiqiane35fdd92008-12-10 05:08:54 +000047#include <gmock/internal/gmock-port.h>
48
49namespace testing {
50namespace internal {
51
52// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
53// function or method with the unpacked values, where F is a function
54// type that takes N arguments.
55template <typename Result, typename ArgumentTuple>
56class InvokeHelper;
57
58
59$range i 0..n
60$for i [[
61$range j 1..i
62$var types = [[$for j [[, typename A$j]]]]
63$var as = [[$for j, [[A$j]]]]
64$var args = [[$if i==0 [[]] $else [[ args]]]]
65$var import = [[$if i==0 [[]] $else [[
66 using ::std::tr1::get;
67
68]]]]
69$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
70template <typename R$types>
71class InvokeHelper<R, ::std::tr1::tuple<$as> > {
72 public:
73 template <typename Function>
74 static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
75$import return function($gets);
76 }
77
78 template <class Class, typename MethodPtr>
79 static R InvokeMethod(Class* obj_ptr,
80 MethodPtr method_ptr,
81 const ::std::tr1::tuple<$as>&$args) {
82$import return (obj_ptr->*method_ptr)($gets);
83 }
84};
85
86
87]]
88
89// Implements the Invoke(f) action. The template argument
90// FunctionImpl is the implementation type of f, which can be either a
91// function pointer or a functor. Invoke(f) can be used as an
92// Action<F> as long as f's type is compatible with F (i.e. f can be
93// assigned to a tr1::function<F>).
94template <typename FunctionImpl>
95class InvokeAction {
96 public:
97 // The c'tor makes a copy of function_impl (either a function
98 // pointer or a functor).
99 explicit InvokeAction(FunctionImpl function_impl)
100 : function_impl_(function_impl) {}
101
102 template <typename Result, typename ArgumentTuple>
103 Result Perform(const ArgumentTuple& args) {
104 return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
105 }
106 private:
107 FunctionImpl function_impl_;
108};
109
110// Implements the Invoke(object_ptr, &Class::Method) action.
111template <class Class, typename MethodPtr>
112class InvokeMethodAction {
113 public:
114 InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
115 : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
116
117 template <typename Result, typename ArgumentTuple>
118 Result Perform(const ArgumentTuple& args) const {
119 return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
120 obj_ptr_, method_ptr_, args);
121 }
122 private:
123 Class* const obj_ptr_;
124 const MethodPtr method_ptr_;
125};
126
zhanyong.wan387bdd52009-07-20 21:16:35 +0000127// TODO(wan@google.com): ReferenceWrapper and ByRef() are neither
128// action-specific nor variadic. Move them to a better place.
129
shiqiane35fdd92008-12-10 05:08:54 +0000130// A ReferenceWrapper<T> object represents a reference to type T,
131// which can be either const or not. It can be explicitly converted
132// from, and implicitly converted to, a T&. Unlike a reference,
133// ReferenceWrapper<T> can be copied and can survive template type
134// inference. This is used to support by-reference arguments in the
135// InvokeArgument<N>(...) action. The idea was from "reference
136// wrappers" in tr1, which we don't have in our source tree yet.
137template <typename T>
138class ReferenceWrapper {
139 public:
140 // Constructs a ReferenceWrapper<T> object from a T&.
141 explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
142
143 // Allows a ReferenceWrapper<T> object to be implicitly converted to
144 // a T&.
145 operator T&() const { return *pointer_; }
146 private:
147 T* pointer_;
148};
149
zhanyong.wan387bdd52009-07-20 21:16:35 +0000150// Allows the expression ByRef(x) to be printed as a reference to x.
151template <typename T>
152void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
153 T& value = ref;
154 UniversalPrinter<T&>::Print(value, os);
155}
156
shiqiane35fdd92008-12-10 05:08:54 +0000157// CallableHelper has static methods for invoking "callables",
158// i.e. function pointers and functors. It uses overloading to
159// provide a uniform interface for invoking different kinds of
160// callables. In particular, you can use:
161//
162// CallableHelper<R>::Call(callable, a1, a2, ..., an)
163//
164// to invoke an n-ary callable, where R is its return type. If an
165// argument, say a2, needs to be passed by reference, you should write
166// ByRef(a2) instead of a2 in the above expression.
167template <typename R>
168class CallableHelper {
169 public:
170 // Calls a nullary callable.
171 template <typename Function>
172 static R Call(Function function) { return function(); }
173
174 // Calls a unary callable.
175
176 // We deliberately pass a1 by value instead of const reference here
177 // in case it is a C-string literal. If we had declared the
178 // parameter as 'const A1& a1' and write Call(function, "Hi"), the
179 // compiler would've thought A1 is 'char[3]', which causes trouble
180 // when you need to copy a value of type A1. By declaring the
181 // parameter as 'A1 a1', the compiler will correctly infer that A1
182 // is 'const char*' when it sees Call(function, "Hi").
183 //
184 // Since this function is defined inline, the compiler can get rid
185 // of the copying of the arguments. Therefore the performance won't
186 // be hurt.
187 template <typename Function, typename A1>
188 static R Call(Function function, A1 a1) { return function(a1); }
189
190$range i 2..n
191$for i
192[[
193$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
194
195 // Calls a $arity callable.
196
197$range j 1..i
198$var typename_As = [[$for j, [[typename A$j]]]]
199$var Aas = [[$for j, [[A$j a$j]]]]
200$var as = [[$for j, [[a$j]]]]
201$var typename_Ts = [[$for j, [[typename T$j]]]]
202$var Ts = [[$for j, [[T$j]]]]
203 template <typename Function, $typename_As>
204 static R Call(Function function, $Aas) {
205 return function($as);
206 }
207
208]]
209
210}; // class CallableHelper
211
shiqiane35fdd92008-12-10 05:08:54 +0000212// An INTERNAL macro for extracting the type of a tuple field. It's
213// subject to change without notice - DO NOT USE IN USER CODE!
zhanyong.wane0d051e2009-02-19 00:33:37 +0000214#define GMOCK_FIELD_(Tuple, N) \
shiqiane35fdd92008-12-10 05:08:54 +0000215 typename ::std::tr1::tuple_element<N, Tuple>::type
216
217$range i 1..n
218
219// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
220// type of an n-ary function whose i-th (1-based) argument type is the
221// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
222// type, and whose return type is Result. For example,
223// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
224// is int(bool, long).
225//
226// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
227// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
228// For example,
229// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
230// ::std::tr1::make_tuple(true, 'a', 2.5))
231// returns ::std::tr1::tuple (2.5, true).
232//
233// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
234// in the range [0, $n]. Duplicates are allowed and they don't have
235// to be in an ascending or descending order.
236
237template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
238class SelectArgs {
239 public:
zhanyong.wane0d051e2009-02-19 00:33:37 +0000240 typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
shiqiane35fdd92008-12-10 05:08:54 +0000241 typedef typename Function<type>::ArgumentTuple SelectedArgs;
242 static SelectedArgs Select(const ArgumentTuple& args) {
243 using ::std::tr1::get;
244 return SelectedArgs($for i, [[get<k$i>(args)]]);
245 }
246};
247
248
249$for i [[
250$range j 1..n
251$range j1 1..i-1
252template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
253class SelectArgs<Result, ArgumentTuple,
254 $for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
255 public:
zhanyong.wane0d051e2009-02-19 00:33:37 +0000256 typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
shiqiane35fdd92008-12-10 05:08:54 +0000257 typedef typename Function<type>::ArgumentTuple SelectedArgs;
zhanyong.wan3fbd2dd2009-03-26 19:06:45 +0000258 static SelectedArgs Select(const ArgumentTuple& [[]]
259$if i == 1 [[/* args */]] $else [[args]]) {
shiqiane35fdd92008-12-10 05:08:54 +0000260 using ::std::tr1::get;
261 return SelectedArgs($for j1, [[get<k$j1>(args)]]);
262 }
263};
264
265
266]]
zhanyong.wane0d051e2009-02-19 00:33:37 +0000267#undef GMOCK_FIELD_
shiqiane35fdd92008-12-10 05:08:54 +0000268
269$var ks = [[$for i, [[k$i]]]]
270
271// Implements the WithArgs action.
272template <typename InnerAction, $for i, [[int k$i = -1]]>
273class WithArgsAction {
274 public:
275 explicit WithArgsAction(const InnerAction& action) : action_(action) {}
276
277 template <typename F>
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000278 operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
279
280 private:
281 template <typename F>
282 class Impl : public ActionInterface<F> {
283 public:
shiqiane35fdd92008-12-10 05:08:54 +0000284 typedef typename Function<F>::Result Result;
285 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000286
287 explicit Impl(const InnerAction& action) : action_(action) {}
288
289 virtual Result Perform(const ArgumentTuple& args) {
290 return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
291 }
292
293 private:
shiqiane35fdd92008-12-10 05:08:54 +0000294 typedef typename SelectArgs<Result, ArgumentTuple,
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000295 $ks>::type InnerFunctionType;
shiqiane35fdd92008-12-10 05:08:54 +0000296
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000297 Action<InnerFunctionType> action_;
298 };
shiqiane35fdd92008-12-10 05:08:54 +0000299
shiqiane35fdd92008-12-10 05:08:54 +0000300 const InnerAction action_;
301};
302
303// Does two actions sequentially. Used for implementing the DoAll(a1,
304// a2, ...) action.
305template <typename Action1, typename Action2>
306class DoBothAction {
307 public:
308 DoBothAction(Action1 action1, Action2 action2)
309 : action1_(action1), action2_(action2) {}
310
311 // This template type conversion operator allows DoAll(a1, ..., a_n)
312 // to be used in ANY function of compatible type.
313 template <typename F>
314 operator Action<F>() const {
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000315 return Action<F>(new Impl<F>(action1_, action2_));
316 }
317
318 private:
319 // Implements the DoAll(...) action for a particular function type F.
320 template <typename F>
321 class Impl : public ActionInterface<F> {
322 public:
shiqiane35fdd92008-12-10 05:08:54 +0000323 typedef typename Function<F>::Result Result;
324 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
325 typedef typename Function<F>::MakeResultVoid VoidResult;
326
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000327 Impl(const Action<VoidResult>& action1, const Action<F>& action2)
328 : action1_(action1), action2_(action2) {}
shiqiane35fdd92008-12-10 05:08:54 +0000329
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000330 virtual Result Perform(const ArgumentTuple& args) {
331 action1_.Perform(args);
332 return action2_.Perform(args);
333 }
shiqiane35fdd92008-12-10 05:08:54 +0000334
zhanyong.wan38ca64d2009-02-19 22:30:22 +0000335 private:
336 const Action<VoidResult> action1_;
337 const Action<F> action2_;
338 };
339
shiqiane35fdd92008-12-10 05:08:54 +0000340 Action1 action1_;
341 Action2 action2_;
342};
343
shiqian326aa562009-01-09 21:43:57 +0000344// A macro from the ACTION* family (defined later in this file)
345// defines an action that can be used in a mock function. Typically,
346// these actions only care about a subset of the arguments of the mock
347// function. For example, if such an action only uses the second
348// argument, it can be used in any mock function that takes >= 2
349// arguments where the type of the second argument is compatible.
350//
351// Therefore, the action implementation must be prepared to take more
352// arguments than it needs. The ExcessiveArg type is used to
353// represent those excessive arguments. In order to keep the compiler
354// error messages tractable, we define it in the testing namespace
355// instead of testing::internal. However, this is an INTERNAL TYPE
356// and subject to change without notice, so a user MUST NOT USE THIS
357// TYPE DIRECTLY.
358struct ExcessiveArg {};
359
360// A helper class needed for implementing the ACTION* macros.
361template <typename Result, class Impl>
362class ActionHelper {
363 public:
364$range i 0..n
365$for i
366
367[[
368$var template = [[$if i==0 [[]] $else [[
369$range j 0..i-1
370 template <$for j, [[typename A$j]]>
371]]]]
372$range j 0..i-1
373$var As = [[$for j, [[A$j]]]]
374$var as = [[$for j, [[get<$j>(args)]]]]
375$range k 1..n-i
376$var eas = [[$for k, [[ExcessiveArg()]]]]
377$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
378$template
379 static Result Perform(Impl* impl, const ::std::tr1::tuple<$As>& args) {
380 using ::std::tr1::get;
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000381 return impl->template gmock_PerformImpl<$As>(args, $arg_list);
shiqian326aa562009-01-09 21:43:57 +0000382 }
383
384]]
385};
386
shiqiane35fdd92008-12-10 05:08:54 +0000387} // namespace internal
388
389// Various overloads for Invoke().
390
391// Creates an action that invokes 'function_impl' with the mock
392// function's arguments.
393template <typename FunctionImpl>
394PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
395 FunctionImpl function_impl) {
396 return MakePolymorphicAction(
397 internal::InvokeAction<FunctionImpl>(function_impl));
398}
399
400// Creates an action that invokes the given method on the given object
401// with the mock function's arguments.
402template <class Class, typename MethodPtr>
403PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
404 Class* obj_ptr, MethodPtr method_ptr) {
405 return MakePolymorphicAction(
406 internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
407}
408
409// Creates a reference wrapper for the given L-value. If necessary,
410// you can explicitly specify the type of the reference. For example,
411// suppose 'derived' is an object of type Derived, ByRef(derived)
412// would wrap a Derived&. If you want to wrap a const Base& instead,
413// where Base is a base class of Derived, just write:
414//
415// ByRef<const Base>(derived)
416template <typename T>
417inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
418 return internal::ReferenceWrapper<T>(l_value);
419}
420
shiqiane35fdd92008-12-10 05:08:54 +0000421// WithoutArgs(inner_action) can be used in a mock function with a
422// non-empty argument list to perform inner_action, which takes no
423// argument. In other words, it adapts an action accepting no
424// argument to one that accepts (and ignores) arguments.
425template <typename InnerAction>
426inline internal::WithArgsAction<InnerAction>
427WithoutArgs(const InnerAction& action) {
428 return internal::WithArgsAction<InnerAction>(action);
429}
430
431// WithArg<k>(an_action) creates an action that passes the k-th
432// (0-based) argument of the mock function to an_action and performs
433// it. It adapts an action accepting one argument to one that accepts
434// multiple arguments. For convenience, we also provide
435// WithArgs<k>(an_action) (defined below) as a synonym.
436template <int k, typename InnerAction>
437inline internal::WithArgsAction<InnerAction, k>
438WithArg(const InnerAction& action) {
439 return internal::WithArgsAction<InnerAction, k>(action);
440}
441
442// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
443// the selected arguments of the mock function to an_action and
444// performs it. It serves as an adaptor between actions with
445// different argument lists. C++ doesn't support default arguments for
446// function templates, so we have to overload it.
447
448$range i 1..n
449$for i [[
450$range j 1..i
451template <$for j [[int k$j, ]]typename InnerAction>
452inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
453WithArgs(const InnerAction& action) {
454 return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
455}
456
457
458]]
459// Creates an action that does actions a1, a2, ..., sequentially in
460// each invocation.
461$range i 2..n
462$for i [[
463$range j 2..i
464$var types = [[$for j, [[typename Action$j]]]]
465$var Aas = [[$for j [[, Action$j a$j]]]]
466
467template <typename Action1, $types>
468$range k 1..i-1
469
470inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
471
472DoAll(Action1 a1$Aas) {
473$if i==2 [[
474
475 return internal::DoBothAction<Action1, Action2>(a1, a2);
476]] $else [[
477$range j2 2..i
478
479 return DoAll(a1, DoAll($for j2, [[a$j2]]));
480]]
481
482}
483
484]]
485
486} // namespace testing
487
shiqian326aa562009-01-09 21:43:57 +0000488// The ACTION* family of macros can be used in a namespace scope to
489// define custom actions easily. The syntax:
490//
491// ACTION(name) { statements; }
492//
493// will define an action with the given name that executes the
494// statements. The value returned by the statements will be used as
495// the return value of the action. Inside the statements, you can
496// refer to the K-th (0-based) argument of the mock function by
497// 'argK', and refer to its type by 'argK_type'. For example:
498//
499// ACTION(IncrementArg1) {
500// arg1_type temp = arg1;
501// return ++(*temp);
502// }
503//
504// allows you to write
505//
506// ...WillOnce(IncrementArg1());
507//
508// You can also refer to the entire argument tuple and its type by
509// 'args' and 'args_type', and refer to the mock function type and its
510// return type by 'function_type' and 'return_type'.
511//
512// Note that you don't need to specify the types of the mock function
513// arguments. However rest assured that your code is still type-safe:
514// you'll get a compiler error if *arg1 doesn't support the ++
515// operator, or if the type of ++(*arg1) isn't compatible with the
516// mock function's return type, for example.
517//
518// Sometimes you'll want to parameterize the action. For that you can use
519// another macro:
520//
521// ACTION_P(name, param_name) { statements; }
522//
523// For example:
524//
525// ACTION_P(Add, n) { return arg0 + n; }
526//
527// will allow you to write:
528//
529// ...WillOnce(Add(5));
530//
531// Note that you don't need to provide the type of the parameter
532// either. If you need to reference the type of a parameter named
533// 'foo', you can write 'foo_type'. For example, in the body of
534// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
535// of 'n'.
536//
537// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
538// multi-parameter actions.
539//
540// For the purpose of typing, you can view
541//
542// ACTION_Pk(Foo, p1, ..., pk) { ... }
543//
544// as shorthand for
545//
546// template <typename p1_type, ..., typename pk_type>
547// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
548//
549// In particular, you can provide the template type arguments
550// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
551// although usually you can rely on the compiler to infer the types
552// for you automatically. You can assign the result of expression
553// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
554// pk_type>. This can be useful when composing actions.
555//
556// You can also overload actions with different numbers of parameters:
557//
558// ACTION_P(Plus, a) { ... }
559// ACTION_P2(Plus, a, b) { ... }
560//
561// While it's tempting to always use the ACTION* macros when defining
562// a new action, you should also consider implementing ActionInterface
563// or using MakePolymorphicAction() instead, especially if you need to
564// use the action a lot. While these approaches require more work,
565// they give you more control on the types of the mock function
566// arguments and the action parameters, which in general leads to
567// better compiler error messages that pay off in the long run. They
568// also allow overloading actions based on parameter types (as opposed
569// to just based on the number of parameters).
570//
571// CAVEAT:
572//
573// ACTION*() can only be used in a namespace scope. The reason is
574// that C++ doesn't yet allow function-local types to be used to
575// instantiate templates. The up-coming C++0x standard will fix this.
576// Once that's done, we'll consider supporting using ACTION*() inside
577// a function.
578//
579// MORE INFORMATION:
580//
581// To learn more about using these macros, please search for 'ACTION'
582// on http://code.google.com/p/googlemock/wiki/CookBook.
583
584$range i 0..n
zhanyong.wan33c0af02009-04-03 00:10:12 +0000585$range k 0..n-1
586
587// An internal macro needed for implementing ACTION*().
588#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
589 const args_type& args GTEST_ATTRIBUTE_UNUSED_
590$for k [[,\
591 arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
592
593
zhanyong.wan18490652009-05-11 18:54:08 +0000594// Sometimes you want to give an action explicit template parameters
595// that cannot be inferred from its value parameters. ACTION() and
596// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
597// and can be viewed as an extension to ACTION() and ACTION_P*().
598//
599// The syntax:
600//
601// ACTION_TEMPLATE(ActionName,
602// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
603// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
604//
605// defines an action template that takes m explicit template
606// parameters and n value parameters. name_i is the name of the i-th
607// template parameter, and kind_i specifies whether it's a typename,
608// an integral constant, or a template. p_i is the name of the i-th
609// value parameter.
610//
611// Example:
612//
613// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
614// // function to type T and copies it to *output.
615// ACTION_TEMPLATE(DuplicateArg,
616// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
617// AND_1_VALUE_PARAMS(output)) {
618// *output = T(std::tr1::get<k>(args));
619// }
620// ...
621// int n;
622// EXPECT_CALL(mock, Foo(_, _))
623// .WillOnce(DuplicateArg<1, unsigned char>(&n));
624//
625// To create an instance of an action template, write:
626//
627// ActionName<t1, ..., t_m>(v1, ..., v_n)
628//
629// where the ts are the template arguments and the vs are the value
630// arguments. The value argument types are inferred by the compiler.
631// If you want to explicitly specify the value argument types, you can
632// provide additional template arguments:
633//
634// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
635//
636// where u_i is the desired type of v_i.
637//
638// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
639// number of value parameters, but not on the number of template
640// parameters. Without the restriction, the meaning of the following
641// is unclear:
642//
643// OverloadedAction<int, bool>(x);
644//
645// Are we using a single-template-parameter action where 'bool' refers
646// to the type of x, or are we using a two-template-parameter action
647// where the compiler is asked to infer the type of x?
648//
649// Implementation notes:
650//
651// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
652// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
653// implementing ACTION_TEMPLATE. The main trick we use is to create
654// new macro invocations when expanding a macro. For example, we have
655//
656// #define ACTION_TEMPLATE(name, template_params, value_params)
657// ... GMOCK_INTERNAL_DECL_##template_params ...
658//
659// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
660// to expand to
661//
662// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
663//
664// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
665// preprocessor will continue to expand it to
666//
667// ... typename T ...
668//
669// This technique conforms to the C++ standard and is portable. It
670// allows us to implement action templates using O(N) code, where N is
671// the maximum number of template/value parameters supported. Without
672// using it, we'd have to devote O(N^2) amount of code to implement all
673// combinations of m and n.
674
675// Declares the template parameters.
676
677$range j 1..n
678$for j [[
679$range m 0..j-1
680#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
681_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
682
683
684]]
685
686// Lists the template parameters.
687
688$for j [[
689$range m 0..j-1
690#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
691_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
692
693
694]]
695
696// Declares the types of value parameters.
697
698$for i [[
699$range j 0..i-1
700#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
701_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
702
703
704]]
705
706// Initializes the value parameters.
707
708$for i [[
709$range j 0..i-1
710#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
711 ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
712
713
714]]
715
716// Declares the fields for storing the value parameters.
717
718$for i [[
719$range j 0..i-1
720#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
721_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
722
723
724]]
725
726// Lists the value parameters.
727
728$for i [[
729$range j 0..i-1
730#define GMOCK_INTERNAL_LIST_AND_$i[[]]
731_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
732
733
734]]
735
736// Lists the value parameter types.
737
738$for i [[
739$range j 0..i-1
740#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
741_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
742
743
744]]
745
746// Declares the value parameters.
747
748$for i [[
749$range j 0..i-1
750#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
751$for j, [[p$j##_type p$j]]
752
753
754]]
755
756// The suffix of the class template implementing the action template.
757$for i [[
758
759
760$range j 0..i-1
761#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
762$if i==1 [[P]] $elif i>=2 [[P$i]]
763]]
764
765
766// The name of the class template implementing the action template.
767#define GMOCK_ACTION_CLASS_(name, value_params)\
768 GMOCK_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
769
770$range k 0..n-1
771
772#define ACTION_TEMPLATE(name, template_params, value_params)\
773 template <GMOCK_INTERNAL_DECL_##template_params\
774 GMOCK_INTERNAL_DECL_TYPE_##value_params>\
775 class GMOCK_ACTION_CLASS_(name, value_params) {\
776 public:\
777 GMOCK_ACTION_CLASS_(name, value_params)\
778 GMOCK_INTERNAL_INIT_##value_params {}\
779 template <typename F>\
780 class gmock_Impl : public ::testing::ActionInterface<F> {\
781 public:\
782 typedef F function_type;\
783 typedef typename ::testing::internal::Function<F>::Result return_type;\
784 typedef typename ::testing::internal::Function<F>::ArgumentTuple\
785 args_type;\
786 explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
787 virtual return_type Perform(const args_type& args) {\
788 return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
789 Perform(this, args);\
790 }\
791 template <$for k, [[typename arg$k[[]]_type]]>\
792 return_type gmock_PerformImpl(const args_type& args[[]]
793$for k [[, arg$k[[]]_type arg$k]]) const;\
794 GMOCK_INTERNAL_DEFN_##value_params\
795 };\
796 template <typename F> operator ::testing::Action<F>() const {\
797 return ::testing::Action<F>(\
798 new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
799 }\
800 GMOCK_INTERNAL_DEFN_##value_params\
801 };\
802 template <GMOCK_INTERNAL_DECL_##template_params\
803 GMOCK_INTERNAL_DECL_TYPE_##value_params>\
804 inline GMOCK_ACTION_CLASS_(name, value_params)<\
805 GMOCK_INTERNAL_LIST_##template_params\
806 GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
807 GMOCK_INTERNAL_DECL_##value_params) {\
808 return GMOCK_ACTION_CLASS_(name, value_params)<\
809 GMOCK_INTERNAL_LIST_##template_params\
810 GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
811 GMOCK_INTERNAL_LIST_##value_params);\
812 }\
813 template <GMOCK_INTERNAL_DECL_##template_params\
814 GMOCK_INTERNAL_DECL_TYPE_##value_params>\
815 template <typename F>\
816 template <typename arg0_type, typename arg1_type, typename arg2_type,\
817 typename arg3_type, typename arg4_type, typename arg5_type,\
818 typename arg6_type, typename arg7_type, typename arg8_type,\
819 typename arg9_type>\
820 typename ::testing::internal::Function<F>::Result\
821 GMOCK_ACTION_CLASS_(name, value_params)<\
822 GMOCK_INTERNAL_LIST_##template_params\
823 GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
824 gmock_PerformImpl(\
825 GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
826
shiqian326aa562009-01-09 21:43:57 +0000827$for i
828
829[[
830$var template = [[$if i==0 [[]] $else [[
831$range j 0..i-1
832
833 template <$for j, [[typename p$j##_type]]>\
834]]]]
835$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
836 $else [[P$i]]]]]]
837$range j 0..i-1
838$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
839$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
840$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000841$var param_field_decls = [[$for j
shiqian326aa562009-01-09 21:43:57 +0000842[[
843
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000844 p$j##_type p$j;\
shiqian326aa562009-01-09 21:43:57 +0000845]]]]
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000846$var param_field_decls2 = [[$for j
shiqian326aa562009-01-09 21:43:57 +0000847[[
848
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000849 p$j##_type p$j;\
shiqian326aa562009-01-09 21:43:57 +0000850]]]]
851$var params = [[$for j, [[p$j]]]]
852$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
shiqian326aa562009-01-09 21:43:57 +0000853$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
854$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
855$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
856 $else [[ACTION_P$i]]]]
857
858#define $macro_name(name$for j [[, p$j]])\$template
859 class $class_name {\
860 public:\
861 $class_name($ctor_param_list)$inits {}\
862 template <typename F>\
863 class gmock_Impl : public ::testing::ActionInterface<F> {\
864 public:\
865 typedef F function_type;\
866 typedef typename ::testing::internal::Function<F>::Result return_type;\
867 typedef typename ::testing::internal::Function<F>::ArgumentTuple\
868 args_type;\
869 [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
870 virtual return_type Perform(const args_type& args) {\
871 return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
872 Perform(this, args);\
873 }\
874 template <$typename_arg_types>\
875 return_type gmock_PerformImpl(const args_type& args, [[]]
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000876$arg_types_and_names) const;\$param_field_decls
shiqian326aa562009-01-09 21:43:57 +0000877 };\
878 template <typename F> operator ::testing::Action<F>() const {\
879 return ::testing::Action<F>(new gmock_Impl<F>($params));\
zhanyong.wanc069d7f2009-02-02 20:51:53 +0000880 }\$param_field_decls2
shiqian326aa562009-01-09 21:43:57 +0000881 };\$template
882 inline $class_name$param_types name($param_types_and_names) {\
883 return $class_name$param_types($params);\
884 }\$template
885 template <typename F>\
886 template <$typename_arg_types>\
887 typename ::testing::internal::Function<F>::Result\
zhanyong.wan33c0af02009-04-03 00:10:12 +0000888 $class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\
889 GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
shiqian326aa562009-01-09 21:43:57 +0000890]]
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000891$$ } // This meta comment fixes auto-indentation in Emacs. It won't
892$$ // show up in the generated code.
shiqian326aa562009-01-09 21:43:57 +0000893
894
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000895// TODO(wan@google.com): move the following to a different .h file
896// such that we don't have to run 'pump' every time the code is
897// updated.
zhanyong.wane1cdce52009-02-06 01:09:43 +0000898namespace testing {
899
zhanyong.wan16cf4732009-05-14 20:55:30 +0000900// Various overloads for InvokeArgument<N>().
901//
902// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
903// (0-based) argument, which must be a k-ary callable, of the mock
904// function, with arguments a1, a2, ..., a_k.
905//
906// Notes:
907//
908// 1. The arguments are passed by value by default. If you need to
909// pass an argument by reference, wrap it inside ByRef(). For
910// example,
911//
912// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
913//
914// passes 5 and string("Hello") by value, and passes foo by
915// reference.
916//
917// 2. If the callable takes an argument by reference but ByRef() is
918// not used, it will receive the reference to a copy of the value,
919// instead of the original value. For example, when the 0-th
920// argument of the mock function takes a const string&, the action
921//
922// InvokeArgument<0>(string("Hello"))
923//
924// makes a copy of the temporary string("Hello") object and passes a
925// reference of the copy, instead of the original temporary object,
926// to the callable. This makes it easy for a user to define an
927// InvokeArgument action from temporary values and have it performed
928// later.
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000929
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +0000930$range i 0..n
931$for i [[
zhanyong.wan16cf4732009-05-14 20:55:30 +0000932$range j 0..i-1
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +0000933
zhanyong.wan16cf4732009-05-14 20:55:30 +0000934ACTION_TEMPLATE(InvokeArgument,
935 HAS_1_TEMPLATE_PARAMS(int, k),
936 AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
937 return internal::CallableHelper<return_type>::Call(
938 ::std::tr1::get<k>(args)$for j [[, p$j]]);
939}
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +0000940
941]]
942
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000943// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
944// mock function to *pointer.
zhanyong.wan16cf4732009-05-14 20:55:30 +0000945ACTION_TEMPLATE(SaveArg,
946 HAS_1_TEMPLATE_PARAMS(int, k),
947 AND_1_VALUE_PARAMS(pointer)) {
948 *pointer = ::std::tr1::get<k>(args);
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000949}
950
951// Action SetArgReferee<k>(value) assigns 'value' to the variable
952// referenced by the k-th (0-based) argument of the mock function.
zhanyong.wan16cf4732009-05-14 20:55:30 +0000953ACTION_TEMPLATE(SetArgReferee,
954 HAS_1_TEMPLATE_PARAMS(int, k),
955 AND_1_VALUE_PARAMS(value)) {
956 typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
957 // Ensures that argument #k is a reference. If you get a compiler
958 // error on the next line, you are using SetArgReferee<k>(value) in
959 // a mock function whose k-th (0-based) argument is not a reference.
960 GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
961 SetArgReferee_must_be_used_with_a_reference_argument);
962 ::std::tr1::get<k>(args) = value;
963}
964
965// Action SetArrayArgument<k>(first, last) copies the elements in
966// source range [first, last) to the array pointed to by the k-th
967// (0-based) argument, which can be either a pointer or an
968// iterator. The action does not take ownership of the elements in the
969// source range.
970ACTION_TEMPLATE(SetArrayArgument,
971 HAS_1_TEMPLATE_PARAMS(int, k),
972 AND_2_VALUE_PARAMS(first, last)) {
973 // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
974 // 4996 (Function call with parameters that may be unsafe) there.
975#ifdef _MSC_VER
976#pragma warning(push) // Saves the current warning state.
977#pragma warning(disable:4996) // Temporarily disables warning 4996.
978#endif
979 ::std::copy(first, last, ::std::tr1::get<k>(args));
980#ifdef _MSC_VER
981#pragma warning(pop) // Restores the warning state.
982#endif
zhanyong.wan7f4c2c02009-02-19 22:38:27 +0000983}
984
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +0000985// Various overloads for ReturnNew<T>().
986//
987// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
988// instance of type T, constructed on the heap with constructor arguments
989// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
990$range i 0..n
991$for i [[
zhanyong.wan16cf4732009-05-14 20:55:30 +0000992$range j 0..i-1
993$var ps = [[$for j, [[p$j]]]]
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +0000994
zhanyong.wan16cf4732009-05-14 20:55:30 +0000995ACTION_TEMPLATE(ReturnNew,
996 HAS_1_TEMPLATE_PARAMS(typename, T),
997 AND_$i[[]]_VALUE_PARAMS($ps)) {
998 return new T($ps);
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +0000999}
1000
1001]]
1002
1003// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
1004// function.
zhanyong.wan16cf4732009-05-14 20:55:30 +00001005ACTION_TEMPLATE(DeleteArg,
1006 HAS_1_TEMPLATE_PARAMS(int, k),
1007 AND_0_VALUE_PARAMS()) {
1008 delete ::std::tr1::get<k>(args);
zhanyong.wan1c8eb1c2009-04-09 07:29:58 +00001009}
1010
zhanyong.wane1cdce52009-02-06 01:09:43 +00001011// Action Throw(exception) can be used in a mock function of any type
1012// to throw the given exception. Any copyable value can be thrown.
1013#if GTEST_HAS_EXCEPTIONS
1014ACTION_P(Throw, exception) { throw exception; }
1015#endif // GTEST_HAS_EXCEPTIONS
1016
1017} // namespace testing
1018
shiqiane35fdd92008-12-10 05:08:54 +00001019#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_