Update googletest to 1.18.0 and SIMDe to 0.8.2.
Googletest 1.18 asks for CMake 3.13 or newer, so configuring the tests no longer warns that CMake compatibility below 3.10 is deprecated. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e4e666f459
commit
3f10e05176
912 changed files with 224964 additions and 11502 deletions
|
|
@ -135,6 +135,7 @@
|
|||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
@ -175,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
|
|||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
return internal::Invalid<T>();
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#else
|
||||
return Invalid<T>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -189,7 +196,7 @@ struct BuiltInDefaultValueGetter<T, false> {
|
|||
// other type T, the built-in default T value is undefined, and the
|
||||
// function will abort the process.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue {
|
||||
class [[nodiscard]] BuiltInDefaultValue {
|
||||
public:
|
||||
// This function returns true if and only if type T has a built-in default
|
||||
// value.
|
||||
|
|
@ -204,7 +211,7 @@ class BuiltInDefaultValue {
|
|||
// This partial specialization says that we use the same built-in
|
||||
// default value for T and const T.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<const T> {
|
||||
class [[nodiscard]] BuiltInDefaultValue<const T> {
|
||||
public:
|
||||
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||
|
|
@ -213,7 +220,7 @@ class BuiltInDefaultValue<const T> {
|
|||
// This partial specialization defines the default values for pointer
|
||||
// types.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<T*> {
|
||||
class [[nodiscard]] BuiltInDefaultValue<T*> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static T* Get() { return nullptr; }
|
||||
|
|
@ -376,7 +383,7 @@ typename std::add_const<T>::type& as_const(T& t) {
|
|||
|
||||
// Specialized for function types below.
|
||||
template <typename F>
|
||||
class OnceAction;
|
||||
class [[nodiscard]] OnceAction;
|
||||
|
||||
// An action that can only be used once.
|
||||
//
|
||||
|
|
@ -414,27 +421,26 @@ class OnceAction;
|
|||
// A less-contrived example would be an action that returns an arbitrary type,
|
||||
// whose &&-qualified call operator is capable of dealing with move-only types.
|
||||
template <typename Result, typename... Args>
|
||||
class OnceAction<Result(Args...)> final {
|
||||
class [[nodiscard]] OnceAction<Result(Args...)> final {
|
||||
private:
|
||||
// True iff we can use the given callable type (or lvalue reference) directly
|
||||
// via StdFunctionAdaptor.
|
||||
template <typename Callable>
|
||||
using IsDirectlyCompatible = internal::conjunction<
|
||||
// It must be possible to capture the callable in StdFunctionAdaptor.
|
||||
std::is_constructible<typename std::decay<Callable>::type, Callable>,
|
||||
// The callable must be compatible with our signature.
|
||||
internal::is_callable_r<Result, typename std::decay<Callable>::type,
|
||||
Args...>>;
|
||||
internal::is_callable_r<Result, std::decay_t<Callable>, Args...>,
|
||||
// It must be possible to capture the callable in StdFunctionAdaptor.
|
||||
std::is_constructible<std::decay_t<Callable>, Callable>>;
|
||||
|
||||
// True iff we can use the given callable type via StdFunctionAdaptor once we
|
||||
// ignore incoming arguments.
|
||||
template <typename Callable>
|
||||
using IsCompatibleAfterIgnoringArguments = internal::conjunction<
|
||||
// It must be possible to capture the callable in a lambda.
|
||||
std::is_constructible<typename std::decay<Callable>::type, Callable>,
|
||||
// The callable must be invocable with zero arguments, returning something
|
||||
// convertible to Result.
|
||||
internal::is_callable_r<Result, typename std::decay<Callable>::type>>;
|
||||
internal::is_callable_r<Result, std::decay_t<Callable>>,
|
||||
// It must be possible to capture the callable in a lambda.
|
||||
std::is_constructible<std::decay_t<Callable>, Callable>>;
|
||||
|
||||
public:
|
||||
// Construct from a callable that is directly compatible with our mocked
|
||||
|
|
@ -567,7 +573,7 @@ class OnceAction<Result(Args...)> final {
|
|||
// // Sets the default value for type T to be foo.
|
||||
// DefaultValue<T>::Set(foo);
|
||||
template <typename T>
|
||||
class DefaultValue {
|
||||
class [[nodiscard]] DefaultValue {
|
||||
public:
|
||||
// Sets the default value for type T; requires T to be
|
||||
// copy-constructable and have a public destructor.
|
||||
|
|
@ -611,7 +617,7 @@ class DefaultValue {
|
|||
private:
|
||||
class ValueProducer {
|
||||
public:
|
||||
virtual ~ValueProducer() {}
|
||||
virtual ~ValueProducer() = default;
|
||||
virtual T Produce() = 0;
|
||||
};
|
||||
|
||||
|
|
@ -644,7 +650,7 @@ class DefaultValue {
|
|||
// This partial specialization allows a user to set default values for
|
||||
// reference types.
|
||||
template <typename T>
|
||||
class DefaultValue<T&> {
|
||||
class [[nodiscard]] DefaultValue<T&> {
|
||||
public:
|
||||
// Sets the default value for type T&.
|
||||
static void Set(T& x) { // NOLINT
|
||||
|
|
@ -678,7 +684,7 @@ class DefaultValue<T&> {
|
|||
// This specialization allows DefaultValue<void>::Get() to
|
||||
// compile.
|
||||
template <>
|
||||
class DefaultValue<void> {
|
||||
class [[nodiscard]] DefaultValue<void> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static void Get() {}
|
||||
|
|
@ -694,13 +700,13 @@ T* DefaultValue<T&>::address_ = nullptr;
|
|||
|
||||
// Implement this interface to define an action for function type F.
|
||||
template <typename F>
|
||||
class ActionInterface {
|
||||
class [[nodiscard]] ActionInterface {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
ActionInterface() {}
|
||||
virtual ~ActionInterface() {}
|
||||
ActionInterface() = default;
|
||||
virtual ~ActionInterface() = default;
|
||||
|
||||
// Performs the action. This method is not const, as in general an
|
||||
// action can have side effects and be stateful. For example, a
|
||||
|
|
@ -714,7 +720,7 @@ class ActionInterface {
|
|||
};
|
||||
|
||||
template <typename F>
|
||||
class Action;
|
||||
class [[nodiscard]] Action;
|
||||
|
||||
// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that represents an action to be taken when a mock function of type
|
||||
|
|
@ -723,7 +729,7 @@ class Action;
|
|||
// can view an object implementing ActionInterface<F> as a concrete action
|
||||
// (including its current state), and an Action<F> object as a handle to it.
|
||||
template <typename R, typename... Args>
|
||||
class Action<R(Args...)> {
|
||||
class [[nodiscard]] Action<R(Args...)> {
|
||||
private:
|
||||
using F = R(Args...);
|
||||
|
||||
|
|
@ -749,7 +755,7 @@ class Action<R(Args...)> {
|
|||
|
||||
// Constructs a null Action. Needed for storing Action objects in
|
||||
// STL containers.
|
||||
Action() {}
|
||||
Action() = default;
|
||||
|
||||
// Construct an Action from a specified callable.
|
||||
// This cannot take std::function directly, because then Action would not be
|
||||
|
|
@ -828,6 +834,10 @@ class Action<R(Args...)> {
|
|||
Result operator()(const InArgs&...) const {
|
||||
return function_impl();
|
||||
}
|
||||
template <typename... InArgs>
|
||||
Result operator()(const InArgs&...) {
|
||||
return function_impl();
|
||||
}
|
||||
|
||||
FunctionImpl function_impl;
|
||||
};
|
||||
|
|
@ -858,7 +868,7 @@ class Action<R(Args...)> {
|
|||
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
||||
// complete examples.
|
||||
template <typename Impl>
|
||||
class PolymorphicAction {
|
||||
class [[nodiscard]] PolymorphicAction {
|
||||
public:
|
||||
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
|
|
@ -918,7 +928,7 @@ struct ByMoveWrapper {
|
|||
|
||||
// The general implementation of Return(R). Specializations follow below.
|
||||
template <typename R>
|
||||
class ReturnAction final {
|
||||
class [[nodiscard]] ReturnAction final {
|
||||
public:
|
||||
explicit ReturnAction(R value) : value_(std::move(value)) {}
|
||||
|
||||
|
|
@ -1084,7 +1094,7 @@ class ReturnAction final {
|
|||
// the const call operator, checking at runtime that it isn't called more than
|
||||
// once, since the user has declared their intent to do so by using ByMove.
|
||||
template <typename T>
|
||||
class ReturnAction<ByMoveWrapper<T>> final {
|
||||
class [[nodiscard]] ReturnAction<ByMoveWrapper<T>> final {
|
||||
public:
|
||||
explicit ReturnAction(ByMoveWrapper<T> wrapper)
|
||||
: state_(new State(std::move(wrapper.payload))) {}
|
||||
|
|
@ -1111,7 +1121,7 @@ class ReturnAction<ByMoveWrapper<T>> final {
|
|||
};
|
||||
|
||||
// Implements the ReturnNull() action.
|
||||
class ReturnNullAction {
|
||||
class [[nodiscard]] ReturnNullAction {
|
||||
public:
|
||||
// Allows ReturnNull() to be used in any pointer-returning function. In C++11
|
||||
// this is enforced by returning nullptr, and in non-C++11 by asserting a
|
||||
|
|
@ -1123,7 +1133,7 @@ class ReturnNullAction {
|
|||
};
|
||||
|
||||
// Implements the Return() action.
|
||||
class ReturnVoidAction {
|
||||
class [[nodiscard]] ReturnVoidAction {
|
||||
public:
|
||||
// Allows Return() to be used in any void-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
|
|
@ -1136,7 +1146,7 @@ class ReturnVoidAction {
|
|||
// in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefAction {
|
||||
class [[nodiscard]] ReturnRefAction {
|
||||
public:
|
||||
// Constructs a ReturnRefAction object from the reference to be returned.
|
||||
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
||||
|
|
@ -1177,7 +1187,7 @@ class ReturnRefAction {
|
|||
// used in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefOfCopyAction {
|
||||
class [[nodiscard]] ReturnRefOfCopyAction {
|
||||
public:
|
||||
// Constructs a ReturnRefOfCopyAction object from the reference to
|
||||
// be returned.
|
||||
|
|
@ -1218,7 +1228,7 @@ class ReturnRefOfCopyAction {
|
|||
// 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 {
|
||||
class [[nodiscard]] ReturnRoundRobinAction {
|
||||
public:
|
||||
explicit ReturnRoundRobinAction(std::vector<T> values) {
|
||||
GTEST_CHECK_(!values.empty())
|
||||
|
|
@ -1246,7 +1256,7 @@ class ReturnRoundRobinAction {
|
|||
};
|
||||
|
||||
// Implements the polymorphic DoDefault() action.
|
||||
class DoDefaultAction {
|
||||
class [[nodiscard]] DoDefaultAction {
|
||||
public:
|
||||
// This template type conversion operator allows DoDefault() to be
|
||||
// used in any function.
|
||||
|
|
@ -1259,7 +1269,7 @@ class DoDefaultAction {
|
|||
// Implements the Assign action to set a given pointer referent to a
|
||||
// particular value.
|
||||
template <typename T1, typename T2>
|
||||
class AssignAction {
|
||||
class [[nodiscard]] AssignAction {
|
||||
public:
|
||||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
||||
|
||||
|
|
@ -1273,12 +1283,12 @@ class AssignAction {
|
|||
const T2 value_;
|
||||
};
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Implements the SetErrnoAndReturn action to simulate return from
|
||||
// various system calls and libc functions.
|
||||
template <typename T>
|
||||
class SetErrnoAndReturnAction {
|
||||
class [[nodiscard]] SetErrnoAndReturnAction {
|
||||
public:
|
||||
SetErrnoAndReturnAction(int errno_value, T result)
|
||||
: errno_(errno_value), result_(result) {}
|
||||
|
|
@ -1320,22 +1330,6 @@ struct InvokeMethodAction {
|
|||
}
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F.
|
||||
template <typename FunctionImpl>
|
||||
struct InvokeWithoutArgsAction {
|
||||
FunctionImpl function_impl;
|
||||
|
||||
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
||||
// compatible with f.
|
||||
template <typename... Args>
|
||||
auto operator()(const Args&...) -> decltype(function_impl()) {
|
||||
return function_impl();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
struct InvokeMethodWithoutArgsAction {
|
||||
|
|
@ -1386,7 +1380,7 @@ class IgnoreResultAction {
|
|||
|
||||
void Perform(const ArgumentTuple& args) override {
|
||||
// Performs the action and ignores its result.
|
||||
action_.Perform(args);
|
||||
(void)action_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -1444,6 +1438,30 @@ struct WithArgsAction {
|
|||
return OA{std::move(inner_action)};
|
||||
}
|
||||
|
||||
// As above, but in the case where we want to create a OnceAction from a const
|
||||
// WithArgsAction. This is fine as long as the inner action doesn't need to
|
||||
// move any of its state to create a OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const InnerAction&,
|
||||
OnceAction<R(internal::TupleElement<
|
||||
I, std::tuple<Args...>>...)>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() const& { // NOLINT
|
||||
struct OA {
|
||||
OnceAction<InnerSignature<R, Args...>> inner_action;
|
||||
|
||||
R operator()(Args&&... args) && {
|
||||
return std::move(inner_action)
|
||||
.Call(std::get<I>(
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))...);
|
||||
}
|
||||
};
|
||||
|
||||
return OA{inner_action};
|
||||
}
|
||||
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
|
|
@ -1468,11 +1486,11 @@ struct WithArgsAction {
|
|||
};
|
||||
|
||||
template <typename... Actions>
|
||||
class DoAllAction;
|
||||
class [[nodiscard]] DoAllAction;
|
||||
|
||||
// Base case: only a single action.
|
||||
template <typename FinalAction>
|
||||
class DoAllAction<FinalAction> {
|
||||
class [[nodiscard]] DoAllAction<FinalAction> {
|
||||
public:
|
||||
struct UserConstructorTag {};
|
||||
|
||||
|
|
@ -1486,6 +1504,7 @@ class DoAllAction<FinalAction> {
|
|||
// providing a call operator because even with a particular set of arguments
|
||||
// they don't have a fixed return type.
|
||||
|
||||
// We support conversion to OnceAction whenever the sub-action does.
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
|
||||
|
|
@ -1494,6 +1513,21 @@ class DoAllAction<FinalAction> {
|
|||
return std::move(final_action_);
|
||||
}
|
||||
|
||||
// We also support conversion to OnceAction whenever the sub-action supports
|
||||
// conversion to Action (since any Action can also be a OnceAction).
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
negation<
|
||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>>,
|
||||
std::is_convertible<FinalAction, Action<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
return Action<R(Args...)>(std::move(final_action_));
|
||||
}
|
||||
|
||||
// We support conversion to Action whenever the sub-action does.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
|
|
@ -1510,7 +1544,7 @@ class DoAllAction<FinalAction> {
|
|||
// Recursive case: support N actions by calling the initial action and then
|
||||
// calling through to the base class containing N-1 actions.
|
||||
template <typename InitialAction, typename... OtherActions>
|
||||
class DoAllAction<InitialAction, OtherActions...>
|
||||
class [[nodiscard]] DoAllAction<InitialAction, OtherActions...>
|
||||
: private DoAllAction<OtherActions...> {
|
||||
private:
|
||||
using Base = DoAllAction<OtherActions...>;
|
||||
|
|
@ -1573,16 +1607,16 @@ class DoAllAction<InitialAction, OtherActions...>
|
|||
: Base({}, std::forward<U>(other_actions)...),
|
||||
initial_action_(std::forward<T>(initial_action)) {}
|
||||
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
// Both the initial action and the rest must support
|
||||
// conversion to OnceAction.
|
||||
std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
// We support conversion to OnceAction whenever both the initial action and
|
||||
// the rest support conversion to OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
// Return an action that first calls the initial action with arguments
|
||||
// filtered through InitialActionArgType, then forwards arguments directly
|
||||
|
|
@ -1605,12 +1639,34 @@ class DoAllAction<InitialAction, OtherActions...>
|
|||
};
|
||||
}
|
||||
|
||||
// We also support conversion to OnceAction whenever the initial action
|
||||
// supports conversion to Action (since any Action can also be a OnceAction).
|
||||
//
|
||||
// The remaining sub-actions must also be compatible, but we don't need to
|
||||
// special case them because the base class deals with them.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
negation<std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>>,
|
||||
std::is_convertible<InitialAction,
|
||||
Action<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
return DoAll(
|
||||
Action<void(InitialActionArgType<Args>...)>(std::move(initial_action_)),
|
||||
std::move(static_cast<Base&>(*this)));
|
||||
}
|
||||
|
||||
// We support conversion to Action whenever both the initial action and the
|
||||
// rest support conversion to Action.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
// Both the initial action and the rest must support conversion to
|
||||
// Action.
|
||||
std::is_convertible<const InitialAction&,
|
||||
Action<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<const Base&, Action<R(Args...)>>>::value,
|
||||
|
|
@ -1674,6 +1730,16 @@ struct SaveArgAction {
|
|||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgByMoveAction {
|
||||
Ptr pointer;
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args) const {
|
||||
*pointer = std::move(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgPointeeAction {
|
||||
Ptr pointer;
|
||||
|
|
@ -1713,11 +1779,24 @@ struct SetArrayArgumentAction {
|
|||
};
|
||||
|
||||
template <size_t k>
|
||||
struct DeleteArgAction {
|
||||
class [[nodiscard]] DeleteArgAction {
|
||||
public:
|
||||
template <typename... Args>
|
||||
void operator()(const Args&... args) const {
|
||||
delete std::get<k>(std::tie(args...));
|
||||
DoDelete(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static void DoDelete(T* ptr) {
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[deprecated(
|
||||
"DeleteArg<N> used for a non-pointer argument, it was likely migrated "
|
||||
"to a smart pointer type. This action should be removed.")]]
|
||||
static void DoDelete(T&) {}
|
||||
};
|
||||
|
||||
template <typename Ptr>
|
||||
|
|
@ -1740,6 +1819,13 @@ struct ThrowAction {
|
|||
return [copy](Args...) -> R { throw copy; };
|
||||
}
|
||||
};
|
||||
struct RethrowAction {
|
||||
std::exception_ptr exception;
|
||||
template <typename R, typename... Args>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
|
||||
}
|
||||
};
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace internal
|
||||
|
|
@ -1776,6 +1862,13 @@ struct ThrowAction {
|
|||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
typedef internal::IgnoredValue Unused;
|
||||
|
||||
// Deprecated single-argument DoAll.
|
||||
template <typename Action>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
|
||||
typename std::decay<Action>::type DoAll(Action&& action) {
|
||||
return std::forward<Action>(action);
|
||||
}
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation. All but the last action will have a readonly view of the
|
||||
// arguments.
|
||||
|
|
@ -1926,7 +2019,7 @@ PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {
|
|||
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Creates an action that sets errno and returns the appropriate error.
|
||||
template <typename T>
|
||||
|
|
@ -1941,10 +2034,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
|
|||
// Various overloads for Invoke().
|
||||
|
||||
// Legacy function.
|
||||
// Actions can now be implicitly constructed from callables. No need to create
|
||||
// wrapper objects.
|
||||
// This function exists for backwards compatibility.
|
||||
template <typename FunctionImpl>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||
"Actions can now be implicitly constructed from callables. No need to "
|
||||
"create wrapper objects using Invoke().")
|
||||
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||
return std::forward<FunctionImpl>(function_impl);
|
||||
}
|
||||
|
|
@ -1959,9 +2053,11 @@ internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
|
|||
|
||||
// Creates an action that invokes 'function_impl' with no argument.
|
||||
template <typename FunctionImpl>
|
||||
internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
|
||||
InvokeWithoutArgs(FunctionImpl function_impl) {
|
||||
return {std::move(function_impl)};
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||
"Actions can now be implicitly constructed from zero-argument callables. "
|
||||
"No need to create wrapper objects using InvokeWithoutArgs().")
|
||||
std::decay_t<FunctionImpl> InvokeWithoutArgs(FunctionImpl&& function_impl) {
|
||||
return std::forward<FunctionImpl>(function_impl);
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
|
|
@ -2017,6 +2113,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
|||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
|
||||
// mock function into *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(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>
|
||||
|
|
@ -2056,13 +2159,23 @@ 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
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown,
|
||||
// except for std::exception_ptr, which is likely a mistake if
|
||||
// thrown directly.
|
||||
template <typename T>
|
||||
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
|
||||
typename std::enable_if<
|
||||
!std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
|
||||
internal::ThrowAction<typename std::decay<T>::type>>::type
|
||||
Throw(T&& exception) {
|
||||
return {std::forward<T>(exception)};
|
||||
}
|
||||
// Action Rethrow(exception_ptr) can be used in a mock function of any type
|
||||
// to rethrow any exception_ptr. Note that the same object is thrown each time.
|
||||
inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
|
||||
return {std::move(exception)};
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
namespace internal {
|
||||
|
|
@ -2111,13 +2224,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
|
|||
R operator()(Args&&... arg) const {
|
||||
static constexpr size_t kMaxArgs =
|
||||
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
|
||||
return Apply(MakeIndexSequence<kMaxArgs>{},
|
||||
MakeIndexSequence<10 - kMaxArgs>{},
|
||||
return Apply(std::make_index_sequence<kMaxArgs>{},
|
||||
std::make_index_sequence<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...>,
|
||||
R Apply(std::index_sequence<arg_id...>, std::index_sequence<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
|
||||
|
|
@ -2150,9 +2263,9 @@ template <typename F, typename 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( \
|
||||
, [[maybe_unused]] const arg##i##_type& arg##i
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
[[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||
|
||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
||||
|
|
@ -2217,8 +2330,8 @@ template <typename F, typename Impl>
|
|||
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)) GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
||||
|
|
@ -2253,7 +2366,7 @@ template <typename F, typename Impl>
|
|||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||
}; \
|
||||
}; \
|
||||
inline name##Action name() GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline name##Action name(); \
|
||||
inline name##Action name() { return name##Action(); } \
|
||||
template <typename function_type, typename return_type, typename args_type, \
|
||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ namespace testing {
|
|||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
class [[nodiscard]] CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
virtual ~CardinalityInterface() = default;
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
|
|
@ -88,11 +88,11 @@ class CardinalityInterface {
|
|||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||
class GTEST_API_ Cardinality {
|
||||
class GTEST_API_ [[nodiscard]] Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
Cardinality() = default;
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#include <utility> // IWYU pragma: keep
|
||||
|
||||
|
|
@ -69,22 +70,22 @@ constexpr bool PrefixOf(const char* a, const char* b) {
|
|||
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(prefix, str);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||
return N == M && internal::PrefixOf(a, b);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||
return internal::Equals("const", spec) ||
|
||||
internal::Equals("override", spec) ||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -521,9 +521,8 @@
|
|||
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)){}) \
|
||||
, : 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 \
|
||||
|
|
@ -551,10 +550,10 @@
|
|||
}; \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
GMOCK_ACTION_CLASS_( \
|
||||
[[nodiscard]] 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_; \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params); \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
inline GMOCK_ACTION_CLASS_( \
|
||||
|
|
@ -592,21 +591,23 @@ namespace internal {
|
|||
// 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...);
|
||||
auto InvokeArgument(F &&f,
|
||||
Args... args) -> decltype(std::forward<F>(f)(args...)) {
|
||||
return std::forward<F>(f)(args...);
|
||||
}
|
||||
|
||||
template <std::size_t index, typename... Params>
|
||||
struct InvokeArgumentAction {
|
||||
template <typename... Args,
|
||||
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
||||
auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params &>()...)) {
|
||||
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>();
|
||||
auto &&callable = std::move(args_tuple.template Get<index>());
|
||||
return internal::InvokeArgument(
|
||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace internal {
|
|||
// Implements the polymorphic IsEmpty matcher, which
|
||||
// can be used as a Matcher<T> as long as T is either a container that defines
|
||||
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
|
||||
class IsEmptyMatcher {
|
||||
class [[nodiscard]] IsEmptyMatcher {
|
||||
public:
|
||||
// Matches anything that defines empty() and size().
|
||||
template <typename MatcheeContainerType>
|
||||
|
|
@ -76,9 +76,22 @@ class IsEmptyMatcher {
|
|||
|
||||
// Matches C-style strings.
|
||||
bool MatchAndExplain(const char* s, MatchResultListener* listener) const {
|
||||
if (s == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return MatchAndExplain(std::string(s), listener);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Matches C-style wide strings.
|
||||
bool MatchAndExplain(const wchar_t* s, MatchResultListener* listener) const {
|
||||
if (s == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return MatchAndExplain(std::wstring(s), listener);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Describes what this matcher matches.
|
||||
void DescribeTo(std::ostream* os) const { *os << "is empty"; }
|
||||
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@
|
|||
|
||||
namespace testing {
|
||||
template <class MockClass>
|
||||
class NiceMock;
|
||||
class [[nodiscard]] NiceMock;
|
||||
template <class MockClass>
|
||||
class NaggyMock;
|
||||
class [[nodiscard]] NaggyMock;
|
||||
template <class MockClass>
|
||||
class StrictMock;
|
||||
class [[nodiscard]] StrictMock;
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
|
|
@ -98,7 +98,7 @@ constexpr bool HasStrictnessModifier() {
|
|||
// 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 && \
|
||||
#if defined(GTEST_OS_WINDOWS) && !defined(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.
|
||||
|
|
@ -108,7 +108,7 @@ constexpr bool HasStrictnessModifier() {
|
|||
#endif
|
||||
|
||||
template <typename Base>
|
||||
class NiceMockImpl {
|
||||
class [[nodiscard]] NiceMockImpl {
|
||||
public:
|
||||
NiceMockImpl() {
|
||||
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
|
|
@ -120,7 +120,7 @@ class NiceMockImpl {
|
|||
};
|
||||
|
||||
template <typename Base>
|
||||
class NaggyMockImpl {
|
||||
class [[nodiscard]] NaggyMockImpl {
|
||||
public:
|
||||
NaggyMockImpl() {
|
||||
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
|
|
@ -132,7 +132,7 @@ class NaggyMockImpl {
|
|||
};
|
||||
|
||||
template <typename Base>
|
||||
class StrictMockImpl {
|
||||
class [[nodiscard]] StrictMockImpl {
|
||||
public:
|
||||
StrictMockImpl() {
|
||||
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
|
|
@ -146,7 +146,7 @@ class StrictMockImpl {
|
|||
} // namespace internal
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
: private internal::NiceMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
|
|
@ -187,7 +187,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
|||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
: private internal::NaggyMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
|
|
@ -229,7 +229,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
|||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
: private internal::StrictMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -204,6 +204,9 @@ class GTEST_API_ UntypedFunctionMockerBase {
|
|||
|
||||
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
|
||||
|
||||
struct UninterestingCallCleanupHandler;
|
||||
struct FailureCleanupHandler;
|
||||
|
||||
// Returns an Expectation object that references and co-owns exp,
|
||||
// which must be an expectation on this mock function.
|
||||
Expectation GetHandleOf(ExpectationBase* exp);
|
||||
|
|
@ -563,7 +566,7 @@ class ExpectationSet {
|
|||
typedef Expectation::Set::value_type value_type;
|
||||
|
||||
// Constructs an empty set.
|
||||
ExpectationSet() {}
|
||||
ExpectationSet() = default;
|
||||
|
||||
// This single-argument ctor must not be explicit, in order to support the
|
||||
// ExpectationSet es = EXPECT_CALL(...);
|
||||
|
|
@ -865,7 +868,7 @@ class GTEST_API_ ExpectationBase {
|
|||
Clause last_clause_;
|
||||
mutable bool action_count_checked_; // Under mutex_.
|
||||
mutable Mutex mutex_; // Protects action_count_checked_.
|
||||
}; // class ExpectationBase
|
||||
}; // class ExpectationBase
|
||||
|
||||
template <typename F>
|
||||
class TypedExpectation;
|
||||
|
|
@ -1289,10 +1292,10 @@ class MockSpec {
|
|||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||
|
||||
// Adds a new default action spec to the function mocker and returns
|
||||
// the newly created spec.
|
||||
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
|
||||
int line, const char* obj,
|
||||
const char* call) {
|
||||
// the newly created spec. .WillByDefault() must be called on the returned
|
||||
// object.
|
||||
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
|
||||
const char* file, int line, const char* obj, const char* call) {
|
||||
LogWithLocation(internal::kInfo, file, line,
|
||||
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
||||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
||||
|
|
@ -1396,6 +1399,41 @@ class Cleanup final {
|
|||
std::function<void()> f_;
|
||||
};
|
||||
|
||||
struct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {
|
||||
CallReaction reaction;
|
||||
std::stringstream& ss;
|
||||
|
||||
~UninterestingCallCleanupHandler() {
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
struct UntypedFunctionMockerBase::FailureCleanupHandler {
|
||||
std::stringstream& ss;
|
||||
std::stringstream& why;
|
||||
std::stringstream& loc;
|
||||
const ExpectationBase* untyped_expectation;
|
||||
bool found;
|
||||
bool is_excessive;
|
||||
|
||||
~FailureCleanupHandler() {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
|
|
@ -1408,7 +1446,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
using ArgumentTuple = std::tuple<Args...>;
|
||||
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||
|
||||
FunctionMocker() {}
|
||||
FunctionMocker() = default;
|
||||
|
||||
// There is no generally useful and implementable semantics of
|
||||
// copying a mock object, so copying a mock is usually a user error.
|
||||
|
|
@ -1429,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
// function have been satisfied. If not, it will report Google Test
|
||||
// non-fatal failures for the violations.
|
||||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
VerifyAndClearExpectationsLocked();
|
||||
Mock::UnregisterLocked(this);
|
||||
ClearDefaultActionsLocked();
|
||||
|
|
@ -1492,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
UntypedOnCallSpecs specs_to_delete;
|
||||
untyped_on_call_specs_.swap(specs_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
||||
it != specs_to_delete.end(); ++it) {
|
||||
delete static_cast<const OnCallSpec<F>*>(*it);
|
||||
|
|
@ -1500,7 +1538,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
|
||||
// Lock the mutex again, since the caller expects it to be locked when we
|
||||
// return.
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
}
|
||||
|
||||
// Returns the result of invoking this mock function with the given
|
||||
|
|
@ -1608,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const ArgumentTuple& args =
|
||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||
if (exp == nullptr) { // A match wasn't found.
|
||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||
|
|
@ -1794,8 +1832,14 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
|||
//
|
||||
// We use RAII to do the latter in case R is void or a non-moveable type. In
|
||||
// either case we can't assign it to a local variable.
|
||||
const Cleanup report_uninteresting_call(
|
||||
[&] { ReportUninterestingCall(reaction, ss.str()); });
|
||||
//
|
||||
// Note that std::bind() is essential here.
|
||||
// We *don't* use any local callback types (like lambdas).
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const UninterestingCallCleanupHandler report_uninteresting_call = {reaction,
|
||||
ss};
|
||||
|
||||
return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
|
||||
}
|
||||
|
|
@ -1839,22 +1883,13 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
|||
//
|
||||
// We use RAII to do the latter in case R is void or a non-moveable type. In
|
||||
// either case we can't assign it to a local variable.
|
||||
const Cleanup handle_failures([&] {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
});
|
||||
//
|
||||
// Note that we *don't* use any local callback types (like lambdas) here.
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const FailureCleanupHandler handle_failures = {
|
||||
ss, why, loc, untyped_expectation, found, is_excessive};
|
||||
|
||||
return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
|
||||
ss);
|
||||
|
|
@ -1922,6 +1957,11 @@ struct SignatureOf<R(Args...)> {
|
|||
using type = R(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct SignatureOf<R(Args...) const> {
|
||||
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>
|
||||
|
|
@ -2097,9 +2137,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|||
// second argument is an internal type derived from the method signature. The
|
||||
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
||||
// is how we block callers from setting expectations on overloaded methods.
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
|
||||
nullptr) \
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::WithoutMatchers::Get(), \
|
||||
nullptr) \
|
||||
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
||||
|
||||
#define ON_CALL(obj, call) \
|
||||
|
|
|
|||
|
|
@ -53,13 +53,14 @@
|
|||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
#include "gmock/gmock-nice-strict.h"
|
||||
#include "gmock/gmock-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-nice-strict.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-spec-builders.h" // IWYU pragma: export
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -41,9 +41,11 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
|
@ -192,11 +194,11 @@ using LosslessArithmeticConvertibleImpl = std::integral_constant<
|
|||
// 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)) ||
|
||||
!(std::is_signed_v<From> && !std::is_signed_v<To>)) ||
|
||||
// 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)))
|
||||
(std::is_signed_v<From> == std::is_signed_v<To>)))
|
||||
) ? true
|
||||
// Floating point conversions are lossless if and only if `To` is at least
|
||||
// as wide as `From`.
|
||||
|
|
@ -219,12 +221,12 @@ using LosslessArithmeticConvertible =
|
|||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
class [[nodiscard]] FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType { kNonfatal, kFatal };
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
virtual ~FailureReporterInterface() = default;
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
|
|
@ -295,14 +297,13 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||
//
|
||||
// ON_CALL(mock, Method({}, nullptr))...
|
||||
//
|
||||
class WithoutMatchers {
|
||||
class [[nodiscard]] WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
WithoutMatchers() = default;
|
||||
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
public:
|
||||
GTEST_API_ static WithoutMatchers Get();
|
||||
};
|
||||
|
||||
// Invalid<T>() is usable as an expression of type T, but will terminate
|
||||
// the program with an assertion failure if actually run. This is useful
|
||||
|
|
@ -311,7 +312,8 @@ GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
|||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
Assert(false, "", -1, "Internal error: attempt to return invalid value");
|
||||
Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
|
||||
"Internal error: attempt to return invalid value");
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
|
|
@ -321,6 +323,24 @@ inline T Invalid() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void GetValueType(const void*);
|
||||
|
||||
template <class T>
|
||||
typename std::iterator_traits<
|
||||
decltype(std::begin(std::declval<T&>()))>::value_type
|
||||
GetValueType(T*);
|
||||
|
||||
template <class T, class = void>
|
||||
struct RangeTraits {
|
||||
typedef decltype(internal::GetValueType(
|
||||
static_cast<std::remove_reference_t<T>*>(nullptr))) value_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct RangeTraits<T, std::conditional_t<true, void, typename T::value_type>> {
|
||||
typedef typename T::value_type value_type;
|
||||
};
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
|
|
@ -338,13 +358,13 @@ inline T Invalid() {
|
|||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
class [[nodiscard]] StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
|
||||
static const_reference ConstReference(const RawContainer& container) {
|
||||
static_assert(!std::is_const<RawContainer>::value,
|
||||
static_assert(!std::is_const_v<RawContainer>,
|
||||
"RawContainer type must not be const");
|
||||
return container;
|
||||
}
|
||||
|
|
@ -353,7 +373,7 @@ class StlContainerView {
|
|||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
class [[nodiscard]] StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef typename std::remove_const<Element>::type RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
|
|
@ -365,7 +385,7 @@ class StlContainerView<Element[N]> {
|
|||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(const Element (&array)[N]) {
|
||||
static_assert(std::is_same<Element, RawElement>::value,
|
||||
static_assert(std::is_same_v<Element, RawElement>,
|
||||
"Element type must not be const");
|
||||
return type(array, N, RelationToSourceReference());
|
||||
}
|
||||
|
|
@ -377,7 +397,7 @@ class StlContainerView<Element[N]> {
|
|||
// This specialization is used when RawContainer is a native array
|
||||
// represented as a (pointer, size) tuple.
|
||||
template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
class [[nodiscard]] StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef typename std::remove_const<
|
||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||
|
|
@ -419,7 +439,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
|||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
||||
auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
|
||||
-> decltype(std::forward<F>(f)(
|
||||
std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||
|
|
@ -429,11 +449,11 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
|||
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<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
std::make_index_sequence<
|
||||
std::tuple_size_v<std::remove_reference_t<Tuple>>>())) {
|
||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>());
|
||||
std::make_index_sequence<
|
||||
std::tuple_size_v<std::remove_reference_t<Tuple>>>());
|
||||
}
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
|
|
@ -464,15 +484,12 @@ struct Function<R(Args...)> {
|
|||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
|
||||
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
||||
// when std::tuple_element is used.
|
||||
// See: https://github.com/google/googletest/issues/3931
|
||||
// Can be replaced with std::tuple_element_t in C++14.
|
||||
template <size_t I, typename T>
|
||||
using TupleElement = typename std::tuple_element<I, T>::type;
|
||||
using TupleElement = std::tuple_element_t<I, T>;
|
||||
|
||||
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -56,7 +57,7 @@
|
|||
#include "gmock/internal/custom/gmock-port.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#endif
|
||||
|
|
@ -73,7 +74,7 @@
|
|||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Pick a command line flags implementation.
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
|
|
@ -85,17 +86,17 @@
|
|||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
|
||||
|
||||
#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
|
||||
#define GMOCK_FLAG_SET(name, value) \
|
||||
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
|
||||
|
||||
#else // GTEST_HAS_ABSL
|
||||
#else // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
|
|
@ -134,6 +135,6 @@
|
|||
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#endif // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
|
|
|||
|
|
@ -25,16 +25,18 @@
|
|||
// GMOCK_PP_NARG(x, y) => 2
|
||||
// GMOCK_PP_NARG(PAIR) => 2
|
||||
//
|
||||
// Requires: the number of arguments after expansion is at most 15.
|
||||
#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))
|
||||
// Requires: the number of arguments after expansion is at most 31.
|
||||
#define GMOCK_PP_NARG(...) \
|
||||
GMOCK_PP_INTERNAL_32ND((__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, \
|
||||
21, 20, 19, 18, 17, 16, 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_16TH( \
|
||||
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
|
||||
// returns 0. Requires no more than 31 unprotected commas.
|
||||
#define GMOCK_PP_HAS_COMMA(...) \
|
||||
GMOCK_PP_INTERNAL_32ND((__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
1, 1, 1, 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((__VA_ARGS__, unusedArg))
|
||||
|
|
@ -51,7 +53,7 @@
|
|||
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
|
||||
// evaluates to `0`.
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// Requires: * the number of arguments after expansion is at most 31.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
//
|
||||
|
|
@ -104,7 +106,7 @@
|
|||
// GMOCK_PP_NARG0(x, y) => 2
|
||||
// GMOCK_PP_NARG0(PAIR) => 2
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// Requires: * the number of arguments after expansion is at most 31.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
#define GMOCK_PP_NARG0(...) \
|
||||
|
|
@ -127,7 +129,7 @@
|
|||
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
|
||||
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
|
||||
// Requires: * |_Macro| can be called with 3 arguments.
|
||||
// * |_Tuple| expansion has no more than 15 elements.
|
||||
// * |_Tuple| expansion has no more than 31 elements.
|
||||
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
|
||||
(0, _Macro, _Data, _Tuple)
|
||||
|
|
@ -135,20 +137,21 @@
|
|||
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
|
||||
// Empty if _K = 0.
|
||||
// Requires: * |_Macro| can be called with 3 arguments.
|
||||
// * |_K| literal between 0 and 15
|
||||
// * |_K| literal between 0 and 31
|
||||
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
|
||||
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
|
||||
|
||||
// Increments the argument, requires the argument to be between 0 and 15.
|
||||
// Increments the argument, requires the argument to be between 0 and 31.
|
||||
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
|
||||
|
||||
// Returns comma if _i != 0. Requires _i to be between 0 and 15.
|
||||
// Returns comma if _i != 0. Requires _i to be between 0 and 31.
|
||||
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
|
||||
|
||||
// Internal details follow. Do not use any of these symbols outside of this
|
||||
// file or we will break your code.
|
||||
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
|
||||
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE \
|
||||
(, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , )
|
||||
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
|
||||
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
|
||||
|
|
@ -164,12 +167,13 @@
|
|||
// 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_32ND( \
|
||||
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
|
||||
_17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \
|
||||
_32, ...) \
|
||||
_32
|
||||
#define GMOCK_PP_INTERNAL_32ND(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_32ND _Args)
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
|
||||
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
|
||||
|
|
@ -198,6 +202,22 @@
|
|||
#define GMOCK_PP_INTERNAL_INC_13 14
|
||||
#define GMOCK_PP_INTERNAL_INC_14 15
|
||||
#define GMOCK_PP_INTERNAL_INC_15 16
|
||||
#define GMOCK_PP_INTERNAL_INC_16 17
|
||||
#define GMOCK_PP_INTERNAL_INC_17 18
|
||||
#define GMOCK_PP_INTERNAL_INC_18 19
|
||||
#define GMOCK_PP_INTERNAL_INC_19 20
|
||||
#define GMOCK_PP_INTERNAL_INC_20 21
|
||||
#define GMOCK_PP_INTERNAL_INC_21 22
|
||||
#define GMOCK_PP_INTERNAL_INC_22 23
|
||||
#define GMOCK_PP_INTERNAL_INC_23 24
|
||||
#define GMOCK_PP_INTERNAL_INC_24 25
|
||||
#define GMOCK_PP_INTERNAL_INC_25 26
|
||||
#define GMOCK_PP_INTERNAL_INC_26 27
|
||||
#define GMOCK_PP_INTERNAL_INC_27 28
|
||||
#define GMOCK_PP_INTERNAL_INC_28 29
|
||||
#define GMOCK_PP_INTERNAL_INC_29 30
|
||||
#define GMOCK_PP_INTERNAL_INC_30 31
|
||||
#define GMOCK_PP_INTERNAL_INC_31 32
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_0
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
|
||||
|
|
@ -214,6 +234,22 @@
|
|||
#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_16 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_17 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_18 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_19 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_20 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_21 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_22 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_23 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_24 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_25 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_26 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_27 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_28 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_29 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_30 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_31 ,
|
||||
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
|
||||
_Macro(_i, _Data, _element)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
|
||||
|
|
@ -275,5 +311,69 @@
|
|||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_16(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_17(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_16(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_18(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_17(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_19(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_18(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_20(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_19(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_21(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_20(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_22(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_21(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_23(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_22(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_24(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_23(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_25(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_24(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_26(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_25(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_27(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_26(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_28(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_27(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_29(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_28(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_30(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_29(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_31(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_30(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue