Unverified Commit edadfecd authored by Akash Patel's avatar Akash Patel Committed by GitHub
Browse files

Update gtest to 1.11.0 (#1086)

Properly resolves #1083, #996.
parent 26e3b704
# Content Moved
We are working on updates to the GoogleTest documentation, which has moved to
the top-level [docs](../../docs) directory.
...@@ -30,12 +30,105 @@ ...@@ -30,12 +30,105 @@
// 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>
...@@ -45,11 +138,13 @@ ...@@ -45,11 +138,13 @@
#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)
...@@ -162,13 +257,17 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); ...@@ -162,13 +257,17 @@ 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
...@@ -350,6 +449,9 @@ class Action { ...@@ -350,6 +449,9 @@ class Action {
} }
}; };
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;
...@@ -361,10 +463,14 @@ class Action { ...@@ -361,10 +463,14 @@ class 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)
...@@ -396,6 +502,26 @@ class Action { ...@@ -396,6 +502,26 @@ class Action {
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_;
}; };
...@@ -446,13 +572,9 @@ class PolymorphicAction { ...@@ -446,13 +572,9 @@ class PolymorphicAction {
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
...@@ -593,13 +715,9 @@ class ReturnAction { ...@@ -593,13 +715,9 @@ class ReturnAction {
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.
...@@ -660,13 +778,9 @@ class ReturnRefAction { ...@@ -660,13 +778,9 @@ class ReturnRefAction {
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
...@@ -707,13 +821,39 @@ class ReturnRefOfCopyAction { ...@@ -707,13 +821,39 @@ class ReturnRefOfCopyAction {
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.
...@@ -740,8 +880,6 @@ class AssignAction { ...@@ -740,8 +880,6 @@ class AssignAction {
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
...@@ -763,8 +901,6 @@ class SetErrnoAndReturnAction { ...@@ -763,8 +901,6 @@ class SetErrnoAndReturnAction {
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
...@@ -816,7 +952,8 @@ struct InvokeMethodWithoutArgsAction { ...@@ -816,7 +952,8 @@ 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 {
...@@ -869,13 +1006,9 @@ class IgnoreResultAction { ...@@ -869,13 +1006,9 @@ class IgnoreResultAction {
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>
...@@ -886,7 +1019,8 @@ struct WithArgsAction { ...@@ -886,7 +1019,8 @@ struct WithArgsAction {
// 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 {
...@@ -899,9 +1033,13 @@ struct WithArgsAction { ...@@ -899,9 +1033,13 @@ struct WithArgsAction {
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:
...@@ -910,21 +1048,121 @@ struct DoAllAction { ...@@ -910,21 +1048,121 @@ struct DoAllAction {
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.
...@@ -960,7 +1198,8 @@ struct DoAllAction { ...@@ -960,7 +1198,8 @@ struct DoAllAction {
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) {
...@@ -1022,6 +1261,10 @@ inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT ...@@ -1022,6 +1261,10 @@ 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.
...@@ -1039,6 +1282,23 @@ internal::ByMoveWrapper<R> ByMove(R x) { ...@@ -1039,6 +1282,23 @@ 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();
...@@ -1047,14 +1307,14 @@ inline internal::DoDefaultAction DoDefault() { ...@@ -1047,14 +1307,14 @@ inline internal::DoDefaultAction DoDefault() {
// 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.
...@@ -1132,11 +1392,296 @@ inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT ...@@ -1132,11 +1392,296 @@ 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 // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#include <limits.h> #include <limits.h>
#include <memory> #include <memory>
...@@ -154,4 +154,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) { ...@@ -154,4 +154,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
...@@ -33,12 +33,47 @@ ...@@ -33,12 +33,47 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#include "gmock/gmock-generated-function-mockers.h" // NOLINT #include <type_traits> // IWYU pragma: keep
#include <utility> // IWYU pragma: keep
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-pp.h" #include "gmock/internal/gmock-pp.h"
namespace testing {
namespace internal {
template <typename T>
using identity_t = T;
template <typename Pattern>
struct ThisRefAdjuster {
template <typename T>
using AdjustT = typename std::conditional<
std::is_const<typename std::remove_reference<Pattern>::type>::value,
typename std::conditional<std::is_lvalue_reference<Pattern>::value,
const T&, const T&&>::type,
typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&,
T&&>::type>::type;
template <typename MockType>
static AdjustT<MockType> Adjust(const MockType& mock) {
return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock));
}
};
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
// inside a header file. However, the FunctionMocker class template
// is meant to be defined in the ::testing namespace. The following
// line is just a trick for working around a bug in MSVC 8.0, which
// cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker;
} // namespace testing
#define MOCK_METHOD(...) \ #define MOCK_METHOD(...) \
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
...@@ -60,7 +95,8 @@ ...@@ -60,7 +95,8 @@
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \ GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ #define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
...@@ -94,21 +130,20 @@ ...@@ -94,21 +130,20 @@
::testing::tuple_size<typename ::testing::internal::Function< \ ::testing::tuple_size<typename ::testing::internal::Function< \
__VA_ARGS__>::ArgumentTuple>::value == _N, \ __VA_ARGS__>::ArgumentTuple>::value == _N, \
"This method does not take " GMOCK_PP_STRINGIZE( \ "This method does not take " GMOCK_PP_STRINGIZE( \
_N) " arguments. Parenthesize all types with unproctected commas.") _N) " arguments. Parenthesize all types with unprotected commas.")
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ #define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec) GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \ #define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
_Override, _Final, _Noexcept, \ _Override, _Final, _NoexceptSpec, \
_CallType, _Signature) \ _CallType, _RefSpec, _Signature) \
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \ typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
_Signature)>::Result \ _Signature)>::Result \
GMOCK_INTERNAL_EXPAND(_CallType) \ GMOCK_INTERNAL_EXPAND(_CallType) \
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \ _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \ GMOCK_PP_IF(_Constness, const, ) _RefSpec _NoexceptSpec \
GMOCK_PP_IF(_Override, override, ) \ GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \
GMOCK_PP_IF(_Final, final, ) { \
GMOCK_MOCKER_(_N, _Constness, _MethodName) \ GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.SetOwnerAndName(this, #_MethodName); \ .SetOwnerAndName(this, #_MethodName); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
...@@ -116,7 +151,7 @@ ...@@ -116,7 +151,7 @@
} \ } \
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
GMOCK_PP_IF(_Constness, const, ) { \ GMOCK_PP_IF(_Constness, const, ) _RefSpec { \
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
...@@ -124,11 +159,10 @@ ...@@ -124,11 +159,10 @@
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
const ::testing::internal::WithoutMatchers&, \ const ::testing::internal::WithoutMatchers&, \
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \ GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
GMOCK_PP_REMOVE_PARENS(_Signature)>*) \ GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \
const GMOCK_PP_IF(_Noexcept, noexcept, ) { \ return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF( \
return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \ _Constness, const, ) int _RefSpec>::Adjust(*this) \
GMOCK_PP_IF(_Constness, const, ))(this) \ .gmock_##_MethodName(GMOCK_PP_REPEAT( \
->gmock_##_MethodName(GMOCK_PP_REPEAT( \
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
} \ } \
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \ mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
...@@ -147,9 +181,20 @@ ...@@ -147,9 +181,20 @@
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \ #define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple)) GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \ #define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \
GMOCK_PP_HAS_COMMA( \ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple)
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem) \
GMOCK_PP_IF( \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
_elem, )
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem) \
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ #define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
...@@ -160,6 +205,7 @@ ...@@ -160,6 +205,7 @@
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
GMOCK_PP_STRINGIZE( \ GMOCK_PP_STRINGIZE( \
_elem) " cannot be recognized as a valid specification modifier."); _elem) " cannot be recognized as a valid specification modifier.");
...@@ -180,12 +226,18 @@ ...@@ -180,12 +226,18 @@
#define GMOCK_INTERNAL_DETECT_FINAL_I_final , #define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
// TODO(iserna): Maybe noexcept should accept an argument here as well.
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \ #define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem) GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept , #define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem)
#define GMOCK_INTERNAL_DETECT_REF_I_ref ,
#define GMOCK_INTERNAL_UNPACK_ref(x) x
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ #define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
...@@ -203,14 +255,28 @@ ...@@ -203,14 +255,28 @@
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ #define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg) GMOCK_PP_IDENTITY _arg
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype #define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ // Note: The use of `identity_t` here allows _Ret to represent return types that
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \ // would normally need to be specified in a different way. For example, a method
GMOCK_PP_IDENTITY) \ // returning a function pointer must be written as
(_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) //
// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)
//
// But we only support placing the return type at the beginning. To handle this,
// we wrap all calls in identity_t, so that a declaration will be expanded to
//
// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)
//
// This allows us to work around the syntactic oddities of function/method
// types.
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \
GMOCK_PP_REMOVE_PARENS, \
GMOCK_PP_IDENTITY)(_Ret)>( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ #define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
GMOCK_PP_COMMA_IF(_i) \ GMOCK_PP_COMMA_IF(_i) \
...@@ -218,36 +284,196 @@ ...@@ -218,36 +284,196 @@
GMOCK_PP_IDENTITY) \ GMOCK_PP_IDENTITY) \
(_elem) (_elem)
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ #define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \ GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
GMOCK_PP_REMOVE_PARENS(_Signature)) \
gmock_a##_i gmock_a##_i
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ #define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \ GMOCK_PP_COMMA_IF(_i) \
::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ ::std::forward<GMOCK_INTERNAL_ARG_O( \
GMOCK_PP_REMOVE_PARENS(_Signature))>( \ _i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i)
gmock_a##_i)
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ #define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \ GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \ GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
GMOCK_PP_REMOVE_PARENS(_Signature)) \
gmock_a##_i gmock_a##_i
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ #define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
GMOCK_PP_COMMA_IF(_i) \ GMOCK_PP_COMMA_IF(_i) \
gmock_a##_i gmock_a##_i
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ #define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \ GMOCK_PP_COMMA_IF(_i) \
::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ ::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>()
GMOCK_PP_REMOVE_PARENS(_Signature))>()
#define GMOCK_INTERNAL_ARG_O(_i, ...) \
#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__) typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type
#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \ #define GMOCK_INTERNAL_MATCHER_O(_i, ...) \
GMOCK_MATCHER_(_tn, _i, __VA_ARGS__) const ::testing::Matcher<typename ::testing::internal::Function< \
__VA_ARGS__>::template Arg<_i>::type>&
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__)
#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__)
#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__)
#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__)
#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__)
#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__)
#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__)
#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__)
#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__)
#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__)
#define MOCK_METHOD10(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__)
#define MOCK_CONST_METHOD0(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__)
#define MOCK_CONST_METHOD1(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__)
#define MOCK_CONST_METHOD2(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__)
#define MOCK_CONST_METHOD3(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__)
#define MOCK_CONST_METHOD4(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__)
#define MOCK_CONST_METHOD5(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__)
#define MOCK_CONST_METHOD6(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__)
#define MOCK_CONST_METHOD7(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__)
#define MOCK_CONST_METHOD8(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__)
#define MOCK_CONST_METHOD9(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__)
#define MOCK_CONST_METHOD10(m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__)
#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__)
#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__)
#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__)
#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__)
#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__)
#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__)
#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__)
#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__)
#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__)
#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__)
#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__)
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__)
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__)
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__)
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__)
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__)
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__)
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__)
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__)
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__)
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__)
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__)
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__)
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__)
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__)
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__)
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__)
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__)
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__)
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__)
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__)
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__)
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__)
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)
#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
args_num, ::testing::internal::identity_t<__VA_ARGS__>); \
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, , \
(::testing::internal::identity_t<__VA_ARGS__>))
#define GMOCK_MOCKER_(arity, constness, Method) \
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
...@@ -30,7 +30,220 @@ ...@@ -30,7 +30,220 @@
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file implements some commonly used argument matchers. More // The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
// Basic Usage
// ===========
//
// The syntax
//
// MATCHER(name, description_string) { statements; }
//
// defines a matcher with the given name that executes the statements,
// which must return a bool to indicate if the match succeeds. Inside
// the statements, you can refer to the value being matched by 'arg',
// and refer to its type by 'arg_type'.
//
// The description string documents what the matcher does, and is used
// to generate the failure message when the match fails. Since a
// MATCHER() is usually defined in a header file shared by multiple
// C++ source files, we require the description to be a C-string
// literal to avoid possible side effects. It can be empty, in which
// case we'll use the sequence of words in the matcher name as the
// description.
//
// For example:
//
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
//
// allows you to write
//
// // Expects mock_foo.Bar(n) to be called where n is even.
// EXPECT_CALL(mock_foo, Bar(IsEven()));
//
// or,
//
// // Verifies that the value of some_expression is even.
// EXPECT_THAT(some_expression, IsEven());
//
// If the above assertion fails, it will print something like:
//
// Value of: some_expression
// Expected: is even
// Actual: 7
//
// where the description "is even" is automatically calculated from the
// matcher name IsEven.
//
// Argument Type
// =============
//
// Note that the type of the value being matched (arg_type) is
// determined by the context in which you use the matcher and is
// supplied to you by the compiler, so you don't need to worry about
// declaring it (nor can you). This allows the matcher to be
// polymorphic. For example, IsEven() can be used to match any type
// where the value of "(arg % 2) == 0" can be implicitly converted to
// a bool. In the "Bar(IsEven())" example above, if method Bar()
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
// 'arg_type' will be unsigned long; and so on.
//
// Parameterizing Matchers
// =======================
//
// Sometimes you'll want to parameterize the matcher. For that you
// can use another macro:
//
// MATCHER_P(name, param_name, description_string) { statements; }
//
// For example:
//
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
//
// will allow you to write:
//
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
//
// which may lead to this message (assuming n is 10):
//
// Value of: Blah("a")
// Expected: has absolute value 10
// Actual: -9
//
// Note that both the matcher description and its parameter are
// printed, making the message human-friendly.
//
// In the matcher definition body, you can write 'foo_type' to
// reference the type of a parameter named 'foo'. For example, in the
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
// 'value_type' to refer to the type of 'value'.
//
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
// support multi-parameter matchers.
//
// Describing Parameterized Matchers
// =================================
//
// The last argument to MATCHER*() is a string-typed expression. The
// expression can reference all of the matcher's parameters and a
// special bool-typed variable named 'negation'. When 'negation' is
// false, the expression should evaluate to the matcher's description;
// otherwise it should evaluate to the description of the negation of
// the matcher. For example,
//
// using testing::PrintToString;
//
// MATCHER_P2(InClosedRange, low, hi,
// std::string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
// ...
// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
// parameter values printed as a tuple. For example,
//
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
// ...
// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
//
// For the purpose of typing, you can view
//
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooMatcherPk<p1_type, ..., pk_type>
// Foo(p1_type p1, ..., pk_type pk) { ... }
//
// When you write Foo(v1, ..., vk), the compiler infers the types of
// the parameters v1, ..., and vk for you. If you are not happy with
// the result of the type inference, you can specify the types by
// explicitly instantiating the template, as in Foo<long, bool>(5,
// false). As said earlier, you don't get to (or need to) specify
// 'arg_type' as that's determined by the context in which the matcher
// is used. You can assign the result of expression Foo(p1, ..., pk)
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
// can be useful when composing matchers.
//
// While you can instantiate a matcher template with reference types,
// passing the parameters by pointer usually makes your code more
// readable. If, however, you still want to pass a parameter by
// reference, be aware that in the failure message generated by the
// matcher you will see the value of the referenced object but not its
// address.
//
// Explaining Match Results
// ========================
//
// Sometimes the matcher description alone isn't enough to explain why
// the match has failed or succeeded. For example, when expecting a
// long string, it can be very helpful to also print the diff between
// the expected string and the actual one. To achieve that, you can
// optionally stream additional information to a special variable
// named result_listener, whose type is a pointer to class
// MatchResultListener:
//
// MATCHER_P(EqualsLongString, str, "") {
// if (arg == str) return true;
//
// *result_listener << "the difference: "
/// << DiffStrings(str, arg);
// return false;
// }
//
// Overloading Matchers
// ====================
//
// You can overload matchers with different numbers of parameters:
//
// MATCHER_P(Blah, a, description_string1) { ... }
// MATCHER_P2(Blah, a, b, description_string2) { ... }
//
// Caveats
// =======
//
// When defining a new matcher, you should also consider implementing
// MatcherInterface or using MakePolymorphicMatcher(). These
// approaches require more work than the MATCHER* macros, but also
// give you more control on the types of the value being matched and
// the matcher parameters, which may leads to better compiler error
// messages when the matcher is used wrong. They also allow
// overloading matchers based on parameter types (as opposed to just
// based on the number of parameters).
//
// MATCHER*() can only be used in a namespace scope as templates cannot be
// declared inside of a local class.
//
// More Information
// ================
//
// To learn more about using these macros, please search for 'MATCHER'
// on
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
//
// This file also implements some commonly used argument matchers. More
// matchers can be defined by the user implementing the // matchers can be defined by the user implementing the
// MatcherInterface<T> interface if necessary. // MatcherInterface<T> interface if necessary.
// //
...@@ -39,11 +252,11 @@ ...@@ -39,11 +252,11 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#include <math.h>
#include <algorithm> #include <algorithm>
#include <cmath>
#include <initializer_list> #include <initializer_list>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
...@@ -54,8 +267,10 @@ ...@@ -54,8 +267,10 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
#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"
#include "gtest/gtest.h" #include "gtest/gtest.h"
// MSVC warning C5046 is new as of VS2017 version 15.8. // MSVC warning C5046 is new as of VS2017 version 15.8.
...@@ -128,7 +343,7 @@ class MatcherCastImpl { ...@@ -128,7 +343,7 @@ class MatcherCastImpl {
// constructor from M (this usually happens when T has an implicit // constructor from M (this usually happens when T has an implicit
// constructor from any type). // constructor from any type).
// //
// It won't work to unconditionally implict_cast // It won't work to unconditionally implicit_cast
// polymorphic_matcher_or_value to Matcher<T> because it won't trigger // polymorphic_matcher_or_value to Matcher<T> because it won't trigger
// a user-defined conversion from M to T if one exists (assuming M is // a user-defined conversion from M to T if one exists (assuming M is
// a value). // a value).
...@@ -141,7 +356,7 @@ class MatcherCastImpl { ...@@ -141,7 +356,7 @@ class MatcherCastImpl {
template <bool Ignore> template <bool Ignore>
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
std::true_type /* convertible_to_matcher */, std::true_type /* convertible_to_matcher */,
bool_constant<Ignore>) { std::integral_constant<bool, Ignore>) {
// M is implicitly convertible to Matcher<T>, which means that either // M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorphic matcher or Matcher<T> has an implicit constructor // M is a polymorphic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a // from M. In both cases using the implicit conversion will produce a
...@@ -209,7 +424,14 @@ class MatcherCastImpl<T, Matcher<U> > { ...@@ -209,7 +424,14 @@ class MatcherCastImpl<T, Matcher<U> > {
!std::is_base_of<FromType, ToType>::value, !std::is_base_of<FromType, ToType>::value,
"Can't implicitly convert from <base> to <derived>"); "Can't implicitly convert from <base> to <derived>");
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); // Do the cast to `U` explicitly if necessary.
// Otherwise, let implicit conversions do the trick.
using CastType =
typename std::conditional<std::is_convertible<T&, const U&>::value,
T&, U>::type;
return source_matcher_.MatchAndExplain(static_cast<CastType>(x),
listener);
} }
void DescribeTo(::std::ostream* os) const override { void DescribeTo(::std::ostream* os) const override {
...@@ -222,8 +444,6 @@ class MatcherCastImpl<T, Matcher<U> > { ...@@ -222,8 +444,6 @@ class MatcherCastImpl<T, Matcher<U> > {
private: private:
const Matcher<U> source_matcher_; const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
}; };
...@@ -235,6 +455,50 @@ class MatcherCastImpl<T, Matcher<T> > { ...@@ -235,6 +455,50 @@ class MatcherCastImpl<T, Matcher<T> > {
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
}; };
// Template specialization for parameterless Matcher.
template <typename Derived>
class MatcherBaseImpl {
public:
MatcherBaseImpl() = default;
template <typename T>
operator ::testing::Matcher<T>() const { // NOLINT(runtime/explicit)
return ::testing::Matcher<T>(new
typename Derived::template gmock_Impl<T>());
}
};
// Template specialization for Matcher with parameters.
template <template <typename...> class Derived, typename... Ts>
class MatcherBaseImpl<Derived<Ts...>> {
public:
// Mark the constructor explicit for single argument T to avoid implicit
// conversions.
template <typename E = std::enable_if<sizeof...(Ts) == 1>,
typename E::type* = nullptr>
explicit MatcherBaseImpl(Ts... params)
: params_(std::forward<Ts>(params)...) {}
template <typename E = std::enable_if<sizeof...(Ts) != 1>,
typename = typename E::type>
MatcherBaseImpl(Ts... params) // NOLINT
: params_(std::forward<Ts>(params)...) {}
template <typename F>
operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit)
return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{});
}
private:
template <typename F, std::size_t... tuple_ids>
::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const {
return ::testing::Matcher<F>(
new typename Derived<Ts...>::template gmock_Impl<F>(
std::get<tuple_ids>(params_)...));
}
const std::tuple<Ts...> params_;
};
} // namespace internal } // namespace internal
// In order to be safe and clear, casting between different matcher // In order to be safe and clear, casting between different matcher
...@@ -246,56 +510,43 @@ inline Matcher<T> MatcherCast(const M& matcher) { ...@@ -246,56 +510,43 @@ inline Matcher<T> MatcherCast(const M& matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher); return internal::MatcherCastImpl<T, M>::Cast(matcher);
} }
// Implements SafeMatcherCast(). // This overload handles polymorphic matchers and values only since
// // monomorphic matchers are handled by the next one.
// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a
// workaround for a compiler bug, and can now be removed.
template <typename T>
class SafeMatcherCastImpl {
public:
// This overload handles polymorphic matchers and values only since
// monomorphic matchers are handled by the next one.
template <typename M>
static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
}
// This overload handles monomorphic matchers.
//
// In general, if type T can be implicitly converted to type U, we can
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
// contravariant): just keep a copy of the original Matcher<U>, convert the
// argument from type T to U, and then pass it to the underlying Matcher<U>.
// The only exception is when U is a reference and T is not, as the
// underlying Matcher<U> may be interested in the argument's address, which
// is not preserved in the conversion from T to U.
template <typename U>
static inline Matcher<T> Cast(const Matcher<U>& matcher) {
// Enforce that T can be implicitly converted to U.
GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value),
"T must be implicitly convertible to U");
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_(
std::is_reference<T>::value || !std::is_reference<U>::value,
cannot_convert_non_reference_arg_to_reference);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
GTEST_COMPILE_ASSERT_(
kTIsOther || kUIsOther ||
(internal::LosslessArithmeticConvertible<RawT, RawU>::value),
conversion_of_arithmetic_types_must_be_lossless);
return MatcherCast<T>(matcher);
}
};
template <typename T, typename M> template <typename T, typename M>
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) { inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {
return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); return MatcherCast<T>(polymorphic_matcher_or_value);
}
// This overload handles monomorphic matchers.
//
// In general, if type T can be implicitly converted to type U, we can
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
// contravariant): just keep a copy of the original Matcher<U>, convert the
// argument from type T to U, and then pass it to the underlying Matcher<U>.
// The only exception is when U is a reference and T is not, as the
// underlying Matcher<U> may be interested in the argument's address, which
// is not preserved in the conversion from T to U.
template <typename T, typename U>
inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
// Enforce that T can be implicitly converted to U.
static_assert(std::is_convertible<const T&, const U&>::value,
"T must be implicitly convertible to U");
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_(
std::is_reference<T>::value || !std::is_reference<U>::value,
cannot_convert_non_reference_arg_to_reference);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
GTEST_COMPILE_ASSERT_(
kTIsOther || kUIsOther ||
(internal::LosslessArithmeticConvertible<RawT, RawU>::value),
conversion_of_arithmetic_types_must_be_lossless);
return MatcherCast<T>(matcher);
} }
// A<T>() returns a matcher that matches any value of type T. // A<T>() returns a matcher that matches any value of type T.
...@@ -484,31 +735,25 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { ...@@ -484,31 +735,25 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out); return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);
} }
// Implements A<T>().
template <typename T>
class AnyMatcherImpl : public MatcherInterface<const T&> {
public:
bool MatchAndExplain(const T& /* x */,
MatchResultListener* /* listener */) const override {
return true;
}
void DescribeTo(::std::ostream* os) const override { *os << "is anything"; }
void DescribeNegationTo(::std::ostream* os) const override {
// This is mostly for completeness' safe, as it's not very useful
// to write Not(A<bool>()). However we cannot completely rule out
// such a possibility, and it doesn't hurt to be prepared.
*os << "never matches";
}
};
// Implements _, a matcher that matches any value of any // Implements _, a matcher that matches any value of any
// type. This is a polymorphic matcher, so we need a template type // type. This is a polymorphic matcher, so we need a template type
// conversion operator to make it appearing as a Matcher<T> for any // conversion operator to make it appearing as a Matcher<T> for any
// type T. // type T.
class AnythingMatcher { class AnythingMatcher {
public: public:
using is_gtest_matcher = void;
template <typename T> template <typename T>
operator Matcher<T>() const { return A<T>(); } bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const {
return true;
}
void DescribeTo(std::ostream* os) const { *os << "is anything"; }
void DescribeNegationTo(::std::ostream* os) const {
// This is mostly for completeness' sake, as it's not very useful
// to write Not(A<bool>()). However we cannot completely rule out
// such a possibility, and it doesn't hurt to be prepared.
*os << "never matches";
}
}; };
// Implements the polymorphic IsNull() matcher, which matches any raw or smart // Implements the polymorphic IsNull() matcher, which matches any raw or smart
...@@ -608,13 +853,9 @@ class RefMatcher<T&> { ...@@ -608,13 +853,9 @@ class RefMatcher<T&> {
private: private:
const Super& object_; const Super& object_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
T& object_; T& object_;
GTEST_DISALLOW_ASSIGN_(RefMatcher);
}; };
// Polymorphic helper functions for narrow and wide string matchers. // Polymorphic helper functions for narrow and wide string matchers.
...@@ -656,19 +897,20 @@ bool CaseInsensitiveStringEquals(const StringType& s1, ...@@ -656,19 +897,20 @@ bool CaseInsensitiveStringEquals(const StringType& s1,
template <typename StringType> template <typename StringType>
class StrEqualityMatcher { class StrEqualityMatcher {
public: public:
StrEqualityMatcher(const StringType& str, bool expect_eq, StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive)
bool case_sensitive) : string_(std::move(str)),
: string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} expect_eq_(expect_eq),
case_sensitive_(case_sensitive) {}
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
...@@ -686,11 +928,11 @@ class StrEqualityMatcher { ...@@ -686,11 +928,11 @@ class StrEqualityMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const StringType& s2(s); const StringType s2(s);
const bool eq = case_sensitive_ ? s2 == string_ : const bool eq = case_sensitive_ ? s2 == string_ :
CaseInsensitiveStringEquals(s2, string_); CaseInsensitiveStringEquals(s2, string_);
return expect_eq_ == eq; return expect_eq_ == eq;
...@@ -717,8 +959,6 @@ class StrEqualityMatcher { ...@@ -717,8 +959,6 @@ class StrEqualityMatcher {
const StringType string_; const StringType string_;
const bool expect_eq_; const bool expect_eq_;
const bool case_sensitive_; const bool case_sensitive_;
GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
}; };
// Implements the polymorphic HasSubstr(substring) matcher, which // Implements the polymorphic HasSubstr(substring) matcher, which
...@@ -730,15 +970,15 @@ class HasSubstrMatcher { ...@@ -730,15 +970,15 @@ class HasSubstrMatcher {
explicit HasSubstrMatcher(const StringType& substring) explicit HasSubstrMatcher(const StringType& substring)
: substring_(substring) {} : substring_(substring) {}
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
...@@ -753,12 +993,11 @@ class HasSubstrMatcher { ...@@ -753,12 +993,11 @@ class HasSubstrMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const StringType& s2(s); return StringType(s).find(substring_) != StringType::npos;
return s2.find(substring_) != StringType::npos;
} }
// Describes what this matcher matches. // Describes what this matcher matches.
...@@ -774,8 +1013,6 @@ class HasSubstrMatcher { ...@@ -774,8 +1013,6 @@ class HasSubstrMatcher {
private: private:
const StringType substring_; const StringType substring_;
GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
}; };
// Implements the polymorphic StartsWith(substring) matcher, which // Implements the polymorphic StartsWith(substring) matcher, which
...@@ -787,15 +1024,15 @@ class StartsWithMatcher { ...@@ -787,15 +1024,15 @@ class StartsWithMatcher {
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
} }
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
...@@ -810,7 +1047,7 @@ class StartsWithMatcher { ...@@ -810,7 +1047,7 @@ class StartsWithMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -831,8 +1068,6 @@ class StartsWithMatcher { ...@@ -831,8 +1068,6 @@ class StartsWithMatcher {
private: private:
const StringType prefix_; const StringType prefix_;
GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
}; };
// Implements the polymorphic EndsWith(substring) matcher, which // Implements the polymorphic EndsWith(substring) matcher, which
...@@ -843,15 +1078,15 @@ class EndsWithMatcher { ...@@ -843,15 +1078,15 @@ class EndsWithMatcher {
public: public:
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
...@@ -866,7 +1101,7 @@ class EndsWithMatcher { ...@@ -866,7 +1101,7 @@ class EndsWithMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -887,8 +1122,6 @@ class EndsWithMatcher { ...@@ -887,8 +1122,6 @@ class EndsWithMatcher {
private: private:
const StringType suffix_; const StringType suffix_;
GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
}; };
// Implements a matcher that compares the two fields of a 2-tuple // Implements a matcher that compares the two fields of a 2-tuple
...@@ -982,8 +1215,6 @@ class NotMatcherImpl : public MatcherInterface<const T&> { ...@@ -982,8 +1215,6 @@ class NotMatcherImpl : public MatcherInterface<const T&> {
private: private:
const Matcher<T> matcher_; const Matcher<T> matcher_;
GTEST_DISALLOW_ASSIGN_(NotMatcherImpl);
}; };
// Implements the Not(m) matcher, which matches a value that doesn't // Implements the Not(m) matcher, which matches a value that doesn't
...@@ -1002,8 +1233,6 @@ class NotMatcher { ...@@ -1002,8 +1233,6 @@ class NotMatcher {
private: private:
InnerMatcher matcher_; InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(NotMatcher);
}; };
// Implements the AllOf(m1, m2) matcher for a particular argument type // Implements the AllOf(m1, m2) matcher for a particular argument type
...@@ -1065,8 +1294,6 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> { ...@@ -1065,8 +1294,6 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
private: private:
const std::vector<Matcher<T> > matchers_; const std::vector<Matcher<T> > matchers_;
GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
}; };
// VariadicMatcher is used for the variadic implementation of // VariadicMatcher is used for the variadic implementation of
...@@ -1081,6 +1308,9 @@ class VariadicMatcher { ...@@ -1081,6 +1308,9 @@ class VariadicMatcher {
static_assert(sizeof...(Args) > 0, "Must have at least one matcher."); static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
} }
VariadicMatcher(const VariadicMatcher&) = default;
VariadicMatcher& operator=(const VariadicMatcher&) = delete;
// This template type conversion operator allows an // This template type conversion operator allows an
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that // VariadicMatcher<Matcher1, Matcher2...> object to match any type that
// all of the provided matchers (Matcher1, Matcher2, ...) can match. // all of the provided matchers (Matcher1, Matcher2, ...) can match.
...@@ -1105,8 +1335,6 @@ class VariadicMatcher { ...@@ -1105,8 +1335,6 @@ class VariadicMatcher {
std::integral_constant<size_t, sizeof...(Args)>) const {} std::integral_constant<size_t, sizeof...(Args)>) const {}
std::tuple<Args...> matchers_; std::tuple<Args...> matchers_;
GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
}; };
template <typename... Args> template <typename... Args>
...@@ -1171,8 +1399,6 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> { ...@@ -1171,8 +1399,6 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
private: private:
const std::vector<Matcher<T> > matchers_; const std::vector<Matcher<T> > matchers_;
GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
}; };
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). // AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
...@@ -1200,8 +1426,6 @@ class SomeOfArrayMatcher { ...@@ -1200,8 +1426,6 @@ class SomeOfArrayMatcher {
private: private:
const ::std::vector<T> matchers_; const ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(SomeOfArrayMatcher);
}; };
template <typename T> template <typename T>
...@@ -1223,7 +1447,7 @@ class TrulyMatcher { ...@@ -1223,7 +1447,7 @@ class TrulyMatcher {
// interested in the address of the argument. // interested in the address of the argument.
template <typename T> template <typename T>
bool MatchAndExplain(T& x, // NOLINT bool MatchAndExplain(T& x, // NOLINT
MatchResultListener* /* listener */) const { MatchResultListener* listener) const {
// Without the if-statement, MSVC sometimes warns about converting // Without the if-statement, MSVC sometimes warns about converting
// a value to bool (warning 4800). // a value to bool (warning 4800).
// //
...@@ -1232,6 +1456,7 @@ class TrulyMatcher { ...@@ -1232,6 +1456,7 @@ class TrulyMatcher {
// having no operator!(). // having no operator!().
if (predicate_(x)) if (predicate_(x))
return true; return true;
*listener << "didn't satisfy the given predicate";
return false; return false;
} }
...@@ -1245,8 +1470,6 @@ class TrulyMatcher { ...@@ -1245,8 +1470,6 @@ class TrulyMatcher {
private: private:
Predicate predicate_; Predicate predicate_;
GTEST_DISALLOW_ASSIGN_(TrulyMatcher);
}; };
// Used for implementing Matches(matcher), which turns a matcher into // Used for implementing Matches(matcher), which turns a matcher into
...@@ -1283,8 +1506,6 @@ class MatcherAsPredicate { ...@@ -1283,8 +1506,6 @@ class MatcherAsPredicate {
private: private:
M matcher_; M matcher_;
GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate);
}; };
// For implementing ASSERT_THAT() and EXPECT_THAT(). The template // For implementing ASSERT_THAT() and EXPECT_THAT(). The template
...@@ -1323,7 +1544,7 @@ class PredicateFormatterFromMatcher { ...@@ -1323,7 +1544,7 @@ class PredicateFormatterFromMatcher {
<< "Expected: "; << "Expected: ";
matcher.DescribeTo(&ss); matcher.DescribeTo(&ss);
// Rerun the matcher to "PrintAndExain" the failure. // Rerun the matcher to "PrintAndExplain" the failure.
StringMatchResultListener listener; StringMatchResultListener listener;
if (MatchPrintAndExplain(x, matcher, &listener)) { if (MatchPrintAndExplain(x, matcher, &listener)) {
ss << "\n The matcher failed on the initial attempt; but passed when " ss << "\n The matcher failed on the initial attempt; but passed when "
...@@ -1335,8 +1556,6 @@ class PredicateFormatterFromMatcher { ...@@ -1335,8 +1556,6 @@ class PredicateFormatterFromMatcher {
private: private:
const M matcher_; const M matcher_;
GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher);
}; };
// A helper function for converting a matcher to a predicate-formatter // A helper function for converting a matcher to a predicate-formatter
...@@ -1349,6 +1568,22 @@ MakePredicateFormatterFromMatcher(M matcher) { ...@@ -1349,6 +1568,22 @@ MakePredicateFormatterFromMatcher(M matcher) {
return PredicateFormatterFromMatcher<M>(std::move(matcher)); return PredicateFormatterFromMatcher<M>(std::move(matcher));
} }
// Implements the polymorphic IsNan() matcher, which matches any floating type
// value that is Nan.
class IsNanMatcher {
public:
template <typename FloatType>
bool MatchAndExplain(const FloatType& f,
MatchResultListener* /* listener */) const {
return (::std::isnan)(f);
}
void DescribeTo(::std::ostream* os) const { *os << "is NaN"; }
void DescribeNegationTo(::std::ostream* os) const {
*os << "isn't NaN";
}
};
// Implements the polymorphic floating point equality matcher, which matches // Implements the polymorphic floating point equality matcher, which matches
// two float values using ULP-based approximation or, optionally, a // two float values using ULP-based approximation or, optionally, a
// user-specified epsilon. The template is meant to be instantiated with // user-specified epsilon. The template is meant to be instantiated with
...@@ -1409,7 +1644,7 @@ class FloatingEqMatcher { ...@@ -1409,7 +1644,7 @@ class FloatingEqMatcher {
} }
const FloatType diff = value - expected_; const FloatType diff = value - expected_;
if (fabs(diff) <= max_abs_error_) { if (::std::fabs(diff) <= max_abs_error_) {
return true; return true;
} }
...@@ -1472,16 +1707,11 @@ class FloatingEqMatcher { ...@@ -1472,16 +1707,11 @@ class FloatingEqMatcher {
const bool nan_eq_nan_; const bool nan_eq_nan_;
// max_abs_error will be used for value comparison when >= 0. // max_abs_error will be used for value comparison when >= 0.
const FloatType max_abs_error_; const FloatType max_abs_error_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
// The following 3 type conversion operators allow FloatEq(expected) and // The following 3 type conversion operators allow FloatEq(expected) and
// NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a
// Matcher<const float&>, or a Matcher<float&>, but nothing else. // Matcher<const float&>, or a Matcher<float&>, but nothing else.
// (While Google's C++ coding style doesn't allow arguments passed
// by non-const reference, we may see them in code not conforming to
// the style. Therefore Google Mock needs to support them.)
operator Matcher<FloatType>() const { operator Matcher<FloatType>() const {
return MakeMatcher( return MakeMatcher(
new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));
...@@ -1502,8 +1732,6 @@ class FloatingEqMatcher { ...@@ -1502,8 +1732,6 @@ class FloatingEqMatcher {
const bool nan_eq_nan_; const bool nan_eq_nan_;
// max_abs_error will be used for value comparison when >= 0. // max_abs_error will be used for value comparison when >= 0.
const FloatType max_abs_error_; const FloatType max_abs_error_;
GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
}; };
// A 2-tuple ("binary") wrapper around FloatingEqMatcher: // A 2-tuple ("binary") wrapper around FloatingEqMatcher:
...@@ -1607,8 +1835,9 @@ class PointeeMatcher { ...@@ -1607,8 +1835,9 @@ class PointeeMatcher {
template <typename Pointer> template <typename Pointer>
class Impl : public MatcherInterface<Pointer> { class Impl : public MatcherInterface<Pointer> {
public: public:
typedef typename PointeeOf<typename std::remove_const< using Pointee =
typename std::remove_reference<Pointer>::type>::type>::type Pointee; typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
Pointer)>::element_type;
explicit Impl(const InnerMatcher& matcher) explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<const Pointee&>(matcher)) {} : matcher_(MatcherCast<const Pointee&>(matcher)) {}
...@@ -1633,13 +1862,67 @@ class PointeeMatcher { ...@@ -1633,13 +1862,67 @@ class PointeeMatcher {
private: private:
const Matcher<const Pointee&> matcher_; const Matcher<const Pointee&> matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
const InnerMatcher matcher_; const InnerMatcher matcher_;
};
// Implements the Pointer(m) matcher
// Implements the Pointer(m) matcher for matching a pointer that matches matcher
// m. The pointer can be either raw or smart, and will match `m` against the
// raw pointer.
template <typename InnerMatcher>
class PointerMatcher {
public:
explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
GTEST_DISALLOW_ASSIGN_(PointeeMatcher); // This type conversion operator template allows Pointer(m) to be
// used as a matcher for any pointer type whose pointer type is
// compatible with the inner matcher, where type PointerType can be
// either a raw pointer or a smart pointer.
//
// The reason we do this instead of relying on
// MakePolymorphicMatcher() is that the latter is not flexible
// enough for implementing the DescribeTo() method of Pointer().
template <typename PointerType>
operator Matcher<PointerType>() const { // NOLINT
return Matcher<PointerType>(new Impl<const PointerType&>(matcher_));
}
private:
// The monomorphic implementation that works for a particular pointer type.
template <typename PointerType>
class Impl : public MatcherInterface<PointerType> {
public:
using Pointer =
const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
PointerType)>::element_type*;
explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<Pointer>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "is a pointer that ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "is not a pointer that ";
matcher_.DescribeTo(os);
}
bool MatchAndExplain(PointerType pointer,
MatchResultListener* listener) const override {
*listener << "which is a pointer that ";
Pointer p = GetRawPointer(pointer);
return MatchPrintAndExplain(p, matcher_, listener);
}
private:
Matcher<Pointer> matcher_;
};
const InnerMatcher matcher_;
}; };
#if GTEST_HAS_RTTI #if GTEST_HAS_RTTI
...@@ -1676,8 +1959,6 @@ class WhenDynamicCastToMatcherBase { ...@@ -1676,8 +1959,6 @@ class WhenDynamicCastToMatcherBase {
static void GetCastTypeDescription(::std::ostream* os) { static void GetCastTypeDescription(::std::ostream* os) {
*os << "when dynamic_cast to " << GetToName() << ", "; *os << "when dynamic_cast to " << GetToName() << ", ";
} }
GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
}; };
// Primary template. // Primary template.
...@@ -1775,8 +2056,6 @@ class FieldMatcher { ...@@ -1775,8 +2056,6 @@ class FieldMatcher {
// Contains either "whose given field " if the name of the field is unknown // Contains either "whose given field " if the name of the field is unknown
// or "whose field `name_of_field` " if the name is known. // or "whose field `name_of_field` " if the name is known.
const std::string whose_field_; const std::string whose_field_;
GTEST_DISALLOW_ASSIGN_(FieldMatcher);
}; };
// Implements the Property() matcher for matching a property // Implements the Property() matcher for matching a property
...@@ -1845,8 +2124,6 @@ class PropertyMatcher { ...@@ -1845,8 +2124,6 @@ class PropertyMatcher {
// Contains either "whose given property " if the name of the property is // Contains either "whose given property " if the name of the property is
// unknown or "whose property `name_of_property` " if the name is known. // unknown or "whose property `name_of_property` " if the name is known.
const std::string whose_property_; const std::string whose_property_;
GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
}; };
// Type traits specifying various features of different functors for ResultOf. // Type traits specifying various features of different functors for ResultOf.
...@@ -1936,14 +2213,10 @@ class ResultOfMatcher { ...@@ -1936,14 +2213,10 @@ class ResultOfMatcher {
// how many times the callable will be invoked. // how many times the callable will be invoked.
mutable CallableStorageType callable_; mutable CallableStorageType callable_;
const Matcher<ResultType> matcher_; const Matcher<ResultType> matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; // class Impl }; // class Impl
const CallableStorageType callable_; const CallableStorageType callable_;
const InnerMatcher matcher_; const InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(ResultOfMatcher);
}; };
// Implements a matcher that checks the size of an STL-style container. // Implements a matcher that checks the size of an STL-style container.
...@@ -1988,12 +2261,10 @@ class SizeIsMatcher { ...@@ -1988,12 +2261,10 @@ class SizeIsMatcher {
private: private:
const Matcher<SizeType> size_matcher_; const Matcher<SizeType> size_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const SizeMatcher size_matcher_; const SizeMatcher size_matcher_;
GTEST_DISALLOW_ASSIGN_(SizeIsMatcher);
}; };
// Implements a matcher that checks the begin()..end() distance of an STL-style // Implements a matcher that checks the begin()..end() distance of an STL-style
...@@ -2045,12 +2316,10 @@ class BeginEndDistanceIsMatcher { ...@@ -2045,12 +2316,10 @@ class BeginEndDistanceIsMatcher {
private: private:
const Matcher<DistanceType> distance_matcher_; const Matcher<DistanceType> distance_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const DistanceMatcher distance_matcher_; const DistanceMatcher distance_matcher_;
GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher);
}; };
// Implements an equality matcher for any STL-style container whose elements // Implements an equality matcher for any STL-style container whose elements
...@@ -2143,8 +2412,6 @@ class ContainerEqMatcher { ...@@ -2143,8 +2412,6 @@ class ContainerEqMatcher {
private: private:
const StlContainer expected_; const StlContainer expected_;
GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
}; };
// A comparator functor that uses the < operator to compare two values. // A comparator functor that uses the < operator to compare two values.
...@@ -2226,8 +2493,6 @@ class WhenSortedByMatcher { ...@@ -2226,8 +2493,6 @@ class WhenSortedByMatcher {
private: private:
const Comparator comparator_; const Comparator comparator_;
const ContainerMatcher matcher_; const ContainerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher);
}; };
// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher // Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher
...@@ -2343,15 +2608,11 @@ class PointwiseMatcher { ...@@ -2343,15 +2608,11 @@ class PointwiseMatcher {
private: private:
const Matcher<InnerMatcherArg> mono_tuple_matcher_; const Matcher<InnerMatcherArg> mono_tuple_matcher_;
const RhsStlContainer rhs_; const RhsStlContainer rhs_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const TupleMatcher tuple_matcher_; const TupleMatcher tuple_matcher_;
const RhsStlContainer rhs_; const RhsStlContainer rhs_;
GTEST_DISALLOW_ASSIGN_(PointwiseMatcher);
}; };
// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl. // Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
...@@ -2394,8 +2655,6 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> { ...@@ -2394,8 +2655,6 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> {
protected: protected:
const Matcher<const Element&> inner_matcher_; const Matcher<const Element&> inner_matcher_;
GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
}; };
// Implements Contains(element_matcher) for the given argument type Container. // Implements Contains(element_matcher) for the given argument type Container.
...@@ -2422,9 +2681,6 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> { ...@@ -2422,9 +2681,6 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
MatchResultListener* listener) const override { MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(false, container, listener); return this->MatchAndExplainImpl(false, container, listener);
} }
private:
GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
}; };
// Implements Each(element_matcher) for the given argument type Container. // Implements Each(element_matcher) for the given argument type Container.
...@@ -2451,9 +2707,6 @@ class EachMatcherImpl : public QuantifierMatcherImpl<Container> { ...@@ -2451,9 +2707,6 @@ class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
MatchResultListener* listener) const override { MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(true, container, listener); return this->MatchAndExplainImpl(true, container, listener);
} }
private:
GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
}; };
// Implements polymorphic Contains(element_matcher). // Implements polymorphic Contains(element_matcher).
...@@ -2470,8 +2723,6 @@ class ContainsMatcher { ...@@ -2470,8 +2723,6 @@ class ContainsMatcher {
private: private:
const M inner_matcher_; const M inner_matcher_;
GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
}; };
// Implements polymorphic Each(element_matcher). // Implements polymorphic Each(element_matcher).
...@@ -2488,8 +2739,6 @@ class EachMatcher { ...@@ -2488,8 +2739,6 @@ class EachMatcher {
private: private:
const M inner_matcher_; const M inner_matcher_;
GTEST_DISALLOW_ASSIGN_(EachMatcher);
}; };
struct Rank1 {}; struct Rank1 {};
...@@ -2560,8 +2809,6 @@ class KeyMatcherImpl : public MatcherInterface<PairType> { ...@@ -2560,8 +2809,6 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
private: private:
const Matcher<const KeyType&> inner_matcher_; const Matcher<const KeyType&> inner_matcher_;
GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl);
}; };
// Implements polymorphic Key(matcher_for_key). // Implements polymorphic Key(matcher_for_key).
...@@ -2578,8 +2825,49 @@ class KeyMatcher { ...@@ -2578,8 +2825,49 @@ class KeyMatcher {
private: private:
const M matcher_for_key_; const M matcher_for_key_;
};
// Implements polymorphic Address(matcher_for_address).
template <typename InnerMatcher>
class AddressMatcher {
public:
explicit AddressMatcher(InnerMatcher m) : matcher_(m) {}
GTEST_DISALLOW_ASSIGN_(KeyMatcher); template <typename Type>
operator Matcher<Type>() const { // NOLINT
return Matcher<Type>(new Impl<const Type&>(matcher_));
}
private:
// The monomorphic implementation that works for a particular object type.
template <typename Type>
class Impl : public MatcherInterface<Type> {
public:
using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *;
explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<Address>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "has address that ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not have address that ";
matcher_.DescribeTo(os);
}
bool MatchAndExplain(Type object,
MatchResultListener* listener) const override {
*listener << "which has address ";
Address address = std::addressof(object);
return MatchPrintAndExplain(address, matcher_, listener);
}
private:
const Matcher<Address> matcher_;
};
const InnerMatcher matcher_;
}; };
// Implements Pair(first_matcher, second_matcher) for the given argument pair // Implements Pair(first_matcher, second_matcher) for the given argument pair
...@@ -2665,8 +2953,6 @@ class PairMatcherImpl : public MatcherInterface<PairType> { ...@@ -2665,8 +2953,6 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
const Matcher<const FirstType&> first_matcher_; const Matcher<const FirstType&> first_matcher_;
const Matcher<const SecondType&> second_matcher_; const Matcher<const SecondType&> second_matcher_;
GTEST_DISALLOW_ASSIGN_(PairMatcherImpl);
}; };
// Implements polymorphic Pair(first_matcher, second_matcher). // Implements polymorphic Pair(first_matcher, second_matcher).
...@@ -2685,8 +2971,203 @@ class PairMatcher { ...@@ -2685,8 +2971,203 @@ class PairMatcher {
private: private:
const FirstMatcher first_matcher_; const FirstMatcher first_matcher_;
const SecondMatcher second_matcher_; const SecondMatcher second_matcher_;
};
template <typename T, size_t... I>
auto UnpackStructImpl(const T& t, IndexSequence<I...>, int)
-> decltype(std::tie(get<I>(t)...)) {
static_assert(std::tuple_size<T>::value == sizeof...(I),
"Number of arguments doesn't match the number of fields.");
return std::tie(get<I>(t)...);
}
#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) {
const auto& [a] = t;
return std::tie(a);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) {
const auto& [a, b] = t;
return std::tie(a, b);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) {
const auto& [a, b, c] = t;
return std::tie(a, b, c);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) {
const auto& [a, b, c, d] = t;
return std::tie(a, b, c, d);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) {
const auto& [a, b, c, d, e] = t;
return std::tie(a, b, c, d, e);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) {
const auto& [a, b, c, d, e, f] = t;
return std::tie(a, b, c, d, e, f);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) {
const auto& [a, b, c, d, e, f, g] = t;
return std::tie(a, b, c, d, e, f, g);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) {
const auto& [a, b, c, d, e, f, g, h] = t;
return std::tie(a, b, c, d, e, f, g, h);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) {
const auto& [a, b, c, d, e, f, g, h, i] = t;
return std::tie(a, b, c, d, e, f, g, h, i);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
}
#endif // defined(__cpp_structured_bindings)
template <size_t I, typename T>
auto UnpackStruct(const T& t)
-> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) {
return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0);
}
// Helper function to do comma folding in C++11.
// The array ensures left-to-right order of evaluation.
// Usage: VariadicExpand({expr...});
template <typename T, size_t N>
void VariadicExpand(const T (&)[N]) {}
template <typename Struct, typename StructSize>
class FieldsAreMatcherImpl;
template <typename Struct, size_t... I>
class FieldsAreMatcherImpl<Struct, IndexSequence<I...>>
: public MatcherInterface<Struct> {
using UnpackedType =
decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));
using MatchersType = std::tuple<
Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>;
GTEST_DISALLOW_ASSIGN_(PairMatcher); public:
template <typename Inner>
explicit FieldsAreMatcherImpl(const Inner& matchers)
: matchers_(testing::SafeMatcherCast<
const typename std::tuple_element<I, UnpackedType>::type&>(
std::get<I>(matchers))...) {}
void DescribeTo(::std::ostream* os) const override {
const char* separator = "";
VariadicExpand(
{(*os << separator << "has field #" << I << " that ",
std::get<I>(matchers_).DescribeTo(os), separator = ", and ")...});
}
void DescribeNegationTo(::std::ostream* os) const override {
const char* separator = "";
VariadicExpand({(*os << separator << "has field #" << I << " that ",
std::get<I>(matchers_).DescribeNegationTo(os),
separator = ", or ")...});
}
bool MatchAndExplain(Struct t, MatchResultListener* listener) const override {
return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener);
}
private:
bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const {
if (!listener->IsInterested()) {
// If the listener is not interested, we don't need to construct the
// explanation.
bool good = true;
VariadicExpand({good = good && std::get<I>(matchers_).Matches(
std::get<I>(tuple))...});
return good;
}
size_t failed_pos = ~size_t{};
std::vector<StringMatchResultListener> inner_listener(sizeof...(I));
VariadicExpand(
{failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(
std::get<I>(tuple), &inner_listener[I])
? failed_pos = I
: 0 ...});
if (failed_pos != ~size_t{}) {
*listener << "whose field #" << failed_pos << " does not match";
PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream());
return false;
}
*listener << "whose all elements match";
const char* separator = ", where";
for (size_t index = 0; index < sizeof...(I); ++index) {
const std::string str = inner_listener[index].str();
if (!str.empty()) {
*listener << separator << " field #" << index << " is a value " << str;
separator = ", and";
}
}
return true;
}
MatchersType matchers_;
};
template <typename... Inner>
class FieldsAreMatcher {
public:
explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {}
template <typename Struct>
operator Matcher<Struct>() const { // NOLINT
return Matcher<Struct>(
new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>(
matchers_));
}
private:
std::tuple<Inner...> matchers_;
}; };
// Implements ElementsAre() and ElementsAreArray(). // Implements ElementsAre() and ElementsAreArray().
...@@ -2832,8 +3313,6 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { ...@@ -2832,8 +3313,6 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
size_t count() const { return matchers_.size(); } size_t count() const { return matchers_.size(); }
::std::vector<Matcher<const Element&> > matchers_; ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl);
}; };
// Connectivity matrix of (elements X matchers), in element-major order. // Connectivity matrix of (elements X matchers), in element-major order.
...@@ -2936,8 +3415,6 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { ...@@ -2936,8 +3415,6 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
private: private:
UnorderedMatcherRequire::Flags match_flags_; UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_; MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
}; };
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and // Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
...@@ -2960,7 +3437,9 @@ class UnorderedElementsAreMatcherImpl ...@@ -2960,7 +3437,9 @@ class UnorderedElementsAreMatcherImpl
: UnorderedElementsAreMatcherImplBase(matcher_flags) { : UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++first) { for (; first != last; ++first) {
matchers_.push_back(MatcherCast<const Element&>(*first)); matchers_.push_back(MatcherCast<const Element&>(*first));
matcher_describers().push_back(matchers_.back().GetDescriber()); }
for (const auto& m : matchers_) {
matcher_describers().push_back(m.GetDescriber());
} }
} }
...@@ -3011,12 +3490,14 @@ class UnorderedElementsAreMatcherImpl ...@@ -3011,12 +3490,14 @@ class UnorderedElementsAreMatcherImpl
element_printouts->clear(); element_printouts->clear();
::std::vector<char> did_match; ::std::vector<char> did_match;
size_t num_elements = 0; size_t num_elements = 0;
DummyMatchResultListener dummy;
for (; elem_first != elem_last; ++num_elements, ++elem_first) { for (; elem_first != elem_last; ++num_elements, ++elem_first) {
if (listener->IsInterested()) { if (listener->IsInterested()) {
element_printouts->push_back(PrintToString(*elem_first)); element_printouts->push_back(PrintToString(*elem_first));
} }
for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
did_match.push_back(Matches(matchers_[irhs])(*elem_first)); did_match.push_back(
matchers_[irhs].MatchAndExplain(*elem_first, &dummy));
} }
} }
...@@ -3031,8 +3512,6 @@ class UnorderedElementsAreMatcherImpl ...@@ -3031,8 +3512,6 @@ class UnorderedElementsAreMatcherImpl
} }
::std::vector<Matcher<const Element&> > matchers_; ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
}; };
// Functor for use in TransformTuple. // Functor for use in TransformTuple.
...@@ -3070,7 +3549,6 @@ class UnorderedElementsAreMatcher { ...@@ -3070,7 +3549,6 @@ class UnorderedElementsAreMatcher {
private: private:
const MatcherTuple matchers_; const MatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher);
}; };
// Implements ElementsAre. // Implements ElementsAre.
...@@ -3100,7 +3578,6 @@ class ElementsAreMatcher { ...@@ -3100,7 +3578,6 @@ class ElementsAreMatcher {
private: private:
const MatcherTuple matchers_; const MatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
}; };
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). // Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
...@@ -3122,8 +3599,6 @@ class UnorderedElementsAreArrayMatcher { ...@@ -3122,8 +3599,6 @@ class UnorderedElementsAreArrayMatcher {
private: private:
UnorderedMatcherRequire::Flags match_flags_; UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_; ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
}; };
// Implements ElementsAreArray(). // Implements ElementsAreArray().
...@@ -3145,8 +3620,6 @@ class ElementsAreArrayMatcher { ...@@ -3145,8 +3620,6 @@ class ElementsAreArrayMatcher {
private: private:
const ::std::vector<T> matchers_; const ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
}; };
// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second // Given a 2-tuple matcher tm of type Tuple2Matcher and a value second
...@@ -3164,6 +3637,8 @@ class BoundSecondMatcher { ...@@ -3164,6 +3637,8 @@ class BoundSecondMatcher {
BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)
: tuple2_matcher_(tm), second_value_(second) {} : tuple2_matcher_(tm), second_value_(second) {}
BoundSecondMatcher(const BoundSecondMatcher& other) = default;
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));
...@@ -3206,8 +3681,6 @@ class BoundSecondMatcher { ...@@ -3206,8 +3681,6 @@ class BoundSecondMatcher {
private: private:
const Matcher<const ArgTuple&> mono_tuple2_matcher_; const Matcher<const ArgTuple&> mono_tuple2_matcher_;
const Second second_value_; const Second second_value_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
const Tuple2Matcher tuple2_matcher_; const Tuple2Matcher tuple2_matcher_;
...@@ -3280,12 +3753,10 @@ class OptionalMatcher { ...@@ -3280,12 +3753,10 @@ class OptionalMatcher {
private: private:
const Matcher<ValueType> value_matcher_; const Matcher<ValueType> value_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const ValueMatcher value_matcher_; const ValueMatcher value_matcher_;
GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
}; };
namespace variant_matcher { namespace variant_matcher {
...@@ -3593,12 +4064,14 @@ const internal::AnythingMatcher _ = {}; ...@@ -3593,12 +4064,14 @@ const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
inline Matcher<T> A() { inline Matcher<T> A() {
return Matcher<T>(new internal::AnyMatcherImpl<T>()); return _;
} }
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
inline Matcher<T> An() { return A<T>(); } inline Matcher<T> An() {
return _;
}
template <typename T, typename M> template <typename T, typename M>
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
...@@ -3626,6 +4099,11 @@ inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT ...@@ -3626,6 +4099,11 @@ inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT
return internal::RefMatcher<T&>(x); return internal::RefMatcher<T&>(x);
} }
// Creates a polymorphic matcher that matches any NaN floating point.
inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {
return MakePolymorphicMatcher(internal::IsNanMatcher());
}
// Creates a matcher that matches any double argument approximately // Creates a matcher that matches any double argument approximately
// equal to rhs, where two NANs are considered unequal. // equal to rhs, where two NANs are considered unequal.
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
...@@ -3808,52 +4286,60 @@ internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( ...@@ -3808,52 +4286,60 @@ internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
// String matchers. // String matchers.
// Matches a string equal to str. // Matches a string equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, true, true)); internal::StrEqualityMatcher<std::string>(std::string(str), true, true));
} }
// Matches a string not equal to str. // Matches a string not equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, false, true)); internal::StrEqualityMatcher<std::string>(std::string(str), false, true));
} }
// Matches a string equal to str, ignoring case. // Matches a string equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, true, false)); internal::StrEqualityMatcher<std::string>(std::string(str), true, false));
} }
// Matches a string not equal to str, ignoring case. // Matches a string not equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe(
return MakePolymorphicMatcher( const internal::StringLike<T>& str) {
internal::StrEqualityMatcher<std::string>(str, false, false)); return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>(
std::string(str), false, false));
} }
// Creates a matcher that matches any string, std::string, or C string // Creates a matcher that matches any string, std::string, or C string
// that contains the given substring. // that contains the given substring.
inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( template <typename T = std::string>
const std::string& substring) { PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr(
const internal::StringLike<T>& substring) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::HasSubstrMatcher<std::string>(substring)); internal::HasSubstrMatcher<std::string>(std::string(substring)));
} }
// Matches a string that starts with 'prefix' (case-sensitive). // Matches a string that starts with 'prefix' (case-sensitive).
inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( template <typename T = std::string>
const std::string& prefix) { PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith(
const internal::StringLike<T>& prefix) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StartsWithMatcher<std::string>(prefix)); internal::StartsWithMatcher<std::string>(std::string(prefix)));
} }
// Matches a string that ends with 'suffix' (case-sensitive). // Matches a string that ends with 'suffix' (case-sensitive).
inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( template <typename T = std::string>
const std::string& suffix) { PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix)); const internal::StringLike<T>& suffix) {
return MakePolymorphicMatcher(
internal::EndsWithMatcher<std::string>(std::string(suffix)));
} }
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
...@@ -4034,11 +4520,7 @@ template <typename Container> ...@@ -4034,11 +4520,7 @@ template <typename Container>
inline PolymorphicMatcher<internal::ContainerEqMatcher< inline PolymorphicMatcher<internal::ContainerEqMatcher<
typename std::remove_const<Container>::type>> typename std::remove_const<Container>::type>>
ContainerEq(const Container& rhs) { ContainerEq(const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0, return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));
// which causes Container to be a const type sometimes.
typedef typename std::remove_const<Container>::type RawContainer;
return MakePolymorphicMatcher(
internal::ContainerEqMatcher<RawContainer>(rhs));
} }
// Returns a matcher that matches a container that, when sorted using // Returns a matcher that matches a container that, when sorted using
...@@ -4071,12 +4553,8 @@ template <typename TupleMatcher, typename Container> ...@@ -4071,12 +4553,8 @@ template <typename TupleMatcher, typename Container>
inline internal::PointwiseMatcher<TupleMatcher, inline internal::PointwiseMatcher<TupleMatcher,
typename std::remove_const<Container>::type> typename std::remove_const<Container>::type>
Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0, return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher,
// which causes Container to be a const type sometimes (e.g. when rhs);
// rhs is a const int[])..
typedef typename std::remove_const<Container>::type RawContainer;
return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
tuple_matcher, rhs);
} }
...@@ -4107,14 +4585,9 @@ inline internal::UnorderedElementsAreArrayMatcher< ...@@ -4107,14 +4585,9 @@ inline internal::UnorderedElementsAreArrayMatcher<
typename std::remove_const<RhsContainer>::type>::type::value_type>> typename std::remove_const<RhsContainer>::type>::type::value_type>>
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
const RhsContainer& rhs_container) { const RhsContainer& rhs_container) {
// This following line is for working around a bug in MSVC 8.0,
// which causes RhsContainer to be a const type sometimes (e.g. when
// rhs_container is a const int[]).
typedef typename std::remove_const<RhsContainer>::type RawRhsContainer;
// RhsView allows the same code to handle RhsContainer being a // RhsView allows the same code to handle RhsContainer being a
// STL-style container and it being a native C-style array. // STL-style container and it being a native C-style array.
typedef typename internal::StlContainerView<RawRhsContainer> RhsView; typedef typename internal::StlContainerView<RhsContainer> RhsView;
typedef typename RhsView::type RhsStlContainer; typedef typename RhsView::type RhsStlContainer;
typedef typename RhsStlContainer::value_type Second; typedef typename RhsStlContainer::value_type Second;
const RhsStlContainer& rhs_stl_container = const RhsStlContainer& rhs_stl_container =
...@@ -4336,6 +4809,35 @@ Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) { ...@@ -4336,6 +4809,35 @@ Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
first_matcher, second_matcher); first_matcher, second_matcher);
} }
namespace no_adl {
// FieldsAre(matchers...) matches piecewise the fields of compatible structs.
// These include those that support `get<I>(obj)`, and when structured bindings
// are enabled any class that supports them.
// In particular, `std::tuple`, `std::pair`, `std::array` and aggregate types.
template <typename... M>
internal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre(
M&&... matchers) {
return internal::FieldsAreMatcher<typename std::decay<M>::type...>(
std::forward<M>(matchers)...);
}
// Creates a matcher that matches a pointer (raw or smart) that matches
// inner_matcher.
template <typename InnerMatcher>
inline internal::PointerMatcher<InnerMatcher> Pointer(
const InnerMatcher& inner_matcher) {
return internal::PointerMatcher<InnerMatcher>(inner_matcher);
}
// Creates a matcher that matches an object that has an address that matches
// inner_matcher.
template <typename InnerMatcher>
inline internal::AddressMatcher<InnerMatcher> Address(
const InnerMatcher& inner_matcher) {
return internal::AddressMatcher<InnerMatcher>(inner_matcher);
}
} // namespace no_adl
// Returns a predicate that is satisfied by anything that matches the // Returns a predicate that is satisfied by anything that matches the
// given matcher. // given matcher.
template <typename M> template <typename M>
...@@ -4520,7 +5022,7 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } ...@@ -4520,7 +5022,7 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// and is printable using 'PrintToString'. It is compatible with // and is printable using 'PrintToString'. It is compatible with
// std::optional/std::experimental::optional. // std::optional/std::experimental::optional.
// Note that to compare an optional type variable against nullopt you should // Note that to compare an optional type variable against nullopt you should
// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the // use Eq(nullopt) and not Eq(Optional(nullopt)). The latter implies that the
// optional value contains an optional itself. // optional value contains an optional itself.
template <typename ValueMatcher> template <typename ValueMatcher>
inline internal::OptionalMatcher<ValueMatcher> Optional( inline internal::OptionalMatcher<ValueMatcher> Optional(
...@@ -4547,6 +5049,175 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( ...@@ -4547,6 +5049,175 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
internal::variant_matcher::VariantMatcher<T>(matcher)); internal::variant_matcher::VariantMatcher<T>(matcher));
} }
#if GTEST_HAS_EXCEPTIONS
// Anything inside the `internal` namespace is internal to the implementation
// and must not be used in user code!
namespace internal {
class WithWhatMatcherImpl {
public:
WithWhatMatcherImpl(Matcher<std::string> matcher)
: matcher_(std::move(matcher)) {}
void DescribeTo(std::ostream* os) const {
*os << "contains .what() that ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "contains .what() that does not ";
matcher_.DescribeTo(os);
}
template <typename Err>
bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
*listener << "which contains .what() that ";
return matcher_.MatchAndExplain(err.what(), listener);
}
private:
const Matcher<std::string> matcher_;
};
inline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat(
Matcher<std::string> m) {
return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m)));
}
template <typename Err>
class ExceptionMatcherImpl {
class NeverThrown {
public:
const char* what() const noexcept {
return "this exception should never be thrown";
}
};
// If the matchee raises an exception of a wrong type, we'd like to
// catch it and print its message and type. To do that, we add an additional
// catch clause:
//
// try { ... }
// catch (const Err&) { /* an expected exception */ }
// catch (const std::exception&) { /* exception of a wrong type */ }
//
// However, if the `Err` itself is `std::exception`, we'd end up with two
// identical `catch` clauses:
//
// try { ... }
// catch (const std::exception&) { /* an expected exception */ }
// catch (const std::exception&) { /* exception of a wrong type */ }
//
// This can cause a warning or an error in some compilers. To resolve
// the issue, we use a fake error type whenever `Err` is `std::exception`:
//
// try { ... }
// catch (const std::exception&) { /* an expected exception */ }
// catch (const NeverThrown&) { /* exception of a wrong type */ }
using DefaultExceptionType = typename std::conditional<
std::is_same<typename std::remove_cv<
typename std::remove_reference<Err>::type>::type,
std::exception>::value,
const NeverThrown&, const std::exception&>::type;
public:
ExceptionMatcherImpl(Matcher<const Err&> matcher)
: matcher_(std::move(matcher)) {}
void DescribeTo(std::ostream* os) const {
*os << "throws an exception which is a " << GetTypeName<Err>();
*os << " which ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "throws an exception which is not a " << GetTypeName<Err>();
*os << " which ";
matcher_.DescribeNegationTo(os);
}
template <typename T>
bool MatchAndExplain(T&& x, MatchResultListener* listener) const {
try {
(void)(std::forward<T>(x)());
} catch (const Err& err) {
*listener << "throws an exception which is a " << GetTypeName<Err>();
*listener << " ";
return matcher_.MatchAndExplain(err, listener);
} catch (DefaultExceptionType err) {
#if GTEST_HAS_RTTI
*listener << "throws an exception of type " << GetTypeName(typeid(err));
*listener << " ";
#else
*listener << "throws an std::exception-derived type ";
#endif
*listener << "with description \"" << err.what() << "\"";
return false;
} catch (...) {
*listener << "throws an exception of an unknown type";
return false;
}
*listener << "does not throw any exception";
return false;
}
private:
const Matcher<const Err&> matcher_;
};
} // namespace internal
// Throws()
// Throws(exceptionMatcher)
// ThrowsMessage(messageMatcher)
//
// This matcher accepts a callable and verifies that when invoked, it throws
// an exception with the given type and properties.
//
// Examples:
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// Throws<std::runtime_error>());
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// ThrowsMessage<std::runtime_error>(HasSubstr("message")));
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// Throws<std::runtime_error>(
// Property(&std::runtime_error::what, HasSubstr("message"))));
template <typename Err>
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() {
return MakePolymorphicMatcher(
internal::ExceptionMatcherImpl<Err>(A<const Err&>()));
}
template <typename Err, typename ExceptionMatcher>
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws(
const ExceptionMatcher& exception_matcher) {
// Using matcher cast allows users to pass a matcher of a more broad type.
// For example user may want to pass Matcher<std::exception>
// to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>.
return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>(
SafeMatcherCast<const Err&>(exception_matcher)));
}
template <typename Err, typename MessageMatcher>
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
MessageMatcher&& message_matcher) {
static_assert(std::is_base_of<std::exception, Err>::value,
"expected an std::exception-derived type");
return Throws<Err>(internal::WithWhat(
MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher))));
}
#endif // GTEST_HAS_EXCEPTIONS
// These macros allow using matchers to check values in Google Test // These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed if and only if the value matches the matcher. If the assertion // succeed if and only if the value matches the matcher. If the assertion
...@@ -4556,6 +5227,159 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( ...@@ -4556,6 +5227,159 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ #define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
// MATCHER* macroses itself are listed below.
#define MATCHER(name, description) \
class name##Matcher \
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
public: \
template <typename arg_type> \
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
public: \
gmock_Impl() {} \
bool MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener) const override; \
void DescribeTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(false); \
} \
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(true); \
} \
\
private: \
::std::string FormatDescription(bool negation) const { \
::std::string gmock_description = (description); \
if (!gmock_description.empty()) { \
return gmock_description; \
} \
return ::testing::internal::FormatMatcherDescription(negation, #name, \
{}); \
} \
}; \
}; \
GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \
template <typename arg_type> \
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \
const
#define MATCHER_P(name, p0, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (p0))
#define MATCHER_P2(name, p0, p1, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (p0, p1))
#define MATCHER_P3(name, p0, p1, p2, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (p0, p1, p2))
#define MATCHER_P4(name, p0, p1, p2, p3, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, (p0, p1, p2, p3))
#define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \
(p0, p1, p2, p3, p4))
#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \
(p0, p1, p2, p3, p4, p5))
#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \
(p0, p1, p2, p3, p4, p5, p6))
#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \
(p0, p1, p2, p3, p4, p5, p6, p7))
#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \
(p0, p1, p2, p3, p4, p5, p6, p7, p8))
#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \
(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))
#define GMOCK_INTERNAL_MATCHER(name, full_name, description, args) \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
class full_name : public ::testing::internal::MatcherBaseImpl< \
full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \
public: \
using full_name::MatcherBaseImpl::MatcherBaseImpl; \
template <typename arg_type> \
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
public: \
explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) \
: GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {} \
bool MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener) const override; \
void DescribeTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(false); \
} \
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(true); \
} \
GMOCK_INTERNAL_MATCHER_MEMBERS(args) \
\
private: \
::std::string FormatDescription(bool negation) const { \
::std::string gmock_description = (description); \
if (!gmock_description.empty()) { \
return gmock_description; \
} \
return ::testing::internal::FormatMatcherDescription( \
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings( \
::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \
GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \
} \
}; \
}; \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name( \
GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) { \
return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \
GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args)); \
} \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
template <typename arg_type> \
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \
arg_type>::MatchAndExplain(const arg_type& arg, \
::testing::MatchResultListener* \
result_listener GTEST_ATTRIBUTE_UNUSED_) \
const
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
GMOCK_PP_TAIL( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args))
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \
, typename arg##_type
#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args))
#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \
, arg##_type
#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \
GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH( \
GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args))
#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \
, arg##_type gmock_p##i
#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args))
#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \
, arg(::std::forward<arg##_type>(gmock_p##i))
#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args)
#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \
const arg##_type arg;
#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args))
#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg
#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args))
#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg_unused) \
, gmock_p##i
// To prevent ADL on certain functions we put them on a separate namespace.
using namespace no_adl; // NOLINT
} // namespace testing } // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
...@@ -4565,4 +5389,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 ...@@ -4565,4 +5389,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
// declarations from this file. // declarations from this file.
#include "gmock/internal/custom/gmock-matchers.h" #include "gmock/internal/custom/gmock-matchers.h"
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic actions.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include <memory>
#include <utility>
#include "gmock/gmock-actions.h"
#include "gmock/internal/gmock-port.h"
// Include any custom callback actions added by the local installation.
#include "gmock/internal/custom/gmock-generated-actions.h"
// Sometimes you want to give an action explicit template parameters
// that cannot be inferred from its value parameters. ACTION() and
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
// and can be viewed as an extension to ACTION() and ACTION_P*().
//
// The syntax:
//
// ACTION_TEMPLATE(ActionName,
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
//
// defines an action template that takes m explicit template
// parameters and n value parameters. name_i is the name of the i-th
// template parameter, and kind_i specifies whether it's a typename,
// an integral constant, or a template. p_i is the name of the i-th
// value parameter.
//
// Example:
//
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
// // function to type T and copies it to *output.
// ACTION_TEMPLATE(DuplicateArg,
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
// AND_1_VALUE_PARAMS(output)) {
// *output = T(::std::get<k>(args));
// }
// ...
// int n;
// EXPECT_CALL(mock, Foo(_, _))
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
//
// To create an instance of an action template, write:
//
// ActionName<t1, ..., t_m>(v1, ..., v_n)
//
// where the ts are the template arguments and the vs are the value
// arguments. The value argument types are inferred by the compiler.
// If you want to explicitly specify the value argument types, you can
// provide additional template arguments:
//
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
//
// where u_i is the desired type of v_i.
//
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
// number of value parameters, but not on the number of template
// parameters. Without the restriction, the meaning of the following
// is unclear:
//
// OverloadedAction<int, bool>(x);
//
// Are we using a single-template-parameter action where 'bool' refers
// to the type of x, or are we using a two-template-parameter action
// where the compiler is asked to infer the type of x?
//
// Implementation notes:
//
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
// implementing ACTION_TEMPLATE. The main trick we use is to create
// new macro invocations when expanding a macro. For example, we have
//
// #define ACTION_TEMPLATE(name, template_params, value_params)
// ... GMOCK_INTERNAL_DECL_##template_params ...
//
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
// to expand to
//
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
//
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
// preprocessor will continue to expand it to
//
// ... typename T ...
//
// This technique conforms to the C++ standard and is portable. It
// allows us to implement action templates using O(N) code, where N is
// the maximum number of template/value parameters supported. Without
// using it, we'd have to devote O(N^2) amount of code to implement all
// combinations of m and n.
// Declares the template parameters.
#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1) kind0 name0, kind1 name1
#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2) kind0 name0, kind1 name1, kind2 name2
#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \
kind3 name3
#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \
kind2 name2, kind3 name3, kind4 name4
#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5
#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
kind5 name5, kind6 name6
#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \
kind4 name4, kind5 name5, kind6 name6, kind7 name7
#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \
kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \
kind8 name8
#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \
kind6 name6, kind7 name7, kind8 name8, kind9 name9
// Lists the template parameters.
#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1) name0, name1
#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2) name0, name1, name2
#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3) name0, name1, name2, name3
#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \
name4
#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \
name2, name3, name4, name5
#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6) name0, name1, name2, name3, name4, name5, name6
#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7
#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \
name6, name7, name8
#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \
name3, name4, name5, name6, name7, name8, name9
// Declares the types of value parameters.
#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \
typename p0##_type, typename p1##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \
typename p0##_type, typename p1##_type, typename p2##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6) , typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \
typename p2##_type, typename p3##_type, typename p4##_type, \
typename p5##_type, typename p6##_type, typename p7##_type, \
typename p8##_type, typename p9##_type
// Initializes the value parameters.
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
()
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
(p0##_type gmock_p0) : p0(::std::move(gmock_p0))
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
(p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1))
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2))
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3))
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4))
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5))
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6))
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
p7(::std::move(gmock_p7))
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8))
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
p9(::std::move(gmock_p9))
// Defines the copy constructor
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
{} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default;
#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default;
// Declares the fields for storing the value parameters.
#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;
#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \
p1##_type p1;
#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \
p1##_type p1; p2##_type p2;
#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \
p1##_type p1; p2##_type p2; p3##_type p3;
#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \
p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4;
#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \
p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
p5##_type p5;
#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
p5##_type p5; p6##_type p6;
#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
p5##_type p5; p6##_type p6; p7##_type p7;
#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \
p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8;
#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \
p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \
p9##_type p9;
// Lists the value parameters.
#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0
#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1
#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2
#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3
#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \
p2, p3, p4
#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \
p1, p2, p3, p4, p5
#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6) p0, p1, p2, p3, p4, p5, p6
#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7) p0, p1, p2, p3, p4, p5, p6, p7
#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8
#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9
// Lists the value parameter types.
#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \
p1##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \
p1##_type, p2##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
p0##_type, p1##_type, p2##_type, p3##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
p0##_type, p1##_type, p2##_type, p3##_type, p4##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \
p6##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type, p8##_type
#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type, p8##_type, p9##_type
// Declares the value parameters.
#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0
#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \
p1##_type p1
#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \
p1##_type p1, p2##_type p2
#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \
p1##_type p1, p2##_type p2, p3##_type p3
#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \
p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4
#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \
p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
p5##_type p5
#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
p5##_type p5, p6##_type p6
#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
p5##_type p5, p6##_type p6, p7##_type p7
#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8
#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \
p9##_type p9
// The suffix of the class template implementing the action template.
#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P
#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2
#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3
#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4
#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5
#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6
#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7
#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7) P8
#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8) P9
#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9) P10
// The name of the class template implementing the action template.
#define GMOCK_ACTION_CLASS_(name, value_params)\
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
#define ACTION_TEMPLATE(name, template_params, value_params) \
template <GMOCK_INTERNAL_DECL_##template_params \
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
class GMOCK_ACTION_CLASS_(name, value_params) { \
public: \
explicit GMOCK_ACTION_CLASS_(name, value_params)( \
GMOCK_INTERNAL_DECL_##value_params) \
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
= default; , \
: impl_(std::make_shared<gmock_Impl>( \
GMOCK_INTERNAL_LIST_##value_params)) { }) \
GMOCK_ACTION_CLASS_(name, value_params)( \
const GMOCK_ACTION_CLASS_(name, value_params)&) noexcept \
GMOCK_INTERNAL_DEFN_COPY_##value_params \
GMOCK_ACTION_CLASS_(name, value_params)( \
GMOCK_ACTION_CLASS_(name, value_params)&&) noexcept \
GMOCK_INTERNAL_DEFN_COPY_##value_params \
template <typename F> \
operator ::testing::Action<F>() const { \
return GMOCK_PP_IF( \
GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
(::testing::internal::MakeAction<F, gmock_Impl>()), \
(::testing::internal::MakeAction<F>(impl_))); \
} \
private: \
class gmock_Impl { \
public: \
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_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_INTERNAL_DEFN_##value_params \
}; \
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
, std::shared_ptr<const gmock_Impl> impl_;) \
}; \
template <GMOCK_INTERNAL_DECL_##template_params \
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
GMOCK_ACTION_CLASS_(name, value_params)< \
GMOCK_INTERNAL_LIST_##template_params \
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
template <GMOCK_INTERNAL_DECL_##template_params \
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
inline GMOCK_ACTION_CLASS_(name, value_params)< \
GMOCK_INTERNAL_LIST_##template_params \
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
GMOCK_INTERNAL_DECL_##value_params) { \
return GMOCK_ACTION_CLASS_(name, value_params)< \
GMOCK_INTERNAL_LIST_##template_params \
GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
GMOCK_INTERNAL_LIST_##value_params); \
} \
template <GMOCK_INTERNAL_DECL_##template_params \
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
template <typename function_type, typename return_type, typename args_type, \
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
return_type GMOCK_ACTION_CLASS_(name, value_params)< \
GMOCK_INTERNAL_LIST_##template_params \
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
namespace internal {
// internal::InvokeArgument - a helper for InvokeArgument action.
// The basic overloads are provided here for generic functors.
// Overloads for other custom-callables are provided in the
// internal/custom/gmock-generated-actions.h header.
template <typename F, typename... Args>
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
return f(args...);
}
template <std::size_t index, typename... Params>
struct InvokeArgumentAction {
template <typename... Args>
auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument(
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
std::declval<const Params&>()...)) {
internal::FlatTuple<Args&&...> args_tuple(FlatTupleConstructTag{},
std::forward<Args>(args)...);
return params.Apply([&](const Params&... unpacked_params) {
auto&& callable = args_tuple.template Get<index>();
return internal::InvokeArgument(
std::forward<decltype(callable)>(callable), unpacked_params...);
});
}
internal::FlatTuple<Params...> params;
};
} // namespace internal
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
// (0-based) argument, which must be a k-ary callable, of the mock
// function, with arguments a1, a2, ..., a_k.
//
// Notes:
//
// 1. The arguments are passed by value by default. If you need to
// pass an argument by reference, wrap it inside std::ref(). For
// example,
//
// InvokeArgument<1>(5, string("Hello"), std::ref(foo))
//
// passes 5 and string("Hello") by value, and passes foo by
// reference.
//
// 2. If the callable takes an argument by reference but std::ref() is
// not used, it will receive the reference to a copy of the value,
// instead of the original value. For example, when the 0-th
// argument of the mock function takes a const string&, the action
//
// InvokeArgument<0>(string("Hello"))
//
// makes a copy of the temporary string("Hello") object and passes a
// reference of the copy, instead of the original temporary object,
// to the callable. This makes it easy for a user to define an
// InvokeArgument action from temporary values and have it performed
// later.
template <std::size_t index, typename... Params>
internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
InvokeArgument(Params&&... params) {
return {internal::FlatTuple<typename std::decay<Params>::type...>(
internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};
}
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
...@@ -30,17 +30,17 @@ ...@@ -30,17 +30,17 @@
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file implements some matchers that depend on gmock-generated-matchers.h. // This file implements some matchers that depend on gmock-matchers.h.
// //
// Note that tests are implemented in gmock-matchers_test.cc rather than // Note that tests are implemented in gmock-matchers_test.cc rather than
// gmock-more-matchers-test.cc. // gmock-more-matchers-test.cc.
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#include "gmock/gmock-generated-matchers.h" #include "gmock/gmock-matchers.h"
namespace testing { namespace testing {
...@@ -89,4 +89,4 @@ MATCHER(IsFalse, negation ? "is true" : "is false") { ...@@ -89,4 +89,4 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
} // namespace testing } // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
...@@ -60,20 +60,91 @@ ...@@ -60,20 +60,91 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#include <type_traits>
#include "gmock/gmock-spec-builders.h" #include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
namespace testing { namespace testing {
template <class MockClass>
class NiceMock;
template <class MockClass>
class NaggyMock;
template <class MockClass>
class StrictMock;
namespace internal {
template <typename T>
std::true_type StrictnessModifierProbe(const NiceMock<T>&);
template <typename T>
std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
template <typename T>
std::true_type StrictnessModifierProbe(const StrictMock<T>&);
std::false_type StrictnessModifierProbe(...);
template <typename T>
constexpr bool HasStrictnessModifier() {
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
}
// Base classes that register and deregister with testing::Mock to alter the
// default behavior around uninteresting calls. Inheriting from one of these
// classes first and then MockClass ensures the MockClass constructor is run
// after registration, and that the MockClass destructor runs before
// deregistration. This guarantees that MockClass's constructor and destructor
// run with the same level of strictness as its instance methods.
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW && \
(defined(_MSC_VER) || defined(__clang__))
// We need to mark these classes with this declspec to ensure that
// the empty base class optimization is performed.
#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)
#else
#define GTEST_INTERNAL_EMPTY_BASE_CLASS
#endif
template <typename Base>
class NiceMockImpl {
public:
NiceMockImpl() { ::testing::Mock::AllowUninterestingCalls(this); }
~NiceMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
template <typename Base>
class NaggyMockImpl {
public:
NaggyMockImpl() { ::testing::Mock::WarnUninterestingCalls(this); }
~NaggyMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
template <typename Base>
class StrictMockImpl {
public:
StrictMockImpl() { ::testing::Mock::FailUninterestingCalls(this); }
~StrictMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
} // namespace internal
template <class MockClass> template <class MockClass>
class NiceMock : public MockClass { class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
: private internal::NiceMockImpl<MockClass>,
public MockClass {
public: public:
static_assert(!internal::HasStrictnessModifier<MockClass>(),
"Can't apply NiceMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
NiceMock() : MockClass() { NiceMock() : MockClass() {
::testing::Mock::AllowUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
} }
// Ideally, we would inherit base class's constructors through a using // Ideally, we would inherit base class's constructors through a using
...@@ -85,21 +156,16 @@ class NiceMock : public MockClass { ...@@ -85,21 +156,16 @@ class NiceMock : public MockClass {
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) { explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::AllowUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
} }
template <typename A1, typename A2, typename... An> template <typename TArg1, typename TArg2, typename... An>
NiceMock(A1&& arg1, A2&& arg2, An&&... args) NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
std::forward<An>(args)...) { std::forward<An>(args)...) {
::testing::Mock::AllowUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
}
~NiceMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
} }
private: private:
...@@ -107,11 +173,19 @@ class NiceMock : public MockClass { ...@@ -107,11 +173,19 @@ class NiceMock : public MockClass {
}; };
template <class MockClass> template <class MockClass>
class NaggyMock : public MockClass { class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
: private internal::NaggyMockImpl<MockClass>,
public MockClass {
static_assert(!internal::HasStrictnessModifier<MockClass>(),
"Can't apply NaggyMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
public: public:
NaggyMock() : MockClass() { NaggyMock() : MockClass() {
::testing::Mock::WarnUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
} }
// Ideally, we would inherit base class's constructors through a using // Ideally, we would inherit base class's constructors through a using
...@@ -123,21 +197,16 @@ class NaggyMock : public MockClass { ...@@ -123,21 +197,16 @@ class NaggyMock : public MockClass {
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) { explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::WarnUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
} }
template <typename A1, typename A2, typename... An> template <typename TArg1, typename TArg2, typename... An>
NaggyMock(A1&& arg1, A2&& arg2, An&&... args) NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
std::forward<An>(args)...) { std::forward<An>(args)...) {
::testing::Mock::WarnUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
}
~NaggyMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
} }
private: private:
...@@ -145,11 +214,19 @@ class NaggyMock : public MockClass { ...@@ -145,11 +214,19 @@ class NaggyMock : public MockClass {
}; };
template <class MockClass> template <class MockClass>
class StrictMock : public MockClass { class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
: private internal::StrictMockImpl<MockClass>,
public MockClass {
public: public:
static_assert(
!internal::HasStrictnessModifier<MockClass>(),
"Can't apply StrictMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
StrictMock() : MockClass() { StrictMock() : MockClass() {
::testing::Mock::FailUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
} }
// Ideally, we would inherit base class's constructors through a using // Ideally, we would inherit base class's constructors through a using
...@@ -161,55 +238,24 @@ class StrictMock : public MockClass { ...@@ -161,55 +238,24 @@ class StrictMock : public MockClass {
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) { explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::FailUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
} }
template <typename A1, typename A2, typename... An> template <typename TArg1, typename TArg2, typename... An>
StrictMock(A1&& arg1, A2&& arg2, An&&... args) StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
std::forward<An>(args)...) { std::forward<An>(args)...) {
::testing::Mock::FailUninterestingCalls( static_assert(sizeof(*this) == sizeof(MockClass),
internal::ImplicitCast_<MockClass*>(this)); "The impl subclass shouldn't introduce any padding");
}
~StrictMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
} }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
}; };
// The following specializations catch some (relatively more common) #undef GTEST_INTERNAL_EMPTY_BASE_CLASS
// user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors.
// These specializations are declared but not defined, as NiceMock,
// NaggyMock, and StrictMock cannot be nested.
template <typename MockClass>
class NiceMock<NiceMock<MockClass> >;
template <typename MockClass>
class NiceMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NiceMock<StrictMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NiceMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NaggyMock<StrictMock<MockClass> >;
template <typename MockClass>
class StrictMock<NiceMock<MockClass> >;
template <typename MockClass>
class StrictMock<NaggyMock<MockClass> >;
template <typename MockClass>
class StrictMock<StrictMock<MockClass> >;
} // namespace testing } // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
...@@ -58,8 +58,8 @@ ...@@ -58,8 +58,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#include <functional> #include <functional>
#include <map> #include <map>
...@@ -108,6 +108,14 @@ template <typename F> class TypedExpectation; ...@@ -108,6 +108,14 @@ template <typename F> class TypedExpectation;
// Helper class for testing the Expectation class template. // Helper class for testing the Expectation class template.
class ExpectationTester; class ExpectationTester;
// Helper classes for implementing NiceMock, StrictMock, and NaggyMock.
template <typename MockClass>
class NiceMockImpl;
template <typename MockClass>
class StrictMockImpl;
template <typename MockClass>
class NaggyMockImpl;
// Protects the mock object registry (in class Mock), all function // Protects the mock object registry (in class Mock), all function
// mockers, and all expectations. // mockers, and all expectations.
// //
...@@ -413,14 +421,12 @@ class GTEST_API_ Mock { ...@@ -413,14 +421,12 @@ class GTEST_API_ Mock {
template <typename F> template <typename F>
friend class internal::FunctionMocker; friend class internal::FunctionMocker;
template <typename M> template <typename MockClass>
friend class NiceMock; friend class internal::NiceMockImpl;
template <typename MockClass>
template <typename M> friend class internal::NaggyMockImpl;
friend class NaggyMock; template <typename MockClass>
friend class internal::StrictMockImpl;
template <typename M>
friend class StrictMock;
// Tells Google Mock to allow uninteresting calls on the given mock // Tells Google Mock to allow uninteresting calls on the given mock
// object. // object.
...@@ -499,7 +505,10 @@ class GTEST_API_ Expectation { ...@@ -499,7 +505,10 @@ class GTEST_API_ Expectation {
public: public:
// Constructs a null object that doesn't reference any expectation. // Constructs a null object that doesn't reference any expectation.
Expectation(); Expectation();
Expectation(Expectation&&) = default;
Expectation(const Expectation&) = default;
Expectation& operator=(Expectation&&) = default;
Expectation& operator=(const Expectation&) = default;
~Expectation(); ~Expectation();
// This single-argument ctor must not be explicit, in order to support the // This single-argument ctor must not be explicit, in order to support the
...@@ -879,8 +888,6 @@ class GTEST_API_ ExpectationBase { ...@@ -879,8 +888,6 @@ class GTEST_API_ ExpectationBase {
Clause last_clause_; Clause last_clause_;
mutable bool action_count_checked_; // Under mutex_. mutable bool action_count_checked_; // Under mutex_.
mutable Mutex mutex_; // Protects action_count_checked_. mutable Mutex mutex_; // Protects action_count_checked_.
GTEST_DISALLOW_ASSIGN_(ExpectationBase);
}; // class ExpectationBase }; // class ExpectationBase
// Impements an expectation for the given function type. // Impements an expectation for the given function type.
...@@ -1295,8 +1302,6 @@ class MockSpec { ...@@ -1295,8 +1302,6 @@ class MockSpec {
internal::FunctionMocker<F>* const function_mocker_; internal::FunctionMocker<F>* const function_mocker_;
// The argument matchers specified in the spec. // The argument matchers specified in the spec.
ArgumentMatcherTuple matchers_; ArgumentMatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(MockSpec);
}; // class MockSpec }; // class MockSpec
// Wrapper type for generically holding an ordinary value or lvalue reference. // Wrapper type for generically holding an ordinary value or lvalue reference.
...@@ -1350,12 +1355,6 @@ class ReferenceOrValueWrapper<T&> { ...@@ -1350,12 +1355,6 @@ class ReferenceOrValueWrapper<T&> {
T* value_ptr_; T* value_ptr_;
}; };
// MSVC warns about using 'this' in base member initializer list, so
// we need to temporarily disable the warning. We have to do it for
// the entire class to suppress the warning, even though it's about
// the constructor only.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355)
// C++ treats the void type specially. For example, you cannot define // C++ treats the void type specially. For example, you cannot define
// a void-typed variable or pass a void value to a function. // a void-typed variable or pass a void value to a function.
// ActionResultHolder<T> holds a value of type T, where T must be a // ActionResultHolder<T> holds a value of type T, where T must be a
...@@ -1786,18 +1785,87 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { ...@@ -1786,18 +1785,87 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
} }
}; // class FunctionMocker }; // class FunctionMocker
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
// Reports an uninteresting call (whose description is in msg) in the // Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'. // manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const std::string& msg); void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
} // namespace internal } // namespace internal
// A MockFunction<F> class has one mock method whose type is F. It is namespace internal {
// useful when you just want your test code to emit some messages and
// have Google Mock verify the right messages are sent (and perhaps at template <typename F>
// the right times). For example, if you are exercising code: class MockFunction;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public:
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
protected:
MockFunction() = default;
~MockFunction() = default;
private:
FunctionMocker<R(Args...)> mock_;
};
/*
The SignatureOf<F> struct is a meta-function returning function signature
corresponding to the provided F argument.
It makes use of MockFunction easier by allowing it to accept more F arguments
than just function signatures.
Specializations provided here cover a signature type itself and any template
that can be parameterized with a signature, including std::function and
boost::function.
*/
template <typename F, typename = void>
struct SignatureOf;
template <typename R, typename... Args>
struct SignatureOf<R(Args...)> {
using type = R(Args...);
};
template <template <typename> class C, typename F>
struct SignatureOf<C<F>,
typename std::enable_if<std::is_function<F>::value>::type>
: SignatureOf<F> {};
template <typename F>
using SignatureOfT = typename SignatureOf<F>::type;
} // namespace internal
// A MockFunction<F> type has one mock method whose type is
// internal::SignatureOfT<F>. It is useful when you just want your
// test code to emit some messages and have Google Mock verify the
// right messages are sent (and perhaps at the right times). For
// example, if you are exercising code:
// //
// Foo(1); // Foo(1);
// Foo(2); // Foo(2);
...@@ -1831,49 +1899,34 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg); ...@@ -1831,49 +1899,34 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
// Bar("a") is called by which call to Foo(). // Bar("a") is called by which call to Foo().
// //
// MockFunction<F> can also be used to exercise code that accepts // MockFunction<F> can also be used to exercise code that accepts
// std::function<F> callbacks. To do so, use AsStdFunction() method // std::function<internal::SignatureOfT<F>> callbacks. To do so, use
// to create std::function proxy forwarding to original object's Call. // AsStdFunction() method to create std::function proxy forwarding to
// Example: // original object's Call. Example:
// //
// TEST(FooTest, RunsCallbackWithBarArgument) { // TEST(FooTest, RunsCallbackWithBarArgument) {
// MockFunction<int(string)> callback; // MockFunction<int(string)> callback;
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); // EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
// Foo(callback.AsStdFunction()); // Foo(callback.AsStdFunction());
// } // }
//
// The internal::SignatureOfT<F> indirection allows to use other types
// than just function signature type. This is typically useful when
// providing a mock for a predefined std::function type. Example:
//
// using FilterPredicate = std::function<bool(string)>;
// void MyFilterAlgorithm(FilterPredicate predicate);
//
// TEST(FooTest, FilterPredicateAlwaysAccepts) {
// MockFunction<FilterPredicate> predicateMock;
// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true));
// MyFilterAlgorithm(predicateMock.AsStdFunction());
// }
template <typename F> template <typename F>
class MockFunction; class MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> {
using Base = internal::MockFunction<internal::SignatureOfT<F>>;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public: public:
MockFunction() {} using Base::Base;
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
private:
internal::FunctionMocker<R(Args...)> mock_;
}; };
// The style guide prohibits "using" statements in a namespace scope // The style guide prohibits "using" statements in a namespace scope
...@@ -1982,4 +2035,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 ...@@ -1982,4 +2035,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#define EXPECT_CALL(obj, call) \ #define EXPECT_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
// This file implements the following syntax: // This file implements the following syntax:
// //
...@@ -59,9 +59,6 @@ ...@@ -59,9 +59,6 @@
#include "gmock/gmock-actions.h" #include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h" #include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-function-mocker.h" #include "gmock/gmock-function-mocker.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h"
#include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-matchers.h" #include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h" #include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h" #include "gmock/gmock-more-matchers.h"
...@@ -98,4 +95,4 @@ GTEST_API_ void InitGoogleMock(); ...@@ -98,4 +95,4 @@ GTEST_API_ void InitGoogleMock();
} // namespace testing } // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
...@@ -31,6 +31,6 @@ ...@@ -31,6 +31,6 @@
// //
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#include <stdio.h> #include <stdio.h>
#include <ostream> // NOLINT #include <ostream> // NOLINT
...@@ -71,20 +71,6 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields); ...@@ -71,20 +71,6 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields);
// "foo_bar_123" are converted to "foo bar 123". // "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name); GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
// PointeeOf<Pointer>::type is the type of a value pointed to by a
// Pointer, which can be either a smart pointer or a raw pointer. The
// following default implementation is for the case where Pointer is a
// smart pointer.
template <typename Pointer>
struct PointeeOf {
// Smart pointer classes define type element_type as the type of
// their pointees.
typedef typename Pointer::element_type type;
};
// This specialization is for the raw pointer case.
template <typename T>
struct PointeeOf<T*> { typedef T type; }; // NOLINT
// GetRawPointer(p) returns the raw pointer underlying p when p is a // GetRawPointer(p) returns the raw pointer underlying p when p is a
// smart pointer, or returns p itself when p is already a raw pointer. // smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case. // The following default implementation is for the smart pointer case.
...@@ -136,15 +122,13 @@ GMOCK_DECLARE_KIND_(int, kInteger); ...@@ -136,15 +122,13 @@ GMOCK_DECLARE_KIND_(int, kInteger);
GMOCK_DECLARE_KIND_(unsigned int, kInteger); GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DECLARE_KIND_(wchar_t, kInteger); GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif #endif
// Non-standard integer types.
GMOCK_DECLARE_KIND_(Int64, kInteger);
GMOCK_DECLARE_KIND_(UInt64, kInteger);
// All standard floating-point types. // All standard floating-point types.
GMOCK_DECLARE_KIND_(float, kFloatingPoint); GMOCK_DECLARE_KIND_(float, kFloatingPoint);
GMOCK_DECLARE_KIND_(double, kFloatingPoint); GMOCK_DECLARE_KIND_(double, kFloatingPoint);
...@@ -157,9 +141,6 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint); ...@@ -157,9 +141,6 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
static_cast< ::testing::internal::TypeKind>( \ static_cast< ::testing::internal::TypeKind>( \
::testing::internal::KindOf<type>::value) ::testing::internal::KindOf<type>::value)
// Evaluates to true if and only if integer type T is signed.
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value // LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
// is true if and only if arithmetic type From can be losslessly converted to // is true if and only if arithmetic type From can be losslessly converted to
// arithmetic type To. // arithmetic type To.
...@@ -170,65 +151,30 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint); ...@@ -170,65 +151,30 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
// From, and kToKind is the kind of To; the value is // From, and kToKind is the kind of To; the value is
// implementation-defined when the above pre-condition is violated. // implementation-defined when the above pre-condition is violated.
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To> template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
struct LosslessArithmeticConvertibleImpl : public std::false_type {}; using LosslessArithmeticConvertibleImpl = std::integral_constant<
bool,
// Converting bool to bool is lossless. // clang-format off
template <> // Converting from bool is always lossless
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool> (kFromKind == kBool) ? true
: public std::true_type {}; // Converting between any other type kinds will be lossy if the type
// kinds are not the same.
// Converting bool to any integer type is lossless. : (kFromKind != kToKind) ? false
template <typename To> : (kFromKind == kInteger &&
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To> // Converting between integers of different widths is allowed so long
: public std::true_type {}; // as the conversion does not go from signed to unsigned.
(((sizeof(From) < sizeof(To)) &&
// Converting bool to any floating-point type is lossless. !(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
template <typename To> // Converting between integers of the same width only requires the
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To> // two types to have the same signedness.
: public std::true_type {}; ((sizeof(From) == sizeof(To)) &&
(std::is_signed<From>::value == std::is_signed<To>::value)))
// Converting an integer to bool is lossy. ) ? true
template <typename From> // Floating point conversions are lossless if and only if `To` is at least
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool> // as wide as `From`.
: public std::false_type {}; : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
: false
// Converting an integer to another non-bool integer is lossless // clang-format on
// if and only if the target type's range encloses the source type's range. >;
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
: public bool_constant<
// When converting from a smaller size to a larger size, we are
// fine as long as we are not converting from signed to unsigned.
((sizeof(From) < sizeof(To)) &&
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
// When converting between the same size, the signedness must match.
((sizeof(From) == sizeof(To)) &&
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
#undef GMOCK_IS_SIGNED_
// Converting an integer to a floating-point type may be lossy, since
// the format of a floating-point number is implementation-defined.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
: public std::false_type {};
// Converting a floating-point to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
: public std::false_type {};
// Converting a floating-point to an integer is lossy.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
: public std::false_type {};
// Converting a floating-point to another floating-point is lossless
// if and only if the target type is at least as big as the source type.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<
kFloatingPoint, From, kFloatingPoint, To>
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
// LosslessArithmeticConvertible<From, To>::value is true if and only if // LosslessArithmeticConvertible<From, To>::value is true if and only if
// arithmetic type From can be losslessly converted to arithmetic type To. // arithmetic type From can be losslessly converted to arithmetic type To.
...@@ -238,9 +184,9 @@ struct LosslessArithmeticConvertibleImpl< ...@@ -238,9 +184,9 @@ struct LosslessArithmeticConvertibleImpl<
// reference) built-in arithmetic types; the value is // reference) built-in arithmetic types; the value is
// implementation-defined when the above pre-condition is violated. // implementation-defined when the above pre-condition is violated.
template <typename From, typename To> template <typename From, typename To>
struct LosslessArithmeticConvertible using LosslessArithmeticConvertible =
: public LosslessArithmeticConvertibleImpl< LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT GMOCK_KIND_OF_(To), To>;
// This interface knows how to report a Google Mock failure (either // This interface knows how to report a Google Mock failure (either
// non-fatal or fatal). // non-fatal or fatal).
...@@ -334,8 +280,6 @@ class WithoutMatchers { ...@@ -334,8 +280,6 @@ class WithoutMatchers {
// Internal use only: access the singleton instance of WithoutMatchers. // Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers(); GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Type traits.
// Disable MSVC warnings for infinite recursion, since in this case the // Disable MSVC warnings for infinite recursion, since in this case the
// the recursion is unreachable. // the recursion is unreachable.
#ifdef _MSC_VER #ifdef _MSC_VER
...@@ -420,7 +364,8 @@ template <typename ElementPointer, typename Size> ...@@ -420,7 +364,8 @@ template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tuple<ElementPointer, Size> > { class StlContainerView< ::std::tuple<ElementPointer, Size> > {
public: public:
typedef typename std::remove_const< typedef typename std::remove_const<
typename internal::PointeeOf<ElementPointer>::type>::type RawElement; typename std::pointer_traits<ElementPointer>::element_type>::type
RawElement;
typedef internal::NativeArray<RawElement> type; typedef internal::NativeArray<RawElement> type;
typedef const type const_reference; typedef const type const_reference;
...@@ -464,11 +409,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype( ...@@ -464,11 +409,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
// Apply the function to a tuple of arguments. // Apply the function to a tuple of arguments.
template <typename F, typename Tuple> template <typename F, typename Tuple>
auto Apply(F&& f, Tuple&& args) auto Apply(F&& f, Tuple&& args) -> decltype(
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<Tuple>::value>())) { MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<Tuple>::value>()); MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>());
} }
// Template struct Function<F>, where F must be a function type, contains // Template struct Function<F>, where F must be a function type, contains
...@@ -492,8 +439,7 @@ struct Function<R(Args...)> { ...@@ -492,8 +439,7 @@ struct Function<R(Args...)> {
using Result = R; using Result = R;
static constexpr size_t ArgumentCount = sizeof...(Args); static constexpr size_t ArgumentCount = sizeof...(Args);
template <size_t I> template <size_t I>
using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type, using Arg = ElemFromList<I, Args...>;
Args...>;
using ArgumentTuple = std::tuple<Args...>; using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
using MakeResultVoid = void(Args...); using MakeResultVoid = void(Args...);
...@@ -510,4 +456,4 @@ constexpr size_t Function<R(Args...)>::ArgumentCount; ...@@ -510,4 +456,4 @@ constexpr size_t Function<R(Args...)>::ArgumentCount;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
...@@ -37,11 +37,12 @@ ...@@ -37,11 +37,12 @@
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <cstdint>
#include <iostream> #include <iostream>
// Most of the utilities needed for porting Google Mock are also // Most of the utilities needed for porting Google Mock are also
...@@ -69,8 +70,7 @@ ...@@ -69,8 +70,7 @@
// Macros for declaring flags. // Macros for declaring flags.
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) # define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
# define GMOCK_DECLARE_int32_(name) \ # define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
# define GMOCK_DECLARE_string_(name) \ # define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::std::string GMOCK_FLAG(name) extern GTEST_API_ ::std::string GMOCK_FLAG(name)
...@@ -78,10 +78,10 @@ ...@@ -78,10 +78,10 @@
# define GMOCK_DEFINE_bool_(name, default_val, doc) \ # define GMOCK_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val) GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
# define GMOCK_DEFINE_int32_(name, default_val, doc) \ # define GMOCK_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val)
# define GMOCK_DEFINE_string_(name, default_val, doc) \ # define GMOCK_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // !defined(GMOCK_DECLARE_bool_) #endif // !defined(GMOCK_DECLARE_bool_)
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#undef GMOCK_PP_INTERNAL_USE_MSVC
#if defined(__clang__)
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#elif defined(_MSC_VER)
// TODO(iserna): Also verify tradional versus comformant preprocessor.
static_assert(
_MSC_VER >= 1900,
"MSVC version not supported. There is support for MSVC 14.0 and above.");
#define GMOCK_PP_INTERNAL_USE_MSVC 1
#else
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#endif
// Expands and concatenates the arguments. Constructed macros reevaluate. // Expands and concatenates the arguments. Constructed macros reevaluate.
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2) #define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
...@@ -29,10 +16,6 @@ static_assert( ...@@ -29,10 +16,6 @@ static_assert(
// Returns the only argument. // Returns the only argument.
#define GMOCK_PP_IDENTITY(_1) _1 #define GMOCK_PP_IDENTITY(_1) _1
// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
// CAT-like directive to force correct evaluation. Each macro has its own.
#if GMOCK_PP_INTERNAL_USE_MSVC
// Evaluates to the number of arguments after expansion. // Evaluates to the number of arguments after expansion.
// //
// #define PAIR x, y // #define PAIR x, y
...@@ -43,45 +26,27 @@ static_assert( ...@@ -43,45 +26,27 @@ static_assert(
// GMOCK_PP_NARG(PAIR) => 2 // GMOCK_PP_NARG(PAIR) => 2
// //
// Requires: the number of arguments after expansion is at most 15. // Requires: the number of arguments after expansion is at most 15.
#define GMOCK_PP_NARG(...) \ #define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_NARG_CAT( \ GMOCK_PP_INTERNAL_16TH( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \ (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
8, 7, 6, 5, 4, 3, 2, 1), )
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise // Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// returns 0. Requires no more than 15 unprotected commas. // returns 0. Requires no more than 15 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...) \ #define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \ GMOCK_PP_INTERNAL_16TH( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
1, 1, 1, 1, 1, 0), )
// Returns the first argument. // Returns the first argument.
#define GMOCK_PP_HEAD(...) \ #define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
// Returns the tail. A variadic list of all arguments minus the first. Requires // Returns the tail. A variadic list of all arguments minus the first. Requires
// at least one argument. // at least one argument.
#define GMOCK_PP_TAIL(...) \ #define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__) // Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \ #define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \ GMOCK_PP_IDENTITY( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), ) GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
7, 6, 5, 4, 3, 2, 1)
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0)
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise // If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`. // evaluates to `0`.
...@@ -121,6 +86,14 @@ static_assert( ...@@ -121,6 +86,14 @@ static_assert(
#define GMOCK_PP_IF(_Cond, _Then, _Else) \ #define GMOCK_PP_IF(_Cond, _Then, _Else) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.
//
// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c
// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f
//
#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \
GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))
// Evaluates to the number of arguments after expansion. Identifies 'empty' as // Evaluates to the number of arguments after expansion. Identifies 'empty' as
// 0. // 0.
// //
...@@ -139,10 +112,9 @@ static_assert( ...@@ -139,10 +112,9 @@ static_assert(
// Expands to 1 if the first argument starts with something in parentheses, // Expands to 1 if the first argument starts with something in parentheses,
// otherwise to 0. // otherwise to 0.
#define GMOCK_PP_IS_BEGIN_PARENS(...) \ #define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \ GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \ GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
// Expands to 1 is there is only one argument and it is enclosed in parentheses. // Expands to 1 is there is only one argument and it is enclosed in parentheses.
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \ #define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
...@@ -179,10 +151,6 @@ static_assert( ...@@ -179,10 +151,6 @@ static_assert(
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , ) #define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2 #define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__ #define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5 #define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \ #define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \ GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
...@@ -190,30 +158,24 @@ static_assert( ...@@ -190,30 +158,24 @@ static_assert(
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 , #define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then #define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else #define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#if GMOCK_PP_INTERNAL_USE_MSVC // Because of MSVC treating a token with a comma in it as a single token when
#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) // passed to another macro, we need to force it to evaluate it as multiple
#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) // tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \ // define one per possible macro that relies on this behavior. Note "_Args" must
GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) // be parenthesized.
#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) #define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \ _10, _11, _12, _13, _14, _15, _16, \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) ...) \
#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2 _16
#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2 #define GMOCK_PP_INTERNAL_16TH(_Args) \
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2 GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2 #define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2 #define GMOCK_PP_INTERNAL_HEAD(_Args) \
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \ GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), ) #define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \ #define GMOCK_PP_INTERNAL_TAIL(_Args) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _ #define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1, #define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
...@@ -314,4 +276,4 @@ static_assert( ...@@ -314,4 +276,4 @@ static_assert(
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple)) (GMOCK_PP_TAIL _Tuple))
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
# Please Note:
Files in this directory are no longer supported by the maintainers. They
represent mostly historical artifacts and supported by the community only. There
is no guarantee whatsoever that these scripts still work.
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
# 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.
"""fuse_gmock_files.py v0.1.0.
"""fuse_gmock_files.py v0.1.0
Fuses Google Mock and Google Test source code into two .h files and a .cc file. Fuses Google Mock and Google Test source code into two .h files and a .cc file.
SYNOPSIS SYNOPSIS
...@@ -55,27 +55,29 @@ EXAMPLES ...@@ -55,27 +55,29 @@ EXAMPLES
This tool is experimental. In particular, it assumes that there is no This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Mock or Google Test headers. Please conditional inclusion of Google Mock or Google Test headers. Please
report any problems to googlemock@googlegroups.com. You can read report any problems to googlemock@googlegroups.com. You can read
https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md for more https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
for more
information. information.
""" """
__author__ = 'wan@google.com (Zhanyong Wan)' from __future__ import print_function
import os import os
import re import re
import sets
import sys import sys
__author__ = 'wan@google.com (Zhanyong Wan)'
# We assume that this file is in the scripts/ directory in the Google # We assume that this file is in the scripts/ directory in the Google
# Mock root directory. # Mock root directory.
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
# We need to call into googletest/scripts/fuse_gtest_files.py. # We need to call into googletest/scripts/fuse_gtest_files.py.
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts')) sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts'))
import fuse_gtest_files import fuse_gtest_files as gtest # pylint:disable=g-import-not-at-top
gtest = fuse_gtest_files
# Regex for matching '#include "gmock/..."'. # Regex for matching
# '#include "gmock/..."'.
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"') INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
# Where to find the source seed files. # Where to find the source seed files.
...@@ -98,6 +100,9 @@ def ValidateGMockRootDir(gmock_root): ...@@ -98,6 +100,9 @@ def ValidateGMockRootDir(gmock_root):
"""Makes sure gmock_root points to a valid gmock root directory. """Makes sure gmock_root points to a valid gmock root directory.
The function aborts the program on failure. The function aborts the program on failure.
Args:
gmock_root: A string with the mock root directory.
""" """
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root)) gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
...@@ -109,6 +114,9 @@ def ValidateOutputDir(output_dir): ...@@ -109,6 +114,9 @@ def ValidateOutputDir(output_dir):
"""Makes sure output_dir points to a valid output directory. """Makes sure output_dir points to a valid output directory.
The function aborts the program on failure. The function aborts the program on failure.
Args:
output_dir: A string representing the output directory.
""" """
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT) gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
...@@ -119,8 +127,8 @@ def ValidateOutputDir(output_dir): ...@@ -119,8 +127,8 @@ def ValidateOutputDir(output_dir):
def FuseGMockH(gmock_root, output_dir): def FuseGMockH(gmock_root, output_dir):
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir.""" """Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w') output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
processed_files = sets.Set() # Holds all gmock headers we've processed. processed_files = set() # Holds all gmock headers we've processed.
def ProcessFile(gmock_header_path): def ProcessFile(gmock_header_path):
"""Processes the given gmock header file.""" """Processes the given gmock header file."""
...@@ -132,25 +140,28 @@ def FuseGMockH(gmock_root, output_dir): ...@@ -132,25 +140,28 @@ def FuseGMockH(gmock_root, output_dir):
processed_files.add(gmock_header_path) processed_files.add(gmock_header_path)
# Reads each line in the given gmock header. # Reads each line in the given gmock header.
for line in file(os.path.join(gmock_root, gmock_header_path), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line) with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh:
if m: for line in fh:
# It's '#include "gmock/..."' - let's process it recursively. m = INCLUDE_GMOCK_FILE_REGEX.match(line)
ProcessFile('include/' + m.group(1))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m: if m:
# It's '#include "gtest/foo.h"'. We translate it to # '#include "gmock/..."'
# "gtest/gtest.h", regardless of what foo is, since all # - let's process it recursively.
# gtest headers are fused into gtest/gtest.h. ProcessFile('include/' + m.group(1))
# There is no need to #include gtest.h twice.
if not gtest.GTEST_H_SEED in processed_files:
processed_files.add(gtest.GTEST_H_SEED)
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
else: else:
# Otherwise we copy the line unchanged to the output file. m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
output_file.write(line) if m:
# '#include "gtest/foo.h"'
# We translate it to "gtest/gtest.h", regardless of what foo is,
# since all gtest headers are fused into gtest/gtest.h.
# There is no need to #include gtest.h twice.
if gtest.GTEST_H_SEED not in processed_files:
processed_files.add(gtest.GTEST_H_SEED)
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
ProcessFile(GMOCK_H_SEED) ProcessFile(GMOCK_H_SEED)
output_file.close() output_file.close()
...@@ -159,7 +170,7 @@ def FuseGMockH(gmock_root, output_dir): ...@@ -159,7 +170,7 @@ def FuseGMockH(gmock_root, output_dir):
def FuseGMockAllCcToFile(gmock_root, output_file): def FuseGMockAllCcToFile(gmock_root, output_file):
"""Scans folder gmock_root to fuse gmock-all.cc into output_file.""" """Scans folder gmock_root to fuse gmock-all.cc into output_file."""
processed_files = sets.Set() processed_files = set()
def ProcessFile(gmock_source_file): def ProcessFile(gmock_source_file):
"""Processes the given gmock source file.""" """Processes the given gmock source file."""
...@@ -171,32 +182,37 @@ def FuseGMockAllCcToFile(gmock_root, output_file): ...@@ -171,32 +182,37 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
processed_files.add(gmock_source_file) processed_files.add(gmock_source_file)
# Reads each line in the given gmock source file. # Reads each line in the given gmock source file.
for line in file(os.path.join(gmock_root, gmock_source_file), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line) with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh:
if m: for line in fh:
# It's '#include "gmock/foo.h"'. We treat it as '#include m = INCLUDE_GMOCK_FILE_REGEX.match(line)
# "gmock/gmock.h"', as all other gmock headers are being fused
# into gmock.h and cannot be #included directly.
# There is no need to #include "gmock/gmock.h" more than once.
if not GMOCK_H_SEED in processed_files:
processed_files.add(GMOCK_H_SEED)
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m: if m:
# It's '#include "gtest/..."'. # '#include "gmock/foo.h"'
# There is no need to #include gtest.h as it has been # We treat it as '#include "gmock/gmock.h"', as all other gmock
# #included by gtest-all.cc. # headers are being fused into gmock.h and cannot be
pass # included directly. No need to
# #include "gmock/gmock.h"
# more than once.
if GMOCK_H_SEED not in processed_files:
processed_files.add(GMOCK_H_SEED)
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
else: else:
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line) m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m: if m:
# It's '#include "src/foo"' - let's process it recursively. # '#include "gtest/..."'
ProcessFile(m.group(1)) # There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.
pass
else: else:
# Otherwise we copy the line unchanged to the output file. m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
output_file.write(line) if m:
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
ProcessFile(GMOCK_ALL_CC_SEED) ProcessFile(GMOCK_ALL_CC_SEED)
...@@ -204,12 +220,12 @@ def FuseGMockAllCcToFile(gmock_root, output_file): ...@@ -204,12 +220,12 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
def FuseGMockGTestAllCc(gmock_root, output_dir): def FuseGMockGTestAllCc(gmock_root, output_dir):
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir.""" """Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""
output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w') with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT),
# First, fuse gtest-all.cc into gmock-gtest-all.cc. 'w') as output_file:
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file) # First, fuse gtest-all.cc into gmock-gtest-all.cc.
# Next, append fused gmock-all.cc to gmock-gtest-all.cc. gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
FuseGMockAllCcToFile(gmock_root, output_file) # Next, append fused gmock-all.cc to gmock-gtest-all.cc.
output_file.close() FuseGMockAllCcToFile(gmock_root, output_file)
def FuseGMock(gmock_root, output_dir): def FuseGMock(gmock_root, output_dir):
...@@ -232,7 +248,7 @@ def main(): ...@@ -232,7 +248,7 @@ def main():
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR # fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
FuseGMock(sys.argv[1], sys.argv[2]) FuseGMock(sys.argv[1], sys.argv[2])
else: else:
print __doc__ print(__doc__)
sys.exit(1) sys.exit(1)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment