Googletest export
Replace pump'd code for DoAll with variadic templates. PiperOrigin-RevId: 225584656
This commit is contained in:
parent
b5f5c596a9
commit
096fb37a19
@ -574,7 +574,7 @@ class ReturnAction {
|
||||
// This template type conversion operator allows Return(x) to be
|
||||
// used in ANY function that returns x's type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
operator Action<F>() const { // NOLINT
|
||||
// Assert statement belongs here because this is the best place to verify
|
||||
// conditions on F. It produces the clearest error messages
|
||||
// in most compilers.
|
||||
@ -587,6 +587,8 @@ class ReturnAction {
|
||||
GTEST_COMPILE_ASSERT_(
|
||||
!is_reference<Result>::value,
|
||||
use_ReturnRef_instead_of_Return_to_return_a_reference);
|
||||
static_assert(!std::is_void<Result>::value,
|
||||
"Can't use Return() on an action expected to return `void`.");
|
||||
return Action<F>(new Impl<R, F>(value_));
|
||||
}
|
||||
|
||||
@ -1017,51 +1019,6 @@ void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
|
||||
UniversalPrinter<T&>::Print(value, os);
|
||||
}
|
||||
|
||||
// Does two actions sequentially. Used for implementing the DoAll(a1,
|
||||
// a2, ...) action.
|
||||
template <typename Action1, typename Action2>
|
||||
class DoBothAction {
|
||||
public:
|
||||
DoBothAction(Action1 action1, Action2 action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
// This template type conversion operator allows DoAll(a1, ..., a_n)
|
||||
// to be used in ANY function of compatible type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new Impl<F>(action1_, action2_));
|
||||
}
|
||||
|
||||
private:
|
||||
// Implements the DoAll(...) action for a particular function type F.
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
typedef typename Function<F>::MakeResultVoid VoidResult;
|
||||
|
||||
Impl(const Action<VoidResult>& action1, const Action<F>& action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
Result Perform(const ArgumentTuple& args) override {
|
||||
action1_.Perform(args);
|
||||
return action2_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
const Action<VoidResult> action1_;
|
||||
const Action<F> action2_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(Impl);
|
||||
};
|
||||
|
||||
Action1 action1_;
|
||||
Action2 action2_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(DoBothAction);
|
||||
};
|
||||
|
||||
template <typename InnerAction, size_t... I>
|
||||
struct WithArgsAction {
|
||||
InnerAction action;
|
||||
@ -1080,6 +1037,35 @@ struct WithArgsAction {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Actions>
|
||||
struct DoAllAction {
|
||||
private:
|
||||
template <typename... Args, size_t... I>
|
||||
std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
|
||||
return {std::get<I>(actions)...};
|
||||
}
|
||||
|
||||
public:
|
||||
std::tuple<Actions...> actions;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
struct Op {
|
||||
std::vector<Action<void(Args...)>> converted;
|
||||
Action<R(Args...)> last;
|
||||
R operator()(Args... args) const {
|
||||
auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
|
||||
for (auto& a : converted) {
|
||||
a.Perform(tuple_args);
|
||||
}
|
||||
return last.Perform(tuple_args);
|
||||
}
|
||||
};
|
||||
return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()),
|
||||
std::get<sizeof...(Actions) - 1>(actions)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// An Unused object can be implicitly constructed from ANY value.
|
||||
@ -1130,6 +1116,14 @@ Action<To>::Action(const Action<From>& from)
|
||||
: new internal::ActionAdaptor<To, From>(from)) {
|
||||
}
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
template <typename... Action>
|
||||
internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
|
||||
Action&&... action) {
|
||||
return {std::forward_as_tuple(std::forward<Action>(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
|
||||
|
@ -474,97 +474,6 @@ class ActionHelper {
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
template <typename Action1, typename Action2>
|
||||
inline internal::DoBothAction<Action1, Action2>
|
||||
DoAll(Action1 a1, Action2 a2) {
|
||||
return internal::DoBothAction<Action1, Action2>(a1, a2);
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
Action3> >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3) {
|
||||
return DoAll(a1, DoAll(a2, a3));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, Action4> > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4, typename Action5>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, internal::DoBothAction<Action4,
|
||||
Action5> > > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4, typename Action5, typename Action6>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, internal::DoBothAction<Action4,
|
||||
internal::DoBothAction<Action5, Action6> > > > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4, a5, a6));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4, typename Action5, typename Action6, typename Action7>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, internal::DoBothAction<Action4,
|
||||
internal::DoBothAction<Action5, internal::DoBothAction<Action6,
|
||||
Action7> > > > > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
Action7 a7) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4, typename Action5, typename Action6, typename Action7,
|
||||
typename Action8>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, internal::DoBothAction<Action4,
|
||||
internal::DoBothAction<Action5, internal::DoBothAction<Action6,
|
||||
internal::DoBothAction<Action7, Action8> > > > > > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
Action7 a7, Action8 a8) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4, typename Action5, typename Action6, typename Action7,
|
||||
typename Action8, typename Action9>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, internal::DoBothAction<Action4,
|
||||
internal::DoBothAction<Action5, internal::DoBothAction<Action6,
|
||||
internal::DoBothAction<Action7, internal::DoBothAction<Action8,
|
||||
Action9> > > > > > > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
Action7 a7, Action8 a8, Action9 a9) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9));
|
||||
}
|
||||
|
||||
template <typename Action1, typename Action2, typename Action3,
|
||||
typename Action4, typename Action5, typename Action6, typename Action7,
|
||||
typename Action8, typename Action9, typename Action10>
|
||||
inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
|
||||
internal::DoBothAction<Action3, internal::DoBothAction<Action4,
|
||||
internal::DoBothAction<Action5, internal::DoBothAction<Action6,
|
||||
internal::DoBothAction<Action7, internal::DoBothAction<Action8,
|
||||
internal::DoBothAction<Action9, Action10> > > > > > > > >
|
||||
DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
Action7 a7, Action8 a8, Action9 a9, Action10 a10) {
|
||||
return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// The ACTION* family of macros can be used in a namespace scope to
|
||||
|
@ -165,34 +165,6 @@ $template
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var types = [[$for j, [[typename Action$j]]]]
|
||||
$var Aas = [[$for j [[, Action$j a$j]]]]
|
||||
|
||||
template <typename Action1, $types>
|
||||
$range k 1..i-1
|
||||
|
||||
inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
|
||||
|
||||
DoAll(Action1 a1$Aas) {
|
||||
$if i==2 [[
|
||||
|
||||
return internal::DoBothAction<Action1, Action2>(a1, a2);
|
||||
]] $else [[
|
||||
$range j2 2..i
|
||||
|
||||
return DoAll(a1, DoAll($for j2, [[a$j2]]));
|
||||
]]
|
||||
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// The ACTION* family of macros can be used in a namespace scope to
|
||||
|
Loading…
Reference in New Issue
Block a user