Googletest export
Upgrade WithArgs family of actions to C++11. PiperOrigin-RevId: 221671690
This commit is contained in:
committed by
Gennadiy Civil
parent
e46e87bb1f
commit
aac18185eb
@@ -1061,6 +1061,24 @@ class DoBothAction {
|
||||
GTEST_DISALLOW_ASSIGN_(DoBothAction);
|
||||
};
|
||||
|
||||
template <typename InnerAction, size_t... I>
|
||||
struct WithArgsAction {
|
||||
InnerAction action;
|
||||
|
||||
// The inner action could be anything convertible to Action<X>.
|
||||
// We use the conversion operator to detect the signature of the inner Action.
|
||||
template <typename R, typename... Args>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)>
|
||||
converted(action);
|
||||
|
||||
return [converted](Args... args) -> R {
|
||||
return converted.Perform(std::forward_as_tuple(
|
||||
std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// An Unused object can be implicitly constructed from ANY value.
|
||||
@@ -1111,6 +1129,37 @@ Action<To>::Action(const Action<From>& from)
|
||||
: new internal::ActionAdaptor<To, From>(from)) {
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <size_t k, typename InnerAction>
|
||||
internal::WithArgsAction<typename std::decay<InnerAction>::type, k>
|
||||
WithArg(InnerAction&& action) {
|
||||
return {std::forward<InnerAction>(action)};
|
||||
}
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
// different argument lists.
|
||||
template <size_t k, size_t... ks, typename InnerAction>
|
||||
internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>
|
||||
WithArgs(InnerAction&& action) {
|
||||
return {std::forward<InnerAction>(action)};
|
||||
}
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
internal::WithArgsAction<typename std::decay<InnerAction>::type>
|
||||
WithoutArgs(InnerAction&& action) {
|
||||
return {std::forward<InnerAction>(action)};
|
||||
}
|
||||
|
||||
// Creates an action that returns 'value'. 'value' is passed by value
|
||||
// instead of const reference - otherwise Return("string literal")
|
||||
// will trigger a compiler error about using array as initializer.
|
||||
|
||||
@@ -352,235 +352,6 @@ class InvokeCallbackAction {
|
||||
const std::shared_ptr<CallbackType> callback_;
|
||||
};
|
||||
|
||||
// An INTERNAL macro for extracting the type of a tuple field. It's
|
||||
// subject to change without notice - DO NOT USE IN USER CODE!
|
||||
#define GMOCK_FIELD_(Tuple, N) \
|
||||
typename ::std::tuple_element<N, Tuple>::type
|
||||
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
|
||||
// type of an n-ary function whose i-th (1-based) argument type is the
|
||||
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
|
||||
// type, and whose return type is Result. For example,
|
||||
// SelectArgs<int, ::std::tuple<bool, char, double, long>, 0, 3>::type
|
||||
// is int(bool, long).
|
||||
//
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
|
||||
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
|
||||
// For example,
|
||||
// SelectArgs<int, std::tuple<bool, char, double>, 2, 0>::Select(
|
||||
// ::std::make_tuple(true, 'a', 2.5))
|
||||
// returns tuple (2.5, true).
|
||||
//
|
||||
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
|
||||
// in the range [0, 10]. Duplicates are allowed and they don't have
|
||||
// to be in an ascending or descending order.
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4, int k5, int k6, int k7, int k8, int k9, int k10>
|
||||
class SelectArgs {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
|
||||
GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
|
||||
GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9),
|
||||
GMOCK_FIELD_(ArgumentTuple, k10));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args), std::get<k5>(args),
|
||||
std::get<k6>(args), std::get<k7>(args), std::get<k8>(args),
|
||||
std::get<k9>(args), std::get<k10>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type();
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& /* args */) {
|
||||
return SelectedArgs();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, -1, -1, -1, -1, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, -1, -1, -1, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, -1, -1, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4, int k5>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, k5, -1, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args), std::get<k5>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4, int k5, int k6>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, k5, k6, -1, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
|
||||
GMOCK_FIELD_(ArgumentTuple, k6));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args), std::get<k5>(args),
|
||||
std::get<k6>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4, int k5, int k6, int k7>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, k5, k6, k7, -1, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
|
||||
GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args), std::get<k5>(args),
|
||||
std::get<k6>(args), std::get<k7>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4, int k5, int k6, int k7, int k8>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, k5, k6, k7, k8, -1, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
|
||||
GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
|
||||
GMOCK_FIELD_(ArgumentTuple, k8));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args), std::get<k5>(args),
|
||||
std::get<k6>(args), std::get<k7>(args), std::get<k8>(args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
|
||||
int k4, int k5, int k6, int k7, int k8, int k9>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, k5, k6, k7, k8, k9, -1> {
|
||||
public:
|
||||
typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
|
||||
GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
|
||||
GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
|
||||
GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
|
||||
GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9));
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs(std::get<k1>(args), std::get<k2>(args),
|
||||
std::get<k3>(args), std::get<k4>(args), std::get<k5>(args),
|
||||
std::get<k6>(args), std::get<k7>(args), std::get<k8>(args),
|
||||
std::get<k9>(args));
|
||||
}
|
||||
};
|
||||
|
||||
#undef GMOCK_FIELD_
|
||||
|
||||
// Implements the WithArgs action.
|
||||
template <typename InnerAction, int k1 = -1, int k2 = -1, int k3 = -1,
|
||||
int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
|
||||
int k9 = -1, int k10 = -1>
|
||||
class WithArgsAction {
|
||||
public:
|
||||
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
|
||||
|
||||
private:
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(const InnerAction& action) : action_(action) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return action_.Perform(SelectArgs<Result, ArgumentTuple, k1, k2, k3, k4,
|
||||
k5, k6, k7, k8, k9, k10>::Select(args));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename SelectArgs<Result, ArgumentTuple,
|
||||
k1, k2, k3, k4, k5, k6, k7, k8, k9, k10>::type InnerFunctionType;
|
||||
|
||||
Action<InnerFunctionType> action_;
|
||||
};
|
||||
|
||||
const InnerAction action_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
|
||||
};
|
||||
|
||||
// A macro from the ACTION* family (defined later in this file)
|
||||
// defines an action that can be used in a mock function. Typically,
|
||||
// these actions only care about a subset of the arguments of the mock
|
||||
@@ -704,82 +475,6 @@ class ActionHelper {
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
// different argument lists. C++ doesn't support default arguments for
|
||||
// function templates, so we have to overload it.
|
||||
template <int k1, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, int k5, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
|
||||
typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6,
|
||||
k7>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
|
||||
typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7,
|
||||
k8>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
|
||||
int k9, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, k9>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
|
||||
k9>(action);
|
||||
}
|
||||
|
||||
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
|
||||
int k9, int k10, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
|
||||
k9, k10>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
|
||||
k9, k10>(action);
|
||||
}
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
template <typename Action1, typename Action2>
|
||||
|
||||
@@ -122,97 +122,6 @@ class InvokeCallbackAction {
|
||||
const std::shared_ptr<CallbackType> callback_;
|
||||
};
|
||||
|
||||
// An INTERNAL macro for extracting the type of a tuple field. It's
|
||||
// subject to change without notice - DO NOT USE IN USER CODE!
|
||||
#define GMOCK_FIELD_(Tuple, N) \
|
||||
typename ::std::tuple_element<N, Tuple>::type
|
||||
|
||||
$range i 1..n
|
||||
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
|
||||
// type of an n-ary function whose i-th (1-based) argument type is the
|
||||
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
|
||||
// type, and whose return type is Result. For example,
|
||||
// SelectArgs<int, ::std::tuple<bool, char, double, long>, 0, 3>::type
|
||||
// is int(bool, long).
|
||||
//
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
|
||||
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
|
||||
// For example,
|
||||
// SelectArgs<int, std::tuple<bool, char, double>, 2, 0>::Select(
|
||||
// ::std::make_tuple(true, 'a', 2.5))
|
||||
// returns tuple (2.5, true).
|
||||
//
|
||||
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
|
||||
// in the range [0, $n]. Duplicates are allowed and they don't have
|
||||
// to be in an ascending or descending order.
|
||||
|
||||
template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
|
||||
class SelectArgs {
|
||||
public:
|
||||
typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
return SelectedArgs($for i, [[std::get<k$i>(args)]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..n
|
||||
$range j1 1..i-1
|
||||
template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
$for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
|
||||
public:
|
||||
typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& [[]]
|
||||
$if i == 1 [[/* args */]] $else [[args]]) {
|
||||
return SelectedArgs($for j1, [[std::get<k$j1>(args)]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
#undef GMOCK_FIELD_
|
||||
|
||||
$var ks = [[$for i, [[k$i]]]]
|
||||
|
||||
// Implements the WithArgs action.
|
||||
template <typename InnerAction, $for i, [[int k$i = -1]]>
|
||||
class WithArgsAction {
|
||||
public:
|
||||
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
|
||||
|
||||
private:
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(const InnerAction& action) : action_(action) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename SelectArgs<Result, ArgumentTuple,
|
||||
$ks>::type InnerFunctionType;
|
||||
|
||||
Action<InnerFunctionType> action_;
|
||||
};
|
||||
|
||||
const InnerAction action_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
|
||||
};
|
||||
|
||||
// A macro from the ACTION* family (defined later in this file)
|
||||
// defines an action that can be used in a mock function. Typically,
|
||||
// these actions only care about a subset of the arguments of the mock
|
||||
@@ -257,25 +166,6 @@ $template
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
// different argument lists. C++ doesn't support default arguments for
|
||||
// function templates, so we have to overload it.
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j [[int k$j, ]]typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
$range i 2..n
|
||||
|
||||
@@ -127,27 +127,6 @@ PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction>
|
||||
WithoutArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction>(action);
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <int k, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k>
|
||||
WithArg(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k>(action);
|
||||
}
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
|
||||
Reference in New Issue
Block a user