659 lines · c
1// Copyright 2007, Google Inc.2// All rights reserved.3//4// Redistribution and use in source and binary forms, with or without5// modification, are permitted provided that the following conditions are6// met:7//8// * Redistributions of source code must retain the above copyright9// notice, this list of conditions and the following disclaimer.10// * Redistributions in binary form must reproduce the above11// copyright notice, this list of conditions and the following disclaimer12// in the documentation and/or other materials provided with the13// distribution.14// * Neither the name of Google Inc. nor the names of its15// contributors may be used to endorse or promote products derived from16// this software without specific prior written permission.17//18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 30// Google Mock - a framework for writing C++ mock classes.31//32// This file implements some commonly used variadic actions.33 34// IWYU pragma: private, include "gmock/gmock.h"35// IWYU pragma: friend gmock/.*36 37#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_38#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_39 40#include <memory>41#include <utility>42 43#include "gmock/gmock-actions.h"44#include "gmock/internal/gmock-port.h"45 46// Include any custom callback actions added by the local installation.47#include "gmock/internal/custom/gmock-generated-actions.h"48 49// Sometimes you want to give an action explicit template parameters50// that cannot be inferred from its value parameters. ACTION() and51// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that52// and can be viewed as an extension to ACTION() and ACTION_P*().53//54// The syntax:55//56// ACTION_TEMPLATE(ActionName,57// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),58// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }59//60// defines an action template that takes m explicit template61// parameters and n value parameters. name_i is the name of the i-th62// template parameter, and kind_i specifies whether it's a typename,63// an integral constant, or a template. p_i is the name of the i-th64// value parameter.65//66// Example:67//68// // DuplicateArg<k, T>(output) converts the k-th argument of the mock69// // function to type T and copies it to *output.70// ACTION_TEMPLATE(DuplicateArg,71// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),72// AND_1_VALUE_PARAMS(output)) {73// *output = T(::std::get<k>(args));74// }75// ...76// int n;77// EXPECT_CALL(mock, Foo(_, _))78// .WillOnce(DuplicateArg<1, unsigned char>(&n));79//80// To create an instance of an action template, write:81//82// ActionName<t1, ..., t_m>(v1, ..., v_n)83//84// where the ts are the template arguments and the vs are the value85// arguments. The value argument types are inferred by the compiler.86// If you want to explicitly specify the value argument types, you can87// provide additional template arguments:88//89// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)90//91// where u_i is the desired type of v_i.92//93// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the94// number of value parameters, but not on the number of template95// parameters. Without the restriction, the meaning of the following96// is unclear:97//98// OverloadedAction<int, bool>(x);99//100// Are we using a single-template-parameter action where 'bool' refers101// to the type of x, or are we using a two-template-parameter action102// where the compiler is asked to infer the type of x?103//104// Implementation notes:105//106// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and107// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for108// implementing ACTION_TEMPLATE. The main trick we use is to create109// new macro invocations when expanding a macro. For example, we have110//111// #define ACTION_TEMPLATE(name, template_params, value_params)112// ... GMOCK_INTERNAL_DECL_##template_params ...113//114// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)115// to expand to116//117// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...118//119// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the120// preprocessor will continue to expand it to121//122// ... typename T ...123//124// This technique conforms to the C++ standard and is portable. It125// allows us to implement action templates using O(N) code, where N is126// the maximum number of template/value parameters supported. Without127// using it, we'd have to devote O(N^2) amount of code to implement all128// combinations of m and n.129 130// Declares the template parameters.131#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0132#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \133 kind0 name0, kind1 name1134#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \135 kind2, name2) \136 kind0 name0, kind1 name1, kind2 name2137#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \138 kind2, name2, kind3, name3) \139 kind0 name0, kind1 name1, kind2 name2, kind3 name3140#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS( \141 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \142 kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4143#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \144 kind2, name2, kind3, name3, \145 kind4, name4, kind5, name5) \146 kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5147#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS( \148 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \149 kind5, name5, kind6, name6) \150 kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \151 kind5 name5, kind6 name6152#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS( \153 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \154 kind5, name5, kind6, name6, kind7, name7) \155 kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \156 kind5 name5, kind6 name6, kind7 name7157#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS( \158 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \159 kind5, name5, kind6, name6, kind7, name7, kind8, name8) \160 kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \161 kind5 name5, kind6 name6, kind7 name7, kind8 name8162#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS( \163 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \164 kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \165 kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \166 kind5 name5, kind6 name6, kind7 name7, kind8 name8, kind9 name9167 168// Lists the template parameters.169#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0170#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \171 name0, name1172#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \173 kind2, name2) \174 name0, name1, name2175#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \176 kind2, name2, kind3, name3) \177 name0, name1, name2, name3178#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS( \179 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \180 name0, name1, name2, name3, name4181#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \182 kind2, name2, kind3, name3, \183 kind4, name4, kind5, name5) \184 name0, name1, name2, name3, name4, name5185#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS( \186 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \187 kind5, name5, kind6, name6) \188 name0, name1, name2, name3, name4, name5, name6189#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS( \190 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \191 kind5, name5, kind6, name6, kind7, name7) \192 name0, name1, name2, name3, name4, name5, name6, name7193#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS( \194 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \195 kind5, name5, kind6, name6, kind7, name7, kind8, name8) \196 name0, name1, name2, name3, name4, name5, name6, name7, name8197#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS( \198 kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \199 kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \200 name0, name1, name2, name3, name4, name5, name6, name7, name8, name9201 202// Declares the types of value parameters.203#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()204#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type205#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) \206 , typename p0##_type, typename p1##_type207#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \208 , typename p0##_type, typename p1##_type, typename p2##_type209#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \210 , typename p0##_type, typename p1##_type, typename p2##_type, \211 typename p3##_type212#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \213 , typename p0##_type, typename p1##_type, typename p2##_type, \214 typename p3##_type, typename p4##_type215#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \216 , typename p0##_type, typename p1##_type, typename p2##_type, \217 typename p3##_type, typename p4##_type, typename p5##_type218#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \219 p6) \220 , typename p0##_type, typename p1##_type, typename p2##_type, \221 typename p3##_type, typename p4##_type, typename p5##_type, \222 typename p6##_type223#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \224 p6, p7) \225 , typename p0##_type, typename p1##_type, typename p2##_type, \226 typename p3##_type, typename p4##_type, typename p5##_type, \227 typename p6##_type, typename p7##_type228#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \229 p6, p7, p8) \230 , typename p0##_type, typename p1##_type, typename p2##_type, \231 typename p3##_type, typename p4##_type, typename p5##_type, \232 typename p6##_type, typename p7##_type, typename p8##_type233#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \234 p6, p7, p8, p9) \235 , typename p0##_type, typename p1##_type, typename p2##_type, \236 typename p3##_type, typename p4##_type, typename p5##_type, \237 typename p6##_type, typename p7##_type, typename p8##_type, \238 typename p9##_type239 240// Initializes the value parameters.241#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS() ()242#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0) \243 (p0##_type gmock_p0) : p0(::std::move(gmock_p0))244#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1) \245 (p0##_type gmock_p0, p1##_type gmock_p1) \246 : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1))247#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2) \248 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2) \249 : p0(::std::move(gmock_p0)), \250 p1(::std::move(gmock_p1)), \251 p2(::std::move(gmock_p2))252#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \253 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \254 p3##_type gmock_p3) \255 : p0(::std::move(gmock_p0)), \256 p1(::std::move(gmock_p1)), \257 p2(::std::move(gmock_p2)), \258 p3(::std::move(gmock_p3))259#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \260 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \261 p3##_type gmock_p3, p4##_type gmock_p4) \262 : p0(::std::move(gmock_p0)), \263 p1(::std::move(gmock_p1)), \264 p2(::std::move(gmock_p2)), \265 p3(::std::move(gmock_p3)), \266 p4(::std::move(gmock_p4))267#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \268 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \269 p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5) \270 : p0(::std::move(gmock_p0)), \271 p1(::std::move(gmock_p1)), \272 p2(::std::move(gmock_p2)), \273 p3(::std::move(gmock_p3)), \274 p4(::std::move(gmock_p4)), \275 p5(::std::move(gmock_p5))276#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \277 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \278 p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \279 p6##_type gmock_p6) \280 : p0(::std::move(gmock_p0)), \281 p1(::std::move(gmock_p1)), \282 p2(::std::move(gmock_p2)), \283 p3(::std::move(gmock_p3)), \284 p4(::std::move(gmock_p4)), \285 p5(::std::move(gmock_p5)), \286 p6(::std::move(gmock_p6))287#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \288 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \289 p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \290 p6##_type gmock_p6, p7##_type gmock_p7) \291 : p0(::std::move(gmock_p0)), \292 p1(::std::move(gmock_p1)), \293 p2(::std::move(gmock_p2)), \294 p3(::std::move(gmock_p3)), \295 p4(::std::move(gmock_p4)), \296 p5(::std::move(gmock_p5)), \297 p6(::std::move(gmock_p6)), \298 p7(::std::move(gmock_p7))299#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \300 p8) \301 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \302 p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \303 p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8) \304 : p0(::std::move(gmock_p0)), \305 p1(::std::move(gmock_p1)), \306 p2(::std::move(gmock_p2)), \307 p3(::std::move(gmock_p3)), \308 p4(::std::move(gmock_p4)), \309 p5(::std::move(gmock_p5)), \310 p6(::std::move(gmock_p6)), \311 p7(::std::move(gmock_p7)), \312 p8(::std::move(gmock_p8))313#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \314 p7, p8, p9) \315 (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \316 p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \317 p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \318 p9##_type gmock_p9) \319 : p0(::std::move(gmock_p0)), \320 p1(::std::move(gmock_p1)), \321 p2(::std::move(gmock_p2)), \322 p3(::std::move(gmock_p3)), \323 p4(::std::move(gmock_p4)), \324 p5(::std::move(gmock_p5)), \325 p6(::std::move(gmock_p6)), \326 p7(::std::move(gmock_p7)), \327 p8(::std::move(gmock_p8)), \328 p9(::std::move(gmock_p9))329 330// Defines the copy constructor331#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \332 {} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134333#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default;334#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;335#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;336#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default;337#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default;338#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default;339#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default;340#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default;341#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default;342#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default;343 344// Declares the fields for storing the value parameters.345#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()346#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;347#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) \348 p0##_type p0; \349 p1##_type p1;350#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) \351 p0##_type p0; \352 p1##_type p1; \353 p2##_type p2;354#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \355 p0##_type p0; \356 p1##_type p1; \357 p2##_type p2; \358 p3##_type p3;359#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \360 p0##_type p0; \361 p1##_type p1; \362 p2##_type p2; \363 p3##_type p3; \364 p4##_type p4;365#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \366 p0##_type p0; \367 p1##_type p1; \368 p2##_type p2; \369 p3##_type p3; \370 p4##_type p4; \371 p5##_type p5;372#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \373 p0##_type p0; \374 p1##_type p1; \375 p2##_type p2; \376 p3##_type p3; \377 p4##_type p4; \378 p5##_type p5; \379 p6##_type p6;380#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \381 p0##_type p0; \382 p1##_type p1; \383 p2##_type p2; \384 p3##_type p3; \385 p4##_type p4; \386 p5##_type p5; \387 p6##_type p6; \388 p7##_type p7;389#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \390 p8) \391 p0##_type p0; \392 p1##_type p1; \393 p2##_type p2; \394 p3##_type p3; \395 p4##_type p4; \396 p5##_type p5; \397 p6##_type p6; \398 p7##_type p7; \399 p8##_type p8;400#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \401 p7, p8, p9) \402 p0##_type p0; \403 p1##_type p1; \404 p2##_type p2; \405 p3##_type p3; \406 p4##_type p4; \407 p5##_type p5; \408 p6##_type p6; \409 p7##_type p7; \410 p8##_type p8; \411 p9##_type p9;412 413// Lists the value parameters.414#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()415#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0416#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1417#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2418#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3419#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \420 p0, p1, p2, p3, p4421#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \422 p0, p1, p2, p3, p4, p5423#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \424 p0, p1, p2, p3, p4, p5, p6425#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \426 p0, p1, p2, p3, p4, p5, p6, p7427#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \428 p8) \429 p0, p1, p2, p3, p4, p5, p6, p7, p8430#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \431 p7, p8, p9) \432 p0, p1, p2, p3, p4, p5, p6, p7, p8, p9433 434// Lists the value parameter types.435#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()436#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type437#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) \438 , p0##_type, p1##_type439#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \440 , p0##_type, p1##_type, p2##_type441#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \442 , p0##_type, p1##_type, p2##_type, p3##_type443#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \444 , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type445#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \446 , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type447#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \448 p6) \449 , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, p6##_type450#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \451 p6, p7) \452 , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \453 p6##_type, p7##_type454#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \455 p6, p7, p8) \456 , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \457 p6##_type, p7##_type, p8##_type458#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \459 p6, p7, p8, p9) \460 , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \461 p6##_type, p7##_type, p8##_type, p9##_type462 463// Declares the value parameters.464#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()465#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0466#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) \467 p0##_type p0, p1##_type p1468#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) \469 p0##_type p0, p1##_type p1, p2##_type p2470#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \471 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3472#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \473 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4474#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \475 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \476 p5##_type p5477#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \478 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \479 p5##_type p5, p6##_type p6480#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \481 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \482 p5##_type p5, p6##_type p6, p7##_type p7483#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \484 p8) \485 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \486 p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8487#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \488 p7, p8, p9) \489 p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \490 p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, p9##_type p9491 492// The suffix of the class template implementing the action template.493#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()494#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P495#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2496#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3497#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4498#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5499#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6500#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7501#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \502 p7) \503 P8504#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \505 p7, p8) \506 P9507#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \508 p7, p8, p9) \509 P10510 511// The name of the class template implementing the action template.512#define GMOCK_ACTION_CLASS_(name, value_params) \513 GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)514 515#define ACTION_TEMPLATE(name, template_params, value_params) \516 template <GMOCK_INTERNAL_DECL_##template_params \517 GMOCK_INTERNAL_DECL_TYPE_##value_params> \518 class GMOCK_ACTION_CLASS_(name, value_params) { \519 public: \520 explicit GMOCK_ACTION_CLASS_(name, value_params)( \521 GMOCK_INTERNAL_DECL_##value_params) \522 GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \523 = default; \524 , \525 : impl_(std::make_shared<gmock_Impl>( \526 GMOCK_INTERNAL_LIST_##value_params)){}) \527 GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \528 name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \529 ##value_params \530 GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_( \531 name, value_params) &&) noexcept GMOCK_INTERNAL_DEFN_COPY_ \532 ##value_params template <typename F> \533 operator ::testing::Action<F>() const { \534 return GMOCK_PP_IF( \535 GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \536 (::testing::internal::MakeAction<F, gmock_Impl>()), \537 (::testing::internal::MakeAction<F>(impl_))); \538 } \539 \540 private: \541 class gmock_Impl { \542 public: \543 explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \544 template <typename function_type, typename return_type, \545 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \546 return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \547 GMOCK_INTERNAL_DEFN_##value_params \548 }; \549 GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), , \550 std::shared_ptr<const gmock_Impl> impl_;) \551 }; \552 template <GMOCK_INTERNAL_DECL_##template_params \553 GMOCK_INTERNAL_DECL_TYPE_##value_params> \554 GMOCK_ACTION_CLASS_( \555 name, value_params)<GMOCK_INTERNAL_LIST_##template_params \556 GMOCK_INTERNAL_LIST_TYPE_##value_params> \557 name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \558 template <GMOCK_INTERNAL_DECL_##template_params \559 GMOCK_INTERNAL_DECL_TYPE_##value_params> \560 inline GMOCK_ACTION_CLASS_( \561 name, value_params)<GMOCK_INTERNAL_LIST_##template_params \562 GMOCK_INTERNAL_LIST_TYPE_##value_params> \563 name(GMOCK_INTERNAL_DECL_##value_params) { \564 return GMOCK_ACTION_CLASS_( \565 name, value_params)<GMOCK_INTERNAL_LIST_##template_params \566 GMOCK_INTERNAL_LIST_TYPE_##value_params>( \567 GMOCK_INTERNAL_LIST_##value_params); \568 } \569 template <GMOCK_INTERNAL_DECL_##template_params \570 GMOCK_INTERNAL_DECL_TYPE_##value_params> \571 template <typename function_type, typename return_type, typename args_type, \572 GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \573 return_type GMOCK_ACTION_CLASS_( \574 name, value_params)<GMOCK_INTERNAL_LIST_##template_params \575 GMOCK_INTERNAL_LIST_TYPE_##value_params>:: \576 gmock_Impl::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) \577 const578 579namespace testing {580 581// The ACTION*() macros trigger warning C4100 (unreferenced formal582// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in583// the macro definition, as the warnings are generated when the macro584// is expanded and macro expansion cannot contain #pragma. Therefore585// we suppress them here.586GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)587 588namespace internal {589 590// internal::InvokeArgument - a helper for InvokeArgument action.591// The basic overloads are provided here for generic functors.592// Overloads for other custom-callables are provided in the593// internal/custom/gmock-generated-actions.h header.594template <typename F, typename... Args>595auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {596 return f(args...);597}598 599template <std::size_t index, typename... Params>600struct InvokeArgumentAction {601 template <typename... Args,602 typename = typename std::enable_if<(index < sizeof...(Args))>::type>603 auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(604 std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),605 std::declval<const Params &>()...)) {606 internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},607 std::forward<Args>(args)...);608 return params.Apply([&](const Params &...unpacked_params) {609 auto &&callable = args_tuple.template Get<index>();610 return internal::InvokeArgument(611 std::forward<decltype(callable)>(callable), unpacked_params...);612 });613 }614 615 internal::FlatTuple<Params...> params;616};617 618} // namespace internal619 620// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th621// (0-based) argument, which must be a k-ary callable, of the mock622// function, with arguments a1, a2, ..., a_k.623//624// Notes:625//626// 1. The arguments are passed by value by default. If you need to627// pass an argument by reference, wrap it inside std::ref(). For628// example,629//630// InvokeArgument<1>(5, string("Hello"), std::ref(foo))631//632// passes 5 and string("Hello") by value, and passes foo by633// reference.634//635// 2. If the callable takes an argument by reference but std::ref() is636// not used, it will receive the reference to a copy of the value,637// instead of the original value. For example, when the 0-th638// argument of the mock function takes a const string&, the action639//640// InvokeArgument<0>(string("Hello"))641//642// makes a copy of the temporary string("Hello") object and passes a643// reference of the copy, instead of the original temporary object,644// to the callable. This makes it easy for a user to define an645// InvokeArgument action from temporary values and have it performed646// later.647template <std::size_t index, typename... Params>648internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>649InvokeArgument(Params &&...params) {650 return {internal::FlatTuple<typename std::decay<Params>::type...>(651 internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};652}653 654GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100655 656} // namespace testing657 658#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_659