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 @@
// 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
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#ifndef _WIN32_WCE
# include <errno.h>
......@@ -45,11 +138,13 @@
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gmock/internal/gmock-pp.h"
#ifdef _MSC_VER
# pragma warning(push)
......@@ -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_(unsigned long, 0UL); // 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_(Int64, 0);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT
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_(double, 0);
#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
// When an unexpected function call is encountered, Google Mock will
......@@ -350,6 +449,9 @@ class Action {
}
};
template <typename G>
using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>;
public:
typedef typename internal::Function<F>::Result Result;
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
......@@ -361,10 +463,14 @@ class Action {
// Construct an Action from a specified callable.
// This cannot take std::function directly, because then Action would not be
// directly constructible from lambda (it would require two conversions).
template <typename G,
typename = typename ::std::enable_if<
::std::is_constructible<::std::function<F>, G>::value>::type>
Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT
template <
typename G,
typename = typename std::enable_if<internal::disjunction<
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.
explicit Action(ActionInterface<F>* impl)
......@@ -396,6 +502,26 @@ class Action {
template <typename G>
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.
::std::function<F> fun_;
};
......@@ -446,13 +572,9 @@ class PolymorphicAction {
private:
Impl impl_;
GTEST_DISALLOW_ASSIGN_(MonomorphicImpl);
};
Impl impl_;
GTEST_DISALLOW_ASSIGN_(PolymorphicAction);
};
// Creates an Action from its implementation and returns it. The
......@@ -593,13 +715,9 @@ class ReturnAction {
private:
bool performed_;
const std::shared_ptr<R> wrapper_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
const std::shared_ptr<R> value_;
GTEST_DISALLOW_ASSIGN_(ReturnAction);
};
// Implements the ReturnNull() action.
......@@ -660,13 +778,9 @@ class ReturnRefAction {
private:
T& ref_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
T& ref_;
GTEST_DISALLOW_ASSIGN_(ReturnRefAction);
};
// Implements the polymorphic ReturnRefOfCopy(x) action, which can be
......@@ -707,13 +821,39 @@ class ReturnRefOfCopyAction {
private:
T value_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
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.
......@@ -740,8 +880,6 @@ class AssignAction {
private:
T1* const ptr_;
const T2 value_;
GTEST_DISALLOW_ASSIGN_(AssignAction);
};
#if !GTEST_OS_WINDOWS_MOBILE
......@@ -763,8 +901,6 @@ class SetErrnoAndReturnAction {
private:
const int errno_;
const T result_;
GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction);
};
#endif // !GTEST_OS_WINDOWS_MOBILE
......@@ -816,7 +952,8 @@ struct InvokeMethodWithoutArgsAction {
Class* const obj_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>
ReturnType operator()(const Args&...) const {
......@@ -869,13 +1006,9 @@ class IgnoreResultAction {
OriginalFunction;
const Action<OriginalFunction> action_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
const A action_;
GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
};
template <typename InnerAction, size_t... I>
......@@ -886,7 +1019,8 @@ struct WithArgsAction {
// We use the conversion operator to detect the signature of the inner Action.
template <typename R, typename... Args>
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);
return [converted](Args... args) -> R {
......@@ -899,9 +1033,13 @@ struct WithArgsAction {
template <typename... Actions>
struct DoAllAction {
private:
template <typename... Args, size_t... I>
std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
return {std::get<I>(actions)...};
template <typename T>
using NonFinalType =
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:
......@@ -910,21 +1048,121 @@ struct DoAllAction {
template <typename R, typename... Args>
operator Action<R(Args...)>() const { // NOLINT
struct Op {
std::vector<Action<void(Args...)>> converted;
std::vector<Action<void(NonFinalType<Args>...)>> converted;
Action<R(Args...)> last;
R operator()(Args... args) const {
auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
for (auto& a : converted) {
a.Perform(tuple_args);
}
return last.Perform(tuple_args);
return 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)};
}
};
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
// An Unused object can be implicitly constructed from ANY value.
......@@ -960,7 +1198,8 @@ struct DoAllAction {
typedef internal::IgnoredValue Unused;
// 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>
internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
Action&&... action) {
......@@ -1022,6 +1261,10 @@ inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
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
// argument. The copy is created when the action is constructed and
// lives as long as the action.
......@@ -1039,6 +1282,23 @@ internal::ByMoveWrapper<R> ByMove(R 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.
inline internal::DoDefaultAction DoDefault() {
return internal::DoDefaultAction();
......@@ -1047,14 +1307,14 @@ inline internal::DoDefaultAction DoDefault() {
// Creates an action that sets the variable pointed by the N-th
// (0-based) function argument to 'value'.
template <size_t N, typename T>
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T x) {
return {std::move(x)};
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) {
return {std::move(value)};
}
// The following version is DEPRECATED.
template <size_t N, typename T>
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T x) {
return {std::move(x)};
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) {
return {std::move(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
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
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
......@@ -36,8 +36,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#include <limits.h>
#include <memory>
......@@ -154,4 +154,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
......@@ -33,12 +33,47 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#ifndef 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"
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(...) \
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
......@@ -60,7 +95,8 @@
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_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)))
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
......@@ -94,21 +130,20 @@
::testing::tuple_size<typename ::testing::internal::Function< \
__VA_ARGS__>::ArgumentTuple>::value == _N, \
"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) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
_Override, _Final, _Noexcept, \
_CallType, _Signature) \
_Override, _Final, _NoexceptSpec, \
_CallType, _RefSpec, _Signature) \
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
_Signature)>::Result \
GMOCK_INTERNAL_EXPAND(_CallType) \
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \
GMOCK_PP_IF(_Override, override, ) \
GMOCK_PP_IF(_Final, final, ) { \
GMOCK_PP_IF(_Constness, const, ) _RefSpec _NoexceptSpec \
GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.SetOwnerAndName(this, #_MethodName); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
......@@ -116,7 +151,7 @@
} \
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
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); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
......@@ -124,11 +159,10 @@
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
const ::testing::internal::WithoutMatchers&, \
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
GMOCK_PP_REMOVE_PARENS(_Signature)>*) \
const GMOCK_PP_IF(_Noexcept, noexcept, ) { \
return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \
GMOCK_PP_IF(_Constness, const, ))(this) \
->gmock_##_MethodName(GMOCK_PP_REPEAT( \
GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \
return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF( \
_Constness, const, ) int _RefSpec>::Adjust(*this) \
.gmock_##_MethodName(GMOCK_PP_REPEAT( \
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
} \
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
......@@ -147,9 +181,20 @@
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \
GMOCK_PP_HAS_COMMA( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_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) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
......@@ -160,6 +205,7 @@
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_NOEXCEPT(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
GMOCK_PP_STRINGIZE( \
_elem) " cannot be recognized as a valid specification modifier.");
......@@ -180,12 +226,18 @@
#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) \
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
#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) \
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
......@@ -203,14 +255,28 @@
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _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_SIGNATURE(_Ret, _Args) \
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))
// Note: The use of `identity_t` here allows _Ret to represent return types that
// would normally need to be specified in a different way. For example, a method
// returning a function pointer must be written as
//
// 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) \
GMOCK_PP_COMMA_IF(_i) \
......@@ -218,36 +284,196 @@
GMOCK_PP_IDENTITY) \
(_elem)
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature)) \
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
gmock_a##_i
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature))>( \
gmock_a##_i)
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::std::forward<GMOCK_INTERNAL_ARG_O( \
_i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i)
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature)) \
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
gmock_a##_i
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
GMOCK_PP_COMMA_IF(_i) \
gmock_a##_i
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature))>()
#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>()
#define GMOCK_INTERNAL_ARG_O(_i, ...) \
typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type
#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \
const ::testing::Matcher<typename ::testing::internal::Function< \
__VA_ARGS__>::template Arg<_i>::type>&
#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 @@
// 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
// MatcherInterface<T> interface if necessary.
//
......@@ -39,11 +252,11 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#include <math.h>
#include <algorithm>
#include <cmath>
#include <initializer_list>
#include <iterator>
#include <limits>
......@@ -54,8 +267,10 @@
#include <type_traits>
#include <utility>
#include <vector>
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gmock/internal/gmock-pp.h"
#include "gtest/gtest.h"
// MSVC warning C5046 is new as of VS2017 version 15.8.
......@@ -128,7 +343,7 @@ class MatcherCastImpl {
// constructor from M (this usually happens when T has an implicit
// 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
// a user-defined conversion from M to T if one exists (assuming M is
// a value).
......@@ -141,7 +356,7 @@ class MatcherCastImpl {
template <bool Ignore>
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
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 a polymorphic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a
......@@ -209,7 +424,14 @@ class MatcherCastImpl<T, Matcher<U> > {
!std::is_base_of<FromType, ToType>::value,
"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 {
......@@ -222,8 +444,6 @@ class MatcherCastImpl<T, Matcher<U> > {
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
......@@ -235,6 +455,50 @@ class MatcherCastImpl<T, Matcher<T> > {
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
// In order to be safe and clear, casting between different matcher
......@@ -246,56 +510,43 @@ inline Matcher<T> MatcherCast(const M& matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// Implements SafeMatcherCast().
//
// 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);
}
};
// This overload handles polymorphic matchers and values only since
// monomorphic matchers are handled by the next one.
template <typename T, typename M>
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) {
return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher);
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {
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.
......@@ -484,31 +735,25 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter 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
// type. This is a polymorphic matcher, so we need a template type
// conversion operator to make it appearing as a Matcher<T> for any
// type T.
class AnythingMatcher {
public:
using is_gtest_matcher = void;
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
......@@ -608,13 +853,9 @@ class RefMatcher<T&> {
private:
const Super& object_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
T& object_;
GTEST_DISALLOW_ASSIGN_(RefMatcher);
};
// Polymorphic helper functions for narrow and wide string matchers.
......@@ -656,19 +897,20 @@ bool CaseInsensitiveStringEquals(const StringType& s1,
template <typename StringType>
class StrEqualityMatcher {
public:
StrEqualityMatcher(const StringType& str, bool expect_eq,
bool case_sensitive)
: string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive)
: string_(std::move(str)),
expect_eq_(expect_eq),
case_sensitive_(case_sensitive) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
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.
const StringType& str = std::string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
......@@ -686,11 +928,11 @@ class StrEqualityMatcher {
// Matches anything that can convert to 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>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
const StringType& s2(s);
const StringType s2(s);
const bool eq = case_sensitive_ ? s2 == string_ :
CaseInsensitiveStringEquals(s2, string_);
return expect_eq_ == eq;
......@@ -717,8 +959,6 @@ class StrEqualityMatcher {
const StringType string_;
const bool expect_eq_;
const bool case_sensitive_;
GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
};
// Implements the polymorphic HasSubstr(substring) matcher, which
......@@ -730,15 +970,15 @@ class HasSubstrMatcher {
explicit HasSubstrMatcher(const StringType& substring)
: substring_(substring) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
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.
const StringType& str = std::string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
......@@ -753,12 +993,11 @@ class HasSubstrMatcher {
// Matches anything that can convert to 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>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
const StringType& s2(s);
return s2.find(substring_) != StringType::npos;
return StringType(s).find(substring_) != StringType::npos;
}
// Describes what this matcher matches.
......@@ -774,8 +1013,6 @@ class HasSubstrMatcher {
private:
const StringType substring_;
GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
};
// Implements the polymorphic StartsWith(substring) matcher, which
......@@ -787,15 +1024,15 @@ class StartsWithMatcher {
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
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.
const StringType& str = std::string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
......@@ -810,7 +1047,7 @@ class StartsWithMatcher {
// Matches anything that can convert to 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>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
......@@ -831,8 +1068,6 @@ class StartsWithMatcher {
private:
const StringType prefix_;
GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
};
// Implements the polymorphic EndsWith(substring) matcher, which
......@@ -843,15 +1078,15 @@ class EndsWithMatcher {
public:
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
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.
const StringType& str = std::string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
......@@ -866,7 +1101,7 @@ class EndsWithMatcher {
// Matches anything that can convert to 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>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
......@@ -887,8 +1122,6 @@ class EndsWithMatcher {
private:
const StringType suffix_;
GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
};
// Implements a matcher that compares the two fields of a 2-tuple
......@@ -982,8 +1215,6 @@ class NotMatcherImpl : public MatcherInterface<const T&> {
private:
const Matcher<T> matcher_;
GTEST_DISALLOW_ASSIGN_(NotMatcherImpl);
};
// Implements the Not(m) matcher, which matches a value that doesn't
......@@ -1002,8 +1233,6 @@ class NotMatcher {
private:
InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(NotMatcher);
};
// Implements the AllOf(m1, m2) matcher for a particular argument type
......@@ -1065,8 +1294,6 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
private:
const std::vector<Matcher<T> > matchers_;
GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
};
// VariadicMatcher is used for the variadic implementation of
......@@ -1081,6 +1308,9 @@ class VariadicMatcher {
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
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that
// all of the provided matchers (Matcher1, Matcher2, ...) can match.
......@@ -1105,8 +1335,6 @@ class VariadicMatcher {
std::integral_constant<size_t, sizeof...(Args)>) const {}
std::tuple<Args...> matchers_;
GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
};
template <typename... Args>
......@@ -1171,8 +1399,6 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
private:
const std::vector<Matcher<T> > matchers_;
GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
};
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
......@@ -1200,8 +1426,6 @@ class SomeOfArrayMatcher {
private:
const ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(SomeOfArrayMatcher);
};
template <typename T>
......@@ -1223,7 +1447,7 @@ class TrulyMatcher {
// interested in the address of the argument.
template <typename T>
bool MatchAndExplain(T& x, // NOLINT
MatchResultListener* /* listener */) const {
MatchResultListener* listener) const {
// Without the if-statement, MSVC sometimes warns about converting
// a value to bool (warning 4800).
//
......@@ -1232,6 +1456,7 @@ class TrulyMatcher {
// having no operator!().
if (predicate_(x))
return true;
*listener << "didn't satisfy the given predicate";
return false;
}
......@@ -1245,8 +1470,6 @@ class TrulyMatcher {
private:
Predicate predicate_;
GTEST_DISALLOW_ASSIGN_(TrulyMatcher);
};
// Used for implementing Matches(matcher), which turns a matcher into
......@@ -1283,8 +1506,6 @@ class MatcherAsPredicate {
private:
M matcher_;
GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate);
};
// For implementing ASSERT_THAT() and EXPECT_THAT(). The template
......@@ -1323,7 +1544,7 @@ class PredicateFormatterFromMatcher {
<< "Expected: ";
matcher.DescribeTo(&ss);
// Rerun the matcher to "PrintAndExain" the failure.
// Rerun the matcher to "PrintAndExplain" the failure.
StringMatchResultListener listener;
if (MatchPrintAndExplain(x, matcher, &listener)) {
ss << "\n The matcher failed on the initial attempt; but passed when "
......@@ -1335,8 +1556,6 @@ class PredicateFormatterFromMatcher {
private:
const M matcher_;
GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher);
};
// A helper function for converting a matcher to a predicate-formatter
......@@ -1349,6 +1568,22 @@ MakePredicateFormatterFromMatcher(M 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
// two float values using ULP-based approximation or, optionally, a
// user-specified epsilon. The template is meant to be instantiated with
......@@ -1409,7 +1644,7 @@ class FloatingEqMatcher {
}
const FloatType diff = value - expected_;
if (fabs(diff) <= max_abs_error_) {
if (::std::fabs(diff) <= max_abs_error_) {
return true;
}
......@@ -1472,16 +1707,11 @@ class FloatingEqMatcher {
const bool nan_eq_nan_;
// max_abs_error will be used for value comparison when >= 0.
const FloatType max_abs_error_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
// The following 3 type conversion operators allow FloatEq(expected) and
// NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a
// 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 {
return MakeMatcher(
new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));
......@@ -1502,8 +1732,6 @@ class FloatingEqMatcher {
const bool nan_eq_nan_;
// max_abs_error will be used for value comparison when >= 0.
const FloatType max_abs_error_;
GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
};
// A 2-tuple ("binary") wrapper around FloatingEqMatcher:
......@@ -1607,8 +1835,9 @@ class PointeeMatcher {
template <typename Pointer>
class Impl : public MatcherInterface<Pointer> {
public:
typedef typename PointeeOf<typename std::remove_const<
typename std::remove_reference<Pointer>::type>::type>::type Pointee;
using Pointee =
typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
Pointer)>::element_type;
explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<const Pointee&>(matcher)) {}
......@@ -1633,13 +1862,67 @@ class PointeeMatcher {
private:
const Matcher<const Pointee&> matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
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
......@@ -1676,8 +1959,6 @@ class WhenDynamicCastToMatcherBase {
static void GetCastTypeDescription(::std::ostream* os) {
*os << "when dynamic_cast to " << GetToName() << ", ";
}
GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
};
// Primary template.
......@@ -1775,8 +2056,6 @@ class FieldMatcher {
// Contains either "whose given field " if the name of the field is unknown
// or "whose field `name_of_field` " if the name is known.
const std::string whose_field_;
GTEST_DISALLOW_ASSIGN_(FieldMatcher);
};
// Implements the Property() matcher for matching a property
......@@ -1845,8 +2124,6 @@ class PropertyMatcher {
// Contains either "whose given property " if the name of the property is
// unknown or "whose property `name_of_property` " if the name is known.
const std::string whose_property_;
GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
};
// Type traits specifying various features of different functors for ResultOf.
......@@ -1936,14 +2213,10 @@ class ResultOfMatcher {
// how many times the callable will be invoked.
mutable CallableStorageType callable_;
const Matcher<ResultType> matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; // class Impl
const CallableStorageType callable_;
const InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(ResultOfMatcher);
};
// Implements a matcher that checks the size of an STL-style container.
......@@ -1988,12 +2261,10 @@ class SizeIsMatcher {
private:
const Matcher<SizeType> size_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
private:
const SizeMatcher size_matcher_;
GTEST_DISALLOW_ASSIGN_(SizeIsMatcher);
};
// Implements a matcher that checks the begin()..end() distance of an STL-style
......@@ -2045,12 +2316,10 @@ class BeginEndDistanceIsMatcher {
private:
const Matcher<DistanceType> distance_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
private:
const DistanceMatcher distance_matcher_;
GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher);
};
// Implements an equality matcher for any STL-style container whose elements
......@@ -2143,8 +2412,6 @@ class ContainerEqMatcher {
private:
const StlContainer expected_;
GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
};
// A comparator functor that uses the < operator to compare two values.
......@@ -2226,8 +2493,6 @@ class WhenSortedByMatcher {
private:
const Comparator comparator_;
const ContainerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher);
};
// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher
......@@ -2343,15 +2608,11 @@ class PointwiseMatcher {
private:
const Matcher<InnerMatcherArg> mono_tuple_matcher_;
const RhsStlContainer rhs_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
private:
const TupleMatcher tuple_matcher_;
const RhsStlContainer rhs_;
GTEST_DISALLOW_ASSIGN_(PointwiseMatcher);
};
// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
......@@ -2394,8 +2655,6 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> {
protected:
const Matcher<const Element&> inner_matcher_;
GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
};
// Implements Contains(element_matcher) for the given argument type Container.
......@@ -2422,9 +2681,6 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(false, container, listener);
}
private:
GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
};
// Implements Each(element_matcher) for the given argument type Container.
......@@ -2451,9 +2707,6 @@ class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(true, container, listener);
}
private:
GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
};
// Implements polymorphic Contains(element_matcher).
......@@ -2470,8 +2723,6 @@ class ContainsMatcher {
private:
const M inner_matcher_;
GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
};
// Implements polymorphic Each(element_matcher).
......@@ -2488,8 +2739,6 @@ class EachMatcher {
private:
const M inner_matcher_;
GTEST_DISALLOW_ASSIGN_(EachMatcher);
};
struct Rank1 {};
......@@ -2560,8 +2809,6 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
private:
const Matcher<const KeyType&> inner_matcher_;
GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl);
};
// Implements polymorphic Key(matcher_for_key).
......@@ -2578,8 +2825,49 @@ class KeyMatcher {
private:
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
......@@ -2665,8 +2953,6 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
const Matcher<const FirstType&> first_matcher_;
const Matcher<const SecondType&> second_matcher_;
GTEST_DISALLOW_ASSIGN_(PairMatcherImpl);
};
// Implements polymorphic Pair(first_matcher, second_matcher).
......@@ -2685,8 +2971,203 @@ class PairMatcher {
private:
const FirstMatcher first_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().
......@@ -2832,8 +3313,6 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
size_t count() const { return matchers_.size(); }
::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl);
};
// Connectivity matrix of (elements X matchers), in element-major order.
......@@ -2936,8 +3415,6 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
private:
UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
};
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
......@@ -2960,7 +3437,9 @@ class UnorderedElementsAreMatcherImpl
: UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++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
element_printouts->clear();
::std::vector<char> did_match;
size_t num_elements = 0;
DummyMatchResultListener dummy;
for (; elem_first != elem_last; ++num_elements, ++elem_first) {
if (listener->IsInterested()) {
element_printouts->push_back(PrintToString(*elem_first));
}
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
}
::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
};
// Functor for use in TransformTuple.
......@@ -3070,7 +3549,6 @@ class UnorderedElementsAreMatcher {
private:
const MatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher);
};
// Implements ElementsAre.
......@@ -3100,7 +3578,6 @@ class ElementsAreMatcher {
private:
const MatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
};
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
......@@ -3122,8 +3599,6 @@ class UnorderedElementsAreArrayMatcher {
private:
UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
};
// Implements ElementsAreArray().
......@@ -3145,8 +3620,6 @@ class ElementsAreArrayMatcher {
private:
const ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
};
// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second
......@@ -3164,6 +3637,8 @@ class BoundSecondMatcher {
BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)
: tuple2_matcher_(tm), second_value_(second) {}
BoundSecondMatcher(const BoundSecondMatcher& other) = default;
template <typename T>
operator Matcher<T>() const {
return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));
......@@ -3206,8 +3681,6 @@ class BoundSecondMatcher {
private:
const Matcher<const ArgTuple&> mono_tuple2_matcher_;
const Second second_value_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
const Tuple2Matcher tuple2_matcher_;
......@@ -3280,12 +3753,10 @@ class OptionalMatcher {
private:
const Matcher<ValueType> value_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
private:
const ValueMatcher value_matcher_;
GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
};
namespace variant_matcher {
......@@ -3593,12 +4064,14 @@ const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T.
template <typename T>
inline Matcher<T> A() {
return Matcher<T>(new internal::AnyMatcherImpl<T>());
return _;
}
// Creates a matcher that matches any value of the given type T.
template <typename T>
inline Matcher<T> An() { return A<T>(); }
inline Matcher<T> An() {
return _;
}
template <typename T, typename M>
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
......@@ -3626,6 +4099,11 @@ inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT
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
// equal to rhs, where two NANs are considered unequal.
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
......@@ -3808,52 +4286,60 @@ internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
// String matchers.
// Matches a string equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq(
const std::string& str) {
template <typename T = std::string>
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq(
const internal::StringLike<T>& str) {
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.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe(
const std::string& str) {
template <typename T = std::string>
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe(
const internal::StringLike<T>& str) {
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.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq(
const std::string& str) {
template <typename T = std::string>
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq(
const internal::StringLike<T>& str) {
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.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe(
const std::string& str) {
return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, false, false));
template <typename T = std::string>
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>(
std::string(str), false, false));
}
// Creates a matcher that matches any string, std::string, or C string
// that contains the given substring.
inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr(
const std::string& substring) {
template <typename T = std::string>
PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr(
const internal::StringLike<T>& substring) {
return MakePolymorphicMatcher(
internal::HasSubstrMatcher<std::string>(substring));
internal::HasSubstrMatcher<std::string>(std::string(substring)));
}
// Matches a string that starts with 'prefix' (case-sensitive).
inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith(
const std::string& prefix) {
template <typename T = std::string>
PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith(
const internal::StringLike<T>& prefix) {
return MakePolymorphicMatcher(
internal::StartsWithMatcher<std::string>(prefix));
internal::StartsWithMatcher<std::string>(std::string(prefix)));
}
// Matches a string that ends with 'suffix' (case-sensitive).
inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
const std::string& suffix) {
return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix));
template <typename T = std::string>
PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
const internal::StringLike<T>& suffix) {
return MakePolymorphicMatcher(
internal::EndsWithMatcher<std::string>(std::string(suffix)));
}
#if GTEST_HAS_STD_WSTRING
......@@ -4034,11 +4520,7 @@ template <typename Container>
inline PolymorphicMatcher<internal::ContainerEqMatcher<
typename std::remove_const<Container>::type>>
ContainerEq(const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0,
// which causes Container to be a const type sometimes.
typedef typename std::remove_const<Container>::type RawContainer;
return MakePolymorphicMatcher(
internal::ContainerEqMatcher<RawContainer>(rhs));
return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));
}
// Returns a matcher that matches a container that, when sorted using
......@@ -4071,12 +4553,8 @@ template <typename TupleMatcher, typename Container>
inline internal::PointwiseMatcher<TupleMatcher,
typename std::remove_const<Container>::type>
Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0,
// which causes Container to be a const type sometimes (e.g. when
// rhs is a const int[])..
typedef typename std::remove_const<Container>::type RawContainer;
return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
tuple_matcher, rhs);
return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher,
rhs);
}
......@@ -4107,14 +4585,9 @@ inline internal::UnorderedElementsAreArrayMatcher<
typename std::remove_const<RhsContainer>::type>::type::value_type>>
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
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
// 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 RhsStlContainer::value_type Second;
const RhsStlContainer& rhs_stl_container =
......@@ -4336,6 +4809,35 @@ Pair(FirstMatcher first_matcher, SecondMatcher 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
// given matcher.
template <typename M>
......@@ -4520,7 +5022,7 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// and is printable using 'PrintToString'. It is compatible with
// std::optional/std::experimental::optional.
// 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.
template <typename ValueMatcher>
inline internal::OptionalMatcher<ValueMatcher> Optional(
......@@ -4547,6 +5049,175 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
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
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed if and only if the value matches the matcher. If the assertion
......@@ -4556,6 +5227,159 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
::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
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
......@@ -4565,4 +5389,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
// declarations from this file.
#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 @@
// 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
// gmock-more-matchers-test.cc.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_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 {
......@@ -89,4 +89,4 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
......@@ -60,20 +60,91 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#ifndef GOOGLEMOCK_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/internal/gmock-port.h"
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>
class NiceMock : public MockClass {
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
: private internal::NiceMockImpl<MockClass>,
public MockClass {
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() {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
// Ideally, we would inherit base class's constructors through a using
......@@ -85,21 +156,16 @@ class NiceMock : public MockClass {
// made explicit.
template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
template <typename A1, typename A2, typename... An>
NiceMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
template <typename TArg1, typename TArg2, typename... An>
NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~NiceMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
private:
......@@ -107,11 +173,19 @@ class NiceMock : public 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:
NaggyMock() : MockClass() {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
// Ideally, we would inherit base class's constructors through a using
......@@ -123,21 +197,16 @@ class NaggyMock : public MockClass {
// made explicit.
template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
template <typename A1, typename A2, typename... An>
NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
template <typename TArg1, typename TArg2, typename... An>
NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~NaggyMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
private:
......@@ -145,11 +214,19 @@ class NaggyMock : public MockClass {
};
template <class MockClass>
class StrictMock : public MockClass {
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
: private internal::StrictMockImpl<MockClass>,
public MockClass {
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() {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
// Ideally, we would inherit base class's constructors through a using
......@@ -161,55 +238,24 @@ class StrictMock : public MockClass {
// made explicit.
template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
template <typename A1, typename A2, typename... An>
StrictMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
template <typename TArg1, typename TArg2, typename... An>
StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~StrictMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
};
// The following specializations catch some (relatively more common)
// 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> >;
#undef GTEST_INTERNAL_EMPTY_BASE_CLASS
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
......@@ -58,8 +58,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#include <functional>
#include <map>
......@@ -108,6 +108,14 @@ template <typename F> class TypedExpectation;
// Helper class for testing the Expectation class template.
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
// mockers, and all expectations.
//
......@@ -413,14 +421,12 @@ class GTEST_API_ Mock {
template <typename F>
friend class internal::FunctionMocker;
template <typename M>
friend class NiceMock;
template <typename M>
friend class NaggyMock;
template <typename M>
friend class StrictMock;
template <typename MockClass>
friend class internal::NiceMockImpl;
template <typename MockClass>
friend class internal::NaggyMockImpl;
template <typename MockClass>
friend class internal::StrictMockImpl;
// Tells Google Mock to allow uninteresting calls on the given mock
// object.
......@@ -499,7 +505,10 @@ class GTEST_API_ Expectation {
public:
// Constructs a null object that doesn't reference any expectation.
Expectation();
Expectation(Expectation&&) = default;
Expectation(const Expectation&) = default;
Expectation& operator=(Expectation&&) = default;
Expectation& operator=(const Expectation&) = default;
~Expectation();
// This single-argument ctor must not be explicit, in order to support the
......@@ -879,8 +888,6 @@ class GTEST_API_ ExpectationBase {
Clause last_clause_;
mutable bool action_count_checked_; // Under mutex_.
mutable Mutex mutex_; // Protects action_count_checked_.
GTEST_DISALLOW_ASSIGN_(ExpectationBase);
}; // class ExpectationBase
// Impements an expectation for the given function type.
......@@ -1295,8 +1302,6 @@ class MockSpec {
internal::FunctionMocker<F>* const function_mocker_;
// The argument matchers specified in the spec.
ArgumentMatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(MockSpec);
}; // class MockSpec
// Wrapper type for generically holding an ordinary value or lvalue reference.
......@@ -1350,12 +1355,6 @@ class ReferenceOrValueWrapper<T&> {
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
// 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
......@@ -1786,18 +1785,87 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
}
}; // class FunctionMocker
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
} // namespace internal
// A MockFunction<F> class has one mock method whose type is 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:
namespace internal {
template <typename F>
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(2);
......@@ -1831,49 +1899,34 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
// Bar("a") is called by which call to Foo().
//
// MockFunction<F> can also be used to exercise code that accepts
// std::function<F> callbacks. To do so, use AsStdFunction() method
// to create std::function proxy forwarding to original object's Call.
// Example:
// std::function<internal::SignatureOfT<F>> callbacks. To do so, use
// AsStdFunction() method to create std::function proxy forwarding to
// original object's Call. Example:
//
// TEST(FooTest, RunsCallbackWithBarArgument) {
// MockFunction<int(string)> callback;
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
// 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>
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:
MockFunction() {}
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_;
using Base::Base;
};
// The style guide prohibits "using" statements in a namespace scope
......@@ -1982,4 +2035,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#define EXPECT_CALL(obj, 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 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
// This file implements the following syntax:
//
......@@ -59,9 +59,6 @@
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.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-more-actions.h"
#include "gmock/gmock-more-matchers.h"
......@@ -98,4 +95,4 @@ GTEST_API_ void InitGoogleMock();
} // 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 @@
//
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
......@@ -33,7 +33,7 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#ifndef GOOGLEMOCK_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 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#include <stdio.h>
#include <ostream> // NOLINT
......@@ -71,20 +71,6 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields);
// "foo_bar_123" are converted to "foo bar 123".
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
// smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case.
......@@ -136,15 +122,13 @@ GMOCK_DECLARE_KIND_(int, kInteger);
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(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_
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif
// Non-standard integer types.
GMOCK_DECLARE_KIND_(Int64, kInteger);
GMOCK_DECLARE_KIND_(UInt64, kInteger);
// All standard floating-point types.
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
......@@ -157,9 +141,6 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
static_cast< ::testing::internal::TypeKind>( \
::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
// is true if and only if arithmetic type From can be losslessly converted to
// arithmetic type To.
......@@ -170,65 +151,30 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
// From, and kToKind is the kind of To; the value is
// implementation-defined when the above pre-condition is violated.
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
struct LosslessArithmeticConvertibleImpl : public std::false_type {};
// Converting bool to bool is lossless.
template <>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
: public std::true_type {};
// Converting bool to any integer type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
: public std::true_type {};
// Converting bool to any floating-point type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
: public std::true_type {};
// Converting an integer to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
: public std::false_type {};
// Converting an integer to another non-bool integer is lossless
// 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
using LosslessArithmeticConvertibleImpl = std::integral_constant<
bool,
// clang-format off
// Converting from bool is always lossless
(kFromKind == kBool) ? true
// Converting between any other type kinds will be lossy if the type
// kinds are not the same.
: (kFromKind != kToKind) ? false
: (kFromKind == kInteger &&
// Converting between integers of different widths is allowed so long
// as the conversion does not go from signed to unsigned.
(((sizeof(From) < sizeof(To)) &&
!(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
// Converting between integers of the same width only requires the
// two types to have the same signedness.
((sizeof(From) == sizeof(To)) &&
(std::is_signed<From>::value == std::is_signed<To>::value)))
) ? true
// Floating point conversions are lossless if and only if `To` is at least
// as wide as `From`.
: (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
: false
// clang-format on
>;
// LosslessArithmeticConvertible<From, To>::value is true if and only if
// arithmetic type From can be losslessly converted to arithmetic type To.
......@@ -238,9 +184,9 @@ struct LosslessArithmeticConvertibleImpl<
// reference) built-in arithmetic types; the value is
// implementation-defined when the above pre-condition is violated.
template <typename From, typename To>
struct LosslessArithmeticConvertible
: public LosslessArithmeticConvertibleImpl<
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
using LosslessArithmeticConvertible =
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
GMOCK_KIND_OF_(To), To>;
// This interface knows how to report a Google Mock failure (either
// non-fatal or fatal).
......@@ -334,8 +280,6 @@ class WithoutMatchers {
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Type traits.
// Disable MSVC warnings for infinite recursion, since in this case the
// the recursion is unreachable.
#ifdef _MSC_VER
......@@ -420,7 +364,8 @@ template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
public:
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 const type const_reference;
......@@ -464,11 +409,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
// Apply the function to a tuple of arguments.
template <typename F, typename Tuple>
auto Apply(F&& f, Tuple&& args)
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<Tuple>::value>())) {
auto Apply(F&& f, Tuple&& args) -> decltype(
ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
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
......@@ -492,8 +439,7 @@ struct Function<R(Args...)> {
using Result = R;
static constexpr size_t ArgumentCount = sizeof...(Args);
template <size_t I>
using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
Args...>;
using Arg = ElemFromList<I, Args...>;
using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
using MakeResultVoid = void(Args...);
......@@ -510,4 +456,4 @@ constexpr size_t Function<R(Args...)>::ArgumentCount;
} // namespace internal
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
......@@ -37,11 +37,12 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h>
#include <stdlib.h>
#include <cstdint>
#include <iostream>
// Most of the utilities needed for porting Google Mock are also
......@@ -69,8 +70,7 @@
// Macros for declaring flags.
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
# define GMOCK_DECLARE_int32_(name) \
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
# define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
......@@ -78,10 +78,10 @@
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
# 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) \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#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_
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_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
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
// Expands and concatenates the arguments. Constructed macros reevaluate.
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
......@@ -29,10 +16,6 @@ static_assert(
// Returns the only argument.
#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.
//
// #define PAIR x, y
......@@ -43,45 +26,27 @@ static_assert(
// GMOCK_PP_NARG(PAIR) => 2
//
// Requires: the number of arguments after expansion is at most 15.
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_NARG_CAT( \
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_NARG(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// returns 0. Requires no more than 15 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \
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_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
// Returns the first argument.
#define GMOCK_PP_HEAD(...) \
GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
// Returns the tail. A variadic list of all arguments minus the first. Requires
// at least one argument.
#define GMOCK_PP_TAIL(...) \
GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
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
GMOCK_PP_IDENTITY( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`.
......@@ -121,6 +86,14 @@ static_assert(
#define GMOCK_PP_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
// 0.
//
......@@ -139,10 +112,9 @@ static_assert(
// Expands to 1 if the first argument starts with something in parentheses,
// otherwise to 0.
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
......@@ -179,10 +151,6 @@ static_assert(
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#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_IS_EMPTY(_1, _2, _3, _4) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
......@@ -190,30 +158,24 @@ static_assert(
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
#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
#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
#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
// Because of MSVC treating a token with a comma in it as a single token when
// passed to another macro, we need to force it to evaluate it as multiple
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
// define one per possible macro that relies on this behavior. Note "_Args" must
// be parenthesized.
#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_16TH(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#define GMOCK_PP_INTERNAL_TAIL(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
......@@ -314,4 +276,4 @@ static_assert(
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
(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 @@
# 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.
"""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.
SYNOPSIS
......@@ -55,27 +55,29 @@ EXAMPLES
This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Mock or Google Test headers. Please
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.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
from __future__ import print_function
import os
import re
import sets
import sys
__author__ = 'wan@google.com (Zhanyong Wan)'
# We assume that this file is in the scripts/ directory in the Google
# Mock root directory.
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
# We need to call into googletest/scripts/fuse_gtest_files.py.
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts'))
import fuse_gtest_files
gtest = fuse_gtest_files
import fuse_gtest_files as gtest # pylint:disable=g-import-not-at-top
# Regex for matching '#include "gmock/..."'.
# Regex for matching
# '#include "gmock/..."'.
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
# Where to find the source seed files.
......@@ -98,6 +100,9 @@ def ValidateGMockRootDir(gmock_root):
"""Makes sure gmock_root points to a valid gmock root directory.
The function aborts the program on failure.
Args:
gmock_root: A string with the mock root directory.
"""
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
......@@ -109,6 +114,9 @@ def ValidateOutputDir(output_dir):
"""Makes sure output_dir points to a valid output directory.
The function aborts the program on failure.
Args:
output_dir: A string representing the output directory.
"""
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
......@@ -119,8 +127,8 @@ def ValidateOutputDir(output_dir):
def FuseGMockH(gmock_root, 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')
processed_files = sets.Set() # Holds all gmock headers we've processed.
output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
processed_files = set() # Holds all gmock headers we've processed.
def ProcessFile(gmock_header_path):
"""Processes the given gmock header file."""
......@@ -132,25 +140,28 @@ def FuseGMockH(gmock_root, output_dir):
processed_files.add(gmock_header_path)
# 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)
if m:
# It's '#include "gmock/..."' - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh:
for line in fh:
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#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 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,))
# '#include "gmock/..."'
# - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(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)
output_file.close()
......@@ -159,7 +170,7 @@ def FuseGMockH(gmock_root, output_dir):
def FuseGMockAllCcToFile(gmock_root, 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):
"""Processes the given gmock source file."""
......@@ -171,32 +182,37 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
processed_files.add(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)
if m:
# It's '#include "gmock/foo.h"'. We treat it as '#include
# "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)
with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh:
for line in fh:
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gtest/..."'.
# There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.
pass
# '#include "gmock/foo.h"'
# We treat it as '#include "gmock/gmock.h"', as all other gmock
# headers are being fused into gmock.h and cannot be
# 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:
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
# '#include "gtest/..."'
# There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.
pass
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
m = gtest.INCLUDE_SRC_FILE_REGEX.match(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)
......@@ -204,12 +220,12 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
def FuseGMockGTestAllCc(gmock_root, 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')
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
FuseGMockAllCcToFile(gmock_root, output_file)
output_file.close()
with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT),
'w') as output_file:
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
FuseGMockAllCcToFile(gmock_root, output_file)
def FuseGMock(gmock_root, output_dir):
......@@ -232,7 +248,7 @@ def main():
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
FuseGMock(sys.argv[1], sys.argv[2])
else:
print __doc__
print(__doc__)
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