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:
parent
eb9225ce36
commit
0adeadd283
@ -817,69 +817,47 @@ class SetArgumentPointeeAction<N, Proto, true> {
|
|||||||
GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
|
GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||||
|
template <class Class, typename MethodPtr>
|
||||||
|
struct InvokeMethodAction {
|
||||||
|
Class* const obj_ptr;
|
||||||
|
const MethodPtr method_ptr;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
auto operator()(Args&&... args) const
|
||||||
|
-> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {
|
||||||
|
return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Implements the InvokeWithoutArgs(f) action. The template argument
|
// Implements the InvokeWithoutArgs(f) action. The template argument
|
||||||
// FunctionImpl is the implementation type of f, which can be either a
|
// FunctionImpl is the implementation type of f, which can be either a
|
||||||
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
||||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
// Action<F> as long as f's type is compatible with F.
|
||||||
// assigned to a tr1::function<F>).
|
|
||||||
template <typename FunctionImpl>
|
template <typename FunctionImpl>
|
||||||
class InvokeWithoutArgsAction {
|
struct InvokeWithoutArgsAction {
|
||||||
public:
|
FunctionImpl function_impl;
|
||||||
// The c'tor makes a copy of function_impl (either a function
|
|
||||||
// pointer or a functor).
|
|
||||||
explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
|
|
||||||
: function_impl_(function_impl) {}
|
|
||||||
|
|
||||||
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
||||||
// compatible with f.
|
// compatible with f.
|
||||||
template <typename Result, typename ArgumentTuple>
|
template <typename... Args>
|
||||||
Result Perform(const ArgumentTuple&) { return function_impl_(); }
|
auto operator()(const Args&...) -> decltype(function_impl()) {
|
||||||
|
return function_impl();
|
||||||
private:
|
}
|
||||||
FunctionImpl function_impl_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
||||||
template <class Class, typename MethodPtr>
|
template <class Class, typename MethodPtr>
|
||||||
class InvokeMethodWithoutArgsAction {
|
struct InvokeMethodWithoutArgsAction {
|
||||||
public:
|
Class* const obj_ptr;
|
||||||
InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
|
const MethodPtr method_ptr;
|
||||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
using ReturnType = typename std::result_of<MethodPtr(Class*)>::type;
|
||||||
Result Perform(const ArgumentTuple&) const {
|
|
||||||
return (obj_ptr_->*method_ptr_)();
|
template <typename... Args>
|
||||||
|
ReturnType operator()(const Args&...) const {
|
||||||
|
return (obj_ptr->*method_ptr)();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
Class* const obj_ptr_;
|
|
||||||
const MethodPtr method_ptr_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements the InvokeWithoutArgs(callback) action.
|
|
||||||
template <typename CallbackType>
|
|
||||||
class InvokeCallbackWithoutArgsAction {
|
|
||||||
public:
|
|
||||||
// The c'tor takes ownership of the callback.
|
|
||||||
explicit InvokeCallbackWithoutArgsAction(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 return type can be implicitly
|
|
||||||
// converted to that of the mock function.
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple&) const { return callback_->Run(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::shared_ptr<CallbackType> callback_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements the IgnoreResult(action) action.
|
// Implements the IgnoreResult(action) action.
|
||||||
@ -1157,24 +1135,38 @@ SetErrnoAndReturn(int errval, T result) {
|
|||||||
|
|
||||||
#endif // !GTEST_OS_WINDOWS_MOBILE
|
#endif // !GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
// Various overloads for InvokeWithoutArgs().
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
|
// Legacy function.
|
||||||
|
// Actions can now be implicitly constructed from callables. No need to create
|
||||||
|
// wrapper objects.
|
||||||
|
// This function exists for backwards compatibility.
|
||||||
|
template <typename FunctionImpl>
|
||||||
|
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||||
|
return std::forward<FunctionImpl>(function_impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an action that invokes the given method on the given object
|
||||||
|
// with the mock function's arguments.
|
||||||
|
template <class Class, typename MethodPtr>
|
||||||
|
internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
|
||||||
|
MethodPtr method_ptr) {
|
||||||
|
return {obj_ptr, method_ptr};
|
||||||
|
}
|
||||||
|
|
||||||
// Creates an action that invokes 'function_impl' with no argument.
|
// Creates an action that invokes 'function_impl' with no argument.
|
||||||
template <typename FunctionImpl>
|
template <typename FunctionImpl>
|
||||||
PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
|
internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
|
||||||
InvokeWithoutArgs(FunctionImpl function_impl) {
|
InvokeWithoutArgs(FunctionImpl function_impl) {
|
||||||
return MakePolymorphicAction(
|
return {std::move(function_impl)};
|
||||||
internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that invokes the given method on the given object
|
// Creates an action that invokes the given method on the given object
|
||||||
// with no argument.
|
// with no argument.
|
||||||
template <class Class, typename MethodPtr>
|
template <class Class, typename MethodPtr>
|
||||||
PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
|
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(
|
||||||
InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
|
Class* obj_ptr, MethodPtr method_ptr) {
|
||||||
return MakePolymorphicAction(
|
return {obj_ptr, method_ptr};
|
||||||
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
|
|
||||||
obj_ptr, method_ptr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that performs an_action and throws away its
|
// Creates an action that performs an_action and throws away its
|
||||||
|
@ -50,308 +50,6 @@
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
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)
|
// A macro from the ACTION* family (defined later in this file)
|
||||||
// defines an action that can be used in a mock function. Typically,
|
// 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
|
// these actions only care about a subset of the arguments of the mock
|
||||||
|
@ -52,76 +52,6 @@ $$}} This meta comment fixes auto-indentation in editors.
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
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;
|
|
||||||
|
|
||||||
|
|
||||||
$var max_callback_arity = 5
|
|
||||||
$range i 0..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var types = [[$for j [[, typename A$j]]]]
|
|
||||||
$var as = [[$for j, [[A$j]]]]
|
|
||||||
$var args = [[$if i==0 [[]] $else [[ args]]]]
|
|
||||||
$var gets = [[$for j, [[std::get<$(j - 1)>(args)]]]]
|
|
||||||
template <typename R$types>
|
|
||||||
class InvokeHelper<R, ::std::tuple<$as> > {
|
|
||||||
public:
|
|
||||||
template <typename Function>
|
|
||||||
static R Invoke(Function function, const ::std::tuple<$as>&$args) {
|
|
||||||
return function($gets);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Class, typename MethodPtr>
|
|
||||||
static R InvokeMethod(Class* obj_ptr,
|
|
||||||
MethodPtr method_ptr,
|
|
||||||
const ::std::tuple<$as>&$args) {
|
|
||||||
return (obj_ptr->*method_ptr)($gets);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$if i <= max_callback_arity [[
|
|
||||||
template <typename CallbackType>
|
|
||||||
static R InvokeCallback(CallbackType* callback,
|
|
||||||
const ::std::tuple<$as>&$args) {
|
|
||||||
return callback->Run($gets);
|
|
||||||
}
|
|
||||||
]] $else [[
|
|
||||||
// There is no InvokeCallback() for $i-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)
|
// A macro from the ACTION* family (defined later in this file)
|
||||||
// defines an action that can be used in a mock function. Typically,
|
// 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
|
// these actions only care about a subset of the arguments of the mock
|
||||||
|
@ -38,59 +38,13 @@
|
|||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "gmock/gmock-generated-actions.h"
|
#include "gmock/gmock-generated-actions.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Implements the Invoke(f) action. The template argument
|
|
||||||
// FunctionImpl is the implementation type of f, which can be either a
|
|
||||||
// function pointer or a functor. Invoke(f) can be used as an
|
|
||||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
|
||||||
// assigned to a tr1::function<F>).
|
|
||||||
template <typename FunctionImpl>
|
|
||||||
class InvokeAction {
|
|
||||||
public:
|
|
||||||
// The c'tor makes a copy of function_impl (either a function
|
|
||||||
// pointer or a functor).
|
|
||||||
explicit InvokeAction(FunctionImpl function_impl)
|
|
||||||
: function_impl_(function_impl) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple& args) {
|
|
||||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FunctionImpl function_impl_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
|
||||||
template <class Class, typename MethodPtr>
|
|
||||||
class InvokeMethodAction {
|
|
||||||
public:
|
|
||||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
|
||||||
: method_ptr_(method_ptr), obj_ptr_(obj_ptr) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple& args) const {
|
|
||||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
|
||||||
obj_ptr_, method_ptr_, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The order of these members matters. Reversing the order can trigger
|
|
||||||
// warning C4121 in MSVC (see
|
|
||||||
// http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm ).
|
|
||||||
const MethodPtr method_ptr_;
|
|
||||||
Class* const obj_ptr_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// An internal replacement for std::copy which mimics its behavior. This is
|
// An internal replacement for std::copy which mimics its behavior. This is
|
||||||
// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
|
// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
|
||||||
// However Visual Studio 2010 and later do not honor #pragmas which disable that
|
// However Visual Studio 2010 and later do not honor #pragmas which disable that
|
||||||
@ -109,24 +63,6 @@ inline OutputIterator CopyElements(InputIterator first,
|
|||||||
|
|
||||||
// Various overloads for Invoke().
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
// Creates an action that invokes 'function_impl' with the mock
|
|
||||||
// function's arguments.
|
|
||||||
template <typename FunctionImpl>
|
|
||||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
|
||||||
FunctionImpl function_impl) {
|
|
||||||
return MakePolymorphicAction(
|
|
||||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates an action that invokes the given method on the given object
|
|
||||||
// with the mock function's arguments.
|
|
||||||
template <class Class, typename MethodPtr>
|
|
||||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
|
||||||
Class* obj_ptr, MethodPtr method_ptr) {
|
|
||||||
return MakePolymorphicAction(
|
|
||||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||||
// the macro definition, as the warnings are generated when the macro
|
// the macro definition, as the warnings are generated when the macro
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
@ -54,12 +54,14 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// This list should be kept sorted.
|
// This list should be kept sorted.
|
||||||
|
using testing::_;
|
||||||
using testing::Action;
|
using testing::Action;
|
||||||
using testing::ActionInterface;
|
using testing::ActionInterface;
|
||||||
using testing::Assign;
|
using testing::Assign;
|
||||||
using testing::ByMove;
|
using testing::ByMove;
|
||||||
using testing::ByRef;
|
using testing::ByRef;
|
||||||
using testing::DefaultValue;
|
using testing::DefaultValue;
|
||||||
|
using testing::DoAll;
|
||||||
using testing::DoDefault;
|
using testing::DoDefault;
|
||||||
using testing::IgnoreResult;
|
using testing::IgnoreResult;
|
||||||
using testing::Invoke;
|
using testing::Invoke;
|
||||||
@ -75,7 +77,6 @@ using testing::SetArgPointee;
|
|||||||
using testing::SetArgumentPointee;
|
using testing::SetArgumentPointee;
|
||||||
using testing::Unused;
|
using testing::Unused;
|
||||||
using testing::WithArgs;
|
using testing::WithArgs;
|
||||||
using testing::_;
|
|
||||||
using testing::internal::BuiltInDefaultValue;
|
using testing::internal::BuiltInDefaultValue;
|
||||||
using testing::internal::Int64;
|
using testing::internal::Int64;
|
||||||
using testing::internal::UInt64;
|
using testing::internal::UInt64;
|
||||||
|
@ -78,6 +78,7 @@ using testing::Expectation;
|
|||||||
using testing::ExpectationSet;
|
using testing::ExpectationSet;
|
||||||
using testing::GMOCK_FLAG(verbose);
|
using testing::GMOCK_FLAG(verbose);
|
||||||
using testing::Gt;
|
using testing::Gt;
|
||||||
|
using testing::IgnoreResult;
|
||||||
using testing::InSequence;
|
using testing::InSequence;
|
||||||
using testing::Invoke;
|
using testing::Invoke;
|
||||||
using testing::InvokeWithoutArgs;
|
using testing::InvokeWithoutArgs;
|
||||||
|
Loading…
Reference in New Issue
Block a user