gmock-actions.h (googletest-release-1.10.0) | : | gmock-actions.h (googletest-release-1.11.0) | ||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
// Google Mock - a framework for writing C++ mock classes. | // Google Mock - a framework for writing C++ mock classes. | |||
// | // | |||
// This file implements some commonly used actions. | // The ACTION* family of macros can be used in a namespace scope to | |||
// define custom actions easily. The syntax: | ||||
// | ||||
// ACTION(name) { statements; } | ||||
// | ||||
// will define an action with the given name that executes the | ||||
// statements. The value returned by the statements will be used as | ||||
// the return value of the action. Inside the statements, you can | ||||
// refer to the K-th (0-based) argument of the mock function by | ||||
// 'argK', and refer to its type by 'argK_type'. For example: | ||||
// | ||||
// ACTION(IncrementArg1) { | ||||
// arg1_type temp = arg1; | ||||
// return ++(*temp); | ||||
// } | ||||
// | ||||
// allows you to write | ||||
// | ||||
// ...WillOnce(IncrementArg1()); | ||||
// | ||||
// You can also refer to the entire argument tuple and its type by | ||||
// 'args' and 'args_type', and refer to the mock function type and its | ||||
// return type by 'function_type' and 'return_type'. | ||||
// | ||||
// Note that you don't need to specify the types of the mock function | ||||
// arguments. However rest assured that your code is still type-safe: | ||||
// you'll get a compiler error if *arg1 doesn't support the ++ | ||||
// operator, or if the type of ++(*arg1) isn't compatible with the | ||||
// mock function's return type, for example. | ||||
// | ||||
// Sometimes you'll want to parameterize the action. For that you can use | ||||
// another macro: | ||||
// | ||||
// ACTION_P(name, param_name) { statements; } | ||||
// | ||||
// For example: | ||||
// | ||||
// ACTION_P(Add, n) { return arg0 + n; } | ||||
// | ||||
// will allow you to write: | ||||
// | ||||
// ...WillOnce(Add(5)); | ||||
// | ||||
// Note that you don't need to provide the type of the parameter | ||||
// either. If you need to reference the type of a parameter named | ||||
// 'foo', you can write 'foo_type'. For example, in the body of | ||||
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type | ||||
// of 'n'. | ||||
// | ||||
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support | ||||
// multi-parameter actions. | ||||
// | ||||
// For the purpose of typing, you can view | ||||
// | ||||
// ACTION_Pk(Foo, p1, ..., pk) { ... } | ||||
// | ||||
// as shorthand for | ||||
// | ||||
// template <typename p1_type, ..., typename pk_type> | ||||
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... } | ||||
// | ||||
// In particular, you can provide the template type arguments | ||||
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false); | ||||
// although usually you can rely on the compiler to infer the types | ||||
// for you automatically. You can assign the result of expression | ||||
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ..., | ||||
// pk_type>. This can be useful when composing actions. | ||||
// | ||||
// You can also overload actions with different numbers of parameters: | ||||
// | ||||
// ACTION_P(Plus, a) { ... } | ||||
// ACTION_P2(Plus, a, b) { ... } | ||||
// | ||||
// While it's tempting to always use the ACTION* macros when defining | ||||
// a new action, you should also consider implementing ActionInterface | ||||
// or using MakePolymorphicAction() instead, especially if you need to | ||||
// use the action a lot. While these approaches require more work, | ||||
// they give you more control on the types of the mock function | ||||
// arguments and the action parameters, which in general leads to | ||||
// better compiler error messages that pay off in the long run. They | ||||
// also allow overloading actions based on parameter types (as opposed | ||||
// to just based on the number of parameters). | ||||
// | ||||
// CAVEAT: | ||||
// | ||||
// ACTION*() can only be used in a namespace scope as templates cannot be | ||||
// declared inside of a local class. | ||||
// Users can, however, define any local functors (e.g. a lambda) that | ||||
// can be used as actions. | ||||
// | ||||
// MORE INFORMATION: | ||||
// | ||||
// To learn more about using these macros, please search for 'ACTION' on | ||||
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md | ||||
// GOOGLETEST_CM0002 DO NOT DELETE | // GOOGLETEST_CM0002 DO NOT DELETE | |||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ | |||
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ | |||
#ifndef _WIN32_WCE | #ifndef _WIN32_WCE | |||
# include <errno.h> | # include <errno.h> | |||
#endif | #endif | |||
#include <algorithm> | #include <algorithm> | |||
#include <functional> | #include <functional> | |||
#include <memory> | #include <memory> | |||
#include <string> | #include <string> | |||
#include <tuple> | ||||
#include <type_traits> | #include <type_traits> | |||
#include <utility> | #include <utility> | |||
#include "gmock/internal/gmock-internal-utils.h" | #include "gmock/internal/gmock-internal-utils.h" | |||
#include "gmock/internal/gmock-port.h" | #include "gmock/internal/gmock-port.h" | |||
#include "gmock/internal/gmock-pp.h" | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
# pragma warning(push) | # pragma warning(push) | |||
# pragma warning(disable:4100) | # pragma warning(disable:4100) | |||
#endif | #endif | |||
namespace testing { | namespace testing { | |||
// To implement an action Foo, define: | // To implement an action Foo, define: | |||
// 1. a class FooAction that implements the ActionInterface interface, and | // 1. a class FooAction that implements the ActionInterface interface, and | |||
skipping to change at line 164 | skipping to change at line 259 | |||
#if GMOCK_WCHAR_T_IS_NATIVE_ | #if GMOCK_WCHAR_T_IS_NATIVE_ | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT | |||
#endif | #endif | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0); | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0); | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); | |||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); | GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); | |||
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ | #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ | |||
// Simple two-arg form of std::disjunction. | ||||
template <typename P, typename Q> | ||||
using disjunction = typename ::std::conditional<P::value, P, Q>::type; | ||||
} // namespace internal | } // namespace internal | |||
// When an unexpected function call is encountered, Google Mock will | // When an unexpected function call is encountered, Google Mock will | |||
// let it return a default value if the user has specified one for its | // let it return a default value if the user has specified one for its | |||
// return type, or if the return type has a built-in default value; | // return type, or if the return type has a built-in default value; | |||
// otherwise Google Mock won't know what value to return and will have | // otherwise Google Mock won't know what value to return and will have | |||
// to abort the process. | // to abort the process. | |||
// | // | |||
// The DefaultValue<T> class allows a user to specify the | // The DefaultValue<T> class allows a user to specify the | |||
// default value for a type T that is both copyable and publicly | // default value for a type T that is both copyable and publicly | |||
skipping to change at line 352 | skipping to change at line 451 | |||
// Adapter must be copyable to satisfy std::function requirements. | // Adapter must be copyable to satisfy std::function requirements. | |||
::std::shared_ptr<ActionInterface<F>> impl_; | ::std::shared_ptr<ActionInterface<F>> impl_; | |||
template <typename... Args> | template <typename... Args> | |||
typename internal::Function<F>::Result operator()(Args&&... args) { | typename internal::Function<F>::Result operator()(Args&&... args) { | |||
return impl_->Perform( | return impl_->Perform( | |||
::std::forward_as_tuple(::std::forward<Args>(args)...)); | ::std::forward_as_tuple(::std::forward<Args>(args)...)); | |||
} | } | |||
}; | }; | |||
template <typename G> | ||||
using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>; | ||||
public: | public: | |||
typedef typename internal::Function<F>::Result Result; | typedef typename internal::Function<F>::Result Result; | |||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | |||
// Constructs a null Action. Needed for storing Action objects in | // Constructs a null Action. Needed for storing Action objects in | |||
// STL containers. | // STL containers. | |||
Action() {} | Action() {} | |||
// Construct an Action from a specified callable. | // Construct an Action from a specified callable. | |||
// This cannot take std::function directly, because then Action would not be | // This cannot take std::function directly, because then Action would not be | |||
// directly constructible from lambda (it would require two conversions). | // directly constructible from lambda (it would require two conversions). | |||
template <typename G, | template < | |||
typename = typename ::std::enable_if< | typename G, | |||
::std::is_constructible<::std::function<F>, G>::value>::type> | typename = typename std::enable_if<internal::disjunction< | |||
Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT | IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>, | |||
G>>::value>::type> | ||||
Action(G&& fun) { // NOLINT | ||||
Init(::std::forward<G>(fun), IsCompatibleFunctor<G>()); | ||||
} | ||||
// Constructs an Action from its implementation. | // Constructs an Action from its implementation. | |||
explicit Action(ActionInterface<F>* impl) | explicit Action(ActionInterface<F>* impl) | |||
: fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {} | : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {} | |||
// This constructor allows us to turn an Action<Func> object into an | // This constructor allows us to turn an Action<Func> object into an | |||
// Action<F>, as long as F's arguments can be implicitly converted | // Action<F>, as long as F's arguments can be implicitly converted | |||
// to Func's and Func's return type can be implicitly converted to F's. | // to Func's and Func's return type can be implicitly converted to F's. | |||
template <typename Func> | template <typename Func> | |||
explicit Action(const Action<Func>& action) : fun_(action.fun_) {} | explicit Action(const Action<Func>& action) : fun_(action.fun_) {} | |||
skipping to change at line 398 | skipping to change at line 504 | |||
if (IsDoDefault()) { | if (IsDoDefault()) { | |||
internal::IllegalDoDefault(__FILE__, __LINE__); | internal::IllegalDoDefault(__FILE__, __LINE__); | |||
} | } | |||
return internal::Apply(fun_, ::std::move(args)); | return internal::Apply(fun_, ::std::move(args)); | |||
} | } | |||
private: | private: | |||
template <typename G> | template <typename G> | |||
friend class Action; | friend class Action; | |||
template <typename G> | ||||
void Init(G&& g, ::std::true_type) { | ||||
fun_ = ::std::forward<G>(g); | ||||
} | ||||
template <typename G> | ||||
void Init(G&& g, ::std::false_type) { | ||||
fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)}; | ||||
} | ||||
template <typename FunctionImpl> | ||||
struct IgnoreArgs { | ||||
template <typename... Args> | ||||
Result operator()(const Args&...) const { | ||||
return function_impl(); | ||||
} | ||||
FunctionImpl function_impl; | ||||
}; | ||||
// fun_ is an empty function if and only if this is the DoDefault() action. | // fun_ is an empty function if and only if this is the DoDefault() action. | |||
::std::function<F> fun_; | ::std::function<F> fun_; | |||
}; | }; | |||
// The PolymorphicAction class template makes it easy to implement a | // The PolymorphicAction class template makes it easy to implement a | |||
// polymorphic action (i.e. an action that can be used in mock | // polymorphic action (i.e. an action that can be used in mock | |||
// functions of than one type, e.g. Return()). | // functions of than one type, e.g. Return()). | |||
// | // | |||
// To define a polymorphic action, a user first provides a COPYABLE | // To define a polymorphic action, a user first provides a COPYABLE | |||
// implementation class that has a Perform() method template: | // implementation class that has a Perform() method template: | |||
skipping to change at line 448 | skipping to change at line 574 | |||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | |||
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} | explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} | |||
Result Perform(const ArgumentTuple& args) override { | Result Perform(const ArgumentTuple& args) override { | |||
return impl_.template Perform<Result>(args); | return impl_.template Perform<Result>(args); | |||
} | } | |||
private: | private: | |||
Impl impl_; | Impl impl_; | |||
GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); | ||||
}; | }; | |||
Impl impl_; | Impl impl_; | |||
GTEST_DISALLOW_ASSIGN_(PolymorphicAction); | ||||
}; | }; | |||
// Creates an Action from its implementation and returns it. The | // Creates an Action from its implementation and returns it. The | |||
// created Action object owns the implementation. | // created Action object owns the implementation. | |||
template <typename F> | template <typename F> | |||
Action<F> MakeAction(ActionInterface<F>* impl) { | Action<F> MakeAction(ActionInterface<F>* impl) { | |||
return Action<F>(impl); | return Action<F>(impl); | |||
} | } | |||
// Creates a polymorphic action from its implementation. This is | // Creates a polymorphic action from its implementation. This is | |||
skipping to change at line 595 | skipping to change at line 717 | |||
Result Perform(const ArgumentTuple&) override { | Result Perform(const ArgumentTuple&) override { | |||
GTEST_CHECK_(!performed_) | GTEST_CHECK_(!performed_) | |||
<< "A ByMove() action should only be performed once."; | << "A ByMove() action should only be performed once."; | |||
performed_ = true; | performed_ = true; | |||
return std::move(wrapper_->payload); | return std::move(wrapper_->payload); | |||
} | } | |||
private: | private: | |||
bool performed_; | bool performed_; | |||
const std::shared_ptr<R> wrapper_; | const std::shared_ptr<R> wrapper_; | |||
GTEST_DISALLOW_ASSIGN_(Impl); | ||||
}; | }; | |||
const std::shared_ptr<R> value_; | const std::shared_ptr<R> value_; | |||
GTEST_DISALLOW_ASSIGN_(ReturnAction); | ||||
}; | }; | |||
// Implements the ReturnNull() action. | // Implements the ReturnNull() action. | |||
class ReturnNullAction { | class ReturnNullAction { | |||
public: | public: | |||
// Allows ReturnNull() to be used in any pointer-returning function. In C++11 | // Allows ReturnNull() to be used in any pointer-returning function. In C++11 | |||
// this is enforced by returning nullptr, and in non-C++11 by asserting a | // this is enforced by returning nullptr, and in non-C++11 by asserting a | |||
// pointer type on compile time. | // pointer type on compile time. | |||
template <typename Result, typename ArgumentTuple> | template <typename Result, typename ArgumentTuple> | |||
static Result Perform(const ArgumentTuple&) { | static Result Perform(const ArgumentTuple&) { | |||
skipping to change at line 662 | skipping to change at line 780 | |||
public: | public: | |||
typedef typename Function<F>::Result Result; | typedef typename Function<F>::Result Result; | |||
typedef typename Function<F>::ArgumentTuple ArgumentTuple; | typedef typename Function<F>::ArgumentTuple ArgumentTuple; | |||
explicit Impl(T& ref) : ref_(ref) {} // NOLINT | explicit Impl(T& ref) : ref_(ref) {} // NOLINT | |||
Result Perform(const ArgumentTuple&) override { return ref_; } | Result Perform(const ArgumentTuple&) override { return ref_; } | |||
private: | private: | |||
T& ref_; | T& ref_; | |||
GTEST_DISALLOW_ASSIGN_(Impl); | ||||
}; | }; | |||
T& ref_; | T& ref_; | |||
GTEST_DISALLOW_ASSIGN_(ReturnRefAction); | ||||
}; | }; | |||
// Implements the polymorphic ReturnRefOfCopy(x) action, which can be | // Implements the polymorphic ReturnRefOfCopy(x) action, which can be | |||
// used in any function that returns a reference to the type of x, | // used in any function that returns a reference to the type of x, | |||
// regardless of the argument types. | // regardless of the argument types. | |||
template <typename T> | template <typename T> | |||
class ReturnRefOfCopyAction { | class ReturnRefOfCopyAction { | |||
public: | public: | |||
// Constructs a ReturnRefOfCopyAction object from the reference to | // Constructs a ReturnRefOfCopyAction object from the reference to | |||
// be returned. | // be returned. | |||
skipping to change at line 709 | skipping to change at line 823 | |||
public: | public: | |||
typedef typename Function<F>::Result Result; | typedef typename Function<F>::Result Result; | |||
typedef typename Function<F>::ArgumentTuple ArgumentTuple; | typedef typename Function<F>::ArgumentTuple ArgumentTuple; | |||
explicit Impl(const T& value) : value_(value) {} // NOLINT | explicit Impl(const T& value) : value_(value) {} // NOLINT | |||
Result Perform(const ArgumentTuple&) override { return value_; } | Result Perform(const ArgumentTuple&) override { return value_; } | |||
private: | private: | |||
T value_; | T value_; | |||
GTEST_DISALLOW_ASSIGN_(Impl); | ||||
}; | }; | |||
const T value_; | const T value_; | |||
}; | ||||
// Implements the polymorphic ReturnRoundRobin(v) action, which can be | ||||
// used in any function that returns the element_type of v. | ||||
template <typename T> | ||||
class ReturnRoundRobinAction { | ||||
public: | ||||
explicit ReturnRoundRobinAction(std::vector<T> values) { | ||||
GTEST_CHECK_(!values.empty()) | ||||
<< "ReturnRoundRobin requires at least one element."; | ||||
state_->values = std::move(values); | ||||
} | ||||
template <typename... Args> | ||||
T operator()(Args&&...) const { | ||||
return state_->Next(); | ||||
} | ||||
private: | ||||
struct State { | ||||
T Next() { | ||||
T ret_val = values[i++]; | ||||
if (i == values.size()) i = 0; | ||||
return ret_val; | ||||
} | ||||
GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); | std::vector<T> values; | |||
size_t i = 0; | ||||
}; | ||||
std::shared_ptr<State> state_ = std::make_shared<State>(); | ||||
}; | }; | |||
// Implements the polymorphic DoDefault() action. | // Implements the polymorphic DoDefault() action. | |||
class DoDefaultAction { | class DoDefaultAction { | |||
public: | public: | |||
// This template type conversion operator allows DoDefault() to be | // This template type conversion operator allows DoDefault() to be | |||
// used in any function. | // used in any function. | |||
template <typename F> | template <typename F> | |||
operator Action<F>() const { return Action<F>(); } // NOLINT | operator Action<F>() const { return Action<F>(); } // NOLINT | |||
}; | }; | |||
skipping to change at line 742 | skipping to change at line 882 | |||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} | AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} | |||
template <typename Result, typename ArgumentTuple> | template <typename Result, typename ArgumentTuple> | |||
void Perform(const ArgumentTuple& /* args */) const { | void Perform(const ArgumentTuple& /* args */) const { | |||
*ptr_ = value_; | *ptr_ = value_; | |||
} | } | |||
private: | private: | |||
T1* const ptr_; | T1* const ptr_; | |||
const T2 value_; | const T2 value_; | |||
GTEST_DISALLOW_ASSIGN_(AssignAction); | ||||
}; | }; | |||
#if !GTEST_OS_WINDOWS_MOBILE | #if !GTEST_OS_WINDOWS_MOBILE | |||
// Implements the SetErrnoAndReturn action to simulate return from | // Implements the SetErrnoAndReturn action to simulate return from | |||
// various system calls and libc functions. | // various system calls and libc functions. | |||
template <typename T> | template <typename T> | |||
class SetErrnoAndReturnAction { | class SetErrnoAndReturnAction { | |||
public: | public: | |||
SetErrnoAndReturnAction(int errno_value, T result) | SetErrnoAndReturnAction(int errno_value, T result) | |||
skipping to change at line 765 | skipping to change at line 903 | |||
result_(result) {} | result_(result) {} | |||
template <typename Result, typename ArgumentTuple> | template <typename Result, typename ArgumentTuple> | |||
Result Perform(const ArgumentTuple& /* args */) const { | Result Perform(const ArgumentTuple& /* args */) const { | |||
errno = errno_; | errno = errno_; | |||
return result_; | return result_; | |||
} | } | |||
private: | private: | |||
const int errno_; | const int errno_; | |||
const T result_; | const T result_; | |||
GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction); | ||||
}; | }; | |||
#endif // !GTEST_OS_WINDOWS_MOBILE | #endif // !GTEST_OS_WINDOWS_MOBILE | |||
// Implements the SetArgumentPointee<N>(x) action for any function | // Implements the SetArgumentPointee<N>(x) action for any function | |||
// whose N-th argument (0-based) is a pointer to x's type. | // whose N-th argument (0-based) is a pointer to x's type. | |||
template <size_t N, typename A, typename = void> | template <size_t N, typename A, typename = void> | |||
struct SetArgumentPointeeAction { | struct SetArgumentPointeeAction { | |||
A value; | A value; | |||
skipping to change at line 818 | skipping to change at line 954 | |||
return function_impl(); | return function_impl(); | |||
} | } | |||
}; | }; | |||
// 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> | |||
struct InvokeMethodWithoutArgsAction { | struct InvokeMethodWithoutArgsAction { | |||
Class* const obj_ptr; | Class* const obj_ptr; | |||
const MethodPtr method_ptr; | const MethodPtr method_ptr; | |||
using ReturnType = typename std::result_of<MethodPtr(Class*)>::type; | using ReturnType = | |||
decltype((std::declval<Class*>()->*std::declval<MethodPtr>())()); | ||||
template <typename... Args> | template <typename... Args> | |||
ReturnType operator()(const Args&...) const { | ReturnType operator()(const Args&...) const { | |||
return (obj_ptr->*method_ptr)(); | return (obj_ptr->*method_ptr)(); | |||
} | } | |||
}; | }; | |||
// Implements the IgnoreResult(action) action. | // Implements the IgnoreResult(action) action. | |||
template <typename A> | template <typename A> | |||
class IgnoreResultAction { | class IgnoreResultAction { | |||
skipping to change at line 871 | skipping to change at line 1008 | |||
action_.Perform(args); | action_.Perform(args); | |||
} | } | |||
private: | private: | |||
// Type OriginalFunction is the same as F except that its return | // Type OriginalFunction is the same as F except that its return | |||
// type is IgnoredValue. | // type is IgnoredValue. | |||
typedef typename internal::Function<F>::MakeResultIgnoredValue | typedef typename internal::Function<F>::MakeResultIgnoredValue | |||
OriginalFunction; | OriginalFunction; | |||
const Action<OriginalFunction> action_; | const Action<OriginalFunction> action_; | |||
GTEST_DISALLOW_ASSIGN_(Impl); | ||||
}; | }; | |||
const A action_; | const A action_; | |||
GTEST_DISALLOW_ASSIGN_(IgnoreResultAction); | ||||
}; | }; | |||
template <typename InnerAction, size_t... I> | template <typename InnerAction, size_t... I> | |||
struct WithArgsAction { | struct WithArgsAction { | |||
InnerAction action; | InnerAction action; | |||
// The inner action could be anything convertible to Action<X>. | // The inner action could be anything convertible to Action<X>. | |||
// We use the conversion operator to detect the signature of the inner Action. | // We use the conversion operator to detect the signature of the inner Action. | |||
template <typename R, typename... Args> | template <typename R, typename... Args> | |||
operator Action<R(Args...)>() const { // NOLINT | operator Action<R(Args...)>() const { // NOLINT | |||
Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)> | using TupleType = std::tuple<Args...>; | |||
Action<R(typename std::tuple_element<I, TupleType>::type...)> | ||||
converted(action); | converted(action); | |||
return [converted](Args... args) -> R { | return [converted](Args... args) -> R { | |||
return converted.Perform(std::forward_as_tuple( | return converted.Perform(std::forward_as_tuple( | |||
std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...)); | std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...)); | |||
}; | }; | |||
} | } | |||
}; | }; | |||
template <typename... Actions> | template <typename... Actions> | |||
struct DoAllAction { | struct DoAllAction { | |||
private: | private: | |||
template <typename... Args, size_t... I> | template <typename T> | |||
std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const { | using NonFinalType = | |||
return {std::get<I>(actions)...}; | typename std::conditional<std::is_scalar<T>::value, T, const T&>::type; | |||
template <typename ActionT, size_t... I> | ||||
std::vector<ActionT> Convert(IndexSequence<I...>) const { | ||||
return {ActionT(std::get<I>(actions))...}; | ||||
} | } | |||
public: | public: | |||
std::tuple<Actions...> actions; | std::tuple<Actions...> actions; | |||
template <typename R, typename... Args> | template <typename R, typename... Args> | |||
operator Action<R(Args...)>() const { // NOLINT | operator Action<R(Args...)>() const { // NOLINT | |||
struct Op { | struct Op { | |||
std::vector<Action<void(Args...)>> converted; | std::vector<Action<void(NonFinalType<Args>...)>> converted; | |||
Action<R(Args...)> last; | Action<R(Args...)> last; | |||
R operator()(Args... args) const { | R operator()(Args... args) const { | |||
auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...); | auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...); | |||
for (auto& a : converted) { | for (auto& a : converted) { | |||
a.Perform(tuple_args); | a.Perform(tuple_args); | |||
} | } | |||
return last.Perform(tuple_args); | return last.Perform(std::move(tuple_args)); | |||
} | } | |||
}; | }; | |||
return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()), | return Op{Convert<Action<void(NonFinalType<Args>...)>>( | |||
MakeIndexSequence<sizeof...(Actions) - 1>()), | ||||
std::get<sizeof...(Actions) - 1>(actions)}; | std::get<sizeof...(Actions) - 1>(actions)}; | |||
} | } | |||
}; | }; | |||
template <typename T, typename... Params> | ||||
struct ReturnNewAction { | ||||
T* operator()() const { | ||||
return internal::Apply( | ||||
[](const Params&... unpacked_params) { | ||||
return new T(unpacked_params...); | ||||
}, | ||||
params); | ||||
} | ||||
std::tuple<Params...> params; | ||||
}; | ||||
template <size_t k> | ||||
struct ReturnArgAction { | ||||
template <typename... Args> | ||||
auto operator()(const Args&... args) const -> | ||||
typename std::tuple_element<k, std::tuple<Args...>>::type { | ||||
return std::get<k>(std::tie(args...)); | ||||
} | ||||
}; | ||||
template <size_t k, typename Ptr> | ||||
struct SaveArgAction { | ||||
Ptr pointer; | ||||
template <typename... Args> | ||||
void operator()(const Args&... args) const { | ||||
*pointer = std::get<k>(std::tie(args...)); | ||||
} | ||||
}; | ||||
template <size_t k, typename Ptr> | ||||
struct SaveArgPointeeAction { | ||||
Ptr pointer; | ||||
template <typename... Args> | ||||
void operator()(const Args&... args) const { | ||||
*pointer = *std::get<k>(std::tie(args...)); | ||||
} | ||||
}; | ||||
template <size_t k, typename T> | ||||
struct SetArgRefereeAction { | ||||
T value; | ||||
template <typename... Args> | ||||
void operator()(Args&&... args) const { | ||||
using argk_type = | ||||
typename ::std::tuple_element<k, std::tuple<Args...>>::type; | ||||
static_assert(std::is_lvalue_reference<argk_type>::value, | ||||
"Argument must be a reference type."); | ||||
std::get<k>(std::tie(args...)) = value; | ||||
} | ||||
}; | ||||
template <size_t k, typename I1, typename I2> | ||||
struct SetArrayArgumentAction { | ||||
I1 first; | ||||
I2 last; | ||||
template <typename... Args> | ||||
void operator()(const Args&... args) const { | ||||
auto value = std::get<k>(std::tie(args...)); | ||||
for (auto it = first; it != last; ++it, (void)++value) { | ||||
*value = *it; | ||||
} | ||||
} | ||||
}; | ||||
template <size_t k> | ||||
struct DeleteArgAction { | ||||
template <typename... Args> | ||||
void operator()(const Args&... args) const { | ||||
delete std::get<k>(std::tie(args...)); | ||||
} | ||||
}; | ||||
template <typename Ptr> | ||||
struct ReturnPointeeAction { | ||||
Ptr pointer; | ||||
template <typename... Args> | ||||
auto operator()(const Args&...) const -> decltype(*pointer) { | ||||
return *pointer; | ||||
} | ||||
}; | ||||
#if GTEST_HAS_EXCEPTIONS | ||||
template <typename T> | ||||
struct ThrowAction { | ||||
T exception; | ||||
// We use a conversion operator to adapt to any return type. | ||||
template <typename R, typename... Args> | ||||
operator Action<R(Args...)>() const { // NOLINT | ||||
T copy = exception; | ||||
return [copy](Args...) -> R { throw copy; }; | ||||
} | ||||
}; | ||||
#endif // GTEST_HAS_EXCEPTIONS | ||||
} // namespace internal | } // namespace internal | |||
// An Unused object can be implicitly constructed from ANY value. | // An Unused object can be implicitly constructed from ANY value. | |||
// This is handy when defining actions that ignore some or all of the | // This is handy when defining actions that ignore some or all of the | |||
// mock function arguments. For example, given | // mock function arguments. For example, given | |||
// | // | |||
// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); | // MOCK_METHOD3(Foo, double(const string& label, double x, double y)); | |||
// MOCK_METHOD3(Bar, double(int index, double x, double y)); | // MOCK_METHOD3(Bar, double(int index, double x, double y)); | |||
// | // | |||
// instead of | // instead of | |||
skipping to change at line 962 | skipping to change at line 1200 | |||
// // We can declare any uninteresting argument as Unused. | // // We can declare any uninteresting argument as Unused. | |||
// double DistanceToOrigin(Unused, double x, double y) { | // double DistanceToOrigin(Unused, double x, double y) { | |||
// return sqrt(x*x + y*y); | // return sqrt(x*x + y*y); | |||
// } | // } | |||
// ... | // ... | |||
// EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); | // EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); | |||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); | // EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); | |||
typedef internal::IgnoredValue Unused; | typedef internal::IgnoredValue Unused; | |||
// Creates an action that does actions a1, a2, ..., sequentially in | // Creates an action that does actions a1, a2, ..., sequentially in | |||
// each invocation. | // each invocation. All but the last action will have a readonly view of the | |||
// arguments. | ||||
template <typename... Action> | template <typename... Action> | |||
internal::DoAllAction<typename std::decay<Action>::type...> DoAll( | internal::DoAllAction<typename std::decay<Action>::type...> DoAll( | |||
Action&&... action) { | Action&&... action) { | |||
return {std::forward_as_tuple(std::forward<Action>(action)...)}; | return {std::forward_as_tuple(std::forward<Action>(action)...)}; | |||
} | } | |||
// WithArg<k>(an_action) creates an action that passes the k-th | // WithArg<k>(an_action) creates an action that passes the k-th | |||
// (0-based) argument of the mock function to an_action and performs | // (0-based) argument of the mock function to an_action and performs | |||
// it. It adapts an action accepting one argument to one that accepts | // it. It adapts an action accepting one argument to one that accepts | |||
// multiple arguments. For convenience, we also provide | // multiple arguments. For convenience, we also provide | |||
skipping to change at line 1024 | skipping to change at line 1263 | |||
inline PolymorphicAction<internal::ReturnVoidAction> Return() { | inline PolymorphicAction<internal::ReturnVoidAction> Return() { | |||
return MakePolymorphicAction(internal::ReturnVoidAction()); | return MakePolymorphicAction(internal::ReturnVoidAction()); | |||
} | } | |||
// Creates an action that returns the reference to a variable. | // Creates an action that returns the reference to a variable. | |||
template <typename R> | template <typename R> | |||
inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT | inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT | |||
return internal::ReturnRefAction<R>(x); | return internal::ReturnRefAction<R>(x); | |||
} | } | |||
// Prevent using ReturnRef on reference to temporary. | ||||
template <typename R, R* = nullptr> | ||||
internal::ReturnRefAction<R> ReturnRef(R&&) = delete; | ||||
// Creates an action that returns the reference to a copy of the | // Creates an action that returns the reference to a copy of the | |||
// argument. The copy is created when the action is constructed and | // argument. The copy is created when the action is constructed and | |||
// lives as long as the action. | // lives as long as the action. | |||
template <typename R> | template <typename R> | |||
inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) { | inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) { | |||
return internal::ReturnRefOfCopyAction<R>(x); | return internal::ReturnRefOfCopyAction<R>(x); | |||
} | } | |||
// Modifies the parent action (a Return() action) to perform a move of the | // Modifies the parent action (a Return() action) to perform a move of the | |||
// argument instead of a copy. | // argument instead of a copy. | |||
// Return(ByMove()) actions can only be executed once and will assert this | // Return(ByMove()) actions can only be executed once and will assert this | |||
// invariant. | // invariant. | |||
template <typename R> | template <typename R> | |||
internal::ByMoveWrapper<R> ByMove(R x) { | internal::ByMoveWrapper<R> ByMove(R x) { | |||
return internal::ByMoveWrapper<R>(std::move(x)); | return internal::ByMoveWrapper<R>(std::move(x)); | |||
} | } | |||
// Creates an action that returns an element of `vals`. Calling this action will | ||||
// repeatedly return the next value from `vals` until it reaches the end and | ||||
// will restart from the beginning. | ||||
template <typename T> | ||||
internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) { | ||||
return internal::ReturnRoundRobinAction<T>(std::move(vals)); | ||||
} | ||||
// Creates an action that returns an element of `vals`. Calling this action will | ||||
// repeatedly return the next value from `vals` until it reaches the end and | ||||
// will restart from the beginning. | ||||
template <typename T> | ||||
internal::ReturnRoundRobinAction<T> ReturnRoundRobin( | ||||
std::initializer_list<T> vals) { | ||||
return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals)); | ||||
} | ||||
// Creates an action that does the default action for the give mock function. | // Creates an action that does the default action for the give mock function. | |||
inline internal::DoDefaultAction DoDefault() { | inline internal::DoDefaultAction DoDefault() { | |||
return internal::DoDefaultAction(); | return internal::DoDefaultAction(); | |||
} | } | |||
// Creates an action that sets the variable pointed by the N-th | // Creates an action that sets the variable pointed by the N-th | |||
// (0-based) function argument to 'value'. | // (0-based) function argument to 'value'. | |||
template <size_t N, typename T> | template <size_t N, typename T> | |||
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T x) { | internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) { | |||
return {std::move(x)}; | return {std::move(value)}; | |||
} | } | |||
// The following version is DEPRECATED. | // The following version is DEPRECATED. | |||
template <size_t N, typename T> | template <size_t N, typename T> | |||
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T x) { | internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) { | |||
return {std::move(x)}; | return {std::move(value)}; | |||
} | } | |||
// Creates an action that sets a pointer referent to a given value. | // Creates an action that sets a pointer referent to a given value. | |||
template <typename T1, typename T2> | template <typename T1, typename T2> | |||
PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) { | PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) { | |||
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val)); | return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val)); | |||
} | } | |||
#if !GTEST_OS_WINDOWS_MOBILE | #if !GTEST_OS_WINDOWS_MOBILE | |||
skipping to change at line 1134 | skipping to change at line 1394 | |||
// | // | |||
// ByRef<const Base>(derived) | // ByRef<const Base>(derived) | |||
// | // | |||
// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper. | // N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper. | |||
// However, it may still be used for consistency with ByMove(). | // However, it may still be used for consistency with ByMove(). | |||
template <typename T> | template <typename T> | |||
inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT | inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT | |||
return ::std::reference_wrapper<T>(l_value); | return ::std::reference_wrapper<T>(l_value); | |||
} | } | |||
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new | ||||
// instance of type T, constructed on the heap with constructor arguments | ||||
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. | ||||
template <typename T, typename... Params> | ||||
internal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew( | ||||
Params&&... params) { | ||||
return {std::forward_as_tuple(std::forward<Params>(params)...)}; | ||||
} | ||||
// Action ReturnArg<k>() returns the k-th argument of the mock function. | ||||
template <size_t k> | ||||
internal::ReturnArgAction<k> ReturnArg() { | ||||
return {}; | ||||
} | ||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the | ||||
// mock function to *pointer. | ||||
template <size_t k, typename Ptr> | ||||
internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) { | ||||
return {pointer}; | ||||
} | ||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to | ||||
// by the k-th (0-based) argument of the mock function to *pointer. | ||||
template <size_t k, typename Ptr> | ||||
internal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) { | ||||
return {pointer}; | ||||
} | ||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable | ||||
// referenced by the k-th (0-based) argument of the mock function. | ||||
template <size_t k, typename T> | ||||
internal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee( | ||||
T&& value) { | ||||
return {std::forward<T>(value)}; | ||||
} | ||||
// Action SetArrayArgument<k>(first, last) copies the elements in | ||||
// source range [first, last) to the array pointed to by the k-th | ||||
// (0-based) argument, which can be either a pointer or an | ||||
// iterator. The action does not take ownership of the elements in the | ||||
// source range. | ||||
template <size_t k, typename I1, typename I2> | ||||
internal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first, | ||||
I2 last) { | ||||
return {first, last}; | ||||
} | ||||
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock | ||||
// function. | ||||
template <size_t k> | ||||
internal::DeleteArgAction<k> DeleteArg() { | ||||
return {}; | ||||
} | ||||
// This action returns the value pointed to by 'pointer'. | ||||
template <typename Ptr> | ||||
internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) { | ||||
return {pointer}; | ||||
} | ||||
// Action Throw(exception) can be used in a mock function of any type | ||||
// to throw the given exception. Any copyable value can be thrown. | ||||
#if GTEST_HAS_EXCEPTIONS | ||||
template <typename T> | ||||
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) { | ||||
return {std::forward<T>(exception)}; | ||||
} | ||||
#endif // GTEST_HAS_EXCEPTIONS | ||||
namespace internal { | ||||
// A macro from the ACTION* family (defined later in gmock-generated-actions.h) | ||||
// 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 | ||||
// function. For example, if such an action only uses the second | ||||
// argument, it can be used in any mock function that takes >= 2 | ||||
// arguments where the type of the second argument is compatible. | ||||
// | ||||
// Therefore, the action implementation must be prepared to take more | ||||
// arguments than it needs. The ExcessiveArg type is used to | ||||
// represent those excessive arguments. In order to keep the compiler | ||||
// error messages tractable, we define it in the testing namespace | ||||
// instead of testing::internal. However, this is an INTERNAL TYPE | ||||
// and subject to change without notice, so a user MUST NOT USE THIS | ||||
// TYPE DIRECTLY. | ||||
struct ExcessiveArg {}; | ||||
// Builds an implementation of an Action<> for some particular signature, using | ||||
// a class defined by an ACTION* macro. | ||||
template <typename F, typename Impl> struct ActionImpl; | ||||
template <typename Impl> | ||||
struct ImplBase { | ||||
struct Holder { | ||||
// Allows each copy of the Action<> to get to the Impl. | ||||
explicit operator const Impl&() const { return *ptr; } | ||||
std::shared_ptr<Impl> ptr; | ||||
}; | ||||
using type = typename std::conditional<std::is_constructible<Impl>::value, | ||||
Impl, Holder>::type; | ||||
}; | ||||
template <typename R, typename... Args, typename Impl> | ||||
struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type { | ||||
using Base = typename ImplBase<Impl>::type; | ||||
using function_type = R(Args...); | ||||
using args_type = std::tuple<Args...>; | ||||
ActionImpl() = default; // Only defined if appropriate for Base. | ||||
explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} { } | ||||
R operator()(Args&&... arg) const { | ||||
static constexpr size_t kMaxArgs = | ||||
sizeof...(Args) <= 10 ? sizeof...(Args) : 10; | ||||
return Apply(MakeIndexSequence<kMaxArgs>{}, | ||||
MakeIndexSequence<10 - kMaxArgs>{}, | ||||
args_type{std::forward<Args>(arg)...}); | ||||
} | ||||
template <std::size_t... arg_id, std::size_t... excess_id> | ||||
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>, | ||||
const args_type& args) const { | ||||
// Impl need not be specific to the signature of action being implemented; | ||||
// only the implementing function body needs to have all of the specific | ||||
// types instantiated. Up to 10 of the args that are provided by the | ||||
// args_type get passed, followed by a dummy of unspecified type for the | ||||
// remainder up to 10 explicit args. | ||||
static constexpr ExcessiveArg kExcessArg{}; | ||||
return static_cast<const Impl&>(*this).template gmock_PerformImpl< | ||||
/*function_type=*/function_type, /*return_type=*/R, | ||||
/*args_type=*/args_type, | ||||
/*argN_type=*/typename std::tuple_element<arg_id, args_type>::type...>( | ||||
/*args=*/args, std::get<arg_id>(args)..., | ||||
((void)excess_id, kExcessArg)...); | ||||
} | ||||
}; | ||||
// Stores a default-constructed Impl as part of the Action<>'s | ||||
// std::function<>. The Impl should be trivial to copy. | ||||
template <typename F, typename Impl> | ||||
::testing::Action<F> MakeAction() { | ||||
return ::testing::Action<F>(ActionImpl<F, Impl>()); | ||||
} | ||||
// Stores just the one given instance of Impl. | ||||
template <typename F, typename Impl> | ||||
::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) { | ||||
return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl))); | ||||
} | ||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \ | ||||
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_ | ||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ | ||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \ | ||||
GMOCK_INTERNAL_ARG_UNUSED, , 10) | ||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i | ||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \ | ||||
const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10) | ||||
#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type | ||||
#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \ | ||||
GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10)) | ||||
#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type | ||||
#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \ | ||||
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params)) | ||||
#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type | ||||
#define GMOCK_ACTION_TYPE_PARAMS_(params) \ | ||||
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params)) | ||||
#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \ | ||||
, param##_type gmock_p##i | ||||
#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \ | ||||
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params)) | ||||
#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \ | ||||
, std::forward<param##_type>(gmock_p##i) | ||||
#define GMOCK_ACTION_GVALUE_PARAMS_(params) \ | ||||
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params)) | ||||
#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \ | ||||
, param(::std::forward<param##_type>(gmock_p##i)) | ||||
#define GMOCK_ACTION_INIT_PARAMS_(params) \ | ||||
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params)) | ||||
#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param; | ||||
#define GMOCK_ACTION_FIELD_PARAMS_(params) \ | ||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params) | ||||
#define GMOCK_INTERNAL_ACTION(name, full_name, params) \ | ||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ | ||||
class full_name { \ | ||||
public: \ | ||||
explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ | ||||
: impl_(std::make_shared<gmock_Impl>( \ | ||||
GMOCK_ACTION_GVALUE_PARAMS_(params))) { } \ | ||||
full_name(const full_name&) = default; \ | ||||
full_name(full_name&&) noexcept = default; \ | ||||
template <typename F> \ | ||||
operator ::testing::Action<F>() const { \ | ||||
return ::testing::internal::MakeAction<F>(impl_); \ | ||||
} \ | ||||
private: \ | ||||
class gmock_Impl { \ | ||||
public: \ | ||||
explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ | ||||
: GMOCK_ACTION_INIT_PARAMS_(params) {} \ | ||||
template <typename function_type, typename return_type, \ | ||||
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ | ||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ | ||||
GMOCK_ACTION_FIELD_PARAMS_(params) \ | ||||
}; \ | ||||
std::shared_ptr<const gmock_Impl> impl_; \ | ||||
}; \ | ||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ | ||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \ | ||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ | ||||
return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \ | ||||
GMOCK_ACTION_GVALUE_PARAMS_(params)); \ | ||||
} \ | ||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ | ||||
template <typename function_type, typename return_type, typename args_type, \ | ||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ | ||||
return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \ | ||||
gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const | ||||
} // namespace internal | ||||
// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored. | ||||
#define ACTION(name) \ | ||||
class name##Action { \ | ||||
public: \ | ||||
explicit name##Action() noexcept {} \ | ||||
name##Action(const name##Action&) noexcept {} \ | ||||
template <typename F> \ | ||||
operator ::testing::Action<F>() const { \ | ||||
return ::testing::internal::MakeAction<F, gmock_Impl>(); \ | ||||
} \ | ||||
private: \ | ||||
class gmock_Impl { \ | ||||
public: \ | ||||
template <typename function_type, typename return_type, \ | ||||
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ | ||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ | ||||
}; \ | ||||
}; \ | ||||
inline name##Action name() GTEST_MUST_USE_RESULT_; \ | ||||
inline name##Action name() { return name##Action(); } \ | ||||
template <typename function_type, typename return_type, typename args_type, \ | ||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ | ||||
return_type name##Action::gmock_Impl::gmock_PerformImpl( \ | ||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const | ||||
#define ACTION_P(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__)) | ||||
#define ACTION_P2(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__)) | ||||
#define ACTION_P3(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__)) | ||||
#define ACTION_P4(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__)) | ||||
#define ACTION_P5(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__)) | ||||
#define ACTION_P6(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__)) | ||||
#define ACTION_P7(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__)) | ||||
#define ACTION_P8(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__)) | ||||
#define ACTION_P9(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__)) | ||||
#define ACTION_P10(name, ...) \ | ||||
GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__)) | ||||
} // namespace testing | } // namespace testing | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
# pragma warning(pop) | # pragma warning(pop) | |||
#endif | #endif | |||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ | |||
End of changes. 36 change blocks. | ||||
45 lines changed or deleted | 591 lines changed or added |