tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gmock-more-actions.h (38344B)


      1 // Copyright 2007, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // 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 parameters
     50 // that cannot be inferred from its value parameters.  ACTION() and
     51 // ACTION_P*() don't support that.  ACTION_TEMPLATE() remedies that
     52 // 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 template
     61 // parameters and n value parameters.  name_i is the name of the i-th
     62 // 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-th
     64 // value parameter.
     65 //
     66 // Example:
     67 //
     68 //   // DuplicateArg<k, T>(output) converts the k-th argument of the mock
     69 //   // 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 value
     85 // arguments.  The value argument types are inferred by the compiler.
     86 // If you want to explicitly specify the value argument types, you can
     87 // 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 the
     94 // number of value parameters, but not on the number of template
     95 // parameters.  Without the restriction, the meaning of the following
     96 // is unclear:
     97 //
     98 //   OverloadedAction<int, bool>(x);
     99 //
    100 // Are we using a single-template-parameter action where 'bool' refers
    101 // to the type of x, or are we using a two-template-parameter action
    102 // where the compiler is asked to infer the type of x?
    103 //
    104 // Implementation notes:
    105 //
    106 // GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
    107 // GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
    108 // implementing ACTION_TEMPLATE.  The main trick we use is to create
    109 // new macro invocations when expanding a macro.  For example, we have
    110 //
    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 to
    116 //
    117 //       ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
    118 //
    119 // Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
    120 // preprocessor will continue to expand it to
    121 //
    122 //       ... typename T ...
    123 //
    124 // This technique conforms to the C++ standard and is portable.  It
    125 // allows us to implement action templates using O(N) code, where N is
    126 // the maximum number of template/value parameters supported.  Without
    127 // using it, we'd have to devote O(N^2) amount of code to implement all
    128 // combinations of m and n.
    129 
    130 // Declares the template parameters.
    131 #define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
    132 #define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \
    133  kind0 name0, kind1 name1
    134 #define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
    135                                                  kind2, name2)               \
    136  kind0 name0, kind1 name1, kind2 name2
    137 #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 name3
    140 #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 name4
    143 #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 name5
    147 #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 name6
    152 #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 name7
    157 #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 name8
    162 #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 name9
    167 
    168 // Lists the template parameters.
    169 #define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
    170 #define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \
    171  name0, name1
    172 #define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
    173                                                  kind2, name2)               \
    174  name0, name1, name2
    175 #define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
    176                                                  kind2, name2, kind3, name3) \
    177  name0, name1, name2, name3
    178 #define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(                        \
    179    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \
    180  name0, name1, name2, name3, name4
    181 #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, name5
    185 #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, name6
    189 #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, name7
    193 #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, name8
    197 #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, name9
    201 
    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##_type
    205 #define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) \
    206  , typename p0##_type, typename p1##_type
    207 #define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \
    208  , typename p0##_type, typename p1##_type, typename p2##_type
    209 #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##_type
    212 #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##_type
    215 #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##_type
    218 #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##_type
    223 #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##_type
    228 #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##_type
    233 #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##_type
    239 
    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 constructor
    331 #define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
    332  {}  // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
    333 #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) p0
    416 #define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1
    417 #define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2
    418 #define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3
    419 #define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
    420  p0, p1, p2, p3, p4
    421 #define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
    422  p0, p1, p2, p3, p4, p5
    423 #define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \
    424  p0, p1, p2, p3, p4, p5, p6
    425 #define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \
    426  p0, p1, p2, p3, p4, p5, p6, p7
    427 #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, p8
    430 #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, p9
    433 
    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##_type
    437 #define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) \
    438  , p0##_type, p1##_type
    439 #define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \
    440  , p0##_type, p1##_type, p2##_type
    441 #define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
    442  , p0##_type, p1##_type, p2##_type, p3##_type
    443 #define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
    444  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type
    445 #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##_type
    447 #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##_type
    450 #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##_type
    454 #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##_type
    458 #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##_type
    462 
    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 p0
    466 #define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) \
    467  p0##_type p0, p1##_type p1
    468 #define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) \
    469  p0##_type p0, p1##_type p1, p2##_type p2
    470 #define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
    471  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3
    472 #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 p4
    474 #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 p5
    477 #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 p6
    480 #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 p7
    483 #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 p8
    487 #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 p9
    491 
    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) P
    495 #define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2
    496 #define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3
    497 #define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4
    498 #define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5
    499 #define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6
    500 #define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7
    501 #define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
    502                                                p7)                         \
    503  P8
    504 #define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
    505                                                p7, p8)                     \
    506  P9
    507 #define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
    508                                                 p7, p8, p9)                 \
    509  P10
    510 
    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                    , : impl_(std::make_shared<gmock_Impl>(                    \
    525                          GMOCK_INTERNAL_LIST_##value_params)){})              \
    526            GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
    527                name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_      \
    528        ##value_params                                                         \
    529        GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_(           \
    530            name, value_params) &&) noexcept GMOCK_INTERNAL_DEFN_COPY_         \
    531        ##value_params template <typename F>                                   \
    532        operator ::testing::Action<F>() const {                                \
    533      return GMOCK_PP_IF(                                                      \
    534          GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params),              \
    535          (::testing::internal::MakeAction<F, gmock_Impl>()),                  \
    536          (::testing::internal::MakeAction<F>(impl_)));                        \
    537    }                                                                          \
    538                                                                               \
    539   private:                                                                    \
    540    class gmock_Impl {                                                         \
    541     public:                                                                   \
    542      explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}                \
    543      template <typename function_type, typename return_type,                  \
    544                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>         \
    545      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;  \
    546      GMOCK_INTERNAL_DEFN_##value_params                                       \
    547    };                                                                         \
    548    GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), ,      \
    549                std::shared_ptr<const gmock_Impl> impl_;)                      \
    550  };                                                                           \
    551  template <GMOCK_INTERNAL_DECL_##template_params                              \
    552                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \
    553  [[nodiscard]] GMOCK_ACTION_CLASS_(                                           \
    554      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \
    555                              GMOCK_INTERNAL_LIST_TYPE_##value_params>         \
    556      name(GMOCK_INTERNAL_DECL_##value_params);                                \
    557  template <GMOCK_INTERNAL_DECL_##template_params                              \
    558                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \
    559  inline GMOCK_ACTION_CLASS_(                                                  \
    560      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \
    561                              GMOCK_INTERNAL_LIST_TYPE_##value_params>         \
    562  name(GMOCK_INTERNAL_DECL_##value_params) {                                   \
    563    return GMOCK_ACTION_CLASS_(                                                \
    564        name, value_params)<GMOCK_INTERNAL_LIST_##template_params              \
    565                                GMOCK_INTERNAL_LIST_TYPE_##value_params>(      \
    566        GMOCK_INTERNAL_LIST_##value_params);                                   \
    567  }                                                                            \
    568  template <GMOCK_INTERNAL_DECL_##template_params                              \
    569                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \
    570  template <typename function_type, typename return_type, typename args_type,  \
    571            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                 \
    572  return_type GMOCK_ACTION_CLASS_(                                             \
    573      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \
    574                              GMOCK_INTERNAL_LIST_TYPE_##value_params>::       \
    575      gmock_Impl::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_)  \
    576          const
    577 
    578 namespace testing {
    579 
    580 // The ACTION*() macros trigger warning C4100 (unreferenced formal
    581 // parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in
    582 // the macro definition, as the warnings are generated when the macro
    583 // is expanded and macro expansion cannot contain #pragma.  Therefore
    584 // we suppress them here.
    585 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
    586 
    587 namespace internal {
    588 
    589 // internal::InvokeArgument - a helper for InvokeArgument action.
    590 // The basic overloads are provided here for generic functors.
    591 // Overloads for other custom-callables are provided in the
    592 // internal/custom/gmock-generated-actions.h header.
    593 template <typename F, typename... Args>
    594 auto InvokeArgument(F &&f,
    595                    Args... args) -> decltype(std::forward<F>(f)(args...)) {
    596  return std::forward<F>(f)(args...);
    597 }
    598 
    599 template <std::size_t index, typename... Params>
    600 struct InvokeArgumentAction {
    601  template <typename... Args,
    602            typename = typename std::enable_if<(index < sizeof...(Args))>::type>
    603  auto operator()(Args &&...args) const
    604      -> decltype(internal::InvokeArgument(
    605          std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
    606          std::declval<const Params &>()...)) {
    607    internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
    608                                               std::forward<Args>(args)...);
    609    return params.Apply([&](const Params &...unpacked_params) {
    610      auto &&callable = std::move(args_tuple.template Get<index>());
    611      return internal::InvokeArgument(
    612          std::forward<decltype(callable)>(callable), unpacked_params...);
    613    });
    614  }
    615 
    616  internal::FlatTuple<Params...> params;
    617 };
    618 
    619 }  // namespace internal
    620 
    621 // The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
    622 // (0-based) argument, which must be a k-ary callable, of the mock
    623 // function, with arguments a1, a2, ..., a_k.
    624 //
    625 // Notes:
    626 //
    627 //   1. The arguments are passed by value by default.  If you need to
    628 //   pass an argument by reference, wrap it inside std::ref().  For
    629 //   example,
    630 //
    631 //     InvokeArgument<1>(5, string("Hello"), std::ref(foo))
    632 //
    633 //   passes 5 and string("Hello") by value, and passes foo by
    634 //   reference.
    635 //
    636 //   2. If the callable takes an argument by reference but std::ref() is
    637 //   not used, it will receive the reference to a copy of the value,
    638 //   instead of the original value.  For example, when the 0-th
    639 //   argument of the mock function takes a const string&, the action
    640 //
    641 //     InvokeArgument<0>(string("Hello"))
    642 //
    643 //   makes a copy of the temporary string("Hello") object and passes a
    644 //   reference of the copy, instead of the original temporary object,
    645 //   to the callable.  This makes it easy for a user to define an
    646 //   InvokeArgument action from temporary values and have it performed
    647 //   later.
    648 template <std::size_t index, typename... Params>
    649 internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
    650 InvokeArgument(Params &&...params) {
    651  return {internal::FlatTuple<typename std::decay<Params>::type...>(
    652      internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};
    653 }
    654 
    655 GTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100
    656 
    657 }  // namespace testing
    658 
    659 #endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_