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
This commit is contained in:
parent
0c400f67fc
commit
fbef0711cf
@ -1480,64 +1480,68 @@ namespace internal {
|
|||||||
// TYPE DIRECTLY.
|
// TYPE DIRECTLY.
|
||||||
struct ExcessiveArg {};
|
struct ExcessiveArg {};
|
||||||
|
|
||||||
// A helper class needed for implementing the ACTION* macros.
|
// Builds an implementation of an Action<> for some particular signature, using
|
||||||
template <typename Result, class Impl>
|
// a class defined by an ACTION* macro.
|
||||||
class ActionHelper {
|
template <typename F, typename Impl> struct ActionImpl;
|
||||||
public:
|
|
||||||
template <typename... Ts>
|
template <typename Impl>
|
||||||
static Result Perform(Impl* impl, const std::tuple<Ts...>& args) {
|
struct ImplBase {
|
||||||
static constexpr size_t kMaxArgs = sizeof...(Ts) <= 10 ? sizeof...(Ts) : 10;
|
struct Holder {
|
||||||
return Apply(impl, args, MakeIndexSequence<kMaxArgs>{},
|
// Allows each copy of the Action<> to get to the Impl.
|
||||||
MakeIndexSequence<10 - kMaxArgs>{});
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
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)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
template <std::size_t... arg_id, std::size_t... excess_id>
|
||||||
template <typename... Ts, std::size_t... tuple_ids, std::size_t... rest_ids>
|
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
|
||||||
static Result Apply(Impl* impl, const std::tuple<Ts...>& args,
|
const args_type& args) const {
|
||||||
IndexSequence<tuple_ids...>, IndexSequence<rest_ids...>) {
|
// Impl need not be specific to the signature of action being implemented;
|
||||||
return impl->template gmock_PerformImpl<
|
// only the implementing function body needs to have all of the specific
|
||||||
typename std::tuple_element<tuple_ids, std::tuple<Ts...>>::type...>(
|
// types instantiated. Up to 10 of the args that are provided by the
|
||||||
args, std::get<tuple_ids>(args)...,
|
// args_type get passed, followed by a dummy of unspecified type for the
|
||||||
((void)rest_ids, ExcessiveArg())...);
|
// 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)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A helper base class needed for implementing the ACTION* macros.
|
// Stores a default-constructed Impl as part of the Action<>'s
|
||||||
// Implements constructor and conversion operator for Action.
|
// std::function<>. The Impl should be trivial to copy.
|
||||||
//
|
template <typename F, typename Impl>
|
||||||
// Template specialization for parameterless Action.
|
::testing::Action<F> MakeAction() {
|
||||||
template <typename Derived>
|
return ::testing::Action<F>(ActionImpl<F, Impl>());
|
||||||
class ActionImpl {
|
}
|
||||||
public:
|
|
||||||
ActionImpl() = default;
|
|
||||||
|
|
||||||
template <typename F>
|
// Stores just the one given instance of Impl.
|
||||||
operator ::testing::Action<F>() const { // NOLINT(runtime/explicit)
|
template <typename F, typename Impl>
|
||||||
return ::testing::Action<F>(new typename Derived::template gmock_Impl<F>());
|
::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) {
|
||||||
}
|
return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl)));
|
||||||
};
|
}
|
||||||
|
|
||||||
// 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)>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
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_)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::tuple<Ts...> params_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
||||||
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
|
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
|
||||||
@ -1582,30 +1586,28 @@ class ActionImpl<Derived<Ts...>> {
|
|||||||
|
|
||||||
#define GMOCK_INTERNAL_ACTION(name, full_name, params) \
|
#define GMOCK_INTERNAL_ACTION(name, full_name, params) \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
class full_name : public ::testing::internal::ActionImpl< \
|
class full_name { \
|
||||||
full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>> { \
|
|
||||||
using base_type = ::testing::internal::ActionImpl<full_name>; \
|
|
||||||
\
|
|
||||||
public: \
|
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> \
|
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: \
|
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)) \
|
explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
|
||||||
: GMOCK_ACTION_INIT_PARAMS_(params) {} \
|
: GMOCK_ACTION_INIT_PARAMS_(params) {} \
|
||||||
return_type Perform(const args_type& args) override { \
|
template <typename function_type, typename return_type, \
|
||||||
return ::testing::internal::ActionHelper<return_type, \
|
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
gmock_Impl>::Perform(this, \
|
|
||||||
args); \
|
|
||||||
} \
|
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
|
||||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||||
GMOCK_ACTION_FIELD_PARAMS_(params) \
|
GMOCK_ACTION_FIELD_PARAMS_(params) \
|
||||||
}; \
|
}; \
|
||||||
|
std::shared_ptr<const gmock_Impl> impl_; \
|
||||||
}; \
|
}; \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||||
@ -1614,47 +1616,36 @@ class ActionImpl<Derived<Ts...>> {
|
|||||||
GMOCK_ACTION_GVALUE_PARAMS_(params)); \
|
GMOCK_ACTION_GVALUE_PARAMS_(params)); \
|
||||||
} \
|
} \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
template <typename F> \
|
template <typename function_type, typename return_type, typename args_type, \
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
typename ::testing::internal::Function<F>::Result \
|
return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \
|
||||||
full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl< \
|
gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||||
F>::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) \
|
|
||||||
const
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored.
|
||||||
#define ACTION(name) \
|
#define ACTION(name) \
|
||||||
class name##Action : public ::testing::internal::ActionImpl<name##Action> { \
|
class name##Action { \
|
||||||
using base_type = ::testing::internal::ActionImpl<name##Action>; \
|
|
||||||
\
|
|
||||||
public: \
|
public: \
|
||||||
using base_type::base_type; \
|
explicit name##Action() noexcept {} \
|
||||||
name##Action() = default; \
|
name##Action(const name##Action&) noexcept {} \
|
||||||
/* Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134 */ \
|
|
||||||
name##Action(const name##Action&) { } \
|
|
||||||
template <typename F> \
|
template <typename F> \
|
||||||
class gmock_Impl : public ::testing::ActionInterface<F> { \
|
operator ::testing::Action<F>() const { \
|
||||||
public: \
|
return ::testing::internal::MakeAction<F, gmock_Impl>(); \
|
||||||
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_> \
|
private: \
|
||||||
|
class gmock_Impl { \
|
||||||
|
public: \
|
||||||
|
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; \
|
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||||
}; \
|
}; \
|
||||||
}; \
|
}; \
|
||||||
inline name##Action name() GTEST_MUST_USE_RESULT_; \
|
inline name##Action name() GTEST_MUST_USE_RESULT_; \
|
||||||
inline name##Action name() { return name##Action(); } \
|
inline name##Action name() { return name##Action(); } \
|
||||||
template <typename F> \
|
template <typename function_type, typename return_type, typename args_type, \
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
typename ::testing::internal::Function<F>::Result \
|
return_type name##Action::gmock_Impl::gmock_PerformImpl( \
|
||||||
name##Action::gmock_Impl<F>::gmock_PerformImpl( \
|
|
||||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||||
|
|
||||||
#define ACTION_P(name, ...) \
|
#define ACTION_P(name, ...) \
|
||||||
|
@ -296,7 +296,7 @@
|
|||||||
|
|
||||||
// Defines the copy constructor
|
// Defines the copy constructor
|
||||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
|
#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_1_VALUE_PARAMS(...) = default;
|
||||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;
|
#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;
|
||||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;
|
#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;
|
||||||
@ -429,66 +429,66 @@
|
|||||||
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
||||||
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||||
|
|
||||||
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
#define ACTION_TEMPLATE(name, template_params, value_params) \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
class GMOCK_ACTION_CLASS_(name, value_params) { \
|
||||||
public:\
|
public: \
|
||||||
explicit GMOCK_ACTION_CLASS_(name, value_params)\
|
explicit GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
GMOCK_INTERNAL_DECL_##value_params) \
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)(\
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
const GMOCK_ACTION_CLASS_(name, value_params)<\
|
= default; , \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
: impl_(std::make_shared<gmock_Impl>( \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>&)\
|
GMOCK_INTERNAL_LIST_##value_params)) { }) \
|
||||||
GMOCK_INTERNAL_DEFN_COPY_##value_params\
|
GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||||
template <typename F>\
|
const GMOCK_ACTION_CLASS_(name, value_params)&) \
|
||||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
GMOCK_INTERNAL_DEFN_COPY_##value_params \
|
||||||
public:\
|
GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||||
typedef F function_type;\
|
GMOCK_ACTION_CLASS_(name, value_params)&&) \
|
||||||
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
GMOCK_INTERNAL_DEFN_COPY_##value_params \
|
||||||
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
template <typename F> \
|
||||||
args_type;\
|
operator ::testing::Action<F>() const { \
|
||||||
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
|
return GMOCK_PP_IF( \
|
||||||
return_type Perform(const args_type& args) override {\
|
GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
(::testing::internal::MakeAction<F, gmock_Impl>()), \
|
||||||
Perform(this, args);\
|
(::testing::internal::MakeAction<F>(impl_))); \
|
||||||
}\
|
} \
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
|
private: \
|
||||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\
|
class gmock_Impl { \
|
||||||
GMOCK_INTERNAL_DEFN_##value_params\
|
public: \
|
||||||
};\
|
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \
|
||||||
template <typename F> operator ::testing::Action<F>() const {\
|
template <typename function_type, typename return_type, \
|
||||||
return ::testing::Action<F>(\
|
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||||
}\
|
GMOCK_INTERNAL_DEFN_##value_params \
|
||||||
GMOCK_INTERNAL_DEFN_##value_params\
|
}; \
|
||||||
};\
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
, std::shared_ptr<const gmock_Impl> impl_;) \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
}; \
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
|
||||||
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
inline GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_DECL_##value_params) {\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
GMOCK_INTERNAL_DECL_##value_params) { \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
return GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_LIST_##value_params);\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
}\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
GMOCK_INTERNAL_LIST_##value_params); \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
} \
|
||||||
template <typename F>\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
typename ::testing::internal::Function<F>::Result\
|
template <typename function_type, typename return_type, typename args_type, \
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
return_type GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
gmock_PerformImpl(\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \
|
||||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
@ -181,7 +181,7 @@ $range j 0..i-1
|
|||||||
|
|
||||||
$for i [[
|
$for i [[
|
||||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_$i[[]]_VALUE_PARAMS$if i == 0[[() \
|
#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;]]
|
]] $else [[(...) = default;]]
|
||||||
|
|
||||||
|
|
||||||
@ -243,66 +243,66 @@ $if i==1 [[P]] $elif i>=2 [[P$i]]
|
|||||||
|
|
||||||
$range k 0..n-1
|
$range k 0..n-1
|
||||||
|
|
||||||
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
#define ACTION_TEMPLATE(name, template_params, value_params) \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
class GMOCK_ACTION_CLASS_(name, value_params) { \
|
||||||
public:\
|
public: \
|
||||||
explicit GMOCK_ACTION_CLASS_(name, value_params)\
|
explicit GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
GMOCK_INTERNAL_DECL_##value_params) \
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)(\
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
const GMOCK_ACTION_CLASS_(name, value_params)<\
|
= default; , \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
: impl_(std::make_shared<gmock_Impl>( \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>&)\
|
GMOCK_INTERNAL_LIST_##value_params)) { }) \
|
||||||
GMOCK_INTERNAL_DEFN_COPY_##value_params\
|
GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||||
template <typename F>\
|
const GMOCK_ACTION_CLASS_(name, value_params)&) \
|
||||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
GMOCK_INTERNAL_DEFN_COPY_##value_params \
|
||||||
public:\
|
GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||||
typedef F function_type;\
|
GMOCK_ACTION_CLASS_(name, value_params)&&) \
|
||||||
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
GMOCK_INTERNAL_DEFN_COPY_##value_params \
|
||||||
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
template <typename F> \
|
||||||
args_type;\
|
operator ::testing::Action<F>() const { \
|
||||||
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
|
return GMOCK_PP_IF( \
|
||||||
return_type Perform(const args_type& args) override {\
|
GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
(::testing::internal::MakeAction<F, gmock_Impl>()), \
|
||||||
Perform(this, args);\
|
(::testing::internal::MakeAction<F>(impl_))); \
|
||||||
}\
|
} \
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
|
private: \
|
||||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\
|
class gmock_Impl { \
|
||||||
GMOCK_INTERNAL_DEFN_##value_params\
|
public: \
|
||||||
};\
|
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \
|
||||||
template <typename F> operator ::testing::Action<F>() const {\
|
template <typename function_type, typename return_type, \
|
||||||
return ::testing::Action<F>(\
|
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||||
}\
|
GMOCK_INTERNAL_DEFN_##value_params \
|
||||||
GMOCK_INTERNAL_DEFN_##value_params\
|
}; \
|
||||||
};\
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
, std::shared_ptr<const gmock_Impl> impl_;) \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
}; \
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
|
||||||
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
inline GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_DECL_##value_params) {\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
GMOCK_INTERNAL_DECL_##value_params) { \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
return GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_LIST_##value_params);\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
}\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
GMOCK_INTERNAL_LIST_##value_params); \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
} \
|
||||||
template <typename F>\
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
typename ::testing::internal::Function<F>::Result\
|
template <typename function_type, typename return_type, typename args_type, \
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
GMOCK_INTERNAL_LIST_##template_params\
|
return_type GMOCK_ACTION_CLASS_(name, value_params)< \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
GMOCK_INTERNAL_LIST_##template_params \
|
||||||
gmock_PerformImpl(\
|
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \
|
||||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
Loading…
Reference in New Issue
Block a user