summaryrefslogtreecommitdiffstats
path: root/googlemock/include/gmock
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2020-11-06 22:09:13 (GMT)
committerMark Barolak <mbar@google.com>2020-11-09 20:43:33 (GMT)
commitfbef0711cfce7b8f149aac773d30ae48ce3e166c (patch)
tree61ebc3eaf7f427a90b63e8b6814770ec0cfd8715 /googlemock/include/gmock
parent0c400f67fcf305869c5fb113dd296eca266c9725 (diff)
downloadgoogletest-fbef0711cfce7b8f149aac773d30ae48ce3e166c.zip
googletest-fbef0711cfce7b8f149aac773d30ae48ce3e166c.tar.gz
googletest-fbef0711cfce7b8f149aac773d30ae48ce3e166c.tar.bz2
Googletest export
Change ACTION{,_Pn,_TEMPLATE} macros to build functors rather than ActionInterface<> subclasses, thus changing the Action<> wrappers they create to use the modernized (non-const) argument tuple type, allowing these macros to mutate their arguments. Functor-based Action<>s deep-copy the implementing object, so have the functors use a shared_ptr to the non-trivial state of bound value parameters. No longer specialize that shared state to the particular action signature, encoding that information instead only in the instantiation of the implementation function. PiperOrigin-RevId: 341116208
Diffstat (limited to 'googlemock/include/gmock')
-rw-r--r--googlemock/include/gmock/gmock-actions.h185
-rw-r--r--googlemock/include/gmock/gmock-generated-actions.h122
-rw-r--r--googlemock/include/gmock/gmock-generated-actions.h.pump122
3 files changed, 210 insertions, 219 deletions
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index f95be3f..fb33f7b 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -1480,68 +1480,72 @@ namespace internal {
// TYPE DIRECTLY.
struct ExcessiveArg {};
-// A helper class needed for implementing the ACTION* macros.
-template <typename Result, class Impl>
-class ActionHelper {
- public:
- template <typename... Ts>
- static Result Perform(Impl* impl, const std::tuple<Ts...>& args) {
- static constexpr size_t kMaxArgs = sizeof...(Ts) <= 10 ? sizeof...(Ts) : 10;
- return Apply(impl, args, MakeIndexSequence<kMaxArgs>{},
- MakeIndexSequence<10 - kMaxArgs>{});
- }
+// Builds an implementation of an Action<> for some particular signature, using
+// a class defined by an ACTION* macro.
+template <typename F, typename Impl> struct ActionImpl;
- private:
- template <typename... Ts, std::size_t... tuple_ids, std::size_t... rest_ids>
- static Result Apply(Impl* impl, const std::tuple<Ts...>& args,
- IndexSequence<tuple_ids...>, IndexSequence<rest_ids...>) {
- return impl->template gmock_PerformImpl<
- typename std::tuple_element<tuple_ids, std::tuple<Ts...>>::type...>(
- args, std::get<tuple_ids>(args)...,
- ((void)rest_ids, ExcessiveArg())...);
- }
+template <typename Impl>
+struct ImplBase {
+ struct Holder {
+ // Allows each copy of the Action<> to get to the Impl.
+ explicit operator const Impl&() const { return *ptr; }
+ std::shared_ptr<Impl> ptr;
+ };
+ using type = typename std::conditional<std::is_constructible<Impl>::value,
+ Impl, Holder>::type;
};
-// A helper base class needed for implementing the ACTION* macros.
-// Implements constructor and conversion operator for Action.
-//
-// Template specialization for parameterless Action.
-template <typename Derived>
-class ActionImpl {
- public:
- ActionImpl() = default;
-
- template <typename F>
- operator ::testing::Action<F>() const { // NOLINT(runtime/explicit)
- return ::testing::Action<F>(new typename Derived::template gmock_Impl<F>());
+template <typename R, typename... Args, typename Impl>
+struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
+ using Base = typename ImplBase<Impl>::type;
+ using function_type = R(Args...);
+ using args_type = std::tuple<Args...>;
+
+ ActionImpl() = default; // Only defined if appropriate for Base.
+ explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} { }
+
+ R operator()(Args&&... arg) const {
+ static constexpr size_t kMaxArgs =
+ sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
+ return Apply(MakeIndexSequence<kMaxArgs>{},
+ MakeIndexSequence<10 - kMaxArgs>{},
+ args_type{std::forward<Args>(arg)...});
}
-};
-
-// Template specialization for parameterized Action.
-template <template <typename...> class Derived, typename... Ts>
-class ActionImpl<Derived<Ts...>> {
- public:
- explicit ActionImpl(Ts... params) : params_(std::forward<Ts>(params)...) {}
- template <typename F>
- operator ::testing::Action<F>() const { // NOLINT(runtime/explicit)
- return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{});
+ template <std::size_t... arg_id, std::size_t... excess_id>
+ R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
+ const args_type& args) const {
+ // Impl need not be specific to the signature of action being implemented;
+ // only the implementing function body needs to have all of the specific
+ // types instantiated. Up to 10 of the args that are provided by the
+ // args_type get passed, followed by a dummy of unspecified type for the
+ // remainder up to 10 explicit args.
+ static const ExcessiveArg kExcessArg;
+ return static_cast<const Impl&>(*this).template gmock_PerformImpl<
+ /*function_type=*/function_type, /*return_type=*/R,
+ /*args_type=*/args_type,
+ /*argN_type=*/typename std::tuple_element<arg_id, args_type>::type...>(
+ /*args=*/args, std::get<arg_id>(args)...,
+ ((void)excess_id, kExcessArg)...);
}
+};
- private:
- template <typename F, std::size_t... tuple_ids>
- ::testing::Action<F> Apply(IndexSequence<tuple_ids...>) const {
- return ::testing::Action<F>(new
- typename Derived<Ts...>::template gmock_Impl<F>(
- std::get<tuple_ids>(params_)...));
- }
+// Stores a default-constructed Impl as part of the Action<>'s
+// std::function<>. The Impl should be trivial to copy.
+template <typename F, typename Impl>
+::testing::Action<F> MakeAction() {
+ return ::testing::Action<F>(ActionImpl<F, Impl>());
+}
- std::tuple<Ts...> params_;
-};
+// Stores just the one given instance of Impl.
+template <typename F, typename Impl>
+::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) {
+ return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl)));
+}
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
-#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
+#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
GMOCK_INTERNAL_ARG_UNUSED, , 10)
@@ -1582,30 +1586,28 @@ class ActionImpl<Derived<Ts...>> {
#define GMOCK_INTERNAL_ACTION(name, full_name, params) \
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
- class full_name : public ::testing::internal::ActionImpl< \
- full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>> { \
- using base_type = ::testing::internal::ActionImpl<full_name>; \
- \
+ class full_name { \
public: \
- using base_type::base_type; \
+ explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
+ : impl_(std::make_shared<gmock_Impl>( \
+ GMOCK_ACTION_GVALUE_PARAMS_(params))) { } \
+ full_name(const full_name&) = default; \
+ full_name(full_name&&) noexcept = default; \
template <typename F> \
- class gmock_Impl : public ::testing::ActionInterface<F> { \
+ operator ::testing::Action<F>() const { \
+ return ::testing::internal::MakeAction<F>(impl_); \
+ } \
+ private: \
+ class gmock_Impl { \
public: \
- typedef F function_type; \
- typedef typename ::testing::internal::Function<F>::Result return_type; \
- typedef \
- typename ::testing::internal::Function<F>::ArgumentTuple args_type; \
explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
: GMOCK_ACTION_INIT_PARAMS_(params) {} \
- return_type Perform(const args_type& args) override { \
- return ::testing::internal::ActionHelper<return_type, \
- gmock_Impl>::Perform(this, \
- args); \
- } \
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ template <typename function_type, typename return_type, \
+ typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
GMOCK_ACTION_FIELD_PARAMS_(params) \
}; \
+ std::shared_ptr<const gmock_Impl> impl_; \
}; \
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
@@ -1614,48 +1616,37 @@ class ActionImpl<Derived<Ts...>> {
GMOCK_ACTION_GVALUE_PARAMS_(params)); \
} \
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
- template <typename F> \
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
- typename ::testing::internal::Function<F>::Result \
- full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl< \
- F>::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) \
- const
+ template <typename function_type, typename return_type, typename args_type, \
+ GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \
+ gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
} // namespace internal
+// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored.
#define ACTION(name) \
- class name##Action : public ::testing::internal::ActionImpl<name##Action> { \
- using base_type = ::testing::internal::ActionImpl<name##Action>; \
- \
+ class name##Action { \
public: \
- using base_type::base_type; \
- name##Action() = default; \
- /* Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134 */ \
- name##Action(const name##Action&) { } \
+ explicit name##Action() noexcept {} \
+ name##Action(const name##Action&) noexcept {} \
template <typename F> \
- class gmock_Impl : public ::testing::ActionInterface<F> { \
+ operator ::testing::Action<F>() const { \
+ return ::testing::internal::MakeAction<F, gmock_Impl>(); \
+ } \
+ private: \
+ class gmock_Impl { \
public: \
- typedef F function_type; \
- typedef typename ::testing::internal::Function<F>::Result return_type; \
- typedef \
- typename ::testing::internal::Function<F>::ArgumentTuple args_type; \
- gmock_Impl() {} \
- return_type Perform(const args_type& args) override { \
- return ::testing::internal::ActionHelper<return_type, \
- gmock_Impl>::Perform(this, \
- args); \
- } \
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ template <typename function_type, typename return_type, \
+ typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
}; \
}; \
inline name##Action name() GTEST_MUST_USE_RESULT_; \
inline name##Action name() { return name##Action(); } \
- template <typename F> \
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
- typename ::testing::internal::Function<F>::Result \
- name##Action::gmock_Impl<F>::gmock_PerformImpl( \
- GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
+ template <typename function_type, typename return_type, typename args_type, \
+ GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ return_type name##Action::gmock_Impl::gmock_PerformImpl( \
+ GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
#define ACTION_P(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))
diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-generated-actions.h
index 8446513..9240ce9 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h
+++ b/googlemock/include/gmock/gmock-generated-actions.h
@@ -296,7 +296,7 @@
// Defines the copy constructor
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
- {} // Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
+ noexcept {} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;
@@ -429,66 +429,66 @@
#define GMOCK_ACTION_CLASS_(name, value_params)\
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
-#define ACTION_TEMPLATE(name, template_params, value_params)\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- class GMOCK_ACTION_CLASS_(name, value_params) {\
- public:\
- explicit GMOCK_ACTION_CLASS_(name, value_params)\
- GMOCK_INTERNAL_INIT_##value_params {}\
- GMOCK_ACTION_CLASS_(name, value_params)(\
- const GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params>&)\
- GMOCK_INTERNAL_DEFN_COPY_##value_params\
- template <typename F>\
- class gmock_Impl : public ::testing::ActionInterface<F> {\
- public:\
- typedef F function_type;\
- typedef typename ::testing::internal::Function<F>::Result return_type;\
- typedef typename ::testing::internal::Function<F>::ArgumentTuple\
- args_type;\
- explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
- return_type Perform(const args_type& args) override {\
- return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
- Perform(this, args);\
- }\
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
- return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\
- GMOCK_INTERNAL_DEFN_##value_params\
- };\
- template <typename F> operator ::testing::Action<F>() const {\
- return ::testing::Action<F>(\
- new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
- }\
- GMOCK_INTERNAL_DEFN_##value_params\
- };\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
- GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- inline GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
- GMOCK_INTERNAL_DECL_##value_params) {\
- return GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
- GMOCK_INTERNAL_LIST_##value_params);\
- }\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- template <typename F>\
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
- typename ::testing::internal::Function<F>::Result\
- GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
- gmock_PerformImpl(\
+#define ACTION_TEMPLATE(name, template_params, value_params) \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ class GMOCK_ACTION_CLASS_(name, value_params) { \
+ public: \
+ explicit GMOCK_ACTION_CLASS_(name, value_params)( \
+ GMOCK_INTERNAL_DECL_##value_params) \
+ GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
+ = default; , \
+ : impl_(std::make_shared<gmock_Impl>( \
+ GMOCK_INTERNAL_LIST_##value_params)) { }) \
+ GMOCK_ACTION_CLASS_(name, value_params)( \
+ const GMOCK_ACTION_CLASS_(name, value_params)&) \
+ GMOCK_INTERNAL_DEFN_COPY_##value_params \
+ GMOCK_ACTION_CLASS_(name, value_params)( \
+ GMOCK_ACTION_CLASS_(name, value_params)&&) \
+ GMOCK_INTERNAL_DEFN_COPY_##value_params \
+ template <typename F> \
+ operator ::testing::Action<F>() const { \
+ return GMOCK_PP_IF( \
+ GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
+ (::testing::internal::MakeAction<F, gmock_Impl>()), \
+ (::testing::internal::MakeAction<F>(impl_))); \
+ } \
+ private: \
+ class gmock_Impl { \
+ public: \
+ explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \
+ template <typename function_type, typename return_type, \
+ typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
+ GMOCK_INTERNAL_DEFN_##value_params \
+ }; \
+ GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
+ , std::shared_ptr<const gmock_Impl> impl_;) \
+ }; \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
+ GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ inline GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
+ GMOCK_INTERNAL_DECL_##value_params) { \
+ return GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
+ GMOCK_INTERNAL_LIST_##value_params); \
+ } \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ template <typename function_type, typename return_type, typename args_type, \
+ GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ return_type GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
namespace testing {
diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump
index 0bdb42e..982caf9 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h.pump
+++ b/googlemock/include/gmock/gmock-generated-actions.h.pump
@@ -181,7 +181,7 @@ $range j 0..i-1
$for i [[
#define GMOCK_INTERNAL_DEFN_COPY_AND_$i[[]]_VALUE_PARAMS$if i == 0[[() \
- {} // Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
+ noexcept {} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
]] $else [[(...) = default;]]
@@ -243,66 +243,66 @@ $if i==1 [[P]] $elif i>=2 [[P$i]]
$range k 0..n-1
-#define ACTION_TEMPLATE(name, template_params, value_params)\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- class GMOCK_ACTION_CLASS_(name, value_params) {\
- public:\
- explicit GMOCK_ACTION_CLASS_(name, value_params)\
- GMOCK_INTERNAL_INIT_##value_params {}\
- GMOCK_ACTION_CLASS_(name, value_params)(\
- const GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params>&)\
- GMOCK_INTERNAL_DEFN_COPY_##value_params\
- template <typename F>\
- class gmock_Impl : public ::testing::ActionInterface<F> {\
- public:\
- typedef F function_type;\
- typedef typename ::testing::internal::Function<F>::Result return_type;\
- typedef typename ::testing::internal::Function<F>::ArgumentTuple\
- args_type;\
- explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
- return_type Perform(const args_type& args) override {\
- return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
- Perform(this, args);\
- }\
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
- return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\
- GMOCK_INTERNAL_DEFN_##value_params\
- };\
- template <typename F> operator ::testing::Action<F>() const {\
- return ::testing::Action<F>(\
- new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
- }\
- GMOCK_INTERNAL_DEFN_##value_params\
- };\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
- GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- inline GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
- GMOCK_INTERNAL_DECL_##value_params) {\
- return GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
- GMOCK_INTERNAL_LIST_##value_params);\
- }\
- template <GMOCK_INTERNAL_DECL_##template_params\
- GMOCK_INTERNAL_DECL_TYPE_##value_params>\
- template <typename F>\
- template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
- typename ::testing::internal::Function<F>::Result\
- GMOCK_ACTION_CLASS_(name, value_params)<\
- GMOCK_INTERNAL_LIST_##template_params\
- GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
- gmock_PerformImpl(\
+#define ACTION_TEMPLATE(name, template_params, value_params) \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ class GMOCK_ACTION_CLASS_(name, value_params) { \
+ public: \
+ explicit GMOCK_ACTION_CLASS_(name, value_params)( \
+ GMOCK_INTERNAL_DECL_##value_params) \
+ GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
+ = default; , \
+ : impl_(std::make_shared<gmock_Impl>( \
+ GMOCK_INTERNAL_LIST_##value_params)) { }) \
+ GMOCK_ACTION_CLASS_(name, value_params)( \
+ const GMOCK_ACTION_CLASS_(name, value_params)&) \
+ GMOCK_INTERNAL_DEFN_COPY_##value_params \
+ GMOCK_ACTION_CLASS_(name, value_params)( \
+ GMOCK_ACTION_CLASS_(name, value_params)&&) \
+ GMOCK_INTERNAL_DEFN_COPY_##value_params \
+ template <typename F> \
+ operator ::testing::Action<F>() const { \
+ return GMOCK_PP_IF( \
+ GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
+ (::testing::internal::MakeAction<F, gmock_Impl>()), \
+ (::testing::internal::MakeAction<F>(impl_))); \
+ } \
+ private: \
+ class gmock_Impl { \
+ public: \
+ explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \
+ template <typename function_type, typename return_type, \
+ typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
+ GMOCK_INTERNAL_DEFN_##value_params \
+ }; \
+ GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
+ , std::shared_ptr<const gmock_Impl> impl_;) \
+ }; \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
+ GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ inline GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
+ GMOCK_INTERNAL_DECL_##value_params) { \
+ return GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
+ GMOCK_INTERNAL_LIST_##value_params); \
+ } \
+ template <GMOCK_INTERNAL_DECL_##template_params \
+ GMOCK_INTERNAL_DECL_TYPE_##value_params> \
+ template <typename function_type, typename return_type, typename args_type, \
+ GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
+ return_type GMOCK_ACTION_CLASS_(name, value_params)< \
+ GMOCK_INTERNAL_LIST_##template_params \
+ GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
namespace testing {