]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | $$ -*- mode: c++; -*- |
2 | $$ This is a Pump source file. Please use Pump to convert it to | |
3 | $$ gmock-generated-actions.h. | |
4 | $$ | |
5 | $var n = 10 $$ The maximum arity we support. | |
6 | $$}} This meta comment fixes auto-indentation in editors. | |
7 | // 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 | ||
37 | // Google Mock - a framework for writing C++ mock classes. | |
38 | // | |
39 | // This file implements some commonly used variadic actions. | |
40 | ||
41 | // GOOGLETEST_CM0002 DO NOT DELETE | |
42 | ||
43 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ | |
44 | #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ | |
45 | ||
46 | #include <memory> | |
47 | #include <utility> | |
48 | ||
49 | #include "gmock/gmock-actions.h" | |
50 | #include "gmock/internal/gmock-port.h" | |
51 | ||
52 | // Include any custom callback actions added by the local installation. | |
53 | #include "gmock/internal/custom/gmock-generated-actions.h" | |
54 | ||
55 | $range i 0..n | |
56 | $range k 0..n-1 | |
57 | ||
58 | // Sometimes you want to give an action explicit template parameters | |
59 | // that cannot be inferred from its value parameters. ACTION() and | |
60 | // ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that | |
61 | // and can be viewed as an extension to ACTION() and ACTION_P*(). | |
62 | // | |
63 | // The syntax: | |
64 | // | |
65 | // ACTION_TEMPLATE(ActionName, | |
66 | // HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), | |
67 | // AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } | |
68 | // | |
69 | // defines an action template that takes m explicit template | |
70 | // parameters and n value parameters. name_i is the name of the i-th | |
71 | // template parameter, and kind_i specifies whether it's a typename, | |
72 | // an integral constant, or a template. p_i is the name of the i-th | |
73 | // value parameter. | |
74 | // | |
75 | // Example: | |
76 | // | |
77 | // // DuplicateArg<k, T>(output) converts the k-th argument of the mock | |
78 | // // function to type T and copies it to *output. | |
79 | // ACTION_TEMPLATE(DuplicateArg, | |
80 | // HAS_2_TEMPLATE_PARAMS(int, k, typename, T), | |
81 | // AND_1_VALUE_PARAMS(output)) { | |
82 | // *output = T(::std::get<k>(args)); | |
83 | // } | |
84 | // ... | |
85 | // int n; | |
86 | // EXPECT_CALL(mock, Foo(_, _)) | |
87 | // .WillOnce(DuplicateArg<1, unsigned char>(&n)); | |
88 | // | |
89 | // To create an instance of an action template, write: | |
90 | // | |
91 | // ActionName<t1, ..., t_m>(v1, ..., v_n) | |
92 | // | |
93 | // where the ts are the template arguments and the vs are the value | |
94 | // arguments. The value argument types are inferred by the compiler. | |
95 | // If you want to explicitly specify the value argument types, you can | |
96 | // provide additional template arguments: | |
97 | // | |
98 | // ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n) | |
99 | // | |
100 | // where u_i is the desired type of v_i. | |
101 | // | |
102 | // ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the | |
103 | // number of value parameters, but not on the number of template | |
104 | // parameters. Without the restriction, the meaning of the following | |
105 | // is unclear: | |
106 | // | |
107 | // OverloadedAction<int, bool>(x); | |
108 | // | |
109 | // Are we using a single-template-parameter action where 'bool' refers | |
110 | // to the type of x, or are we using a two-template-parameter action | |
111 | // where the compiler is asked to infer the type of x? | |
112 | // | |
113 | // Implementation notes: | |
114 | // | |
115 | // GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and | |
116 | // GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for | |
117 | // implementing ACTION_TEMPLATE. The main trick we use is to create | |
118 | // new macro invocations when expanding a macro. For example, we have | |
119 | // | |
120 | // #define ACTION_TEMPLATE(name, template_params, value_params) | |
121 | // ... GMOCK_INTERNAL_DECL_##template_params ... | |
122 | // | |
123 | // which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) | |
124 | // to expand to | |
125 | // | |
126 | // ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... | |
127 | // | |
128 | // Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the | |
129 | // preprocessor will continue to expand it to | |
130 | // | |
131 | // ... typename T ... | |
132 | // | |
133 | // This technique conforms to the C++ standard and is portable. It | |
134 | // allows us to implement action templates using O(N) code, where N is | |
135 | // the maximum number of template/value parameters supported. Without | |
136 | // using it, we'd have to devote O(N^2) amount of code to implement all | |
137 | // combinations of m and n. | |
138 | ||
139 | // Declares the template parameters. | |
140 | ||
141 | $range j 1..n | |
142 | $for j [[ | |
143 | $range m 0..j-1 | |
144 | #define GMOCK_INTERNAL_DECL_HAS_$j[[]] | |
145 | _TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]] | |
146 | ||
147 | ||
148 | ]] | |
149 | ||
150 | // Lists the template parameters. | |
151 | ||
152 | $for j [[ | |
153 | $range m 0..j-1 | |
154 | #define GMOCK_INTERNAL_LIST_HAS_$j[[]] | |
155 | _TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]] | |
156 | ||
157 | ||
158 | ]] | |
159 | ||
160 | // Declares the types of value parameters. | |
161 | ||
162 | $for i [[ | |
163 | $range j 0..i-1 | |
164 | #define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]] | |
165 | _VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] | |
166 | ||
167 | ||
168 | ]] | |
169 | ||
170 | // Initializes the value parameters. | |
171 | ||
172 | $for i [[ | |
173 | $range j 0..i-1 | |
174 | #define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ | |
175 | ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]] | |
176 | ||
177 | ||
178 | ]] | |
179 | ||
180 | // Defines the copy constructor | |
181 | ||
182 | $for i [[ | |
183 | #define GMOCK_INTERNAL_DEFN_COPY_AND_$i[[]]_VALUE_PARAMS$if i == 0[[() \ | |
184 | {} // Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134 | |
185 | ]] $else [[(...) = default;]] | |
186 | ||
187 | ||
188 | ]] | |
189 | ||
190 | // Declares the fields for storing the value parameters. | |
191 | ||
192 | $for i [[ | |
193 | $range j 0..i-1 | |
194 | #define GMOCK_INTERNAL_DEFN_AND_$i[[]] | |
195 | _VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]] | |
196 | ||
197 | ||
198 | ]] | |
199 | ||
200 | // Lists the value parameters. | |
201 | ||
202 | $for i [[ | |
203 | $range j 0..i-1 | |
204 | #define GMOCK_INTERNAL_LIST_AND_$i[[]] | |
205 | _VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]] | |
206 | ||
207 | ||
208 | ]] | |
209 | ||
210 | // Lists the value parameter types. | |
211 | ||
212 | $for i [[ | |
213 | $range j 0..i-1 | |
214 | #define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]] | |
215 | _VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]] | |
216 | ||
217 | ||
218 | ]] | |
219 | ||
220 | // Declares the value parameters. | |
221 | ||
222 | $for i [[ | |
223 | $range j 0..i-1 | |
224 | #define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] | |
225 | $for j, [[p$j##_type p$j]] | |
226 | ||
227 | ||
228 | ]] | |
229 | ||
230 | // The suffix of the class template implementing the action template. | |
231 | $for i [[ | |
232 | ||
233 | ||
234 | $range j 0..i-1 | |
235 | #define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] | |
236 | $if i==1 [[P]] $elif i>=2 [[P$i]] | |
237 | ]] | |
238 | ||
239 | ||
240 | // The name of the class template implementing the action template. | |
241 | #define GMOCK_ACTION_CLASS_(name, value_params)\ | |
242 | GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) | |
243 | ||
244 | $range k 0..n-1 | |
245 | ||
246 | #define ACTION_TEMPLATE(name, template_params, value_params)\ | |
247 | template <GMOCK_INTERNAL_DECL_##template_params\ | |
248 | GMOCK_INTERNAL_DECL_TYPE_##value_params>\ | |
249 | class GMOCK_ACTION_CLASS_(name, value_params) {\ | |
250 | public:\ | |
251 | explicit GMOCK_ACTION_CLASS_(name, value_params)\ | |
252 | GMOCK_INTERNAL_INIT_##value_params {}\ | |
253 | GMOCK_ACTION_CLASS_(name, value_params)(\ | |
254 | const GMOCK_ACTION_CLASS_(name, value_params)<\ | |
255 | GMOCK_INTERNAL_LIST_##template_params\ | |
256 | GMOCK_INTERNAL_LIST_TYPE_##value_params>&)\ | |
257 | GMOCK_INTERNAL_DEFN_COPY_##value_params\ | |
258 | template <typename F>\ | |
259 | class gmock_Impl : public ::testing::ActionInterface<F> {\ | |
260 | public:\ | |
261 | typedef F function_type;\ | |
262 | typedef typename ::testing::internal::Function<F>::Result return_type;\ | |
263 | typedef typename ::testing::internal::Function<F>::ArgumentTuple\ | |
264 | args_type;\ | |
265 | explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ | |
266 | return_type Perform(const args_type& args) override {\ | |
267 | return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ | |
268 | Perform(this, args);\ | |
269 | }\ | |
270 | template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\ | |
271 | return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\ | |
272 | GMOCK_INTERNAL_DEFN_##value_params\ | |
273 | };\ | |
274 | template <typename F> operator ::testing::Action<F>() const {\ | |
275 | return ::testing::Action<F>(\ | |
276 | new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\ | |
277 | }\ | |
278 | GMOCK_INTERNAL_DEFN_##value_params\ | |
279 | };\ | |
280 | template <GMOCK_INTERNAL_DECL_##template_params\ | |
281 | GMOCK_INTERNAL_DECL_TYPE_##value_params>\ | |
282 | GMOCK_ACTION_CLASS_(name, value_params)<\ | |
283 | GMOCK_INTERNAL_LIST_##template_params\ | |
284 | GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ | |
285 | GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;\ | |
286 | template <GMOCK_INTERNAL_DECL_##template_params\ | |
287 | GMOCK_INTERNAL_DECL_TYPE_##value_params>\ | |
288 | inline GMOCK_ACTION_CLASS_(name, value_params)<\ | |
289 | GMOCK_INTERNAL_LIST_##template_params\ | |
290 | GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ | |
291 | GMOCK_INTERNAL_DECL_##value_params) {\ | |
292 | return GMOCK_ACTION_CLASS_(name, value_params)<\ | |
293 | GMOCK_INTERNAL_LIST_##template_params\ | |
294 | GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ | |
295 | GMOCK_INTERNAL_LIST_##value_params);\ | |
296 | }\ | |
297 | template <GMOCK_INTERNAL_DECL_##template_params\ | |
298 | GMOCK_INTERNAL_DECL_TYPE_##value_params>\ | |
299 | template <typename F>\ | |
300 | template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\ | |
301 | typename ::testing::internal::Function<F>::Result\ | |
302 | GMOCK_ACTION_CLASS_(name, value_params)<\ | |
303 | GMOCK_INTERNAL_LIST_##template_params\ | |
304 | GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\ | |
305 | gmock_PerformImpl(\ | |
306 | GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const | |
307 | ||
308 | ||
309 | namespace testing { | |
310 | ||
311 | ||
312 | // The ACTION*() macros trigger warning C4100 (unreferenced formal | |
313 | // parameter) in MSVC with -W4. Unfortunately they cannot be fixed in | |
314 | // the macro definition, as the warnings are generated when the macro | |
315 | // is expanded and macro expansion cannot contain #pragma. Therefore | |
316 | // we suppress them here. | |
317 | #ifdef _MSC_VER | |
318 | # pragma warning(push) | |
319 | # pragma warning(disable:4100) | |
320 | #endif | |
321 | ||
322 | // Various overloads for InvokeArgument<N>(). | |
323 | // | |
324 | // The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th | |
325 | // (0-based) argument, which must be a k-ary callable, of the mock | |
326 | // function, with arguments a1, a2, ..., a_k. | |
327 | // | |
328 | // Notes: | |
329 | // | |
330 | // 1. The arguments are passed by value by default. If you need to | |
331 | // pass an argument by reference, wrap it inside ByRef(). For | |
332 | // example, | |
333 | // | |
334 | // InvokeArgument<1>(5, string("Hello"), ByRef(foo)) | |
335 | // | |
336 | // passes 5 and string("Hello") by value, and passes foo by | |
337 | // reference. | |
338 | // | |
339 | // 2. If the callable takes an argument by reference but ByRef() is | |
340 | // not used, it will receive the reference to a copy of the value, | |
341 | // instead of the original value. For example, when the 0-th | |
342 | // argument of the mock function takes a const string&, the action | |
343 | // | |
344 | // InvokeArgument<0>(string("Hello")) | |
345 | // | |
346 | // makes a copy of the temporary string("Hello") object and passes a | |
347 | // reference of the copy, instead of the original temporary object, | |
348 | // to the callable. This makes it easy for a user to define an | |
349 | // InvokeArgument action from temporary values and have it performed | |
350 | // later. | |
351 | ||
352 | $range i 0..n | |
353 | $for i [[ | |
354 | $range j 0..i-1 | |
355 | ||
356 | ACTION_TEMPLATE(InvokeArgument, | |
357 | HAS_1_TEMPLATE_PARAMS(int, k), | |
358 | AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { | |
359 | return internal::InvokeArgument(::std::get<k>(args)$for j[[, p$j]]); | |
360 | } | |
361 | ||
362 | ]] | |
363 | ||
364 | #ifdef _MSC_VER | |
365 | # pragma warning(pop) | |
366 | #endif | |
367 | ||
368 | } // namespace testing | |
369 | ||
370 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ |