Googletest export

Upgrade WithArgs family of actions to C++11.

PiperOrigin-RevId: 221671690
This commit is contained in:
Abseil Team
2018-11-15 15:43:19 -05:00
committed by Gennadiy Civil
parent 792e898e09
commit 03ab019046
6 changed files with 167 additions and 598 deletions

View File

@@ -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.

View File

@@ -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>

View File

@@ -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

View File

@@ -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