130#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
131#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
142#include <type_traits>
150# pragma warning(push)
151# pragma warning(disable:4100)
172template <
typename T,
bool kDefaultConstructible>
174 static T
Get() {
return T(); }
179 Assert(
false, __FILE__, __LINE__,
180 "Default action undefined for the function return type.");
181 return internal::Invalid<T>();
224 static T*
Get() {
return nullptr; }
229#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \
231 class BuiltInDefaultValue<type> { \
233 static bool Exists() { return true; } \
234 static type Get() { return value; } \
250#if GMOCK_WCHAR_T_IS_NATIVE_
265#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
268template <
typename P,
typename Q>
293 producer_ =
new FixedValueProducer(
x);
302 producer_ =
new FactoryValueProducer(factory);
312 static bool IsSet() {
return producer_ !=
nullptr; }
325 : producer_->Produce();
329 class ValueProducer {
331 virtual ~ValueProducer() {}
332 virtual T Produce() = 0;
335 class FixedValueProducer :
public ValueProducer {
337 explicit FixedValueProducer(T
value) : value_(
value) {}
338 T Produce()
override {
return value_; }
345 class FactoryValueProducer :
public ValueProducer {
348 : factory_(factory) {}
349 T Produce()
override {
return factory_(); }
356 static ValueProducer* producer_;
370 static void Clear() { address_ =
nullptr; }
373 static bool IsSet() {
return address_ !=
nullptr; }
404typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ =
nullptr;
408T* DefaultValue<T&>::address_ =
nullptr;
441 struct ActionAdapter {
443 ::std::shared_ptr<ActionInterface<F>> impl_;
445 template <
typename... Args>
447 return impl_->Perform(
448 ::std::forward_as_tuple(::std::forward<Args>(args)...));
452 template <
typename G>
453 using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>;
469 IsCompatibleFunctor<G>, std::is_constructible<std::function<
Result()>,
472 Init(::std::forward<G>(fun), IsCompatibleFunctor<G>());
482 template <
typename Func>
502 template <
typename G>
505 template <
typename G>
506 void Init(G&& g, ::std::true_type) {
507 fun_ = ::std::forward<G>(g);
510 template <
typename G>
511 void Init(G&& g, ::std::false_type) {
515 template <
typename FunctionImpl>
517 template <
typename... Args>
518 Result operator()(
const Args&...)
const {
519 return function_impl();
522 FunctionImpl function_impl;
526 ::std::function<F> fun_;
550template <
typename Impl>
555 template <
typename F>
557 return Action<F>(
new MonomorphicImpl<F>(impl_));
561 template <
typename F>
567 explicit MonomorphicImpl(
const Impl& impl) : impl_(impl) {}
569 Result Perform(
const ArgumentTuple& args)
override {
570 return impl_.template Perform<Result>(args);
594template <
typename Impl>
646 template <
typename F>
659 use_ReturnRef_instead_of_Return_to_return_a_reference);
661 "Can't use Return() on an action expected to return `void`.");
662 return Action<F>(
new Impl<R, F>(value_));
667 template <
typename R_,
typename F>
680 explicit Impl(
const std::shared_ptr<R>&
value)
681 : value_before_cast_(*
value),
684 Result Perform(
const ArgumentTuple&)
override {
return value_; }
688 Result_cannot_be_a_reference_type);
691 R value_before_cast_;
699 template <
typename R_,
typename F>
700 class Impl<ByMoveWrapper<R_>, F> :
public ActionInterface<F> {
702 typedef typename Function<F>::Result Result;
703 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
705 explicit Impl(
const std::shared_ptr<R>& wrapper)
706 : performed_(false), wrapper_(wrapper) {}
708 Result Perform(
const ArgumentTuple&)
override {
710 <<
"A ByMove() action should only be performed once.";
712 return std::move(wrapper_->payload);
717 const std::shared_ptr<R> wrapper_;
720 const std::shared_ptr<R> value_;
729 template <
typename Result,
typename ArgumentTuple>
739 template <
typename Result,
typename ArgumentTuple>
756 template <
typename F>
763 use_Return_instead_of_ReturnRef_to_return_a_value);
769 template <
typename F>
775 explicit Impl(T& ref) : ref_(ref) {}
777 Result Perform(
const ArgumentTuple&)
override {
return ref_; }
798 template <
typename F>
806 use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
812 template <
typename F>
818 explicit Impl(
const T&
value) : value_(
value) {}
820 Result Perform(
const ArgumentTuple&)
override {
return value_; }
836 <<
"ReturnRoundRobin requires at least one element.";
837 state_->values = std::move(values);
840 template <
typename... Args>
842 return state_->Next();
848 T ret_val = values[
i++];
849 if (
i == values.size())
i = 0;
853 std::vector<T> values;
856 std::shared_ptr<State> state_ = std::make_shared<State>();
864 template <
typename F>
870template <
typename T1,
typename T2>
875 template <
typename Result,
typename ArgumentTuple>
885#if !GTEST_OS_WINDOWS_MOBILE
893 : errno_(errno_value),
895 template <
typename Result,
typename ArgumentTuple>
910template <
size_t N,
typename A,
typename =
void>
914 template <
typename... Args>
916 *::std::get<N>(std::tie(args...)) =
value;
921template <
class Class,
typename MethodPtr>
926 template <
typename... Args>
937template <
typename FunctionImpl>
943 template <
typename... Args>
950template <
class Class,
typename MethodPtr>
956 decltype((std::declval<Class*>()->*std::declval<MethodPtr>())());
958 template <
typename... Args>
970 template <
typename F>
989 template <
typename F>
997 void Perform(
const ArgumentTuple& args)
override {
999 action_.Perform(args);
1005 typedef typename internal::Function<F>::MakeResultIgnoredValue
1008 const Action<OriginalFunction> action_;
1014template <
typename InnerAction,
size_t... I>
1020 template <
typename R,
typename... Args>
1022 using TupleType = std::tuple<Args...>;
1026 return [converted](Args... args) -> R {
1027 return converted.
Perform(std::forward_as_tuple(
1028 std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
1033template <
typename... Actions>
1036 template <
typename T>
1037 using NonFinalType =
1040 template <
typename ActionT,
size_t... I>
1042 return {ActionT(std::get<I>(
actions))...};
1048 template <
typename R,
typename... Args>
1051 std::vector<
Action<void(NonFinalType<Args>...)>> converted;
1053 R operator()(Args... args)
const {
1054 auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
1055 for (
auto& a : converted) {
1056 a.Perform(tuple_args);
1058 return last.Perform(std::move(tuple_args));
1061 return Op{Convert<
Action<void(NonFinalType<Args>...)>>(
1063 std::get<
sizeof...(Actions) - 1>(
actions)};
1067template <
typename T,
typename... Params>
1071 [](
const Params&... unpacked_params) {
1072 return new T(unpacked_params...);
1081 template <
typename... Args>
1083 typename std::tuple_element<k, std::tuple<Args...>>
::type {
1084 return std::get<k>(std::tie(args...));
1088template <
size_t k,
typename Ptr>
1092 template <
typename... Args>
1094 *
pointer = std::get<k>(std::tie(args...));
1098template <
size_t k,
typename Ptr>
1102 template <
typename... Args>
1104 *
pointer = *std::get<k>(std::tie(args...));
1108template <
size_t k,
typename T>
1112 template <
typename... Args>
1115 typename ::std::tuple_element<k, std::tuple<Args...>>
::type;
1117 "Argument must be a reference type.");
1118 std::get<k>(std::tie(args...)) =
value;
1122template <
size_t k,
typename I1,
typename I2>
1127 template <
typename... Args>
1129 auto value = std::get<k>(std::tie(args...));
1138 template <
typename... Args>
1140 delete std::get<k>(std::tie(args...));
1144template <
typename Ptr>
1147 template <
typename... Args>
1153#if GTEST_HAS_EXCEPTIONS
1154template <
typename T>
1158 template <
typename R,
typename... Args>
1159 operator Action<R(Args...)>()
const {
1161 return [copy](Args...) -> R {
throw copy; };
1203template <
typename...
Action>
1206 return {std::forward_as_tuple(std::forward<Action>(
action)...)};
1214template <
size_t k,
typename InnerAction>
1217 return {std::forward<InnerAction>(
action)};
1224template <
size_t k,
size_t... ks,
typename InnerAction>
1227 return {std::forward<InnerAction>(
action)};
1234template <
typename InnerAction>
1237 return {std::forward<InnerAction>(
action)};
1243template <
typename R>
1259template <
typename R>
1265template <
typename R, R* =
nullptr>
1271template <
typename R>
1280template <
typename R>
1288template <
typename T>
1296template <
typename T>
1298 std::initializer_list<T> vals) {
1309template <
size_t N,
typename T>
1311 return {std::move(
value)};
1315template <
size_t N,
typename T>
1317 return {std::move(
value)};
1321template <
typename T1,
typename T2>
1326#if !GTEST_OS_WINDOWS_MOBILE
1329template <
typename T>
1330PolymorphicAction<internal::SetErrnoAndReturnAction<T> >
1344template <
typename FunctionImpl>
1346 return std::forward<FunctionImpl>(function_impl);
1351template <
class Class,
typename MethodPtr>
1353 MethodPtr method_ptr) {
1354 return {obj_ptr, method_ptr};
1358template <
typename FunctionImpl>
1361 return {std::move(function_impl)};
1366template <
class Class,
typename MethodPtr>
1368 Class* obj_ptr, MethodPtr method_ptr) {
1369 return {obj_ptr, method_ptr};
1375template <
typename A>
1390template <
typename T>
1391inline ::std::reference_wrapper<T>
ByRef(T& l_value) {
1392 return ::std::reference_wrapper<T>(l_value);
1398template <
typename T,
typename... Params>
1400 Params&&... params) {
1401 return {std::forward_as_tuple(std::forward<Params>(params)...)};
1412template <
size_t k,
typename Ptr>
1419template <
size_t k,
typename Ptr>
1426template <
size_t k,
typename T>
1429 return {std::forward<T>(
value)};
1437template <
size_t k,
typename I1,
typename I2>
1440 return {first,
last};
1451template <
typename Ptr>
1458#if GTEST_HAS_EXCEPTIONS
1459template <
typename T>
1461 return {std::forward<T>(exception)};
1487template <
typename Impl>
1491 explicit operator const Impl&()
const {
return *
ptr; }
1498template <
typename R,
typename... Args,
typename Impl>
1508 static constexpr size_t kMaxArgs =
1509 sizeof...(Args) <= 10 ?
sizeof...(Args) : 10;
1515 template <std::size_t... arg_id, std::size_t... excess_id>
1524 return static_cast<const Impl&
>(*this).template gmock_PerformImpl<
1528 args, std::get<arg_id>(args)...,
1529 ((void)excess_id, kExcessArg)...);
1535template <
typename F,
typename Impl>
1541template <
typename F,
typename Impl>
1546#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
1547 , const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
1548#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
1549 const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
1550 GMOCK_INTERNAL_ARG_UNUSED, , 10)
1552#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
1553#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \
1554 const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10)
1556#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type
1557#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \
1558 GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10))
1560#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type
1561#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \
1562 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params))
1564#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type
1565#define GMOCK_ACTION_TYPE_PARAMS_(params) \
1566 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params))
1568#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \
1569 , param##_type gmock_p##i
1570#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \
1571 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params))
1573#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \
1574 , std::forward<param##_type>(gmock_p##i)
1575#define GMOCK_ACTION_GVALUE_PARAMS_(params) \
1576 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params))
1578#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \
1579 , param(::std::forward<param##_type>(gmock_p##i))
1580#define GMOCK_ACTION_INIT_PARAMS_(params) \
1581 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params))
1583#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param;
1584#define GMOCK_ACTION_FIELD_PARAMS_(params) \
1585 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params)
1587#define GMOCK_INTERNAL_ACTION(name, full_name, params) \
1588 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
1591 explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
1592 : impl_(std::make_shared<gmock_Impl>( \
1593 GMOCK_ACTION_GVALUE_PARAMS_(params))) { } \
1594 full_name(const full_name&) = default; \
1595 full_name(full_name&&) noexcept = default; \
1596 template <typename F> \
1597 operator ::testing::Action<F>() const { \
1598 return ::testing::internal::MakeAction<F>(impl_); \
1601 class gmock_Impl { \
1603 explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
1604 : GMOCK_ACTION_INIT_PARAMS_(params) {} \
1605 template <typename function_type, typename return_type, \
1606 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
1607 return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
1608 GMOCK_ACTION_FIELD_PARAMS_(params) \
1610 std::shared_ptr<const gmock_Impl> impl_; \
1612 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
1613 inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
1614 GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
1615 return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \
1616 GMOCK_ACTION_GVALUE_PARAMS_(params)); \
1618 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
1619 template <typename function_type, typename return_type, typename args_type, \
1620 GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
1621 return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \
1622 gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1627#define ACTION(name) \
1628 class name##Action { \
1630 explicit name##Action() noexcept {} \
1631 name##Action(const name##Action&) noexcept {} \
1632 template <typename F> \
1633 operator ::testing::Action<F>() const { \
1634 return ::testing::internal::MakeAction<F, gmock_Impl>(); \
1637 class gmock_Impl { \
1639 template <typename function_type, typename return_type, \
1640 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
1641 return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
1644 inline name##Action name() GTEST_MUST_USE_RESULT_; \
1645 inline name##Action name() { return name##Action(); } \
1646 template <typename function_type, typename return_type, typename args_type, \
1647 GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
1648 return_type name##Action::gmock_Impl::gmock_PerformImpl( \
1649 GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
1651#define ACTION_P(name, ...) \
1652 GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))
1654#define ACTION_P2(name, ...) \
1655 GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__))
1657#define ACTION_P3(name, ...) \
1658 GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__))
1660#define ACTION_P4(name, ...) \
1661 GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__))
1663#define ACTION_P5(name, ...) \
1664 GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__))
1666#define ACTION_P6(name, ...) \
1667 GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__))
1669#define ACTION_P7(name, ...) \
1670 GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__))
1672#define ACTION_P8(name, ...) \
1673 GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__))
1675#define ACTION_P9(name, ...) \
1676 GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__))
1678#define ACTION_P10(name, ...) \
1679 GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__))
1684# pragma warning(pop)
#define GTEST_CHECK_(condition)
#define GTEST_COMPILE_ASSERT_(expr, msg)
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)
internal::DeleteArgAction< k > DeleteArg()
internal::WithArgsAction< typename std::decay< InnerAction >::type > WithoutArgs(InnerAction &&action)
internal::SaveArgAction< k, Ptr > SaveArg(Ptr pointer)
internal::ReturnRoundRobinAction< T > ReturnRoundRobin(std::vector< T > vals)
internal::SaveArgPointeeAction< k, Ptr > SaveArgPointee(Ptr pointer)
internal::IgnoreResultAction< A > IgnoreResult(const A &an_action)
internal::SetArrayArgumentAction< k, I1, I2 > SetArrayArgument(I1 first, I2 last)
internal::SetArgRefereeAction< k, typename std::decay< T >::type > SetArgReferee(T &&value)
internal::ReturnPointeeAction< Ptr > ReturnPointee(Ptr pointer)
inline ::std::reference_wrapper< T > ByRef(T &l_value)
internal::DoAllAction< typename std::decay< Action >::type... > DoAll(Action &&... action)
internal::ByMoveWrapper< R > ByMove(R x)
PolymorphicAction< Impl > MakePolymorphicAction(const Impl &impl)
internal::WithArgsAction< typename std::decay< InnerAction >::type, k, ks... > WithArgs(InnerAction &&action)
internal::IgnoredValue Unused
PolymorphicAction< internal::AssignAction< T1, T2 > > Assign(T1 *ptr, T2 val)
internal::SetArgumentPointeeAction< N, T > SetArgPointee(T value)
PolymorphicAction< internal::SetErrnoAndReturnAction< T > > SetErrnoAndReturn(int errval, T result)
Action< F > MakeAction(ActionInterface< F > *impl)
internal::InvokeWithoutArgsAction< typename std::decay< FunctionImpl >::type > InvokeWithoutArgs(FunctionImpl function_impl)
internal::ReturnArgAction< k > ReturnArg()
internal::WithArgsAction< typename std::decay< InnerAction >::type, k > WithArg(InnerAction &&action)
internal::ReturnRefOfCopyAction< R > ReturnRefOfCopy(const R &x)
internal::ReturnRefAction< R > ReturnRef(R &x)
internal::SetArgumentPointeeAction< N, T > SetArgumentPointee(T value)
internal::ReturnNewAction< T, typename std::decay< Params >::type... > ReturnNew(Params &&... params)
internal::ReturnAction< R > Return(R value)
internal::DoDefaultAction DoDefault()
PolymorphicAction< internal::ReturnNullAction > ReturnNull()
std::decay< FunctionImpl >::type Invoke(FunctionImpl &&function_impl)
typename ::std::conditional< P::value, P, Q >::type disjunction
auto Apply(F &&f, Tuple &&args) -> decltype(ApplyImpl(std::forward< F >(f), std::forward< Tuple >(args), MakeIndexSequence< std::tuple_size< typename std::remove_reference< Tuple >::type >::value >()))
::testing::Action< F > MakeAction()
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void,)
void Assert(bool condition, const char *file, int line, const std::string &msg)
GTEST_API_ void IllegalDoDefault(const char *file, int line)
typename MakeIndexSequenceImpl< N >::type MakeIndexSequence
static void SetFactory(FactoryFunction factory)
virtual Result Perform(const ArgumentTuple &args)=0
internal::Function< F >::Result Result
virtual ~ActionInterface()
internal::Function< F >::ArgumentTuple ArgumentTuple
Result Perform(ArgumentTuple args) const
Action(ActionInterface< F > *impl)
Action(const Action< Func > &action)
internal::Function< F >::Result Result
internal::Function< F >::ArgumentTuple ArgumentTuple
PolymorphicAction(const Impl &impl)
static Result Perform(const ArgumentTuple &)
static void Perform(const ArgumentTuple &)
ReturnRefOfCopyAction(const T &value)
T operator()(Args &&...) const
ReturnRoundRobinAction(std::vector< T > values)
void Perform(const ArgumentTuple &) const
AssignAction(T1 *ptr, T2 value)
Result Perform(const ArgumentTuple &) const
SetErrnoAndReturnAction(int errno_value, T result)
void operator()(const Args &... args) const
auto operator()(Args &&... args) const -> decltype((obj_ptr-> *method_ptr)(std::forward< Args >(args)...))
const MethodPtr method_ptr
FunctionImpl function_impl
auto operator()(const Args &...) -> decltype(function_impl())
ReturnType operator()(const Args &...) const
const MethodPtr method_ptr
decltype((std::declval< Class * >() -> *std::declval< MethodPtr >())()) ReturnType
IgnoreResultAction(const A &action)
std::tuple< Actions... > actions
std::tuple< Params... > params
auto operator()(const Args &... args) const -> typename std::tuple_element< k, std::tuple< Args... > >::type
void operator()(const Args &... args) const
void operator()(const Args &... args) const
void operator()(Args &&... args) const
void operator()(const Args &... args) const
void operator()(const Args &... args) const
auto operator()(const Args &...) const -> decltype(*pointer)
typename std::conditional< std::is_constructible< Impl >::value, Impl, Holder >::type type
std::shared_ptr< Impl > ptr
std::tuple< Args... > args_type
R operator()(Args &&... arg) const
R Apply(IndexSequence< arg_id... >, IndexSequence< excess_id... >, const args_type &args) const
ActionImpl(std::shared_ptr< Impl > impl)