Googletest export

Refactor the `Invoke` and `InvokeWithoutArgs` actions:
 - Replace pump'd classes and functions with templates.
 - Make the polymorphic actions be polymorphic functors instead.
 - Fix Invoke(Callback*) to work with subclasses of the callbacks, instead of trying to diagnose that in gmock_doctor.

PiperOrigin-RevId: 229604112
This commit is contained in:
Abseil Team
2019-01-16 15:23:44 -05:00
committed by Alex Strelnikov
parent eb9225ce36
commit 0adeadd283
7 changed files with 56 additions and 497 deletions

View File

@@ -50,308 +50,6 @@
namespace testing {
namespace internal {
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
// function, method, or callback with the unpacked values, where F is
// a function type that takes N arguments.
template <typename Result, typename ArgumentTuple>
class InvokeHelper;
template <typename R>
class InvokeHelper<R, ::std::tuple<> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<>&) {
return function();
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<>&) {
return (obj_ptr->*method_ptr)();
}
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::std::tuple<>&) {
return callback->Run();
}
};
template <typename R, typename A1>
class InvokeHelper<R, ::std::tuple<A1> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1>& args) {
return function(std::get<0>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args));
}
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::std::tuple<A1>& args) {
return callback->Run(std::get<0>(args));
}
};
template <typename R, typename A1, typename A2>
class InvokeHelper<R, ::std::tuple<A1, A2> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2>& args) {
return function(std::get<0>(args), std::get<1>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args));
}
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::std::tuple<A1, A2>& args) {
return callback->Run(std::get<0>(args), std::get<1>(args));
}
};
template <typename R, typename A1, typename A2, typename A3>
class InvokeHelper<R, ::std::tuple<A1, A2, A3> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args));
}
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::std::tuple<A1, A2, A3>& args) {
return callback->Run(std::get<0>(args), std::get<1>(args),
std::get<2>(args));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args));
}
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::std::tuple<A1, A2, A3, A4>& args) {
return callback->Run(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4, A5> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4,
A5>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4, A5>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args));
}
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::std::tuple<A1, A2, A3, A4, A5>& args) {
return callback->Run(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4, A5, A6> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4, A5,
A6>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4, A5, A6>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args));
}
// There is no InvokeCallback() for 6-tuples
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4, A5, A6, A7> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4, A5, A6,
A7>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4, A5, A6, A7>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args));
}
// There is no InvokeCallback() for 7-tuples
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4, A5, A6,
A7, A8>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args), std::get<7>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4, A5, A6, A7,
A8>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args), std::get<7>(args));
}
// There is no InvokeCallback() for 8-tuples
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4, A5, A6,
A7, A8, A9>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args), std::get<7>(args),
std::get<8>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
A9>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args), std::get<7>(args),
std::get<8>(args));
}
// There is no InvokeCallback() for 9-tuples
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9,
typename A10>
class InvokeHelper<R, ::std::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tuple<A1, A2, A3, A4, A5, A6,
A7, A8, A9, A10>& args) {
return function(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args), std::get<7>(args),
std::get<8>(args), std::get<9>(args));
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
A10>& args) {
return (obj_ptr->*method_ptr)(std::get<0>(args), std::get<1>(args),
std::get<2>(args), std::get<3>(args), std::get<4>(args),
std::get<5>(args), std::get<6>(args), std::get<7>(args),
std::get<8>(args), std::get<9>(args));
}
// There is no InvokeCallback() for 10-tuples
};
// Implements the Invoke(callback) action.
template <typename CallbackType>
class InvokeCallbackAction {
public:
// The c'tor takes ownership of the callback.
explicit InvokeCallbackAction(CallbackType* callback)
: callback_(callback) {
callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
}
// This type conversion operator template allows Invoke(callback) to
// be used wherever the callback's type is compatible with that of
// the mock function, i.e. if the mock function's arguments can be
// implicitly converted to the callback's arguments and the
// callback's result can be implicitly converted to the mock
// function's result.
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) const {
return InvokeHelper<Result, ArgumentTuple>::InvokeCallback(
callback_.get(), args);
}
private:
const std::shared_ptr<CallbackType> callback_;
};
// 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