mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[upstream_utils] Update googletest to HEAD (#8755)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
This commit is contained in:
238
thirdparty/googletest/include/gmock/gmock-actions.h
vendored
238
thirdparty/googletest/include/gmock/gmock-actions.h
vendored
@@ -135,6 +135,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <exception>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -175,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
|
|||||||
static T Get() {
|
static T Get() {
|
||||||
Assert(false, __FILE__, __LINE__,
|
Assert(false, __FILE__, __LINE__,
|
||||||
"Default action undefined for the function return type.");
|
"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
|
// The above statement will never be reached, but is required in
|
||||||
// order for this function to compile.
|
// 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
|
// other type T, the built-in default T value is undefined, and the
|
||||||
// function will abort the process.
|
// function will abort the process.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class BuiltInDefaultValue {
|
class [[nodiscard]] BuiltInDefaultValue {
|
||||||
public:
|
public:
|
||||||
// This function returns true if and only if type T has a built-in default
|
// This function returns true if and only if type T has a built-in default
|
||||||
// value.
|
// value.
|
||||||
@@ -204,7 +211,7 @@ class BuiltInDefaultValue {
|
|||||||
// This partial specialization says that we use the same built-in
|
// This partial specialization says that we use the same built-in
|
||||||
// default value for T and const T.
|
// default value for T and const T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class BuiltInDefaultValue<const T> {
|
class [[nodiscard]] BuiltInDefaultValue<const T> {
|
||||||
public:
|
public:
|
||||||
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
||||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||||
@@ -213,7 +220,7 @@ class BuiltInDefaultValue<const T> {
|
|||||||
// This partial specialization defines the default values for pointer
|
// This partial specialization defines the default values for pointer
|
||||||
// types.
|
// types.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class BuiltInDefaultValue<T*> {
|
class [[nodiscard]] BuiltInDefaultValue<T*> {
|
||||||
public:
|
public:
|
||||||
static bool Exists() { return true; }
|
static bool Exists() { return true; }
|
||||||
static T* Get() { return nullptr; }
|
static T* Get() { return nullptr; }
|
||||||
@@ -376,7 +383,7 @@ typename std::add_const<T>::type& as_const(T& t) {
|
|||||||
|
|
||||||
// Specialized for function types below.
|
// Specialized for function types below.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class OnceAction;
|
class [[nodiscard]] OnceAction;
|
||||||
|
|
||||||
// An action that can only be used once.
|
// An action that can only be used once.
|
||||||
//
|
//
|
||||||
@@ -414,7 +421,7 @@ class OnceAction;
|
|||||||
// A less-contrived example would be an action that returns an arbitrary type,
|
// 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.
|
// whose &&-qualified call operator is capable of dealing with move-only types.
|
||||||
template <typename Result, typename... Args>
|
template <typename Result, typename... Args>
|
||||||
class OnceAction<Result(Args...)> final {
|
class [[nodiscard]] OnceAction<Result(Args...)> final {
|
||||||
private:
|
private:
|
||||||
// True iff we can use the given callable type (or lvalue reference) directly
|
// True iff we can use the given callable type (or lvalue reference) directly
|
||||||
// via StdFunctionAdaptor.
|
// via StdFunctionAdaptor.
|
||||||
@@ -567,7 +574,7 @@ class OnceAction<Result(Args...)> final {
|
|||||||
// // Sets the default value for type T to be foo.
|
// // Sets the default value for type T to be foo.
|
||||||
// DefaultValue<T>::Set(foo);
|
// DefaultValue<T>::Set(foo);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class DefaultValue {
|
class [[nodiscard]] DefaultValue {
|
||||||
public:
|
public:
|
||||||
// Sets the default value for type T; requires T to be
|
// Sets the default value for type T; requires T to be
|
||||||
// copy-constructable and have a public destructor.
|
// copy-constructable and have a public destructor.
|
||||||
@@ -644,7 +651,7 @@ class DefaultValue {
|
|||||||
// This partial specialization allows a user to set default values for
|
// This partial specialization allows a user to set default values for
|
||||||
// reference types.
|
// reference types.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class DefaultValue<T&> {
|
class [[nodiscard]] DefaultValue<T&> {
|
||||||
public:
|
public:
|
||||||
// Sets the default value for type T&.
|
// Sets the default value for type T&.
|
||||||
static void Set(T& x) { // NOLINT
|
static void Set(T& x) { // NOLINT
|
||||||
@@ -678,7 +685,7 @@ class DefaultValue<T&> {
|
|||||||
// This specialization allows DefaultValue<void>::Get() to
|
// This specialization allows DefaultValue<void>::Get() to
|
||||||
// compile.
|
// compile.
|
||||||
template <>
|
template <>
|
||||||
class DefaultValue<void> {
|
class [[nodiscard]] DefaultValue<void> {
|
||||||
public:
|
public:
|
||||||
static bool Exists() { return true; }
|
static bool Exists() { return true; }
|
||||||
static void Get() {}
|
static void Get() {}
|
||||||
@@ -694,7 +701,7 @@ T* DefaultValue<T&>::address_ = nullptr;
|
|||||||
|
|
||||||
// Implement this interface to define an action for function type F.
|
// Implement this interface to define an action for function type F.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class ActionInterface {
|
class [[nodiscard]] ActionInterface {
|
||||||
public:
|
public:
|
||||||
typedef typename internal::Function<F>::Result Result;
|
typedef typename internal::Function<F>::Result Result;
|
||||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
@@ -714,7 +721,7 @@ class ActionInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class Action;
|
class [[nodiscard]] Action;
|
||||||
|
|
||||||
// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)
|
// 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
|
// object that represents an action to be taken when a mock function of type
|
||||||
@@ -723,7 +730,7 @@ class Action;
|
|||||||
// can view an object implementing ActionInterface<F> as a concrete 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.
|
// (including its current state), and an Action<F> object as a handle to it.
|
||||||
template <typename R, typename... Args>
|
template <typename R, typename... Args>
|
||||||
class Action<R(Args...)> {
|
class [[nodiscard]] Action<R(Args...)> {
|
||||||
private:
|
private:
|
||||||
using F = R(Args...);
|
using F = R(Args...);
|
||||||
|
|
||||||
@@ -828,6 +835,10 @@ class Action<R(Args...)> {
|
|||||||
Result operator()(const InArgs&...) const {
|
Result operator()(const InArgs&...) const {
|
||||||
return function_impl();
|
return function_impl();
|
||||||
}
|
}
|
||||||
|
template <typename... InArgs>
|
||||||
|
Result operator()(const InArgs&...) {
|
||||||
|
return function_impl();
|
||||||
|
}
|
||||||
|
|
||||||
FunctionImpl function_impl;
|
FunctionImpl function_impl;
|
||||||
};
|
};
|
||||||
@@ -858,7 +869,7 @@ class Action<R(Args...)> {
|
|||||||
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
||||||
// complete examples.
|
// complete examples.
|
||||||
template <typename Impl>
|
template <typename Impl>
|
||||||
class PolymorphicAction {
|
class [[nodiscard]] PolymorphicAction {
|
||||||
public:
|
public:
|
||||||
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
||||||
|
|
||||||
@@ -918,7 +929,7 @@ struct ByMoveWrapper {
|
|||||||
|
|
||||||
// The general implementation of Return(R). Specializations follow below.
|
// The general implementation of Return(R). Specializations follow below.
|
||||||
template <typename R>
|
template <typename R>
|
||||||
class ReturnAction final {
|
class [[nodiscard]] ReturnAction final {
|
||||||
public:
|
public:
|
||||||
explicit ReturnAction(R value) : value_(std::move(value)) {}
|
explicit ReturnAction(R value) : value_(std::move(value)) {}
|
||||||
|
|
||||||
@@ -1084,7 +1095,7 @@ class ReturnAction final {
|
|||||||
// the const call operator, checking at runtime that it isn't called more than
|
// 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.
|
// once, since the user has declared their intent to do so by using ByMove.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ReturnAction<ByMoveWrapper<T>> final {
|
class [[nodiscard]] ReturnAction<ByMoveWrapper<T>> final {
|
||||||
public:
|
public:
|
||||||
explicit ReturnAction(ByMoveWrapper<T> wrapper)
|
explicit ReturnAction(ByMoveWrapper<T> wrapper)
|
||||||
: state_(new State(std::move(wrapper.payload))) {}
|
: state_(new State(std::move(wrapper.payload))) {}
|
||||||
@@ -1111,7 +1122,7 @@ class ReturnAction<ByMoveWrapper<T>> final {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Implements the ReturnNull() action.
|
// Implements the ReturnNull() action.
|
||||||
class ReturnNullAction {
|
class [[nodiscard]] ReturnNullAction {
|
||||||
public:
|
public:
|
||||||
// Allows ReturnNull() to be used in any pointer-returning function. In C++11
|
// Allows ReturnNull() to be used in any pointer-returning function. In C++11
|
||||||
// this is enforced by returning nullptr, and in non-C++11 by asserting a
|
// this is enforced by returning nullptr, and in non-C++11 by asserting a
|
||||||
@@ -1123,7 +1134,7 @@ class ReturnNullAction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Implements the Return() action.
|
// Implements the Return() action.
|
||||||
class ReturnVoidAction {
|
class [[nodiscard]] ReturnVoidAction {
|
||||||
public:
|
public:
|
||||||
// Allows Return() to be used in any void-returning function.
|
// Allows Return() to be used in any void-returning function.
|
||||||
template <typename Result, typename ArgumentTuple>
|
template <typename Result, typename ArgumentTuple>
|
||||||
@@ -1136,7 +1147,7 @@ class ReturnVoidAction {
|
|||||||
// in any function that returns a reference to the type of x,
|
// in any function that returns a reference to the type of x,
|
||||||
// regardless of the argument types.
|
// regardless of the argument types.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ReturnRefAction {
|
class [[nodiscard]] ReturnRefAction {
|
||||||
public:
|
public:
|
||||||
// Constructs a ReturnRefAction object from the reference to be returned.
|
// Constructs a ReturnRefAction object from the reference to be returned.
|
||||||
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
||||||
@@ -1177,7 +1188,7 @@ class ReturnRefAction {
|
|||||||
// used in any function that returns a reference to the type of x,
|
// used in any function that returns a reference to the type of x,
|
||||||
// regardless of the argument types.
|
// regardless of the argument types.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ReturnRefOfCopyAction {
|
class [[nodiscard]] ReturnRefOfCopyAction {
|
||||||
public:
|
public:
|
||||||
// Constructs a ReturnRefOfCopyAction object from the reference to
|
// Constructs a ReturnRefOfCopyAction object from the reference to
|
||||||
// be returned.
|
// be returned.
|
||||||
@@ -1218,7 +1229,7 @@ class ReturnRefOfCopyAction {
|
|||||||
// Implements the polymorphic ReturnRoundRobin(v) action, which can be
|
// Implements the polymorphic ReturnRoundRobin(v) action, which can be
|
||||||
// used in any function that returns the element_type of v.
|
// used in any function that returns the element_type of v.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ReturnRoundRobinAction {
|
class [[nodiscard]] ReturnRoundRobinAction {
|
||||||
public:
|
public:
|
||||||
explicit ReturnRoundRobinAction(std::vector<T> values) {
|
explicit ReturnRoundRobinAction(std::vector<T> values) {
|
||||||
GTEST_CHECK_(!values.empty())
|
GTEST_CHECK_(!values.empty())
|
||||||
@@ -1246,7 +1257,7 @@ class ReturnRoundRobinAction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Implements the polymorphic DoDefault() action.
|
// Implements the polymorphic DoDefault() action.
|
||||||
class DoDefaultAction {
|
class [[nodiscard]] DoDefaultAction {
|
||||||
public:
|
public:
|
||||||
// This template type conversion operator allows DoDefault() to be
|
// This template type conversion operator allows DoDefault() to be
|
||||||
// used in any function.
|
// used in any function.
|
||||||
@@ -1259,7 +1270,7 @@ class DoDefaultAction {
|
|||||||
// Implements the Assign action to set a given pointer referent to a
|
// Implements the Assign action to set a given pointer referent to a
|
||||||
// particular value.
|
// particular value.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
class AssignAction {
|
class [[nodiscard]] AssignAction {
|
||||||
public:
|
public:
|
||||||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
||||||
|
|
||||||
@@ -1278,7 +1289,7 @@ class AssignAction {
|
|||||||
// Implements the SetErrnoAndReturn action to simulate return from
|
// Implements the SetErrnoAndReturn action to simulate return from
|
||||||
// various system calls and libc functions.
|
// various system calls and libc functions.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SetErrnoAndReturnAction {
|
class [[nodiscard]] SetErrnoAndReturnAction {
|
||||||
public:
|
public:
|
||||||
SetErrnoAndReturnAction(int errno_value, T result)
|
SetErrnoAndReturnAction(int errno_value, T result)
|
||||||
: errno_(errno_value), result_(result) {}
|
: errno_(errno_value), result_(result) {}
|
||||||
@@ -1386,7 +1397,7 @@ class IgnoreResultAction {
|
|||||||
|
|
||||||
void Perform(const ArgumentTuple& args) override {
|
void Perform(const ArgumentTuple& args) override {
|
||||||
// Performs the action and ignores its result.
|
// Performs the action and ignores its result.
|
||||||
action_.Perform(args);
|
(void)action_.Perform(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1444,6 +1455,30 @@ struct WithArgsAction {
|
|||||||
return OA{std::move(inner_action)};
|
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 <
|
template <
|
||||||
typename R, typename... Args,
|
typename R, typename... Args,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
@@ -1468,11 +1503,11 @@ struct WithArgsAction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Actions>
|
template <typename... Actions>
|
||||||
class DoAllAction;
|
class [[nodiscard]] DoAllAction;
|
||||||
|
|
||||||
// Base case: only a single action.
|
// Base case: only a single action.
|
||||||
template <typename FinalAction>
|
template <typename FinalAction>
|
||||||
class DoAllAction<FinalAction> {
|
class [[nodiscard]] DoAllAction<FinalAction> {
|
||||||
public:
|
public:
|
||||||
struct UserConstructorTag {};
|
struct UserConstructorTag {};
|
||||||
|
|
||||||
@@ -1486,6 +1521,7 @@ class DoAllAction<FinalAction> {
|
|||||||
// providing a call operator because even with a particular set of arguments
|
// providing a call operator because even with a particular set of arguments
|
||||||
// they don't have a fixed return type.
|
// they don't have a fixed return type.
|
||||||
|
|
||||||
|
// We support conversion to OnceAction whenever the sub-action does.
|
||||||
template <typename R, typename... Args,
|
template <typename R, typename... Args,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
|
std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
|
||||||
@@ -1494,6 +1530,21 @@ class DoAllAction<FinalAction> {
|
|||||||
return std::move(final_action_);
|
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 <
|
template <
|
||||||
typename R, typename... Args,
|
typename R, typename... Args,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
@@ -1510,7 +1561,7 @@ class DoAllAction<FinalAction> {
|
|||||||
// Recursive case: support N actions by calling the initial action and then
|
// Recursive case: support N actions by calling the initial action and then
|
||||||
// calling through to the base class containing N-1 actions.
|
// calling through to the base class containing N-1 actions.
|
||||||
template <typename InitialAction, typename... OtherActions>
|
template <typename InitialAction, typename... OtherActions>
|
||||||
class DoAllAction<InitialAction, OtherActions...>
|
class [[nodiscard]] DoAllAction<InitialAction, OtherActions...>
|
||||||
: private DoAllAction<OtherActions...> {
|
: private DoAllAction<OtherActions...> {
|
||||||
private:
|
private:
|
||||||
using Base = DoAllAction<OtherActions...>;
|
using Base = DoAllAction<OtherActions...>;
|
||||||
@@ -1573,16 +1624,16 @@ class DoAllAction<InitialAction, OtherActions...>
|
|||||||
: Base({}, std::forward<U>(other_actions)...),
|
: Base({}, std::forward<U>(other_actions)...),
|
||||||
initial_action_(std::forward<T>(initial_action)) {}
|
initial_action_(std::forward<T>(initial_action)) {}
|
||||||
|
|
||||||
template <typename R, typename... Args,
|
// We support conversion to OnceAction whenever both the initial action and
|
||||||
typename std::enable_if<
|
// the rest support conversion to OnceAction.
|
||||||
conjunction<
|
template <
|
||||||
// Both the initial action and the rest must support
|
typename R, typename... Args,
|
||||||
// conversion to OnceAction.
|
typename std::enable_if<
|
||||||
std::is_convertible<
|
conjunction<std::is_convertible<
|
||||||
InitialAction,
|
InitialAction,
|
||||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||||
// Return an action that first calls the initial action with arguments
|
// Return an action that first calls the initial action with arguments
|
||||||
// filtered through InitialActionArgType, then forwards arguments directly
|
// filtered through InitialActionArgType, then forwards arguments directly
|
||||||
@@ -1605,12 +1656,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 <
|
template <
|
||||||
typename R, typename... Args,
|
typename R, typename... Args,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
conjunction<
|
conjunction<
|
||||||
// Both the initial action and the rest must support conversion to
|
|
||||||
// Action.
|
|
||||||
std::is_convertible<const InitialAction&,
|
std::is_convertible<const InitialAction&,
|
||||||
Action<void(InitialActionArgType<Args>...)>>,
|
Action<void(InitialActionArgType<Args>...)>>,
|
||||||
std::is_convertible<const Base&, Action<R(Args...)>>>::value,
|
std::is_convertible<const Base&, Action<R(Args...)>>>::value,
|
||||||
@@ -1674,6 +1747,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>
|
template <size_t k, typename Ptr>
|
||||||
struct SaveArgPointeeAction {
|
struct SaveArgPointeeAction {
|
||||||
Ptr pointer;
|
Ptr pointer;
|
||||||
@@ -1713,11 +1796,24 @@ struct SetArrayArgumentAction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <size_t k>
|
template <size_t k>
|
||||||
struct DeleteArgAction {
|
class [[nodiscard]] DeleteArgAction {
|
||||||
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void operator()(const Args&... args) const {
|
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>
|
template <typename Ptr>
|
||||||
@@ -1740,6 +1836,13 @@ struct ThrowAction {
|
|||||||
return [copy](Args...) -> R { throw copy; };
|
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
|
#endif // GTEST_HAS_EXCEPTIONS
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
@@ -1776,6 +1879,13 @@ struct ThrowAction {
|
|||||||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||||
typedef internal::IgnoredValue Unused;
|
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
|
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||||
// each invocation. All but the last action will have a readonly view of the
|
// each invocation. All but the last action will have a readonly view of the
|
||||||
// arguments.
|
// arguments.
|
||||||
@@ -1941,10 +2051,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
|
|||||||
// Various overloads for Invoke().
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
// Legacy function.
|
// Legacy function.
|
||||||
// Actions can now be implicitly constructed from callables. No need to create
|
|
||||||
// wrapper objects.
|
|
||||||
// This function exists for backwards compatibility.
|
// This function exists for backwards compatibility.
|
||||||
template <typename FunctionImpl>
|
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) {
|
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||||
return std::forward<FunctionImpl>(function_impl);
|
return std::forward<FunctionImpl>(function_impl);
|
||||||
}
|
}
|
||||||
@@ -2017,6 +2128,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
|||||||
return {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
|
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||||
template <size_t k, typename Ptr>
|
template <size_t k, typename Ptr>
|
||||||
@@ -2056,13 +2174,23 @@ internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
|
|||||||
return {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
|
#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>
|
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)};
|
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
|
#endif // GTEST_HAS_EXCEPTIONS
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@@ -2111,13 +2239,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
|
|||||||
R operator()(Args&&... arg) const {
|
R operator()(Args&&... arg) const {
|
||||||
static constexpr size_t kMaxArgs =
|
static constexpr size_t kMaxArgs =
|
||||||
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
|
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
|
||||||
return Apply(MakeIndexSequence<kMaxArgs>{},
|
return Apply(std::make_index_sequence<kMaxArgs>{},
|
||||||
MakeIndexSequence<10 - kMaxArgs>{},
|
std::make_index_sequence<10 - kMaxArgs>{},
|
||||||
args_type{std::forward<Args>(arg)...});
|
args_type{std::forward<Args>(arg)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t... arg_id, std::size_t... excess_id>
|
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 {
|
const args_type& args) const {
|
||||||
// Impl need not be specific to the signature of action being implemented;
|
// Impl need not be specific to the signature of action being implemented;
|
||||||
// only the implementing function body needs to have all of the specific
|
// only the implementing function body needs to have all of the specific
|
||||||
@@ -2150,9 +2278,9 @@ template <typename F, typename Impl>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
||||||
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
|
, [[maybe_unused]] const arg##i##_type& arg##i
|
||||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
|
[[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
|
||||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
||||||
@@ -2217,8 +2345,8 @@ template <typename F, typename Impl>
|
|||||||
std::shared_ptr<const gmock_Impl> impl_; \
|
std::shared_ptr<const gmock_Impl> impl_; \
|
||||||
}; \
|
}; \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
[[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \
|
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
||||||
@@ -2253,7 +2381,7 @@ template <typename F, typename Impl>
|
|||||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
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(); } \
|
inline name##Action name() { return name##Action(); } \
|
||||||
template <typename function_type, typename return_type, typename args_type, \
|
template <typename function_type, typename return_type, typename args_type, \
|
||||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace testing {
|
|||||||
// management as Cardinality objects can now be copied like plain values.
|
// management as Cardinality objects can now be copied like plain values.
|
||||||
|
|
||||||
// The implementation of a cardinality.
|
// The implementation of a cardinality.
|
||||||
class CardinalityInterface {
|
class [[nodiscard]] CardinalityInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~CardinalityInterface() = default;
|
virtual ~CardinalityInterface() = default;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ class CardinalityInterface {
|
|||||||
// object that specifies how many times a mock function is expected to
|
// object that specifies how many times a mock function is expected to
|
||||||
// be called. The implementation of Cardinality is just a std::shared_ptr
|
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||||
// to const CardinalityInterface. Don't inherit from Cardinality!
|
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||||
class GTEST_API_ Cardinality {
|
class GTEST_API_ [[nodiscard]] Cardinality {
|
||||||
public:
|
public:
|
||||||
// Constructs a null cardinality. Needed for storing Cardinality
|
// Constructs a null cardinality. Needed for storing Cardinality
|
||||||
// objects in STL containers.
|
// objects in STL containers.
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <type_traits> // IWYU pragma: keep
|
#include <type_traits> // IWYU pragma: keep
|
||||||
#include <utility> // 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));
|
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]) {
|
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||||
return N <= M && internal::PrefixOf(prefix, str);
|
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]) {
|
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||||
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
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]) {
|
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||||
return N == M && internal::PrefixOf(a, b);
|
return N == M && internal::PrefixOf(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <size_t N>
|
||||||
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||||
return internal::Equals("const", spec) ||
|
return internal::Equals("const", spec) ||
|
||||||
internal::Equals("override", spec) ||
|
internal::Equals("override", spec) ||
|
||||||
|
|||||||
858
thirdparty/googletest/include/gmock/gmock-matchers.h
vendored
858
thirdparty/googletest/include/gmock/gmock-matchers.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -521,9 +521,8 @@
|
|||||||
GMOCK_INTERNAL_DECL_##value_params) \
|
GMOCK_INTERNAL_DECL_##value_params) \
|
||||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
= default; \
|
= default; \
|
||||||
, \
|
, : impl_(std::make_shared<gmock_Impl>( \
|
||||||
: impl_(std::make_shared<gmock_Impl>( \
|
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||||
##value_params \
|
##value_params \
|
||||||
@@ -551,10 +550,10 @@
|
|||||||
}; \
|
}; \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
GMOCK_ACTION_CLASS_( \
|
[[nodiscard]] GMOCK_ACTION_CLASS_( \
|
||||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_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 \
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
inline GMOCK_ACTION_CLASS_( \
|
inline GMOCK_ACTION_CLASS_( \
|
||||||
@@ -592,21 +591,23 @@ namespace internal {
|
|||||||
// Overloads for other custom-callables are provided in the
|
// Overloads for other custom-callables are provided in the
|
||||||
// internal/custom/gmock-generated-actions.h header.
|
// internal/custom/gmock-generated-actions.h header.
|
||||||
template <typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
|
auto InvokeArgument(F &&f,
|
||||||
return f(args...);
|
Args... args) -> decltype(std::forward<F>(f)(args...)) {
|
||||||
|
return std::forward<F>(f)(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t index, typename... Params>
|
template <std::size_t index, typename... Params>
|
||||||
struct InvokeArgumentAction {
|
struct InvokeArgumentAction {
|
||||||
template <typename... Args,
|
template <typename... Args,
|
||||||
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
||||||
auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
|
auto operator()(Args &&...args) const
|
||||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
-> decltype(internal::InvokeArgument(
|
||||||
std::declval<const Params &>()...)) {
|
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||||
|
std::declval<const Params &>()...)) {
|
||||||
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
|
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
return params.Apply([&](const Params &...unpacked_params) {
|
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(
|
return internal::InvokeArgument(
|
||||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace internal {
|
|||||||
// Implements the polymorphic IsEmpty matcher, which
|
// Implements the polymorphic IsEmpty matcher, which
|
||||||
// can be used as a Matcher<T> as long as T is either a container that defines
|
// 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.
|
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
|
||||||
class IsEmptyMatcher {
|
class [[nodiscard]] IsEmptyMatcher {
|
||||||
public:
|
public:
|
||||||
// Matches anything that defines empty() and size().
|
// Matches anything that defines empty() and size().
|
||||||
template <typename MatcheeContainerType>
|
template <typename MatcheeContainerType>
|
||||||
|
|||||||
@@ -71,11 +71,11 @@
|
|||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class NiceMock;
|
class [[nodiscard]] NiceMock;
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class NaggyMock;
|
class [[nodiscard]] NaggyMock;
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class StrictMock;
|
class [[nodiscard]] StrictMock;
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -108,7 +108,7 @@ constexpr bool HasStrictnessModifier() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Base>
|
template <typename Base>
|
||||||
class NiceMockImpl {
|
class [[nodiscard]] NiceMockImpl {
|
||||||
public:
|
public:
|
||||||
NiceMockImpl() {
|
NiceMockImpl() {
|
||||||
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||||
@@ -120,7 +120,7 @@ class NiceMockImpl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Base>
|
template <typename Base>
|
||||||
class NaggyMockImpl {
|
class [[nodiscard]] NaggyMockImpl {
|
||||||
public:
|
public:
|
||||||
NaggyMockImpl() {
|
NaggyMockImpl() {
|
||||||
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||||
@@ -132,7 +132,7 @@ class NaggyMockImpl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Base>
|
template <typename Base>
|
||||||
class StrictMockImpl {
|
class [[nodiscard]] StrictMockImpl {
|
||||||
public:
|
public:
|
||||||
StrictMockImpl() {
|
StrictMockImpl() {
|
||||||
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||||
@@ -146,7 +146,7 @@ class StrictMockImpl {
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||||
: private internal::NiceMockImpl<MockClass>,
|
: private internal::NiceMockImpl<MockClass>,
|
||||||
public MockClass {
|
public MockClass {
|
||||||
public:
|
public:
|
||||||
@@ -187,7 +187,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||||
: private internal::NaggyMockImpl<MockClass>,
|
: private internal::NaggyMockImpl<MockClass>,
|
||||||
public MockClass {
|
public MockClass {
|
||||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||||
@@ -229,7 +229,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||||
: private internal::StrictMockImpl<MockClass>,
|
: private internal::StrictMockImpl<MockClass>,
|
||||||
public MockClass {
|
public MockClass {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -868,7 +868,7 @@ class GTEST_API_ ExpectationBase {
|
|||||||
Clause last_clause_;
|
Clause last_clause_;
|
||||||
mutable bool action_count_checked_; // Under mutex_.
|
mutable bool action_count_checked_; // Under mutex_.
|
||||||
mutable Mutex mutex_; // Protects action_count_checked_.
|
mutable Mutex mutex_; // Protects action_count_checked_.
|
||||||
}; // class ExpectationBase
|
}; // class ExpectationBase
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class TypedExpectation;
|
class TypedExpectation;
|
||||||
@@ -1292,10 +1292,10 @@ class MockSpec {
|
|||||||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||||
|
|
||||||
// Adds a new default action spec to the function mocker and returns
|
// Adds a new default action spec to the function mocker and returns
|
||||||
// the newly created spec.
|
// the newly created spec. .WillByDefault() must be called on the returned
|
||||||
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
|
// object.
|
||||||
int line, const char* obj,
|
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
|
||||||
const char* call) {
|
const char* file, int line, const char* obj, const char* call) {
|
||||||
LogWithLocation(internal::kInfo, file, line,
|
LogWithLocation(internal::kInfo, file, line,
|
||||||
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
||||||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
||||||
@@ -1467,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
// function have been satisfied. If not, it will report Google Test
|
// function have been satisfied. If not, it will report Google Test
|
||||||
// non-fatal failures for the violations.
|
// non-fatal failures for the violations.
|
||||||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
VerifyAndClearExpectationsLocked();
|
VerifyAndClearExpectationsLocked();
|
||||||
Mock::UnregisterLocked(this);
|
Mock::UnregisterLocked(this);
|
||||||
ClearDefaultActionsLocked();
|
ClearDefaultActionsLocked();
|
||||||
@@ -1530,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
UntypedOnCallSpecs specs_to_delete;
|
UntypedOnCallSpecs specs_to_delete;
|
||||||
untyped_on_call_specs_.swap(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();
|
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
||||||
it != specs_to_delete.end(); ++it) {
|
it != specs_to_delete.end(); ++it) {
|
||||||
delete static_cast<const OnCallSpec<F>*>(*it);
|
delete static_cast<const OnCallSpec<F>*>(*it);
|
||||||
@@ -1538,7 +1538,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
|
|
||||||
// Lock the mutex again, since the caller expects it to be locked when we
|
// Lock the mutex again, since the caller expects it to be locked when we
|
||||||
// return.
|
// return.
|
||||||
g_gmock_mutex.Lock();
|
g_gmock_mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the result of invoking this mock function with the given
|
// Returns the result of invoking this mock function with the given
|
||||||
@@ -1646,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
const ArgumentTuple& args =
|
const ArgumentTuple& args =
|
||||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||||
if (exp == nullptr) { // A match wasn't found.
|
if (exp == nullptr) { // A match wasn't found.
|
||||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||||
@@ -1838,9 +1838,8 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
|||||||
// Doing so slows down compilation dramatically because the *constructor* of
|
// Doing so slows down compilation dramatically because the *constructor* of
|
||||||
// std::function<T> is re-instantiated with different template
|
// std::function<T> is re-instantiated with different template
|
||||||
// parameters each time.
|
// parameters each time.
|
||||||
const UninterestingCallCleanupHandler report_uninteresting_call = {
|
const UninterestingCallCleanupHandler report_uninteresting_call = {reaction,
|
||||||
reaction, ss
|
ss};
|
||||||
};
|
|
||||||
|
|
||||||
return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
|
return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
|
||||||
}
|
}
|
||||||
@@ -1890,8 +1889,7 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
|||||||
// std::function<T> is re-instantiated with different template
|
// std::function<T> is re-instantiated with different template
|
||||||
// parameters each time.
|
// parameters each time.
|
||||||
const FailureCleanupHandler handle_failures = {
|
const FailureCleanupHandler handle_failures = {
|
||||||
ss, why, loc, untyped_expectation, found, is_excessive
|
ss, why, loc, untyped_expectation, found, is_excessive};
|
||||||
};
|
|
||||||
|
|
||||||
return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
|
return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
|
||||||
ss);
|
ss);
|
||||||
@@ -2134,9 +2132,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|||||||
// second argument is an internal type derived from the method signature. The
|
// 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
|
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
||||||
// is how we block callers from setting expectations on overloaded methods.
|
// is how we block callers from setting expectations on overloaded methods.
|
||||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
|
((mock_expr).gmock_##call)(::testing::internal::WithoutMatchers::Get(), \
|
||||||
nullptr) \
|
nullptr) \
|
||||||
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
||||||
|
|
||||||
#define ON_CALL(obj, call) \
|
#define ON_CALL(obj, call) \
|
||||||
|
|||||||
15
thirdparty/googletest/include/gmock/gmock.h
vendored
15
thirdparty/googletest/include/gmock/gmock.h
vendored
@@ -53,13 +53,14 @@
|
|||||||
//
|
//
|
||||||
// where all clauses are optional and WillOnce() can be repeated.
|
// where all clauses are optional and WillOnce() can be repeated.
|
||||||
|
|
||||||
#include "gmock/gmock-actions.h"
|
#include "gmock/gmock-actions.h" // IWYU pragma: export
|
||||||
#include "gmock/gmock-cardinalities.h"
|
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
|
||||||
#include "gmock/gmock-function-mocker.h"
|
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
|
||||||
#include "gmock/gmock-matchers.h"
|
#include "gmock/gmock-matchers.h" // IWYU pragma: export
|
||||||
#include "gmock/gmock-more-actions.h"
|
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
|
||||||
#include "gmock/gmock-more-matchers.h"
|
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
|
||||||
#include "gmock/gmock-nice-strict.h"
|
#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-internal-utils.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,11 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
@@ -219,7 +221,7 @@ using LosslessArithmeticConvertible =
|
|||||||
|
|
||||||
// This interface knows how to report a Google Mock failure (either
|
// This interface knows how to report a Google Mock failure (either
|
||||||
// non-fatal or fatal).
|
// non-fatal or fatal).
|
||||||
class FailureReporterInterface {
|
class [[nodiscard]] FailureReporterInterface {
|
||||||
public:
|
public:
|
||||||
// The type of a failure (either non-fatal or fatal).
|
// The type of a failure (either non-fatal or fatal).
|
||||||
enum FailureType { kNonfatal, kFatal };
|
enum FailureType { kNonfatal, kFatal };
|
||||||
@@ -295,14 +297,13 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||||||
//
|
//
|
||||||
// ON_CALL(mock, Method({}, nullptr))...
|
// ON_CALL(mock, Method({}, nullptr))...
|
||||||
//
|
//
|
||||||
class WithoutMatchers {
|
class [[nodiscard]] WithoutMatchers {
|
||||||
private:
|
private:
|
||||||
WithoutMatchers() {}
|
WithoutMatchers() = default;
|
||||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
public:
|
||||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
GTEST_API_ static WithoutMatchers Get();
|
||||||
|
};
|
||||||
|
|
||||||
// Invalid<T>() is usable as an expression of type T, but will terminate
|
// 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
|
// the program with an assertion failure if actually run. This is useful
|
||||||
@@ -322,6 +323,24 @@ inline T Invalid() {
|
|||||||
#endif
|
#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
|
// Given a raw type (i.e. having no top-level reference or const
|
||||||
// modifier) RawContainer that's either an STL-style container or a
|
// modifier) RawContainer that's either an STL-style container or a
|
||||||
// native array, class StlContainerView<RawContainer> has the
|
// native array, class StlContainerView<RawContainer> has the
|
||||||
@@ -339,7 +358,7 @@ inline T Invalid() {
|
|||||||
// This generic version is used when RawContainer itself is already an
|
// This generic version is used when RawContainer itself is already an
|
||||||
// STL-style container.
|
// STL-style container.
|
||||||
template <class RawContainer>
|
template <class RawContainer>
|
||||||
class StlContainerView {
|
class [[nodiscard]] StlContainerView {
|
||||||
public:
|
public:
|
||||||
typedef RawContainer type;
|
typedef RawContainer type;
|
||||||
typedef const type& const_reference;
|
typedef const type& const_reference;
|
||||||
@@ -354,7 +373,7 @@ class StlContainerView {
|
|||||||
|
|
||||||
// This specialization is used when RawContainer is a native array type.
|
// This specialization is used when RawContainer is a native array type.
|
||||||
template <typename Element, size_t N>
|
template <typename Element, size_t N>
|
||||||
class StlContainerView<Element[N]> {
|
class [[nodiscard]] StlContainerView<Element[N]> {
|
||||||
public:
|
public:
|
||||||
typedef typename std::remove_const<Element>::type RawElement;
|
typedef typename std::remove_const<Element>::type RawElement;
|
||||||
typedef internal::NativeArray<RawElement> type;
|
typedef internal::NativeArray<RawElement> type;
|
||||||
@@ -378,7 +397,7 @@ class StlContainerView<Element[N]> {
|
|||||||
// This specialization is used when RawContainer is a native array
|
// This specialization is used when RawContainer is a native array
|
||||||
// represented as a (pointer, size) tuple.
|
// represented as a (pointer, size) tuple.
|
||||||
template <typename ElementPointer, typename Size>
|
template <typename ElementPointer, typename Size>
|
||||||
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
class [[nodiscard]] StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||||
public:
|
public:
|
||||||
typedef typename std::remove_const<
|
typedef typename std::remove_const<
|
||||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||||
@@ -420,7 +439,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
|||||||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||||
|
|
||||||
template <typename F, typename Tuple, size_t... Idx>
|
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)(
|
-> decltype(std::forward<F>(f)(
|
||||||
std::get<Idx>(std::forward<Tuple>(args))...)) {
|
std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||||
@@ -428,12 +447,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
|||||||
|
|
||||||
// Apply the function to a tuple of arguments.
|
// Apply the function to a tuple of arguments.
|
||||||
template <typename F, typename Tuple>
|
template <typename F, typename Tuple>
|
||||||
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
|
auto Apply(F&& f, Tuple&& args)
|
||||||
std::forward<F>(f), std::forward<Tuple>(args),
|
-> decltype(ApplyImpl(
|
||||||
MakeIndexSequence<std::tuple_size<
|
std::forward<F>(f), std::forward<Tuple>(args),
|
||||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
std::make_index_sequence<std::tuple_size<
|
||||||
|
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||||
MakeIndexSequence<std::tuple_size<
|
std::make_index_sequence<std::tuple_size<
|
||||||
typename std::remove_reference<Tuple>::type>::value>());
|
typename std::remove_reference<Tuple>::type>::value>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,11 +485,6 @@ struct Function<R(Args...)> {
|
|||||||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
|
||||||
template <typename R, typename... Args>
|
|
||||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
||||||
// when std::tuple_element is used.
|
// when std::tuple_element is used.
|
||||||
// See: https://github.com/google/googletest/issues/3931
|
// See: https://github.com/google/googletest/issues/3931
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@
|
|||||||
#include "gmock/internal/custom/gmock-port.h"
|
#include "gmock/internal/custom/gmock-port.h"
|
||||||
#include "gtest/internal/gtest-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/declare.h"
|
||||||
#include "absl/flags/flag.h"
|
#include "absl/flags/flag.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -73,7 +74,7 @@
|
|||||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||||
|
|
||||||
// Pick a command line flags implementation.
|
// Pick a command line flags implementation.
|
||||||
#ifdef GTEST_HAS_ABSL
|
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||||
|
|
||||||
// Macros for defining flags.
|
// Macros for defining flags.
|
||||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||||
@@ -85,17 +86,17 @@
|
|||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
#define GMOCK_DECLARE_bool_(name) \
|
#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) \
|
#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) \
|
#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_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
|
||||||
#define GMOCK_FLAG_SET(name, value) \
|
#define GMOCK_FLAG_SET(name, value) \
|
||||||
(void)(::absl::SetFlag(&GMOCK_FLAG(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.
|
// Macros for defining flags.
|
||||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||||
@@ -134,6 +135,6 @@
|
|||||||
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||||
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
#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_
|
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
|
|||||||
@@ -130,7 +130,14 @@ namespace testing {
|
|||||||
// Expected: Foo() is even
|
// Expected: Foo() is even
|
||||||
// Actual: it's 5
|
// Actual: it's 5
|
||||||
//
|
//
|
||||||
class GTEST_API_ AssertionResult {
|
|
||||||
|
// Returned AssertionResult objects may not be ignored.
|
||||||
|
// Note: Disabled for SWIG as it doesn't parse attributes correctly.
|
||||||
|
#if !defined(SWIG)
|
||||||
|
class [[nodiscard]] AssertionResult;
|
||||||
|
#endif // !SWIG
|
||||||
|
|
||||||
|
class GTEST_API_ [[nodiscard]] AssertionResult {
|
||||||
public:
|
public:
|
||||||
// Copy constructor.
|
// Copy constructor.
|
||||||
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ GTEST_API_ bool InDeathTestChild();
|
|||||||
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||||
|
|
||||||
// Tests that an exit code describes a normal exit with a given exit code.
|
// Tests that an exit code describes a normal exit with a given exit code.
|
||||||
class GTEST_API_ ExitedWithCode {
|
class GTEST_API_ [[nodiscard]] ExitedWithCode {
|
||||||
public:
|
public:
|
||||||
explicit ExitedWithCode(int exit_code);
|
explicit ExitedWithCode(int exit_code);
|
||||||
ExitedWithCode(const ExitedWithCode&) = default;
|
ExitedWithCode(const ExitedWithCode&) = default;
|
||||||
@@ -206,7 +206,7 @@ class GTEST_API_ ExitedWithCode {
|
|||||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||||
// Tests that an exit code describes an exit due to termination by a
|
// Tests that an exit code describes an exit due to termination by a
|
||||||
// given signal.
|
// given signal.
|
||||||
class GTEST_API_ KilledBySignal {
|
class GTEST_API_ [[nodiscard]] KilledBySignal {
|
||||||
public:
|
public:
|
||||||
explicit KilledBySignal(int signum);
|
explicit KilledBySignal(int signum);
|
||||||
bool operator()(int exit_status) const;
|
bool operator()(int exit_status) const;
|
||||||
@@ -293,8 +293,8 @@ class GTEST_API_ KilledBySignal {
|
|||||||
// statement is compiled but not executed, to ensure that
|
// statement is compiled but not executed, to ensure that
|
||||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||||
// parameter if and only if EXPECT_DEATH compiles with it.
|
// parameter if and only if EXPECT_DEATH compiles with it.
|
||||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
// regex_or_matcher - A regex that a macro such as EXPECT_DEATH would use
|
||||||
// the output of statement. This parameter has to be
|
// to test the output of statement. This parameter has to be
|
||||||
// compiled but not evaluated by this macro, to ensure that
|
// compiled but not evaluated by this macro, to ensure that
|
||||||
// this macro only accepts expressions that a macro such as
|
// this macro only accepts expressions that a macro such as
|
||||||
// EXPECT_DEATH would accept.
|
// EXPECT_DEATH would accept.
|
||||||
@@ -311,13 +311,13 @@ class GTEST_API_ KilledBySignal {
|
|||||||
// statement unconditionally returns or throws. The Message constructor at
|
// statement unconditionally returns or throws. The Message constructor at
|
||||||
// the end allows the syntax of streaming additional messages into the
|
// the end allows the syntax of streaming additional messages into the
|
||||||
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||||
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
|
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex_or_matcher, terminator) \
|
||||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
if (::testing::internal::AlwaysTrue()) { \
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
|
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
|
||||||
<< "Statement '" #statement "' cannot be verified."; \
|
<< "Statement '" #statement "' cannot be verified."; \
|
||||||
} else if (::testing::internal::AlwaysFalse()) { \
|
} else if (::testing::internal::AlwaysFalse()) { \
|
||||||
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
(void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||||
terminator; \
|
terminator; \
|
||||||
} else \
|
} else \
|
||||||
|
|||||||
106
thirdparty/googletest/include/gtest/gtest-matchers.h
vendored
106
thirdparty/googletest/include/gtest/gtest-matchers.h
vendored
@@ -40,6 +40,7 @@
|
|||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@@ -67,15 +68,15 @@ namespace testing {
|
|||||||
// To implement a matcher Foo for type T, define:
|
// To implement a matcher Foo for type T, define:
|
||||||
// 1. a class FooMatcherMatcher that implements the matcher interface:
|
// 1. a class FooMatcherMatcher that implements the matcher interface:
|
||||||
// using is_gtest_matcher = void;
|
// using is_gtest_matcher = void;
|
||||||
// bool MatchAndExplain(const T&, std::ostream*);
|
// bool MatchAndExplain(const T&, std::ostream*) const;
|
||||||
// (MatchResultListener* can also be used instead of std::ostream*)
|
// (MatchResultListener* can also be used instead of std::ostream*)
|
||||||
// void DescribeTo(std::ostream*);
|
// void DescribeTo(std::ostream*) const;
|
||||||
// void DescribeNegationTo(std::ostream*);
|
// void DescribeNegationTo(std::ostream*) const;
|
||||||
//
|
//
|
||||||
// 2. a factory function that creates a Matcher<T> object from a
|
// 2. a factory function that creates a Matcher<T> object from a
|
||||||
// FooMatcherMatcher.
|
// FooMatcherMatcher.
|
||||||
|
|
||||||
class MatchResultListener {
|
class [[nodiscard]] MatchResultListener {
|
||||||
public:
|
public:
|
||||||
// Creates a listener object with the given underlying ostream. The
|
// Creates a listener object with the given underlying ostream. The
|
||||||
// listener does not own the ostream, and does not dereference it
|
// listener does not own the ostream, and does not dereference it
|
||||||
@@ -111,7 +112,7 @@ inline MatchResultListener::~MatchResultListener() = default;
|
|||||||
|
|
||||||
// An instance of a subclass of this knows how to describe itself as a
|
// An instance of a subclass of this knows how to describe itself as a
|
||||||
// matcher.
|
// matcher.
|
||||||
class GTEST_API_ MatcherDescriberInterface {
|
class GTEST_API_ [[nodiscard]] MatcherDescriberInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~MatcherDescriberInterface() = default;
|
virtual ~MatcherDescriberInterface() = default;
|
||||||
|
|
||||||
@@ -137,7 +138,7 @@ class GTEST_API_ MatcherDescriberInterface {
|
|||||||
|
|
||||||
// The implementation of a matcher.
|
// The implementation of a matcher.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MatcherInterface : public MatcherDescriberInterface {
|
class [[nodiscard]] MatcherInterface : public MatcherDescriberInterface {
|
||||||
public:
|
public:
|
||||||
// Returns true if and only if the matcher matches x; also explains the
|
// Returns true if and only if the matcher matches x; also explains the
|
||||||
// match result to 'listener' if necessary (see the next paragraph), in
|
// match result to 'listener' if necessary (see the next paragraph), in
|
||||||
@@ -180,7 +181,7 @@ class MatcherInterface : public MatcherDescriberInterface {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// A match result listener that ignores the explanation.
|
// A match result listener that ignores the explanation.
|
||||||
class DummyMatchResultListener : public MatchResultListener {
|
class [[nodiscard]] DummyMatchResultListener : public MatchResultListener {
|
||||||
public:
|
public:
|
||||||
DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
||||||
|
|
||||||
@@ -192,7 +193,7 @@ class DummyMatchResultListener : public MatchResultListener {
|
|||||||
// A match result listener that forwards the explanation to a given
|
// A match result listener that forwards the explanation to a given
|
||||||
// ostream. The difference between this and MatchResultListener is
|
// ostream. The difference between this and MatchResultListener is
|
||||||
// that the former is concrete.
|
// that the former is concrete.
|
||||||
class StreamMatchResultListener : public MatchResultListener {
|
class [[nodiscard]] StreamMatchResultListener : public MatchResultListener {
|
||||||
public:
|
public:
|
||||||
explicit StreamMatchResultListener(::std::ostream* os)
|
explicit StreamMatchResultListener(::std::ostream* os)
|
||||||
: MatchResultListener(os) {}
|
: MatchResultListener(os) {}
|
||||||
@@ -225,7 +226,7 @@ struct SharedPayload : SharedPayloadBase {
|
|||||||
// from it. We put functionalities common to all Matcher<T>
|
// from it. We put functionalities common to all Matcher<T>
|
||||||
// specializations here to avoid code duplication.
|
// specializations here to avoid code duplication.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MatcherBase : private MatcherDescriberInterface {
|
class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
|
||||||
public:
|
public:
|
||||||
// Returns true if and only if the matcher matches x; also explains the
|
// Returns true if and only if the matcher matches x; also explains the
|
||||||
// match result to 'listener'.
|
// match result to 'listener'.
|
||||||
@@ -296,12 +297,12 @@ class MatcherBase : private MatcherDescriberInterface {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatcherBase(MatcherBase&& other)
|
MatcherBase(MatcherBase&& other) noexcept
|
||||||
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
||||||
other.vtable_ = nullptr;
|
other.vtable_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatcherBase& operator=(MatcherBase&& other) {
|
MatcherBase& operator=(MatcherBase&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
Destroy();
|
Destroy();
|
||||||
vtable_ = other.vtable_;
|
vtable_ = other.vtable_;
|
||||||
@@ -460,7 +461,7 @@ class MatcherBase : private MatcherDescriberInterface {
|
|||||||
// implementation of Matcher<T> is just a std::shared_ptr to const
|
// implementation of Matcher<T> is just a std::shared_ptr to const
|
||||||
// MatcherInterface<T>. Don't inherit from Matcher!
|
// MatcherInterface<T>. Don't inherit from Matcher!
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Matcher : public internal::MatcherBase<T> {
|
class [[nodiscard]] Matcher : public internal::MatcherBase<T> {
|
||||||
public:
|
public:
|
||||||
// Constructs a null matcher. Needed for storing Matcher objects in STL
|
// Constructs a null matcher. Needed for storing Matcher objects in STL
|
||||||
// containers. A default-constructed matcher is not yet initialized. You
|
// containers. A default-constructed matcher is not yet initialized. You
|
||||||
@@ -485,14 +486,23 @@ class Matcher : public internal::MatcherBase<T> {
|
|||||||
// Implicit constructor here allows people to write
|
// Implicit constructor here allows people to write
|
||||||
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
||||||
Matcher(T value); // NOLINT
|
Matcher(T value); // NOLINT
|
||||||
|
|
||||||
|
// Implicit constructor here allows people to write
|
||||||
|
// EXPECT_THAT(foo, nullptr) instead of EXPECT_THAT(foo, IsNull()) for smart
|
||||||
|
// pointer types.
|
||||||
|
//
|
||||||
|
// The second argument is needed to avoid capturing literal '0'.
|
||||||
|
template <typename U>
|
||||||
|
Matcher(U, // NOLINT
|
||||||
|
std::enable_if_t<std::is_same_v<U, std::nullptr_t>>* = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following two specializations allow the user to write str
|
// The following two specializations allow the user to write str
|
||||||
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
||||||
// matcher is expected.
|
// matcher is expected.
|
||||||
template <>
|
template <>
|
||||||
class GTEST_API_ Matcher<const std::string&>
|
class GTEST_API_ [[nodiscard]]
|
||||||
: public internal::MatcherBase<const std::string&> {
|
Matcher<const std::string&> : public internal::MatcherBase<const std::string&> {
|
||||||
public:
|
public:
|
||||||
Matcher() = default;
|
Matcher() = default;
|
||||||
|
|
||||||
@@ -513,8 +523,8 @@ class GTEST_API_ Matcher<const std::string&>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class GTEST_API_ Matcher<std::string>
|
class GTEST_API_ [[nodiscard]]
|
||||||
: public internal::MatcherBase<std::string> {
|
Matcher<std::string> : public internal::MatcherBase<std::string> {
|
||||||
public:
|
public:
|
||||||
Matcher() = default;
|
Matcher() = default;
|
||||||
|
|
||||||
@@ -541,7 +551,7 @@ class GTEST_API_ Matcher<std::string>
|
|||||||
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
|
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
|
||||||
// matcher is expected.
|
// matcher is expected.
|
||||||
template <>
|
template <>
|
||||||
class GTEST_API_ Matcher<const internal::StringView&>
|
class GTEST_API_ [[nodiscard]] Matcher<const internal::StringView&>
|
||||||
: public internal::MatcherBase<const internal::StringView&> {
|
: public internal::MatcherBase<const internal::StringView&> {
|
||||||
public:
|
public:
|
||||||
Matcher() = default;
|
Matcher() = default;
|
||||||
@@ -567,7 +577,7 @@ class GTEST_API_ Matcher<const internal::StringView&>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class GTEST_API_ Matcher<internal::StringView>
|
class GTEST_API_ [[nodiscard]] Matcher<internal::StringView>
|
||||||
: public internal::MatcherBase<internal::StringView> {
|
: public internal::MatcherBase<internal::StringView> {
|
||||||
public:
|
public:
|
||||||
Matcher() = default;
|
Matcher() = default;
|
||||||
@@ -614,7 +624,7 @@ std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
|
|||||||
//
|
//
|
||||||
// See the definition of NotNull() for a complete example.
|
// See the definition of NotNull() for a complete example.
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
class PolymorphicMatcher {
|
class [[nodiscard]] PolymorphicMatcher {
|
||||||
public:
|
public:
|
||||||
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
|
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
|
||||||
|
|
||||||
@@ -689,7 +699,7 @@ namespace internal {
|
|||||||
// The following template definition assumes that the Rhs parameter is
|
// The following template definition assumes that the Rhs parameter is
|
||||||
// a "bare" type (i.e. neither 'const T' nor 'T&').
|
// a "bare" type (i.e. neither 'const T' nor 'T&').
|
||||||
template <typename D, typename Rhs, typename Op>
|
template <typename D, typename Rhs, typename Op>
|
||||||
class ComparisonBase {
|
class [[nodiscard]] ComparisonBase {
|
||||||
public:
|
public:
|
||||||
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
||||||
|
|
||||||
@@ -722,7 +732,8 @@ class ComparisonBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Rhs>
|
template <typename Rhs>
|
||||||
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
|
class [[nodiscard]] EqMatcher
|
||||||
|
: public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
|
||||||
public:
|
public:
|
||||||
explicit EqMatcher(const Rhs& rhs)
|
explicit EqMatcher(const Rhs& rhs)
|
||||||
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
|
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
|
||||||
@@ -730,7 +741,7 @@ class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
|
|||||||
static const char* NegatedDesc() { return "isn't equal to"; }
|
static const char* NegatedDesc() { return "isn't equal to"; }
|
||||||
};
|
};
|
||||||
template <typename Rhs>
|
template <typename Rhs>
|
||||||
class NeMatcher
|
class [[nodiscard]] NeMatcher
|
||||||
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
|
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
|
||||||
public:
|
public:
|
||||||
explicit NeMatcher(const Rhs& rhs)
|
explicit NeMatcher(const Rhs& rhs)
|
||||||
@@ -739,7 +750,8 @@ class NeMatcher
|
|||||||
static const char* NegatedDesc() { return "is equal to"; }
|
static const char* NegatedDesc() { return "is equal to"; }
|
||||||
};
|
};
|
||||||
template <typename Rhs>
|
template <typename Rhs>
|
||||||
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
class [[nodiscard]] LtMatcher
|
||||||
|
: public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
||||||
public:
|
public:
|
||||||
explicit LtMatcher(const Rhs& rhs)
|
explicit LtMatcher(const Rhs& rhs)
|
||||||
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
|
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
|
||||||
@@ -747,7 +759,8 @@ class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
|||||||
static const char* NegatedDesc() { return "isn't <"; }
|
static const char* NegatedDesc() { return "isn't <"; }
|
||||||
};
|
};
|
||||||
template <typename Rhs>
|
template <typename Rhs>
|
||||||
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
class [[nodiscard]] GtMatcher
|
||||||
|
: public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
||||||
public:
|
public:
|
||||||
explicit GtMatcher(const Rhs& rhs)
|
explicit GtMatcher(const Rhs& rhs)
|
||||||
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
|
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
|
||||||
@@ -755,7 +768,7 @@ class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
|||||||
static const char* NegatedDesc() { return "isn't >"; }
|
static const char* NegatedDesc() { return "isn't >"; }
|
||||||
};
|
};
|
||||||
template <typename Rhs>
|
template <typename Rhs>
|
||||||
class LeMatcher
|
class [[nodiscard]] LeMatcher
|
||||||
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
|
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
|
||||||
public:
|
public:
|
||||||
explicit LeMatcher(const Rhs& rhs)
|
explicit LeMatcher(const Rhs& rhs)
|
||||||
@@ -764,7 +777,7 @@ class LeMatcher
|
|||||||
static const char* NegatedDesc() { return "isn't <="; }
|
static const char* NegatedDesc() { return "isn't <="; }
|
||||||
};
|
};
|
||||||
template <typename Rhs>
|
template <typename Rhs>
|
||||||
class GeMatcher
|
class [[nodiscard]] GeMatcher
|
||||||
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
|
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
|
||||||
public:
|
public:
|
||||||
explicit GeMatcher(const Rhs& rhs)
|
explicit GeMatcher(const Rhs& rhs)
|
||||||
@@ -773,6 +786,35 @@ class GeMatcher
|
|||||||
static const char* NegatedDesc() { return "isn't >="; }
|
static const char* NegatedDesc() { return "isn't >="; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Same as `EqMatcher<Rhs>`, except that the `rhs` is stored as `StoredRhs` and
|
||||||
|
// must be implicitly convertible to `Rhs`.
|
||||||
|
template <typename Rhs, typename StoredRhs>
|
||||||
|
class [[nodiscard]] ImplicitCastEqMatcher {
|
||||||
|
public:
|
||||||
|
explicit ImplicitCastEqMatcher(const StoredRhs& rhs) : stored_rhs_(rhs) {}
|
||||||
|
|
||||||
|
using is_gtest_matcher = void;
|
||||||
|
|
||||||
|
template <typename Lhs>
|
||||||
|
bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
|
||||||
|
return lhs == rhs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeTo(std::ostream* os) const {
|
||||||
|
*os << "is equal to ";
|
||||||
|
UniversalPrint(rhs(), os);
|
||||||
|
}
|
||||||
|
void DescribeNegationTo(std::ostream* os) const {
|
||||||
|
*os << "isn't equal to ";
|
||||||
|
UniversalPrint(rhs(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Rhs rhs() const { return ImplicitCast_<Rhs>(stored_rhs_); }
|
||||||
|
|
||||||
|
StoredRhs stored_rhs_;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<
|
template <typename T, typename = typename std::enable_if<
|
||||||
std::is_constructible<std::string, T>::value>::type>
|
std::is_constructible<std::string, T>::value>::type>
|
||||||
using StringLike = T;
|
using StringLike = T;
|
||||||
@@ -780,7 +822,7 @@ using StringLike = T;
|
|||||||
// Implements polymorphic matchers MatchesRegex(regex) and
|
// Implements polymorphic matchers MatchesRegex(regex) and
|
||||||
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
||||||
// T can be converted to a string.
|
// T can be converted to a string.
|
||||||
class MatchesRegexMatcher {
|
class [[nodiscard]] MatchesRegexMatcher {
|
||||||
public:
|
public:
|
||||||
MatchesRegexMatcher(const RE* regex, bool full_match)
|
MatchesRegexMatcher(const RE* regex, bool full_match)
|
||||||
: regex_(regex), full_match_(full_match) {}
|
: regex_(regex), full_match_(full_match) {}
|
||||||
@@ -863,13 +905,21 @@ inline internal::EqMatcher<T> Eq(T x) {
|
|||||||
return internal::EqMatcher<T>(x);
|
return internal::EqMatcher<T>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a Matcher<T> from a 'value' of type T. The constructed
|
// Constructs a Matcher<T> from a 'value' of type T. The constructed
|
||||||
// matcher matches any value that's equal to 'value'.
|
// matcher matches any value that's equal to 'value'.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Matcher<T>::Matcher(T value) {
|
Matcher<T>::Matcher(T value) {
|
||||||
*this = Eq(value);
|
*this = Eq(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructs a Matcher<T> from nullptr. The constructed matcher matches any
|
||||||
|
// value that is equal to nullptr.
|
||||||
|
template <typename T>
|
||||||
|
template <typename U>
|
||||||
|
Matcher<T>::Matcher(U, std::enable_if_t<std::is_same_v<U, std::nullptr_t>>*) {
|
||||||
|
*this = Eq(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a monomorphic matcher that matches anything with type Lhs
|
// Creates a monomorphic matcher that matches anything with type Lhs
|
||||||
// and equal to rhs. A user may need to use this instead of Eq(...)
|
// and equal to rhs. A user may need to use this instead of Eq(...)
|
||||||
// in order to resolve an overloading ambiguity.
|
// in order to resolve an overloading ambiguity.
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "absl/strings/internal/has_absl_stringify.h"
|
#include "absl/strings/has_absl_stringify.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
@@ -121,14 +121,14 @@ class GTEST_API_ Message {
|
|||||||
// Streams a non-pointer value to this object. If building a version of
|
// Streams a non-pointer value to this object. If building a version of
|
||||||
// GoogleTest with ABSL, this overload is only enabled if the value does not
|
// GoogleTest with ABSL, this overload is only enabled if the value does not
|
||||||
// have an AbslStringify definition.
|
// have an AbslStringify definition.
|
||||||
template <typename T
|
template <
|
||||||
|
typename T
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
,
|
,
|
||||||
typename std::enable_if<
|
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
|
||||||
!absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
|
int>::type = 0
|
||||||
int>::type = 0
|
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
>
|
>
|
||||||
inline Message& operator<<(const T& val) {
|
inline Message& operator<<(const T& val) {
|
||||||
// Some libraries overload << for STL containers. These
|
// Some libraries overload << for STL containers. These
|
||||||
// overloads are defined in the global namespace instead of ::std.
|
// overloads are defined in the global namespace instead of ::std.
|
||||||
@@ -153,9 +153,8 @@ class GTEST_API_ Message {
|
|||||||
// Streams a non-pointer value with an AbslStringify definition to this
|
// Streams a non-pointer value with an AbslStringify definition to this
|
||||||
// object.
|
// object.
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename std::enable_if<
|
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
|
||||||
absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
|
int>::type = 0>
|
||||||
int>::type = 0>
|
|
||||||
inline Message& operator<<(const T& val) {
|
inline Message& operator<<(const T& val) {
|
||||||
// ::operator<< is needed here for a similar reason as with the non-Abseil
|
// ::operator<< is needed here for a similar reason as with the non-Abseil
|
||||||
// version above
|
// version above
|
||||||
|
|||||||
@@ -174,11 +174,12 @@ TEST_P(DerivedTest, DoesBlah) {
|
|||||||
|
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-param-util.h"
|
#include "gtest/internal/gtest-param-util.h" // IWYU pragma: export
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@@ -413,7 +414,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|||||||
// Synopsis:
|
// Synopsis:
|
||||||
// ConvertGenerator<T>(gen)
|
// ConvertGenerator<T>(gen)
|
||||||
// - returns a generator producing the same elements as generated by gen, but
|
// - returns a generator producing the same elements as generated by gen, but
|
||||||
// each element is static_cast to type T before being returned
|
// each T-typed element is static_cast to a type deduced from the interface
|
||||||
|
// that accepts this generator, and then returned
|
||||||
//
|
//
|
||||||
// It is useful when using the Combine() function to get the generated
|
// It is useful when using the Combine() function to get the generated
|
||||||
// parameters in a custom type instead of std::tuple
|
// parameters in a custom type instead of std::tuple
|
||||||
@@ -441,10 +443,65 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|||||||
// Combine(Values("cat", "dog"),
|
// Combine(Values("cat", "dog"),
|
||||||
// Values(BLACK, WHITE))));
|
// Values(BLACK, WHITE))));
|
||||||
//
|
//
|
||||||
template <typename T>
|
template <typename RequestedT>
|
||||||
internal::ParamConverterGenerator<T> ConvertGenerator(
|
internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
|
||||||
internal::ParamGenerator<T> gen) {
|
internal::ParamGenerator<RequestedT> gen) {
|
||||||
return internal::ParamConverterGenerator<T>(gen);
|
return internal::ParamConverterGenerator<RequestedT>(std::move(gen));
|
||||||
|
}
|
||||||
|
|
||||||
|
// As above, but takes a callable as a second argument. The callable converts
|
||||||
|
// the generated parameter to the test fixture's parameter type. This allows you
|
||||||
|
// to use a parameter type that does not have a converting constructor from the
|
||||||
|
// generated type.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// This will instantiate tests in test suite AnimalTest each one with
|
||||||
|
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||||
|
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||||
|
//
|
||||||
|
// enum Color { BLACK, GRAY, WHITE };
|
||||||
|
// struct ParamType {
|
||||||
|
// std::string animal;
|
||||||
|
// Color color;
|
||||||
|
// };
|
||||||
|
// class AnimalTest
|
||||||
|
// : public testing::TestWithParam<ParamType> {...};
|
||||||
|
//
|
||||||
|
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||||
|
//
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(
|
||||||
|
// AnimalVariations, AnimalTest,
|
||||||
|
// ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)),
|
||||||
|
// [](std::tuple<std::string, Color> t) {
|
||||||
|
// return ParamType{.animal = std::get<0>(t),
|
||||||
|
// .color = std::get<1>(t)};
|
||||||
|
// }));
|
||||||
|
//
|
||||||
|
template <typename T, int&... ExplicitArgumentBarrier, typename Gen,
|
||||||
|
typename Func,
|
||||||
|
typename StdFunction = decltype(std::function(std::declval<Func>()))>
|
||||||
|
internal::ParamConverterGenerator<T, StdFunction> ConvertGenerator(Gen&& gen,
|
||||||
|
Func&& f) {
|
||||||
|
return internal::ParamConverterGenerator<T, StdFunction>(
|
||||||
|
std::forward<Gen>(gen), std::forward<Func>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// As above, but infers the T from the supplied std::function instead of
|
||||||
|
// having the caller specify it.
|
||||||
|
template <int&... ExplicitArgumentBarrier, typename Gen, typename Func,
|
||||||
|
typename StdFunction = decltype(std::function(std::declval<Func>()))>
|
||||||
|
auto ConvertGenerator(Gen&& gen, Func&& f) {
|
||||||
|
constexpr bool is_single_arg_std_function =
|
||||||
|
internal::IsSingleArgStdFunction<StdFunction>::value;
|
||||||
|
if constexpr (is_single_arg_std_function) {
|
||||||
|
return ConvertGenerator<
|
||||||
|
typename internal::FuncSingleParamType<StdFunction>::type>(
|
||||||
|
std::forward<Gen>(gen), std::forward<Func>(f));
|
||||||
|
} else {
|
||||||
|
static_assert(is_single_arg_std_function,
|
||||||
|
"The call signature must contain a single argument.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_P(test_suite_name, test_name) \
|
#define TEST_P(test_suite_name, test_name) \
|
||||||
@@ -469,7 +526,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
|||||||
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
[[maybe_unused]] static int gtest_registering_dummy_; \
|
||||||
}; \
|
}; \
|
||||||
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
test_name)::gtest_registering_dummy_ = \
|
test_name)::gtest_registering_dummy_ = \
|
||||||
@@ -493,39 +550,38 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
|||||||
#define GTEST_GET_FIRST_(first, ...) first
|
#define GTEST_GET_FIRST_(first, ...) first
|
||||||
#define GTEST_GET_SECOND_(first, second, ...) second
|
#define GTEST_GET_SECOND_(first, second, ...) second
|
||||||
|
|
||||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||||
} \
|
} \
|
||||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||||
if (::testing::internal::AlwaysFalse()) { \
|
if (::testing::internal::AlwaysFalse()) { \
|
||||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||||
__VA_ARGS__, \
|
__VA_ARGS__, \
|
||||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||||
DUMMY_PARAM_))); \
|
DUMMY_PARAM_))); \
|
||||||
auto t = std::make_tuple(__VA_ARGS__); \
|
auto t = std::make_tuple(__VA_ARGS__); \
|
||||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||||
"Too Many Args!"); \
|
"Too Many Args!"); \
|
||||||
} \
|
} \
|
||||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||||
__VA_ARGS__, \
|
__VA_ARGS__, \
|
||||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||||
DUMMY_PARAM_))))(info); \
|
DUMMY_PARAM_))))(info); \
|
||||||
} \
|
} \
|
||||||
static int gtest_##prefix##test_suite_name##_dummy_ \
|
[[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
|
||||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
::testing::UnitTest::GetInstance() \
|
||||||
::testing::UnitTest::GetInstance() \
|
->parameterized_test_registry() \
|
||||||
->parameterized_test_registry() \
|
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
GTEST_STRINGIFY_(test_suite_name), \
|
||||||
GTEST_STRINGIFY_(test_suite_name), \
|
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
->AddTestSuiteInstantiation( \
|
||||||
->AddTestSuiteInstantiation( \
|
GTEST_STRINGIFY_(prefix), \
|
||||||
GTEST_STRINGIFY_(prefix), \
|
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
>est_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
|
||||||
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
__LINE__)
|
||||||
__FILE__, __LINE__)
|
|
||||||
|
|
||||||
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
||||||
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
|
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
|
||||||
|
|||||||
269
thirdparty/googletest/include/gtest/gtest-printers.h
vendored
269
thirdparty/googletest/include/gtest/gtest-printers.h
vendored
@@ -104,24 +104,36 @@
|
|||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
|
||||||
|
#include <any>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
#include "absl/strings/internal/has_absl_stringify.h"
|
#include "absl/strings/has_absl_stringify.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
#include <span> // NOLINT
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_COMPARE_LIB
|
||||||
|
#include <compare> // NOLINT
|
||||||
|
#endif // GTEST_INTERNAL_HAS_COMPARE_LIB
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Definitions in the internal* namespaces are subject to change without notice.
|
// Definitions in the internal* namespaces are subject to change without notice.
|
||||||
@@ -131,13 +143,32 @@ namespace internal {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void UniversalPrint(const T& value, ::std::ostream* os);
|
void UniversalPrint(const T& value, ::std::ostream* os);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsStdSpan {
|
||||||
|
static constexpr bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
template <typename E>
|
||||||
|
struct IsStdSpan<std::span<E>> {
|
||||||
|
static constexpr bool value = true;
|
||||||
|
};
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
|
||||||
// Used to print an STL-style container when the user doesn't define
|
// Used to print an STL-style container when the user doesn't define
|
||||||
// a PrintTo() for it.
|
// a PrintTo() for it.
|
||||||
|
//
|
||||||
|
// NOTE: Since std::span does not have const_iterator until C++23, it would
|
||||||
|
// fail IsContainerTest before C++23. However, IsContainerTest only uses
|
||||||
|
// the presence of const_iterator to avoid treating iterators as containers
|
||||||
|
// because of iterator::iterator. Which means std::span satisfies the *intended*
|
||||||
|
// condition of IsContainerTest.
|
||||||
struct ContainerPrinter {
|
struct ContainerPrinter {
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if<
|
typename = typename std::enable_if<
|
||||||
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||||
!IsRecursiveContainer<T>::value>::type>
|
!IsRecursiveContainer<T>::value) ||
|
||||||
|
IsStdSpan<T>::value>::type>
|
||||||
static void PrintValue(const T& container, std::ostream* os) {
|
static void PrintValue(const T& container, std::ostream* os) {
|
||||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||||
*os << '{';
|
*os << '{';
|
||||||
@@ -269,10 +300,9 @@ struct ConvertibleToStringViewPrinter {
|
|||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
struct ConvertibleToAbslStringifyPrinter {
|
struct ConvertibleToAbslStringifyPrinter {
|
||||||
template <
|
template <typename T,
|
||||||
typename T,
|
typename = typename std::enable_if<
|
||||||
typename = typename std::enable_if<
|
absl::HasAbslStringify<T>::value>::type> // NOLINT
|
||||||
absl::strings_internal::HasAbslStringify<T>::value>::type> // NOLINT
|
|
||||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||||
*os << absl::StrCat(value);
|
*os << absl::StrCat(value);
|
||||||
}
|
}
|
||||||
@@ -352,7 +382,7 @@ void PrintWithFallback(const T& value, ::std::ostream* os) {
|
|||||||
|
|
||||||
// The default case.
|
// The default case.
|
||||||
template <typename ToPrint, typename OtherOperand>
|
template <typename ToPrint, typename OtherOperand>
|
||||||
class FormatForComparison {
|
class [[nodiscard]] FormatForComparison {
|
||||||
public:
|
public:
|
||||||
static ::std::string Format(const ToPrint& value) {
|
static ::std::string Format(const ToPrint& value) {
|
||||||
return ::testing::PrintToString(value);
|
return ::testing::PrintToString(value);
|
||||||
@@ -361,7 +391,7 @@ class FormatForComparison {
|
|||||||
|
|
||||||
// Array.
|
// Array.
|
||||||
template <typename ToPrint, size_t N, typename OtherOperand>
|
template <typename ToPrint, size_t N, typename OtherOperand>
|
||||||
class FormatForComparison<ToPrint[N], OtherOperand> {
|
class [[nodiscard]] FormatForComparison<ToPrint[N], OtherOperand> {
|
||||||
public:
|
public:
|
||||||
static ::std::string Format(const ToPrint* value) {
|
static ::std::string Format(const ToPrint* value) {
|
||||||
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
||||||
@@ -447,7 +477,7 @@ std::string FormatForComparisonFailureMessage(const T1& value,
|
|||||||
// function template), as we need to partially specialize it for
|
// function template), as we need to partially specialize it for
|
||||||
// reference types, which cannot be done with function templates.
|
// reference types, which cannot be done with function templates.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter;
|
class [[nodiscard]] UniversalPrinter;
|
||||||
|
|
||||||
// Prints the given value using the << operator if it has one;
|
// Prints the given value using the << operator if it has one;
|
||||||
// otherwise prints the bytes in it. This is what
|
// otherwise prints the bytes in it. This is what
|
||||||
@@ -495,11 +525,15 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
|
|||||||
|
|
||||||
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
|
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
|
||||||
inline void PrintTo(char16_t c, ::std::ostream* os) {
|
inline void PrintTo(char16_t c, ::std::ostream* os) {
|
||||||
PrintTo(ImplicitCast_<char32_t>(c), os);
|
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
|
||||||
|
// Also see https://github.com/google/googletest/issues/4762.
|
||||||
|
PrintTo(static_cast<char32_t>(c), os);
|
||||||
}
|
}
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
inline void PrintTo(char8_t c, ::std::ostream* os) {
|
inline void PrintTo(char8_t c, ::std::ostream* os) {
|
||||||
PrintTo(ImplicitCast_<char32_t>(c), os);
|
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
|
||||||
|
// Also see https://github.com/google/googletest/issues/4762.
|
||||||
|
PrintTo(static_cast<char32_t>(c), os);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -530,49 +564,63 @@ int AppropriateResolution(FloatType val) {
|
|||||||
int full = std::numeric_limits<FloatType>::max_digits10;
|
int full = std::numeric_limits<FloatType>::max_digits10;
|
||||||
if (val < 0) val = -val;
|
if (val < 0) val = -val;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
if (val < 1000000) {
|
if (val < 1000000) {
|
||||||
FloatType mulfor6 = 1e10;
|
FloatType mulfor6 = 1e10;
|
||||||
if (val >= 100000.0) { // 100,000 to 999,999
|
// Without these static casts, the template instantiation for float would
|
||||||
|
// fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
|
||||||
|
// comparison logic would promote floats to doubles.
|
||||||
|
if (val >= static_cast<FloatType>(100000.0)) { // 100,000 to 999,999
|
||||||
mulfor6 = 1.0;
|
mulfor6 = 1.0;
|
||||||
} else if (val >= 10000.0) {
|
} else if (val >= static_cast<FloatType>(10000.0)) {
|
||||||
mulfor6 = 1e1;
|
mulfor6 = 1e1;
|
||||||
} else if (val >= 1000.0) {
|
} else if (val >= static_cast<FloatType>(1000.0)) {
|
||||||
mulfor6 = 1e2;
|
mulfor6 = 1e2;
|
||||||
} else if (val >= 100.0) {
|
} else if (val >= static_cast<FloatType>(100.0)) {
|
||||||
mulfor6 = 1e3;
|
mulfor6 = 1e3;
|
||||||
} else if (val >= 10.0) {
|
} else if (val >= static_cast<FloatType>(10.0)) {
|
||||||
mulfor6 = 1e4;
|
mulfor6 = 1e4;
|
||||||
} else if (val >= 1.0) {
|
} else if (val >= static_cast<FloatType>(1.0)) {
|
||||||
mulfor6 = 1e5;
|
mulfor6 = 1e5;
|
||||||
} else if (val >= 0.1) {
|
} else if (val >= static_cast<FloatType>(0.1)) {
|
||||||
mulfor6 = 1e6;
|
mulfor6 = 1e6;
|
||||||
} else if (val >= 0.01) {
|
} else if (val >= static_cast<FloatType>(0.01)) {
|
||||||
mulfor6 = 1e7;
|
mulfor6 = 1e7;
|
||||||
} else if (val >= 0.001) {
|
} else if (val >= static_cast<FloatType>(0.001)) {
|
||||||
mulfor6 = 1e8;
|
mulfor6 = 1e8;
|
||||||
} else if (val >= 0.0001) {
|
} else if (val >= static_cast<FloatType>(0.0001)) {
|
||||||
mulfor6 = 1e9;
|
mulfor6 = 1e9;
|
||||||
}
|
}
|
||||||
if (static_cast<FloatType>(static_cast<int32_t>(val * mulfor6 + 0.5)) /
|
if (static_cast<FloatType>(static_cast<int32_t>(
|
||||||
|
val * mulfor6 + (static_cast<FloatType>(0.5)))) /
|
||||||
mulfor6 ==
|
mulfor6 ==
|
||||||
val)
|
val)
|
||||||
return 6;
|
return 6;
|
||||||
} else if (val < 1e10) {
|
} else if (val < static_cast<FloatType>(1e10)) {
|
||||||
FloatType divfor6 = 1.0;
|
FloatType divfor6 = static_cast<FloatType>(1.0);
|
||||||
if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999
|
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
|
||||||
divfor6 = 10000;
|
divfor6 = 10000;
|
||||||
} else if (val >= 1e8) { // 100,000,000 to 999,999,999
|
} else if (val >=
|
||||||
|
static_cast<FloatType>(1e8)) { // 100,000,000 to 999,999,999
|
||||||
divfor6 = 1000;
|
divfor6 = 1000;
|
||||||
} else if (val >= 1e7) { // 10,000,000 to 99,999,999
|
} else if (val >=
|
||||||
|
static_cast<FloatType>(1e7)) { // 10,000,000 to 99,999,999
|
||||||
divfor6 = 100;
|
divfor6 = 100;
|
||||||
} else if (val >= 1e6) { // 1,000,000 to 9,999,999
|
} else if (val >= static_cast<FloatType>(1e6)) { // 1,000,000 to 9,999,999
|
||||||
divfor6 = 10;
|
divfor6 = 10;
|
||||||
}
|
}
|
||||||
if (static_cast<FloatType>(static_cast<int32_t>(val / divfor6 + 0.5)) *
|
if (static_cast<FloatType>(static_cast<int32_t>(
|
||||||
|
val / divfor6 + (static_cast<FloatType>(0.5)))) *
|
||||||
divfor6 ==
|
divfor6 ==
|
||||||
val)
|
val)
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,44 +703,63 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for ::std::string.
|
// Overloads for ::std::string and ::std::string_view
|
||||||
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
|
GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||||
PrintStringTo(s, os);
|
PrintStringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::string_view s, ::std::ostream* os) {
|
||||||
|
PrintStringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloads for ::std::u8string
|
// Overloads for ::std::u8string and ::std::u8string_view
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU8StringTo(::std::u8string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
|
||||||
PrintU8StringTo(s, os);
|
PrintU8StringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::u8string_view s, ::std::ostream* os) {
|
||||||
|
PrintU8StringTo(s, os);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Overloads for ::std::u16string
|
// Overloads for ::std::u16string and ::std::u16string_view
|
||||||
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
|
||||||
PrintU16StringTo(s, os);
|
PrintU16StringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::u16string_view s, ::std::ostream* os) {
|
||||||
|
PrintU16StringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloads for ::std::u32string
|
// Overloads for ::std::u32string and ::std::u32string_view
|
||||||
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
|
||||||
PrintU32StringTo(s, os);
|
PrintU32StringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::u32string_view s, ::std::ostream* os) {
|
||||||
|
PrintU32StringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloads for ::std::wstring.
|
// Overloads for ::std::wstring and ::std::wstring_view
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
|
GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||||
PrintWideStringTo(s, os);
|
PrintWideStringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::wstring_view s, ::std::ostream* os) {
|
||||||
|
PrintWideStringTo(s, os);
|
||||||
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
// Overload for internal::StringView.
|
// Overload for internal::StringView. Needed for build configurations where
|
||||||
|
// internal::StringView is an alias for absl::string_view, but absl::string_view
|
||||||
|
// is a distinct type from std::string_view.
|
||||||
|
template <int&... ExplicitArgumentBarrier, typename T = internal::StringView,
|
||||||
|
std::enable_if_t<!std::is_same_v<T, ::std::string_view>, int> = 0>
|
||||||
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
||||||
PrintTo(::std::string(sp), os);
|
PrintStringTo(sp, os);
|
||||||
}
|
}
|
||||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
|
||||||
@@ -746,6 +813,41 @@ void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
|
|||||||
(PrintSmartPointer<T>)(ptr, os, 0);
|
(PrintSmartPointer<T>)(ptr, os, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_COMPARE_LIB
|
||||||
|
template <typename T>
|
||||||
|
void PrintOrderingHelper(T ordering, std::ostream* os) {
|
||||||
|
if (ordering == T::less) {
|
||||||
|
*os << "(less)";
|
||||||
|
} else if (ordering == T::greater) {
|
||||||
|
*os << "(greater)";
|
||||||
|
} else if (ordering == T::equivalent) {
|
||||||
|
*os << "(equivalent)";
|
||||||
|
} else {
|
||||||
|
*os << "(unknown ordering)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrintTo(std::strong_ordering ordering, std::ostream* os) {
|
||||||
|
if (ordering == std::strong_ordering::equal) {
|
||||||
|
*os << "(equal)";
|
||||||
|
} else {
|
||||||
|
PrintOrderingHelper(ordering, os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrintTo(std::partial_ordering ordering, std::ostream* os) {
|
||||||
|
if (ordering == std::partial_ordering::unordered) {
|
||||||
|
*os << "(unordered)";
|
||||||
|
} else {
|
||||||
|
PrintOrderingHelper(ordering, os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrintTo(std::weak_ordering ordering, std::ostream* os) {
|
||||||
|
PrintOrderingHelper(ordering, os);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Helper function for printing a tuple. T must be instantiated with
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
// a tuple type.
|
// a tuple type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -787,7 +889,7 @@ void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
|||||||
// Implements printing a non-reference type T by letting the compiler
|
// Implements printing a non-reference type T by letting the compiler
|
||||||
// pick the right overload of PrintTo() for T.
|
// pick the right overload of PrintTo() for T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter {
|
class [[nodiscard]] UniversalPrinter {
|
||||||
public:
|
public:
|
||||||
// MSVC warns about adding const to a function type, so we want to
|
// MSVC warns about adding const to a function type, so we want to
|
||||||
// disable the warning.
|
// disable the warning.
|
||||||
@@ -813,16 +915,13 @@ class UniversalPrinter {
|
|||||||
|
|
||||||
// Remove any const-qualifiers before passing a type to UniversalPrinter.
|
// Remove any const-qualifiers before passing a type to UniversalPrinter.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
class [[nodiscard]] UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_ANY
|
|
||||||
|
|
||||||
// Printer for std::any / absl::any
|
|
||||||
|
|
||||||
|
// Printer for std::any
|
||||||
template <>
|
template <>
|
||||||
class UniversalPrinter<Any> {
|
class [[nodiscard]] UniversalPrinter<std::any> {
|
||||||
public:
|
public:
|
||||||
static void Print(const Any& value, ::std::ostream* os) {
|
static void Print(const std::any& value, ::std::ostream* os) {
|
||||||
if (value.has_value()) {
|
if (value.has_value()) {
|
||||||
*os << "value of type " << GetTypeName(value);
|
*os << "value of type " << GetTypeName(value);
|
||||||
} else {
|
} else {
|
||||||
@@ -831,7 +930,7 @@ class UniversalPrinter<Any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string GetTypeName(const Any& value) {
|
static std::string GetTypeName(const std::any& value) {
|
||||||
#if GTEST_HAS_RTTI
|
#if GTEST_HAS_RTTI
|
||||||
return internal::GetTypeName(value.type());
|
return internal::GetTypeName(value.type());
|
||||||
#else
|
#else
|
||||||
@@ -841,16 +940,11 @@ class UniversalPrinter<Any> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_ANY
|
// Printer for std::optional
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_OPTIONAL
|
|
||||||
|
|
||||||
// Printer for std::optional / absl::optional
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter<Optional<T>> {
|
class [[nodiscard]] UniversalPrinter<std::optional<T>> {
|
||||||
public:
|
public:
|
||||||
static void Print(const Optional<T>& value, ::std::ostream* os) {
|
static void Print(const std::optional<T>& value, ::std::ostream* os) {
|
||||||
*os << '(';
|
*os << '(';
|
||||||
if (!value) {
|
if (!value) {
|
||||||
*os << "nullopt";
|
*os << "nullopt";
|
||||||
@@ -862,29 +956,18 @@ class UniversalPrinter<Optional<T>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class UniversalPrinter<decltype(Nullopt())> {
|
class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
|
||||||
public:
|
public:
|
||||||
static void Print(decltype(Nullopt()), ::std::ostream* os) {
|
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
|
||||||
*os << "(nullopt)";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
// Printer for std::variant
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
|
|
||||||
// Printer for std::variant / absl::variant
|
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class UniversalPrinter<Variant<T...>> {
|
class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
|
||||||
public:
|
public:
|
||||||
static void Print(const Variant<T...>& value, ::std::ostream* os) {
|
static void Print(const std::variant<T...>& value, ::std::ostream* os) {
|
||||||
*os << '(';
|
*os << '(';
|
||||||
#ifdef GTEST_HAS_ABSL
|
|
||||||
absl::visit(Visitor{os, value.index()}, value);
|
|
||||||
#else
|
|
||||||
std::visit(Visitor{os, value.index()}, value);
|
std::visit(Visitor{os, value.index()}, value);
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
*os << ')';
|
*os << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,8 +984,6 @@ class UniversalPrinter<Variant<T...>> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
|
|
||||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||||
// elements, starting at address 'begin'.
|
// elements, starting at address 'begin'.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -950,7 +1031,7 @@ GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
|
|||||||
|
|
||||||
// Implements printing an array type T[N].
|
// Implements printing an array type T[N].
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
class UniversalPrinter<T[N]> {
|
class [[nodiscard]] UniversalPrinter<T[N]> {
|
||||||
public:
|
public:
|
||||||
// Prints the given array, omitting some elements when there are too
|
// Prints the given array, omitting some elements when there are too
|
||||||
// many.
|
// many.
|
||||||
@@ -961,7 +1042,7 @@ class UniversalPrinter<T[N]> {
|
|||||||
|
|
||||||
// Implements printing a reference type T&.
|
// Implements printing a reference type T&.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter<T&> {
|
class [[nodiscard]] UniversalPrinter<T&> {
|
||||||
public:
|
public:
|
||||||
// MSVC warns about adding const to a function type, so we want to
|
// MSVC warns about adding const to a function type, so we want to
|
||||||
// disable the warning.
|
// disable the warning.
|
||||||
@@ -984,35 +1065,35 @@ class UniversalPrinter<T&> {
|
|||||||
// NUL-terminated string (but not the pointer) is printed.
|
// NUL-terminated string (but not the pointer) is printed.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalTersePrinter {
|
class [[nodiscard]] UniversalTersePrinter {
|
||||||
public:
|
public:
|
||||||
static void Print(const T& value, ::std::ostream* os) {
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
UniversalPrint(value, os);
|
UniversalPrint(value, os);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalTersePrinter<T&> {
|
class [[nodiscard]] UniversalTersePrinter<T&> {
|
||||||
public:
|
public:
|
||||||
static void Print(const T& value, ::std::ostream* os) {
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
UniversalPrint(value, os);
|
UniversalPrint(value, os);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalTersePrinter<std::reference_wrapper<T>> {
|
class [[nodiscard]] UniversalTersePrinter<std::reference_wrapper<T>> {
|
||||||
public:
|
public:
|
||||||
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
|
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
|
||||||
UniversalTersePrinter<T>::Print(value.get(), os);
|
UniversalTersePrinter<T>::Print(value.get(), os);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
class UniversalTersePrinter<T[N]> {
|
class [[nodiscard]] UniversalTersePrinter<T[N]> {
|
||||||
public:
|
public:
|
||||||
static void Print(const T (&value)[N], ::std::ostream* os) {
|
static void Print(const T (&value)[N], ::std::ostream* os) {
|
||||||
UniversalPrinter<T[N]>::Print(value, os);
|
UniversalPrinter<T[N]>::Print(value, os);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<const char*> {
|
class [[nodiscard]] UniversalTersePrinter<const char*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const char* str, ::std::ostream* os) {
|
static void Print(const char* str, ::std::ostream* os) {
|
||||||
if (str == nullptr) {
|
if (str == nullptr) {
|
||||||
@@ -1023,12 +1104,12 @@ class UniversalTersePrinter<const char*> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
|
class [[nodiscard]]
|
||||||
};
|
UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {};
|
||||||
|
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<const char8_t*> {
|
class [[nodiscard]] UniversalTersePrinter<const char8_t*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const char8_t* str, ::std::ostream* os) {
|
static void Print(const char8_t* str, ::std::ostream* os) {
|
||||||
if (str == nullptr) {
|
if (str == nullptr) {
|
||||||
@@ -1039,12 +1120,12 @@ class UniversalTersePrinter<const char8_t*> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<char8_t*>
|
class [[nodiscard]] UniversalTersePrinter<char8_t*>
|
||||||
: public UniversalTersePrinter<const char8_t*> {};
|
: public UniversalTersePrinter<const char8_t*> {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<const char16_t*> {
|
class [[nodiscard]] UniversalTersePrinter<const char16_t*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const char16_t* str, ::std::ostream* os) {
|
static void Print(const char16_t* str, ::std::ostream* os) {
|
||||||
if (str == nullptr) {
|
if (str == nullptr) {
|
||||||
@@ -1055,11 +1136,11 @@ class UniversalTersePrinter<const char16_t*> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<char16_t*>
|
class [[nodiscard]] UniversalTersePrinter<char16_t*>
|
||||||
: public UniversalTersePrinter<const char16_t*> {};
|
: public UniversalTersePrinter<const char16_t*> {};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<const char32_t*> {
|
class [[nodiscard]] UniversalTersePrinter<const char32_t*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const char32_t* str, ::std::ostream* os) {
|
static void Print(const char32_t* str, ::std::ostream* os) {
|
||||||
if (str == nullptr) {
|
if (str == nullptr) {
|
||||||
@@ -1070,12 +1151,12 @@ class UniversalTersePrinter<const char32_t*> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<char32_t*>
|
class [[nodiscard]] UniversalTersePrinter<char32_t*>
|
||||||
: public UniversalTersePrinter<const char32_t*> {};
|
: public UniversalTersePrinter<const char32_t*> {};
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<const wchar_t*> {
|
class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const wchar_t* str, ::std::ostream* os) {
|
static void Print(const wchar_t* str, ::std::ostream* os) {
|
||||||
if (str == nullptr) {
|
if (str == nullptr) {
|
||||||
@@ -1088,7 +1169,7 @@ class UniversalTersePrinter<const wchar_t*> {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class UniversalTersePrinter<wchar_t*> {
|
class [[nodiscard]] UniversalTersePrinter<wchar_t*> {
|
||||||
public:
|
public:
|
||||||
static void Print(wchar_t* str, ::std::ostream* os) {
|
static void Print(wchar_t* str, ::std::ostream* os) {
|
||||||
UniversalTersePrinter<const wchar_t*>::Print(str, os);
|
UniversalTersePrinter<const wchar_t*>::Print(str, os);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace testing {
|
|||||||
// generated in the same thread that created this object or it can intercept
|
// generated in the same thread that created this object or it can intercept
|
||||||
// all generated failures. The scope of this mock object can be controlled with
|
// all generated failures. The scope of this mock object can be controlled with
|
||||||
// the second argument to the two arguments constructor.
|
// the second argument to the two arguments constructor.
|
||||||
class GTEST_API_ ScopedFakeTestPartResultReporter
|
class GTEST_API_ [[nodiscard]] ScopedFakeTestPartResultReporter
|
||||||
: public TestPartResultReporterInterface {
|
: public TestPartResultReporterInterface {
|
||||||
public:
|
public:
|
||||||
// The two possible mocking modes of this object.
|
// The two possible mocking modes of this object.
|
||||||
@@ -100,7 +100,7 @@ namespace internal {
|
|||||||
// TestPartResultArray contains exactly one failure that has the given
|
// TestPartResultArray contains exactly one failure that has the given
|
||||||
// type and contains the given substring. If that's not the case, a
|
// type and contains the given substring. If that's not the case, a
|
||||||
// non-fatal failure will be generated.
|
// non-fatal failure will be generated.
|
||||||
class GTEST_API_ SingleFailureChecker {
|
class GTEST_API_ [[nodiscard]] SingleFailureChecker {
|
||||||
public:
|
public:
|
||||||
// The constructor remembers the arguments.
|
// The constructor remembers the arguments.
|
||||||
SingleFailureChecker(const TestPartResultArray* results,
|
SingleFailureChecker(const TestPartResultArray* results,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
@@ -51,7 +52,7 @@ namespace testing {
|
|||||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||||
//
|
//
|
||||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||||
class GTEST_API_ TestPartResult {
|
class GTEST_API_ [[nodiscard]] TestPartResult {
|
||||||
public:
|
public:
|
||||||
// The possible outcomes of a test part (i.e. an assertion or an
|
// The possible outcomes of a test part (i.e. an assertion or an
|
||||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||||
@@ -65,10 +66,10 @@ class GTEST_API_ TestPartResult {
|
|||||||
// C'tor. TestPartResult does NOT have a default constructor.
|
// C'tor. TestPartResult does NOT have a default constructor.
|
||||||
// Always use this constructor (with parameters) to create a
|
// Always use this constructor (with parameters) to create a
|
||||||
// TestPartResult object.
|
// TestPartResult object.
|
||||||
TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
|
TestPartResult(Type a_type, std::string_view a_file_name, int a_line_number,
|
||||||
const char* a_message)
|
std::string_view a_message)
|
||||||
: type_(a_type),
|
: type_(a_type),
|
||||||
file_name_(a_file_name == nullptr ? "" : a_file_name),
|
file_name_(a_file_name),
|
||||||
line_number_(a_line_number),
|
line_number_(a_line_number),
|
||||||
summary_(ExtractSummary(a_message)),
|
summary_(ExtractSummary(a_message)),
|
||||||
message_(a_message) {}
|
message_(a_message) {}
|
||||||
@@ -112,7 +113,7 @@ class GTEST_API_ TestPartResult {
|
|||||||
|
|
||||||
// Gets the summary of the failure message by omitting the stack
|
// Gets the summary of the failure message by omitting the stack
|
||||||
// trace in it.
|
// trace in it.
|
||||||
static std::string ExtractSummary(const char* message);
|
static std::string ExtractSummary(std::string_view message);
|
||||||
|
|
||||||
// The name of the source file where the test part took place, or
|
// The name of the source file where the test part took place, or
|
||||||
// "" if the source file is unknown.
|
// "" if the source file is unknown.
|
||||||
@@ -131,7 +132,7 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
|||||||
//
|
//
|
||||||
// Don't inherit from TestPartResultArray as its destructor is not
|
// Don't inherit from TestPartResultArray as its destructor is not
|
||||||
// virtual.
|
// virtual.
|
||||||
class GTEST_API_ TestPartResultArray {
|
class GTEST_API_ [[nodiscard]] TestPartResultArray {
|
||||||
public:
|
public:
|
||||||
TestPartResultArray() = default;
|
TestPartResultArray() = default;
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ class GTEST_API_ TestPartResultArray {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// This interface knows how to report a test part result.
|
// This interface knows how to report a test part result.
|
||||||
class GTEST_API_ TestPartResultReporterInterface {
|
class GTEST_API_ [[nodiscard]] TestPartResultReporterInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~TestPartResultReporterInterface() = default;
|
virtual ~TestPartResultReporterInterface() = default;
|
||||||
|
|
||||||
@@ -167,7 +168,7 @@ namespace internal {
|
|||||||
// reported, it only delegates the reporting to the former result reporter.
|
// reported, it only delegates the reporting to the former result reporter.
|
||||||
// The original result reporter is restored in the destructor.
|
// The original result reporter is restored in the destructor.
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
class GTEST_API_ HasNewFatalFailureHelper
|
class GTEST_API_ [[nodiscard]] HasNewFatalFailureHelper
|
||||||
: public TestPartResultReporterInterface {
|
: public TestPartResultReporterInterface {
|
||||||
public:
|
public:
|
||||||
HasNewFatalFailureHelper();
|
HasNewFatalFailureHelper();
|
||||||
|
|||||||
@@ -45,18 +45,18 @@
|
|||||||
// First, define a fixture class template. It should be parameterized
|
// First, define a fixture class template. It should be parameterized
|
||||||
// by a type. Remember to derive it from testing::Test.
|
// by a type. Remember to derive it from testing::Test.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class FooTest : public testing::Test {
|
class [[nodiscard]] FooTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
...
|
...
|
||||||
typedef std::list<T> List;
|
using List = ::std::list<T>;
|
||||||
static T shared_;
|
static T shared_;
|
||||||
T value_;
|
T value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Next, associate a list of types with the test suite, which will be
|
// Next, associate a list of types with the test suite, which will be
|
||||||
// repeated for each type in the list. The typedef is necessary for
|
// repeated for each type in the list. The using-declaration is necessary for
|
||||||
// the macro to parse correctly.
|
// the macro to parse correctly.
|
||||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
using MyTypes = ::testing::Types<char, int, unsigned int>;
|
||||||
TYPED_TEST_SUITE(FooTest, MyTypes);
|
TYPED_TEST_SUITE(FooTest, MyTypes);
|
||||||
|
|
||||||
// If the type list contains only one type, you can write that type
|
// If the type list contains only one type, you can write that type
|
||||||
@@ -123,7 +123,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... }
|
|||||||
// First, define a fixture class template. It should be parameterized
|
// First, define a fixture class template. It should be parameterized
|
||||||
// by a type. Remember to derive it from testing::Test.
|
// by a type. Remember to derive it from testing::Test.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class FooTest : public testing::Test {
|
class [[nodiscard]] FooTest : public testing::Test {
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ REGISTER_TYPED_TEST_SUITE_P(FooTest,
|
|||||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||||
// to the actual test suite name. Remember to pick unique prefixes for
|
// to the actual test suite name. Remember to pick unique prefixes for
|
||||||
// different instances.
|
// different instances.
|
||||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
using MyTypes = ::testing::Types<char, int, unsigned int>;
|
||||||
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||||
|
|
||||||
// If the type list contains only one type, you can write that type
|
// If the type list contains only one type, you can write that type
|
||||||
@@ -205,8 +205,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|||||||
typedef gtest_TypeParam_ TypeParam; \
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
}; \
|
}; \
|
||||||
static bool gtest_##CaseName##_##TestName##_registered_ \
|
[[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \
|
||||||
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
|
::testing::internal::TypeParameterizedTest< \
|
||||||
CaseName, \
|
CaseName, \
|
||||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||||
TestName)>, \
|
TestName)>, \
|
||||||
@@ -267,22 +267,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|||||||
TYPED_TEST_SUITE_P
|
TYPED_TEST_SUITE_P
|
||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
template <typename gtest_TypeParam_> \
|
template <typename gtest_TypeParam_> \
|
||||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||||
private: \
|
private: \
|
||||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||||
typedef gtest_TypeParam_ TypeParam; \
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
}; \
|
}; \
|
||||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
|
||||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||||
GTEST_STRINGIFY_(TestName)); \
|
GTEST_STRINGIFY_(TestName)); \
|
||||||
} \
|
} \
|
||||||
template <typename gtest_TypeParam_> \
|
template <typename gtest_TypeParam_> \
|
||||||
void GTEST_SUITE_NAMESPACE_( \
|
void GTEST_SUITE_NAMESPACE_( \
|
||||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
// Note: this won't work correctly if the trailing arguments are macros.
|
// Note: this won't work correctly if the trailing arguments are macros.
|
||||||
@@ -290,8 +290,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|||||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||||
} \
|
} \
|
||||||
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
[[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||||
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
|
SuiteName) = \
|
||||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||||
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|||||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||||
"test-suit-prefix must not be empty"); \
|
"test-suit-prefix must not be empty"); \
|
||||||
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
|
[[maybe_unused]] static bool gtest_##Prefix##_##SuiteName = \
|
||||||
::testing::internal::TypeParameterizedTestSuite< \
|
::testing::internal::TypeParameterizedTestSuite< \
|
||||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||||
|
|||||||
124
thirdparty/googletest/include/gtest/gtest.h
vendored
124
thirdparty/googletest/include/gtest/gtest.h
vendored
@@ -51,26 +51,26 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iomanip>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest-assertion-result.h"
|
#include "gtest/gtest-assertion-result.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-death-test.h"
|
#include "gtest/gtest-death-test.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-matchers.h"
|
#include "gtest/gtest-matchers.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-param-test.h"
|
#include "gtest/gtest-param-test.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-printers.h"
|
#include "gtest/gtest-printers.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-test-part.h"
|
#include "gtest/gtest-test-part.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest-typed-test.h"
|
#include "gtest/gtest-typed-test.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest_pred_impl.h"
|
#include "gtest/gtest_pred_impl.h" // IWYU pragma: export
|
||||||
#include "gtest/gtest_prod.h"
|
#include "gtest/gtest_prod.h" // IWYU pragma: export
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-string.h"
|
#include "gtest/internal/gtest-string.h"
|
||||||
|
|
||||||
@@ -137,6 +137,10 @@ GTEST_DECLARE_int32_(repeat);
|
|||||||
// only torn down once, for the last.
|
// only torn down once, for the last.
|
||||||
GTEST_DECLARE_bool_(recreate_environments_when_repeating);
|
GTEST_DECLARE_bool_(recreate_environments_when_repeating);
|
||||||
|
|
||||||
|
// Together these flags determine which tests are run if the test is sharded.
|
||||||
|
GTEST_DECLARE_int32_(shard_index);
|
||||||
|
GTEST_DECLARE_int32_(total_shards);
|
||||||
|
|
||||||
// This flag controls whether Google Test includes Google Test internal
|
// This flag controls whether Google Test includes Google Test internal
|
||||||
// stack frames in failure stack traces.
|
// stack frames in failure stack traces.
|
||||||
GTEST_DECLARE_bool_(show_internal_stack_frames);
|
GTEST_DECLARE_bool_(show_internal_stack_frames);
|
||||||
@@ -194,7 +198,7 @@ std::set<std::string>* GetIgnoredParameterizedTestSuites();
|
|||||||
// A base class that prevents subclasses from being copyable.
|
// A base class that prevents subclasses from being copyable.
|
||||||
// We do this instead of using '= delete' so as to avoid triggering warnings
|
// We do this instead of using '= delete' so as to avoid triggering warnings
|
||||||
// inside user code regarding any of our declarations.
|
// inside user code regarding any of our declarations.
|
||||||
class GTestNonCopyable {
|
class [[nodiscard]] GTestNonCopyable {
|
||||||
public:
|
public:
|
||||||
GTestNonCopyable() = default;
|
GTestNonCopyable() = default;
|
||||||
GTestNonCopyable(const GTestNonCopyable&) = delete;
|
GTestNonCopyable(const GTestNonCopyable&) = delete;
|
||||||
@@ -207,15 +211,15 @@ class GTestNonCopyable {
|
|||||||
// The friend relationship of some of these classes is cyclic.
|
// The friend relationship of some of these classes is cyclic.
|
||||||
// If we don't forward declare them the compiler might confuse the classes
|
// If we don't forward declare them the compiler might confuse the classes
|
||||||
// in friendship clauses with same named classes on the scope.
|
// in friendship clauses with same named classes on the scope.
|
||||||
class Test;
|
class [[nodiscard]] Test;
|
||||||
class TestSuite;
|
class [[nodiscard]] TestSuite;
|
||||||
|
|
||||||
// Old API is still available but deprecated
|
// Old API is still available but deprecated
|
||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
using TestCase = TestSuite;
|
using TestCase = TestSuite;
|
||||||
#endif
|
#endif
|
||||||
class TestInfo;
|
class [[nodiscard]] TestInfo;
|
||||||
class UnitTest;
|
class [[nodiscard]] UnitTest;
|
||||||
|
|
||||||
// The abstract class that all tests inherit from.
|
// The abstract class that all tests inherit from.
|
||||||
//
|
//
|
||||||
@@ -240,7 +244,7 @@ class UnitTest;
|
|||||||
// TEST_F(FooTest, Baz) { ... }
|
// TEST_F(FooTest, Baz) { ... }
|
||||||
//
|
//
|
||||||
// Test is not copyable.
|
// Test is not copyable.
|
||||||
class GTEST_API_ Test {
|
class GTEST_API_ [[nodiscard]] Test {
|
||||||
public:
|
public:
|
||||||
friend class TestInfo;
|
friend class TestInfo;
|
||||||
|
|
||||||
@@ -367,7 +371,7 @@ typedef internal::TimeInMillis TimeInMillis;
|
|||||||
// output as a key/value string pair.
|
// output as a key/value string pair.
|
||||||
//
|
//
|
||||||
// Don't inherit from TestProperty as its destructor is not virtual.
|
// Don't inherit from TestProperty as its destructor is not virtual.
|
||||||
class TestProperty {
|
class [[nodiscard]] TestProperty {
|
||||||
public:
|
public:
|
||||||
// C'tor. TestProperty does NOT have a default constructor.
|
// C'tor. TestProperty does NOT have a default constructor.
|
||||||
// Always use this constructor (with parameters) to create a
|
// Always use this constructor (with parameters) to create a
|
||||||
@@ -397,7 +401,7 @@ class TestProperty {
|
|||||||
// the Test.
|
// the Test.
|
||||||
//
|
//
|
||||||
// TestResult is not copyable.
|
// TestResult is not copyable.
|
||||||
class GTEST_API_ TestResult {
|
class GTEST_API_ [[nodiscard]] TestResult {
|
||||||
public:
|
public:
|
||||||
// Creates an empty TestResult.
|
// Creates an empty TestResult.
|
||||||
TestResult();
|
TestResult();
|
||||||
@@ -531,7 +535,7 @@ class GTEST_API_ TestResult {
|
|||||||
// The constructor of TestInfo registers itself with the UnitTest
|
// The constructor of TestInfo registers itself with the UnitTest
|
||||||
// singleton such that the RUN_ALL_TESTS() macro knows which tests to
|
// singleton such that the RUN_ALL_TESTS() macro knows which tests to
|
||||||
// run.
|
// run.
|
||||||
class GTEST_API_ TestInfo {
|
class GTEST_API_ [[nodiscard]] TestInfo {
|
||||||
public:
|
public:
|
||||||
// Destructs a TestInfo object. This function is not virtual, so
|
// Destructs a TestInfo object. This function is not virtual, so
|
||||||
// don't inherit from TestInfo.
|
// don't inherit from TestInfo.
|
||||||
@@ -608,7 +612,7 @@ class GTEST_API_ TestInfo {
|
|||||||
friend class internal::UnitTestImpl;
|
friend class internal::UnitTestImpl;
|
||||||
friend class internal::StreamingListenerTest;
|
friend class internal::StreamingListenerTest;
|
||||||
friend TestInfo* internal::MakeAndRegisterTestInfo(
|
friend TestInfo* internal::MakeAndRegisterTestInfo(
|
||||||
const char* test_suite_name, const char* name, const char* type_param,
|
std::string test_suite_name, const char* name, const char* type_param,
|
||||||
const char* value_param, internal::CodeLocation code_location,
|
const char* value_param, internal::CodeLocation code_location,
|
||||||
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc,
|
internal::TearDownTestSuiteFunc tear_down_tc,
|
||||||
@@ -616,7 +620,7 @@ class GTEST_API_ TestInfo {
|
|||||||
|
|
||||||
// Constructs a TestInfo object. The newly constructed instance assumes
|
// Constructs a TestInfo object. The newly constructed instance assumes
|
||||||
// ownership of the factory object.
|
// ownership of the factory object.
|
||||||
TestInfo(const std::string& test_suite_name, const std::string& name,
|
TestInfo(std::string test_suite_name, std::string name,
|
||||||
const char* a_type_param, // NULL if not a type-parameterized test
|
const char* a_type_param, // NULL if not a type-parameterized test
|
||||||
const char* a_value_param, // NULL if not a value-parameterized test
|
const char* a_value_param, // NULL if not a value-parameterized test
|
||||||
internal::CodeLocation a_code_location,
|
internal::CodeLocation a_code_location,
|
||||||
@@ -670,7 +674,7 @@ class GTEST_API_ TestInfo {
|
|||||||
// A test suite, which consists of a vector of TestInfos.
|
// A test suite, which consists of a vector of TestInfos.
|
||||||
//
|
//
|
||||||
// TestSuite is not copyable.
|
// TestSuite is not copyable.
|
||||||
class GTEST_API_ TestSuite {
|
class GTEST_API_ [[nodiscard]] TestSuite {
|
||||||
public:
|
public:
|
||||||
// Creates a TestSuite with the given name.
|
// Creates a TestSuite with the given name.
|
||||||
//
|
//
|
||||||
@@ -684,7 +688,7 @@ class GTEST_API_ TestSuite {
|
|||||||
// this is not a type-parameterized test.
|
// this is not a type-parameterized test.
|
||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test suite
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
TestSuite(const char* name, const char* a_type_param,
|
TestSuite(const std::string& name, const char* a_type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc);
|
internal::TearDownTestSuiteFunc tear_down_tc);
|
||||||
|
|
||||||
@@ -891,7 +895,7 @@ class GTEST_API_ TestSuite {
|
|||||||
// available.
|
// available.
|
||||||
// 2. You cannot use ASSERT_* directly in a constructor or
|
// 2. You cannot use ASSERT_* directly in a constructor or
|
||||||
// destructor.
|
// destructor.
|
||||||
class Environment {
|
class [[nodiscard]] Environment {
|
||||||
public:
|
public:
|
||||||
// The d'tor is virtual as we need to subclass Environment.
|
// The d'tor is virtual as we need to subclass Environment.
|
||||||
virtual ~Environment() = default;
|
virtual ~Environment() = default;
|
||||||
@@ -912,7 +916,7 @@ class Environment {
|
|||||||
#if GTEST_HAS_EXCEPTIONS
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
|
|
||||||
// Exception which can be thrown from TestEventListener::OnTestPartResult.
|
// Exception which can be thrown from TestEventListener::OnTestPartResult.
|
||||||
class GTEST_API_ AssertionException
|
class GTEST_API_ [[nodiscard]] AssertionException
|
||||||
: public internal::GoogleTestFailureException {
|
: public internal::GoogleTestFailureException {
|
||||||
public:
|
public:
|
||||||
explicit AssertionException(const TestPartResult& result)
|
explicit AssertionException(const TestPartResult& result)
|
||||||
@@ -923,7 +927,7 @@ class GTEST_API_ AssertionException
|
|||||||
|
|
||||||
// The interface for tracing execution of tests. The methods are organized in
|
// The interface for tracing execution of tests. The methods are organized in
|
||||||
// the order the corresponding events are fired.
|
// the order the corresponding events are fired.
|
||||||
class TestEventListener {
|
class [[nodiscard]] TestEventListener {
|
||||||
public:
|
public:
|
||||||
virtual ~TestEventListener() = default;
|
virtual ~TestEventListener() = default;
|
||||||
|
|
||||||
@@ -990,7 +994,7 @@ class TestEventListener {
|
|||||||
// the methods they override will not be caught during the build. For
|
// the methods they override will not be caught during the build. For
|
||||||
// comments about each method please see the definition of TestEventListener
|
// comments about each method please see the definition of TestEventListener
|
||||||
// above.
|
// above.
|
||||||
class EmptyTestEventListener : public TestEventListener {
|
class [[nodiscard]] EmptyTestEventListener : public TestEventListener {
|
||||||
public:
|
public:
|
||||||
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
|
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
|
||||||
void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
||||||
@@ -1020,7 +1024,7 @@ class EmptyTestEventListener : public TestEventListener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TestEventListeners lets users add listeners to track events in Google Test.
|
// TestEventListeners lets users add listeners to track events in Google Test.
|
||||||
class GTEST_API_ TestEventListeners {
|
class GTEST_API_ [[nodiscard]] TestEventListeners {
|
||||||
public:
|
public:
|
||||||
TestEventListeners();
|
TestEventListeners();
|
||||||
~TestEventListeners();
|
~TestEventListeners();
|
||||||
@@ -1111,7 +1115,7 @@ class GTEST_API_ TestEventListeners {
|
|||||||
//
|
//
|
||||||
// This class is thread-safe as long as the methods are called
|
// This class is thread-safe as long as the methods are called
|
||||||
// according to their specification.
|
// according to their specification.
|
||||||
class GTEST_API_ UnitTest {
|
class GTEST_API_ [[nodiscard]] UnitTest {
|
||||||
public:
|
public:
|
||||||
// Gets the singleton UnitTest object. The first time this method
|
// Gets the singleton UnitTest object. The first time this method
|
||||||
// is called, a UnitTest object is constructed and returned.
|
// is called, a UnitTest object is constructed and returned.
|
||||||
@@ -1124,7 +1128,7 @@ class GTEST_API_ UnitTest {
|
|||||||
// This method can only be called from the main thread.
|
// This method can only be called from the main thread.
|
||||||
//
|
//
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
int Run() GTEST_MUST_USE_RESULT_;
|
[[nodiscard]] int Run();
|
||||||
|
|
||||||
// Returns the working directory when the first TEST() or TEST_F()
|
// Returns the working directory when the first TEST() or TEST_F()
|
||||||
// was executed. The UnitTest object owns the string.
|
// was executed. The UnitTest object owns the string.
|
||||||
@@ -1247,7 +1251,7 @@ class GTEST_API_ UnitTest {
|
|||||||
// eventually call this to report their results. The user code
|
// eventually call this to report their results. The user code
|
||||||
// should use the assertion macros instead of calling this directly.
|
// should use the assertion macros instead of calling this directly.
|
||||||
void AddTestPartResult(TestPartResult::Type result_type,
|
void AddTestPartResult(TestPartResult::Type result_type,
|
||||||
const char* file_name, int line_number,
|
std::string_view file_name, int line_number,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& os_stack_trace)
|
const std::string& os_stack_trace)
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_);
|
GTEST_LOCK_EXCLUDED_(mutex_);
|
||||||
@@ -1263,6 +1267,20 @@ class GTEST_API_ UnitTest {
|
|||||||
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
||||||
TestSuite* GetMutableTestSuite(int i);
|
TestSuite* GetMutableTestSuite(int i);
|
||||||
|
|
||||||
|
// Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest()
|
||||||
|
// should be called immediately before Google Test calls user code. It saves
|
||||||
|
// some information about the current stack that CurrentStackTrace() will use
|
||||||
|
// to find and hide Google Test stack frames.
|
||||||
|
void UponLeavingGTest();
|
||||||
|
|
||||||
|
// Sets the TestSuite object for the test that's currently running.
|
||||||
|
void set_current_test_suite(TestSuite* a_current_test_suite)
|
||||||
|
GTEST_LOCK_EXCLUDED_(mutex_);
|
||||||
|
|
||||||
|
// Sets the TestInfo object for the test that's currently running.
|
||||||
|
void set_current_test_info(TestInfo* a_current_test_info)
|
||||||
|
GTEST_LOCK_EXCLUDED_(mutex_);
|
||||||
|
|
||||||
// Accessors for the implementation object.
|
// Accessors for the implementation object.
|
||||||
internal::UnitTestImpl* impl() { return impl_; }
|
internal::UnitTestImpl* impl() { return impl_; }
|
||||||
const internal::UnitTestImpl* impl() const { return impl_; }
|
const internal::UnitTestImpl* impl() const { return impl_; }
|
||||||
@@ -1271,6 +1289,8 @@ class GTEST_API_ UnitTest {
|
|||||||
// members of UnitTest.
|
// members of UnitTest.
|
||||||
friend class ScopedTrace;
|
friend class ScopedTrace;
|
||||||
friend class Test;
|
friend class Test;
|
||||||
|
friend class TestInfo;
|
||||||
|
friend class TestSuite;
|
||||||
friend class internal::AssertHelper;
|
friend class internal::AssertHelper;
|
||||||
friend class internal::StreamingListenerTest;
|
friend class internal::StreamingListenerTest;
|
||||||
friend class internal::UnitTestRecordPropertyTestHelper;
|
friend class internal::UnitTestRecordPropertyTestHelper;
|
||||||
@@ -1383,7 +1403,7 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
|
|||||||
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
|
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EqHelper {
|
class [[nodiscard]] EqHelper {
|
||||||
public:
|
public:
|
||||||
// This templatized version is for the general case.
|
// This templatized version is for the general case.
|
||||||
template <
|
template <
|
||||||
@@ -1574,12 +1594,12 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
|
|||||||
}
|
}
|
||||||
|
|
||||||
::std::stringstream lhs_ss;
|
::std::stringstream lhs_ss;
|
||||||
lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
|
||||||
<< lhs_value;
|
lhs_ss << lhs_value;
|
||||||
|
|
||||||
::std::stringstream rhs_ss;
|
::std::stringstream rhs_ss;
|
||||||
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
|
||||||
<< rhs_value;
|
rhs_ss << rhs_value;
|
||||||
|
|
||||||
return EqFailure(lhs_expression, rhs_expression,
|
return EqFailure(lhs_expression, rhs_expression,
|
||||||
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
|
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
|
||||||
@@ -1595,18 +1615,23 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
|
|||||||
double val1, double val2,
|
double val1, double val2,
|
||||||
double abs_error);
|
double abs_error);
|
||||||
|
|
||||||
|
using GoogleTest_NotSupported_OnFunctionReturningNonVoid = void;
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
// A class that enables one to stream messages to assertion macros
|
// A class that enables one to stream messages to assertion macros
|
||||||
class GTEST_API_ AssertHelper {
|
class GTEST_API_ [[nodiscard]] AssertHelper {
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
AssertHelper(TestPartResult::Type type, const char* file, int line,
|
AssertHelper(TestPartResult::Type type, const char* file, int line,
|
||||||
const char* message);
|
const char* message);
|
||||||
|
AssertHelper(TestPartResult::Type type, std::string_view file, int line,
|
||||||
|
std::string_view message);
|
||||||
~AssertHelper();
|
~AssertHelper();
|
||||||
|
|
||||||
// Message assignment is a semantic trick to enable assertion
|
// Message assignment is a semantic trick to enable assertion
|
||||||
// streaming; see the GTEST_MESSAGE_ macro below.
|
// streaming; see the GTEST_MESSAGE_ macro below.
|
||||||
void operator=(const Message& message) const;
|
GoogleTest_NotSupported_OnFunctionReturningNonVoid operator=(
|
||||||
|
const Message& message) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// We put our data in a struct so that the size of the AssertHelper class can
|
// We put our data in a struct so that the size of the AssertHelper class can
|
||||||
@@ -1614,12 +1639,12 @@ class GTEST_API_ AssertHelper {
|
|||||||
// re-using stack space even for temporary variables, so every EXPECT_EQ
|
// re-using stack space even for temporary variables, so every EXPECT_EQ
|
||||||
// reserves stack space for another AssertHelper.
|
// reserves stack space for another AssertHelper.
|
||||||
struct AssertHelperData {
|
struct AssertHelperData {
|
||||||
AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,
|
AssertHelperData(TestPartResult::Type t, std::string_view srcfile,
|
||||||
const char* msg)
|
int line_num, std::string_view msg)
|
||||||
: type(t), file(srcfile), line(line_num), message(msg) {}
|
: type(t), file(srcfile), line(line_num), message(msg) {}
|
||||||
|
|
||||||
TestPartResult::Type const type;
|
TestPartResult::Type const type;
|
||||||
const char* const file;
|
const std::string_view file;
|
||||||
int const line;
|
int const line;
|
||||||
std::string const message;
|
std::string const message;
|
||||||
|
|
||||||
@@ -1671,14 +1696,14 @@ class GTEST_API_ AssertHelper {
|
|||||||
// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
|
// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class WithParamInterface {
|
class [[nodiscard]] WithParamInterface {
|
||||||
public:
|
public:
|
||||||
typedef T ParamType;
|
typedef T ParamType;
|
||||||
virtual ~WithParamInterface() = default;
|
virtual ~WithParamInterface() = default;
|
||||||
|
|
||||||
// The current parameter value. Is also available in the test fixture's
|
// The current parameter value. Is also available in the test fixture's
|
||||||
// constructor.
|
// constructor.
|
||||||
static const ParamType& GetParam() {
|
[[nodiscard]] static const ParamType& GetParam() {
|
||||||
GTEST_CHECK_(parameter_ != nullptr)
|
GTEST_CHECK_(parameter_ != nullptr)
|
||||||
<< "GetParam() can only be called inside a value-parameterized test "
|
<< "GetParam() can only be called inside a value-parameterized test "
|
||||||
<< "-- did you intend to write TEST_P instead of TEST_F?";
|
<< "-- did you intend to write TEST_P instead of TEST_F?";
|
||||||
@@ -1705,7 +1730,8 @@ const T* WithParamInterface<T>::parameter_ = nullptr;
|
|||||||
// WithParamInterface, and can just inherit from ::testing::TestWithParam.
|
// WithParamInterface, and can just inherit from ::testing::TestWithParam.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TestWithParam : public Test, public WithParamInterface<T> {};
|
class [[nodiscard]] TestWithParam : public Test,
|
||||||
|
public WithParamInterface<T> {};
|
||||||
|
|
||||||
// Macros for indicating success/failure in test code.
|
// Macros for indicating success/failure in test code.
|
||||||
|
|
||||||
@@ -1752,6 +1778,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
|||||||
// generic name and clashes with some other libraries.
|
// generic name and clashes with some other libraries.
|
||||||
#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
|
#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
|
||||||
#define FAIL() GTEST_FAIL()
|
#define FAIL() GTEST_FAIL()
|
||||||
|
#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Generates a success with a generic message.
|
// Generates a success with a generic message.
|
||||||
@@ -2052,7 +2079,7 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
|
|||||||
// Example:
|
// Example:
|
||||||
// testing::ScopedTrace trace("file.cc", 123, "message");
|
// testing::ScopedTrace trace("file.cc", 123, "message");
|
||||||
//
|
//
|
||||||
class GTEST_API_ ScopedTrace {
|
class GTEST_API_ [[nodiscard]] ScopedTrace {
|
||||||
public:
|
public:
|
||||||
// The c'tor pushes the given source file location and message onto
|
// The c'tor pushes the given source file location and message onto
|
||||||
// a trace stack maintained by Google Test.
|
// a trace stack maintained by Google Test.
|
||||||
@@ -2308,11 +2335,12 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
|
|||||||
// tests are successful, or 1 otherwise.
|
// tests are successful, or 1 otherwise.
|
||||||
//
|
//
|
||||||
// RUN_ALL_TESTS() should be invoked after the command line has been
|
// RUN_ALL_TESTS() should be invoked after the command line has been
|
||||||
// parsed by InitGoogleTest().
|
// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any
|
||||||
|
// installed environments and should only be called once per binary.
|
||||||
//
|
//
|
||||||
// This function was formerly a macro; thus, it is in the global
|
// This function was formerly a macro; thus, it is in the global
|
||||||
// namespace and has an all-caps name.
|
// namespace and has an all-caps name.
|
||||||
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
|
[[nodiscard]] int RUN_ALL_TESTS();
|
||||||
|
|
||||||
inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }
|
inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }
|
||||||
|
|
||||||
|
|||||||
@@ -46,17 +46,38 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-matchers.h"
|
#include "gtest/gtest-matchers.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
GTEST_DECLARE_string_(internal_run_death_test);
|
GTEST_DECLARE_string_(internal_run_death_test);
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Names of the flags (needed for parsing Google Test flags).
|
// Name of the flag (needed for parsing Google Test flag).
|
||||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
|
||||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
|
||||||
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
||||||
|
|
||||||
|
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
|
||||||
|
// and interpreted as a regex (rather than an Eq matcher) for legacy
|
||||||
|
// compatibility.
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
::testing::internal::RE regex) {
|
||||||
|
return ContainsRegex(regex.pattern());
|
||||||
|
}
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
|
||||||
|
return ContainsRegex(regex);
|
||||||
|
}
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
const ::std::string& regex) {
|
||||||
|
return ContainsRegex(regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
|
||||||
|
// used directly.
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
Matcher<const ::std::string&> matcher) {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GTEST_HAS_DEATH_TEST
|
#ifdef GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
@@ -73,9 +94,9 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|||||||
//
|
//
|
||||||
// exit status: The integer exit information in the format specified
|
// exit status: The integer exit information in the format specified
|
||||||
// by wait(2)
|
// by wait(2)
|
||||||
// exit code: The integer code passed to exit(3), _exit(2), or
|
// exit code: The integer code passed to exit(3), _Exit(2), or
|
||||||
// returned from main()
|
// returned from main()
|
||||||
class GTEST_API_ DeathTest {
|
class GTEST_API_ [[nodiscard]] DeathTest {
|
||||||
public:
|
public:
|
||||||
// Create returns false if there was an error determining the
|
// Create returns false if there was an error determining the
|
||||||
// appropriate action to take for the current death test; for example,
|
// appropriate action to take for the current death test; for example,
|
||||||
@@ -151,7 +172,7 @@ class GTEST_API_ DeathTest {
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
// Factory interface for death tests. May be mocked out for testing.
|
// Factory interface for death tests. May be mocked out for testing.
|
||||||
class DeathTestFactory {
|
class [[nodiscard]] DeathTestFactory {
|
||||||
public:
|
public:
|
||||||
virtual ~DeathTestFactory() = default;
|
virtual ~DeathTestFactory() = default;
|
||||||
virtual bool Create(const char* statement,
|
virtual bool Create(const char* statement,
|
||||||
@@ -160,7 +181,7 @@ class DeathTestFactory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A concrete DeathTestFactory implementation for normal use.
|
// A concrete DeathTestFactory implementation for normal use.
|
||||||
class DefaultDeathTestFactory : public DeathTestFactory {
|
class [[nodiscard]] DefaultDeathTestFactory : public DeathTestFactory {
|
||||||
public:
|
public:
|
||||||
bool Create(const char* statement, Matcher<const std::string&> matcher,
|
bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||||
const char* file, int line, DeathTest** test) override;
|
const char* file, int line, DeathTest** test) override;
|
||||||
@@ -170,28 +191,6 @@ class DefaultDeathTestFactory : public DeathTestFactory {
|
|||||||
// by a signal, or exited normally with a nonzero exit code.
|
// by a signal, or exited normally with a nonzero exit code.
|
||||||
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
||||||
|
|
||||||
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
|
|
||||||
// and interpreted as a regex (rather than an Eq matcher) for legacy
|
|
||||||
// compatibility.
|
|
||||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|
||||||
::testing::internal::RE regex) {
|
|
||||||
return ContainsRegex(regex.pattern());
|
|
||||||
}
|
|
||||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
|
|
||||||
return ContainsRegex(regex);
|
|
||||||
}
|
|
||||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|
||||||
const ::std::string& regex) {
|
|
||||||
return ContainsRegex(regex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
|
|
||||||
// used directly.
|
|
||||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|
||||||
Matcher<const ::std::string&> matcher) {
|
|
||||||
return matcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Traps C++ exceptions escaping statement and reports them as test
|
// Traps C++ exceptions escaping statement and reports them as test
|
||||||
// failures. Note that trapping SEH exceptions is not implemented here.
|
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||||
#if GTEST_HAS_EXCEPTIONS
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
@@ -257,19 +256,19 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|||||||
// must accept a streamed message even though the message is never printed.
|
// must accept a streamed message even though the message is never printed.
|
||||||
// The regex object is not evaluated, but it is used to prevent "unused"
|
// The regex object is not evaluated, but it is used to prevent "unused"
|
||||||
// warnings and to avoid an expression that doesn't compile in debug mode.
|
// warnings and to avoid an expression that doesn't compile in debug mode.
|
||||||
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
||||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
if (::testing::internal::AlwaysTrue()) { \
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||||
} else if (!::testing::internal::AlwaysTrue()) { \
|
} else if (!::testing::internal::AlwaysTrue()) { \
|
||||||
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
(void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||||
} else \
|
} else \
|
||||||
::testing::Message()
|
::testing::Message()
|
||||||
|
|
||||||
// A class representing the parsed contents of the
|
// A class representing the parsed contents of the
|
||||||
// --gtest_internal_run_death_test flag, as it existed when
|
// --gtest_internal_run_death_test flag, as it existed when
|
||||||
// RUN_ALL_TESTS was called.
|
// RUN_ALL_TESTS was called.
|
||||||
class InternalRunDeathTestFlag {
|
class [[nodiscard]] InternalRunDeathTestFlag {
|
||||||
public:
|
public:
|
||||||
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
|
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
|
||||||
int a_write_fd)
|
int a_write_fd)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gtest/internal/gtest-string.h"
|
#include "gtest/internal/gtest-string.h"
|
||||||
@@ -66,12 +67,13 @@ namespace internal {
|
|||||||
// Names are NOT checked for syntax correctness -- no checking for illegal
|
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||||
// characters, malformed paths, etc.
|
// characters, malformed paths, etc.
|
||||||
|
|
||||||
class GTEST_API_ FilePath {
|
class GTEST_API_ [[nodiscard]] FilePath {
|
||||||
public:
|
public:
|
||||||
FilePath() : pathname_("") {}
|
FilePath() : pathname_("") {}
|
||||||
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
||||||
|
FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}
|
||||||
|
|
||||||
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {
|
||||||
Normalize();
|
Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +81,10 @@ class GTEST_API_ FilePath {
|
|||||||
Set(rhs);
|
Set(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
FilePath& operator=(FilePath&& rhs) noexcept {
|
||||||
|
pathname_ = std::move(rhs.pathname_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iomanip>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
@@ -79,7 +78,7 @@
|
|||||||
//
|
//
|
||||||
// will result in the token foo__LINE__, instead of foo followed by
|
// will result in the token foo__LINE__, instead of foo followed by
|
||||||
// the current line number. For more details, see
|
// the current line number. For more details, see
|
||||||
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
// https://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
||||||
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
|
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
|
||||||
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
|
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
|
||||||
|
|
||||||
@@ -96,7 +95,7 @@
|
|||||||
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
|
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
|
||||||
|
|
||||||
namespace proto2 {
|
namespace proto2 {
|
||||||
class MessageLite;
|
class [[nodiscard]] MessageLite;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@@ -116,15 +115,15 @@ template <typename T>
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
struct TraceInfo; // Information about a trace point.
|
struct TraceInfo; // Information about a trace point.
|
||||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
class [[nodiscard]] TestInfoImpl; // Opaque implementation of TestInfo
|
||||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
class [[nodiscard]] UnitTestImpl; // Opaque implementation of UnitTest
|
||||||
|
|
||||||
// The text used in failure messages to indicate the start of the
|
// The text used in failure messages to indicate the start of the
|
||||||
// stack trace.
|
// stack trace.
|
||||||
GTEST_API_ extern const char kStackTraceMarker[];
|
GTEST_API_ extern const char kStackTraceMarker[];
|
||||||
|
|
||||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||||
class IgnoredValue {
|
class [[nodiscard]] IgnoredValue {
|
||||||
struct Sink {};
|
struct Sink {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -156,7 +155,8 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
|||||||
// errors presumably detectable only at run time. Since
|
// errors presumably detectable only at run time. Since
|
||||||
// std::runtime_error inherits from std::exception, many testing
|
// std::runtime_error inherits from std::exception, many testing
|
||||||
// frameworks know how to extract and print the message inside it.
|
// frameworks know how to extract and print the message inside it.
|
||||||
class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
|
class GTEST_API_ [[nodiscard]] GoogleTestFailureException
|
||||||
|
: public ::std::runtime_error {
|
||||||
public:
|
public:
|
||||||
explicit GoogleTestFailureException(const TestPartResult& failure);
|
explicit GoogleTestFailureException(const TestPartResult& failure);
|
||||||
};
|
};
|
||||||
@@ -170,7 +170,7 @@ namespace edit_distance {
|
|||||||
// All edits cost the same, with replace having lower priority than
|
// All edits cost the same, with replace having lower priority than
|
||||||
// add/remove.
|
// add/remove.
|
||||||
// Simple implementation of the Wagner-Fischer algorithm.
|
// Simple implementation of the Wagner-Fischer algorithm.
|
||||||
// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
|
// See https://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
|
||||||
enum EditType { kMatch, kAdd, kRemove, kReplace };
|
enum EditType { kMatch, kAdd, kRemove, kReplace };
|
||||||
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
||||||
const std::vector<size_t>& left, const std::vector<size_t>& right);
|
const std::vector<size_t>& left, const std::vector<size_t>& right);
|
||||||
@@ -237,13 +237,13 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage(
|
|||||||
// For double, there are 11 exponent bits and 52 fraction bits.
|
// For double, there are 11 exponent bits and 52 fraction bits.
|
||||||
//
|
//
|
||||||
// More details can be found at
|
// More details can be found at
|
||||||
// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
|
// https://en.wikipedia.org/wiki/IEEE_floating-point_standard.
|
||||||
//
|
//
|
||||||
// Template parameter:
|
// Template parameter:
|
||||||
//
|
//
|
||||||
// RawType: the raw floating-point type (either float or double)
|
// RawType: the raw floating-point type (either float or double)
|
||||||
template <typename RawType>
|
template <typename RawType>
|
||||||
class FloatingPoint {
|
class [[nodiscard]] FloatingPoint {
|
||||||
public:
|
public:
|
||||||
// Defines the unsigned integer type that has the same size as the
|
// Defines the unsigned integer type that has the same size as the
|
||||||
// floating point number.
|
// floating point number.
|
||||||
@@ -282,7 +282,7 @@ class FloatingPoint {
|
|||||||
// bits. Therefore, 4 should be enough for ordinary use.
|
// bits. Therefore, 4 should be enough for ordinary use.
|
||||||
//
|
//
|
||||||
// See the following article for more details on ULP:
|
// See the following article for more details on ULP:
|
||||||
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
||||||
static const uint32_t kMaxUlps = 4;
|
static const uint32_t kMaxUlps = 4;
|
||||||
|
|
||||||
// Constructs a FloatingPoint from a raw floating-point number.
|
// Constructs a FloatingPoint from a raw floating-point number.
|
||||||
@@ -291,17 +291,17 @@ class FloatingPoint {
|
|||||||
// around may change its bits, although the new value is guaranteed
|
// around may change its bits, although the new value is guaranteed
|
||||||
// to be also a NAN. Therefore, don't expect this constructor to
|
// to be also a NAN. Therefore, don't expect this constructor to
|
||||||
// preserve the bits in x when x is a NAN.
|
// preserve the bits in x when x is a NAN.
|
||||||
explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
|
explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
|
|
||||||
// Reinterprets a bit pattern as a floating-point number.
|
// Reinterprets a bit pattern as a floating-point number.
|
||||||
//
|
//
|
||||||
// This function is needed to test the AlmostEquals() method.
|
// This function is needed to test the AlmostEquals() method.
|
||||||
static RawType ReinterpretBits(const Bits bits) {
|
static RawType ReinterpretBits(Bits bits) {
|
||||||
FloatingPoint fp(0);
|
RawType fp;
|
||||||
fp.u_.bits_ = bits;
|
memcpy(&fp, &bits, sizeof(fp));
|
||||||
return fp.u_.value_;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the floating-point number that represent positive infinity.
|
// Returns the floating-point number that represent positive infinity.
|
||||||
@@ -310,16 +310,16 @@ class FloatingPoint {
|
|||||||
// Non-static methods
|
// Non-static methods
|
||||||
|
|
||||||
// Returns the bits that represents this number.
|
// Returns the bits that represents this number.
|
||||||
const Bits& bits() const { return u_.bits_; }
|
const Bits& bits() const { return bits_; }
|
||||||
|
|
||||||
// Returns the exponent bits of this number.
|
// Returns the exponent bits of this number.
|
||||||
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
|
Bits exponent_bits() const { return kExponentBitMask & bits_; }
|
||||||
|
|
||||||
// Returns the fraction bits of this number.
|
// Returns the fraction bits of this number.
|
||||||
Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
|
Bits fraction_bits() const { return kFractionBitMask & bits_; }
|
||||||
|
|
||||||
// Returns the sign bit of this number.
|
// Returns the sign bit of this number.
|
||||||
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
|
Bits sign_bit() const { return kSignBitMask & bits_; }
|
||||||
|
|
||||||
// Returns true if and only if this is NAN (not a number).
|
// Returns true if and only if this is NAN (not a number).
|
||||||
bool is_nan() const {
|
bool is_nan() const {
|
||||||
@@ -333,23 +333,16 @@ class FloatingPoint {
|
|||||||
//
|
//
|
||||||
// - returns false if either number is (or both are) NAN.
|
// - returns false if either number is (or both are) NAN.
|
||||||
// - treats really large numbers as almost equal to infinity.
|
// - treats really large numbers as almost equal to infinity.
|
||||||
// - thinks +0.0 and -0.0 are 0 DLP's apart.
|
// - thinks +0.0 and -0.0 are 0 ULP's apart.
|
||||||
bool AlmostEquals(const FloatingPoint& rhs) const {
|
bool AlmostEquals(const FloatingPoint& rhs) const {
|
||||||
// The IEEE standard says that any comparison operation involving
|
// The IEEE standard says that any comparison operation involving
|
||||||
// a NAN must return false.
|
// a NAN must return false.
|
||||||
if (is_nan() || rhs.is_nan()) return false;
|
if (is_nan() || rhs.is_nan()) return false;
|
||||||
|
|
||||||
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
|
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
|
||||||
kMaxUlps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The data type used to store the actual floating-point number.
|
|
||||||
union FloatingPointUnion {
|
|
||||||
RawType value_; // The raw floating-point number.
|
|
||||||
Bits bits_; // The bits that represent the number.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Converts an integer from the sign-and-magnitude representation to
|
// Converts an integer from the sign-and-magnitude representation to
|
||||||
// the biased representation. More precisely, let N be 2 to the
|
// the biased representation. More precisely, let N be 2 to the
|
||||||
// power of (kBitCount - 1), an integer x is represented by the
|
// power of (kBitCount - 1), an integer x is represented by the
|
||||||
@@ -363,9 +356,9 @@ class FloatingPoint {
|
|||||||
// N - 1 (the biggest number representable using
|
// N - 1 (the biggest number representable using
|
||||||
// sign-and-magnitude) is represented by 2N - 1.
|
// sign-and-magnitude) is represented by 2N - 1.
|
||||||
//
|
//
|
||||||
// Read http://en.wikipedia.org/wiki/Signed_number_representations
|
// Read https://en.wikipedia.org/wiki/Signed_number_representations
|
||||||
// for more details on signed number representations.
|
// for more details on signed number representations.
|
||||||
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
static Bits SignAndMagnitudeToBiased(Bits sam) {
|
||||||
if (kSignBitMask & sam) {
|
if (kSignBitMask & sam) {
|
||||||
// sam represents a negative number.
|
// sam represents a negative number.
|
||||||
return ~sam + 1;
|
return ~sam + 1;
|
||||||
@@ -377,14 +370,13 @@ class FloatingPoint {
|
|||||||
|
|
||||||
// Given two numbers in the sign-and-magnitude representation,
|
// Given two numbers in the sign-and-magnitude representation,
|
||||||
// returns the distance between them as an unsigned number.
|
// returns the distance between them as an unsigned number.
|
||||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
|
static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
|
||||||
const Bits& sam2) {
|
|
||||||
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
||||||
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
||||||
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingPointUnion u_;
|
Bits bits_; // The bits that represent the number.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Typedefs the instances of the FloatingPoint template class that we
|
// Typedefs the instances of the FloatingPoint template class that we
|
||||||
@@ -401,7 +393,7 @@ typedef FloatingPoint<double> Double;
|
|||||||
typedef const void* TypeId;
|
typedef const void* TypeId;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TypeIdHelper {
|
class [[nodiscard]] TypeIdHelper {
|
||||||
public:
|
public:
|
||||||
// dummy_ must not have a const type. Otherwise an overly eager
|
// dummy_ must not have a const type. Otherwise an overly eager
|
||||||
// compiler (e.g. MSVC 7.1 & 8.0) may try to merge
|
// compiler (e.g. MSVC 7.1 & 8.0) may try to merge
|
||||||
@@ -433,7 +425,7 @@ GTEST_API_ TypeId GetTestTypeId();
|
|||||||
|
|
||||||
// Defines the abstract factory interface that creates instances
|
// Defines the abstract factory interface that creates instances
|
||||||
// of a Test object.
|
// of a Test object.
|
||||||
class TestFactoryBase {
|
class [[nodiscard]] TestFactoryBase {
|
||||||
public:
|
public:
|
||||||
virtual ~TestFactoryBase() = default;
|
virtual ~TestFactoryBase() = default;
|
||||||
|
|
||||||
@@ -452,7 +444,7 @@ class TestFactoryBase {
|
|||||||
// This class provides implementation of TestFactoryBase interface.
|
// This class provides implementation of TestFactoryBase interface.
|
||||||
// It is used in TEST and TEST_F macros.
|
// It is used in TEST and TEST_F macros.
|
||||||
template <class TestClass>
|
template <class TestClass>
|
||||||
class TestFactoryImpl : public TestFactoryBase {
|
class [[nodiscard]] TestFactoryImpl : public TestFactoryBase {
|
||||||
public:
|
public:
|
||||||
Test* CreateTest() override { return new TestClass; }
|
Test* CreateTest() override { return new TestClass; }
|
||||||
};
|
};
|
||||||
@@ -475,8 +467,8 @@ using SetUpTestSuiteFunc = void (*)();
|
|||||||
using TearDownTestSuiteFunc = void (*)();
|
using TearDownTestSuiteFunc = void (*)();
|
||||||
|
|
||||||
struct CodeLocation {
|
struct CodeLocation {
|
||||||
CodeLocation(const std::string& a_file, int a_line)
|
CodeLocation(std::string a_file, int a_line)
|
||||||
: file(a_file), line(a_line) {}
|
: file(std::move(a_file)), line(a_line) {}
|
||||||
|
|
||||||
std::string file;
|
std::string file;
|
||||||
int line;
|
int line;
|
||||||
@@ -556,7 +548,7 @@ struct SuiteApiResolver : T {
|
|||||||
// type_param: the name of the test's type parameter, or NULL if
|
// type_param: the name of the test's type parameter, or NULL if
|
||||||
// this is not a typed or a type-parameterized test.
|
// this is not a typed or a type-parameterized test.
|
||||||
// value_param: text representation of the test's value parameter,
|
// value_param: text representation of the test's value parameter,
|
||||||
// or NULL if this is not a type-parameterized test.
|
// or NULL if this is not a value-parameterized test.
|
||||||
// code_location: code location where the test is defined
|
// code_location: code location where the test is defined
|
||||||
// fixture_class_id: ID of the test fixture class
|
// fixture_class_id: ID of the test fixture class
|
||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
@@ -565,7 +557,7 @@ struct SuiteApiResolver : T {
|
|||||||
// The newly created TestInfo instance will assume
|
// The newly created TestInfo instance will assume
|
||||||
// ownership of the factory object.
|
// ownership of the factory object.
|
||||||
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
||||||
const char* test_suite_name, const char* name, const char* type_param,
|
std::string test_suite_name, const char* name, const char* type_param,
|
||||||
const char* value_param, CodeLocation code_location,
|
const char* value_param, CodeLocation code_location,
|
||||||
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
||||||
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
||||||
@@ -579,7 +571,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|||||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
// State of the definition of a type-parameterized test suite.
|
// State of the definition of a type-parameterized test suite.
|
||||||
class GTEST_API_ TypedTestSuitePState {
|
class GTEST_API_ [[nodiscard]] TypedTestSuitePState {
|
||||||
public:
|
public:
|
||||||
TypedTestSuitePState() : registered_(false) {}
|
TypedTestSuitePState() : registered_(false) {}
|
||||||
|
|
||||||
@@ -596,8 +588,7 @@ class GTEST_API_ TypedTestSuitePState {
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
posix::Abort();
|
posix::Abort();
|
||||||
}
|
}
|
||||||
registered_tests_.insert(
|
registered_tests_.emplace(test_name, CodeLocation(file, line));
|
||||||
::std::make_pair(test_name, CodeLocation(file, line)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -695,13 +686,13 @@ std::vector<std::string> GenerateNames() {
|
|||||||
// Implementation note: The GTEST_TEMPLATE_ macro declares a template
|
// Implementation note: The GTEST_TEMPLATE_ macro declares a template
|
||||||
// template parameter. It's defined in gtest-type-util.h.
|
// template parameter. It's defined in gtest-type-util.h.
|
||||||
template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
|
||||||
class TypeParameterizedTest {
|
class [[nodiscard]] TypeParameterizedTest {
|
||||||
public:
|
public:
|
||||||
// 'index' is the index of the test in the type list 'Types'
|
// 'index' is the index of the test in the type list 'Types'
|
||||||
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
||||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||||
// length of Types.
|
// length of Types.
|
||||||
static bool Register(const char* prefix, const CodeLocation& code_location,
|
static bool Register(const char* prefix, CodeLocation code_location,
|
||||||
const char* case_name, const char* test_names, int index,
|
const char* case_name, const char* test_names, int index,
|
||||||
const std::vector<std::string>& type_names =
|
const std::vector<std::string>& type_names =
|
||||||
GenerateNames<DefaultNameGenerator, Types>()) {
|
GenerateNames<DefaultNameGenerator, Types>()) {
|
||||||
@@ -713,8 +704,7 @@ class TypeParameterizedTest {
|
|||||||
// list.
|
// list.
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
||||||
"/" + type_names[static_cast<size_t>(index)])
|
"/" + type_names[static_cast<size_t>(index)]),
|
||||||
.c_str(),
|
|
||||||
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
||||||
GetTypeName<Type>().c_str(),
|
GetTypeName<Type>().c_str(),
|
||||||
nullptr, // No value parameter.
|
nullptr, // No value parameter.
|
||||||
@@ -726,21 +716,17 @@ class TypeParameterizedTest {
|
|||||||
new TestFactoryImpl<TestClass>);
|
new TestFactoryImpl<TestClass>);
|
||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the type list.
|
// Next, recurses (at compile time) with the tail of the type list.
|
||||||
return TypeParameterizedTest<Fixture, TestSel,
|
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
|
||||||
typename Types::Tail>::Register(prefix,
|
Register(prefix, std::move(code_location), case_name, test_names,
|
||||||
code_location,
|
index + 1, type_names);
|
||||||
case_name,
|
|
||||||
test_names,
|
|
||||||
index + 1,
|
|
||||||
type_names);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The base case for the compile time recursion.
|
// The base case for the compile time recursion.
|
||||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||||
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
class [[nodiscard]] TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||||
const char* /*case_name*/, const char* /*test_names*/,
|
const char* /*case_name*/, const char* /*test_names*/,
|
||||||
int /*index*/,
|
int /*index*/,
|
||||||
const std::vector<std::string>& =
|
const std::vector<std::string>& =
|
||||||
@@ -759,7 +745,7 @@ GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
|
|||||||
// Test. The return value is insignificant - we just need to return
|
// Test. The return value is insignificant - we just need to return
|
||||||
// something such that we can call this function in a namespace scope.
|
// something such that we can call this function in a namespace scope.
|
||||||
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
||||||
class TypeParameterizedTestSuite {
|
class [[nodiscard]] TypeParameterizedTestSuite {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* prefix, CodeLocation code_location,
|
static bool Register(const char* prefix, CodeLocation code_location,
|
||||||
const TypedTestSuitePState* state, const char* case_name,
|
const TypedTestSuitePState* state, const char* case_name,
|
||||||
@@ -787,7 +773,8 @@ class TypeParameterizedTestSuite {
|
|||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the test list.
|
// Next, recurses (at compile time) with the tail of the test list.
|
||||||
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
||||||
Types>::Register(prefix, code_location,
|
Types>::Register(prefix,
|
||||||
|
std::move(code_location),
|
||||||
state, case_name,
|
state, case_name,
|
||||||
SkipComma(test_names),
|
SkipComma(test_names),
|
||||||
type_names);
|
type_names);
|
||||||
@@ -796,7 +783,7 @@ class TypeParameterizedTestSuite {
|
|||||||
|
|
||||||
// The base case for the compile time recursion.
|
// The base case for the compile time recursion.
|
||||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||||
class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
|
class [[nodiscard]] TypeParameterizedTestSuite<Fixture, internal::None, Types> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||||
const TypedTestSuitePState* /*state*/,
|
const TypedTestSuitePState* /*state*/,
|
||||||
@@ -852,7 +839,7 @@ struct TrueWithString {
|
|||||||
// doesn't use global state (and therefore can't interfere with user
|
// doesn't use global state (and therefore can't interfere with user
|
||||||
// code). Unlike rand_r(), it's portable. An LCG isn't very random,
|
// code). Unlike rand_r(), it's portable. An LCG isn't very random,
|
||||||
// but it's good enough for our purposes.
|
// but it's good enough for our purposes.
|
||||||
class GTEST_API_ Random {
|
class GTEST_API_ [[nodiscard]] Random {
|
||||||
public:
|
public:
|
||||||
static const uint32_t kMaxRange = 1u << 31;
|
static const uint32_t kMaxRange = 1u << 31;
|
||||||
|
|
||||||
@@ -878,7 +865,7 @@ class GTEST_API_ Random {
|
|||||||
// that's true if and only if T has methods DebugString() and ShortDebugString()
|
// that's true if and only if T has methods DebugString() and ShortDebugString()
|
||||||
// that return std::string.
|
// that return std::string.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class HasDebugStringAndShortDebugString {
|
class [[nodiscard]] HasDebugStringAndShortDebugString {
|
||||||
private:
|
private:
|
||||||
template <typename C>
|
template <typename C>
|
||||||
static auto CheckDebugString(C*) -> typename std::is_same<
|
static auto CheckDebugString(C*) -> typename std::is_same<
|
||||||
@@ -900,11 +887,6 @@ class HasDebugStringAndShortDebugString {
|
|||||||
HasDebugStringType::value && HasShortDebugStringType::value;
|
HasDebugStringType::value && HasShortDebugStringType::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
|
||||||
template <typename T>
|
|
||||||
constexpr bool HasDebugStringAndShortDebugString<T>::value;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// When the compiler sees expression IsContainerTest<C>(0), if C is an
|
// When the compiler sees expression IsContainerTest<C>(0), if C is an
|
||||||
// STL-style container class, the first overload of IsContainerTest
|
// STL-style container class, the first overload of IsContainerTest
|
||||||
// will be viable (since both C::iterator* and C::const_iterator* are
|
// will be viable (since both C::iterator* and C::const_iterator* are
|
||||||
@@ -1083,7 +1065,7 @@ struct RelationToSourceCopy {};
|
|||||||
// this requirement. Element can be an array type itself (hence
|
// this requirement. Element can be an array type itself (hence
|
||||||
// multi-dimensional arrays are supported).
|
// multi-dimensional arrays are supported).
|
||||||
template <typename Element>
|
template <typename Element>
|
||||||
class NativeArray {
|
class [[nodiscard]] NativeArray {
|
||||||
public:
|
public:
|
||||||
// STL-style container typedefs.
|
// STL-style container typedefs.
|
||||||
typedef Element value_type;
|
typedef Element value_type;
|
||||||
@@ -1143,40 +1125,6 @@ class NativeArray {
|
|||||||
void (NativeArray::*clone_)(const Element*, size_t);
|
void (NativeArray::*clone_)(const Element*, size_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Backport of std::index_sequence.
|
|
||||||
template <size_t... Is>
|
|
||||||
struct IndexSequence {
|
|
||||||
using type = IndexSequence;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Double the IndexSequence, and one if plus_one is true.
|
|
||||||
template <bool plus_one, typename T, size_t sizeofT>
|
|
||||||
struct DoubleSequence;
|
|
||||||
template <size_t... I, size_t sizeofT>
|
|
||||||
struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
|
|
||||||
using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
|
|
||||||
};
|
|
||||||
template <size_t... I, size_t sizeofT>
|
|
||||||
struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
|
|
||||||
using type = IndexSequence<I..., (sizeofT + I)...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Backport of std::make_index_sequence.
|
|
||||||
// It uses O(ln(N)) instantiation depth.
|
|
||||||
template <size_t N>
|
|
||||||
struct MakeIndexSequenceImpl
|
|
||||||
: DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
|
|
||||||
N / 2>::type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
|
|
||||||
|
|
||||||
template <size_t N>
|
|
||||||
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
|
|
||||||
|
|
||||||
template <typename... T>
|
|
||||||
using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
|
|
||||||
|
|
||||||
template <size_t>
|
template <size_t>
|
||||||
struct Ignore {
|
struct Ignore {
|
||||||
Ignore(...); // NOLINT
|
Ignore(...); // NOLINT
|
||||||
@@ -1185,7 +1133,7 @@ struct Ignore {
|
|||||||
template <typename>
|
template <typename>
|
||||||
struct ElemFromListImpl;
|
struct ElemFromListImpl;
|
||||||
template <size_t... I>
|
template <size_t... I>
|
||||||
struct ElemFromListImpl<IndexSequence<I...>> {
|
struct ElemFromListImpl<std::index_sequence<I...>> {
|
||||||
// We make Ignore a template to solve a problem with MSVC.
|
// We make Ignore a template to solve a problem with MSVC.
|
||||||
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
|
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
|
||||||
// MSVC doesn't understand how to deal with that pack expansion.
|
// MSVC doesn't understand how to deal with that pack expansion.
|
||||||
@@ -1196,15 +1144,14 @@ struct ElemFromListImpl<IndexSequence<I...>> {
|
|||||||
|
|
||||||
template <size_t N, typename... T>
|
template <size_t N, typename... T>
|
||||||
struct ElemFromList {
|
struct ElemFromList {
|
||||||
using type =
|
using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(
|
||||||
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
|
static_cast<T (*)()>(nullptr)...));
|
||||||
static_cast<T (*)()>(nullptr)...));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlatTupleConstructTag {};
|
struct FlatTupleConstructTag {};
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class FlatTuple;
|
class [[nodiscard]] FlatTuple;
|
||||||
|
|
||||||
template <typename Derived, size_t I>
|
template <typename Derived, size_t I>
|
||||||
struct FlatTupleElemBase;
|
struct FlatTupleElemBase;
|
||||||
@@ -1223,9 +1170,9 @@ template <typename Derived, typename Idx>
|
|||||||
struct FlatTupleBase;
|
struct FlatTupleBase;
|
||||||
|
|
||||||
template <size_t... Idx, typename... T>
|
template <size_t... Idx, typename... T>
|
||||||
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
|
||||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
||||||
using Indices = IndexSequence<Idx...>;
|
using Indices = std::index_sequence<Idx...>;
|
||||||
FlatTupleBase() = default;
|
FlatTupleBase() = default;
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
|
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
|
||||||
@@ -1260,14 +1207,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
|||||||
// implementations.
|
// implementations.
|
||||||
// FlatTuple and ElemFromList are not recursive and have a fixed depth
|
// FlatTuple and ElemFromList are not recursive and have a fixed depth
|
||||||
// regardless of T...
|
// regardless of T...
|
||||||
// MakeIndexSequence, on the other hand, it is recursive but with an
|
// std::make_index_sequence, on the other hand, it is recursive but with an
|
||||||
// instantiation depth of O(ln(N)).
|
// instantiation depth of O(ln(N)).
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class FlatTuple
|
class [[nodiscard]] FlatTuple
|
||||||
: private FlatTupleBase<FlatTuple<T...>,
|
: private FlatTupleBase<FlatTuple<T...>,
|
||||||
typename MakeIndexSequence<sizeof...(T)>::type> {
|
std::make_index_sequence<sizeof...(T)>> {
|
||||||
using Indices = typename FlatTupleBase<
|
using Indices =
|
||||||
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
|
typename FlatTupleBase<FlatTuple<T...>,
|
||||||
|
std::make_index_sequence<sizeof...(T)>>::Indices;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FlatTuple() = default;
|
FlatTuple() = default;
|
||||||
@@ -1281,30 +1229,40 @@ class FlatTuple
|
|||||||
|
|
||||||
// Utility functions to be called with static_assert to induce deprecation
|
// Utility functions to be called with static_assert to induce deprecation
|
||||||
// warnings.
|
// warnings.
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
||||||
"INSTANTIATE_TEST_SUITE_P")
|
"INSTANTIATE_TEST_SUITE_P")]]
|
||||||
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
|
constexpr bool InstantiateTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"TYPED_TEST_CASE_P is deprecated, please use "
|
"TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
"TYPED_TEST_SUITE_P")
|
"TYPED_TEST_SUITE_P")]]
|
||||||
constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
|
constexpr bool TypedTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"TYPED_TEST_CASE is deprecated, please use "
|
"TYPED_TEST_CASE is deprecated, please use "
|
||||||
"TYPED_TEST_SUITE")
|
"TYPED_TEST_SUITE")]]
|
||||||
constexpr bool TypedTestCaseIsDeprecated() { return true; }
|
constexpr bool TypedTestCaseIsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
"REGISTER_TYPED_TEST_SUITE_P")
|
"REGISTER_TYPED_TEST_SUITE_P")]]
|
||||||
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
|
constexpr bool RegisterTypedTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
"INSTANTIATE_TYPED_TEST_SUITE_P")
|
"INSTANTIATE_TYPED_TEST_SUITE_P")]]
|
||||||
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
|
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
@@ -1360,7 +1318,7 @@ struct tuple_size<testing::internal::FlatTuple<Ts...>>
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
class NeverThrown {
|
class [[nodiscard]] NeverThrown {
|
||||||
public:
|
public:
|
||||||
const char* what() const noexcept {
|
const char* what() const noexcept {
|
||||||
return "this exception should never be thrown";
|
return "this exception should never be thrown";
|
||||||
@@ -1494,8 +1452,7 @@ class NeverThrown {
|
|||||||
; \
|
; \
|
||||||
else \
|
else \
|
||||||
fail(::testing::internal::GetBoolAssertionFailureMessage( \
|
fail(::testing::internal::GetBoolAssertionFailureMessage( \
|
||||||
gtest_ar_, text, #actual, #expected) \
|
gtest_ar_, text, #actual, #expected))
|
||||||
.c_str())
|
|
||||||
|
|
||||||
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
|
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
|
||||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
@@ -1541,7 +1498,7 @@ class NeverThrown {
|
|||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
|
[[maybe_unused]] static ::testing::TestInfo* const test_info_; \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -85,17 +87,17 @@ namespace internal {
|
|||||||
// TEST_P macro is used to define two tests with the same name
|
// TEST_P macro is used to define two tests with the same name
|
||||||
// but in different namespaces.
|
// but in different namespaces.
|
||||||
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||||
CodeLocation code_location);
|
const CodeLocation& code_location);
|
||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
class ParamGeneratorInterface;
|
class [[nodiscard]] ParamGeneratorInterface;
|
||||||
template <typename>
|
template <typename>
|
||||||
class ParamGenerator;
|
class [[nodiscard]] ParamGenerator;
|
||||||
|
|
||||||
// Interface for iterating over elements provided by an implementation
|
// Interface for iterating over elements provided by an implementation
|
||||||
// of ParamGeneratorInterface<T>.
|
// of ParamGeneratorInterface<T>.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ParamIteratorInterface {
|
class [[nodiscard]] ParamIteratorInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~ParamIteratorInterface() = default;
|
virtual ~ParamIteratorInterface() = default;
|
||||||
// A pointer to the base generator instance.
|
// A pointer to the base generator instance.
|
||||||
@@ -125,7 +127,7 @@ class ParamIteratorInterface {
|
|||||||
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
|
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
|
||||||
// and implements the const forward iterator concept.
|
// and implements the const forward iterator concept.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ParamIterator {
|
class [[nodiscard]] ParamIterator {
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef const T& reference;
|
typedef const T& reference;
|
||||||
@@ -167,7 +169,7 @@ class ParamIterator {
|
|||||||
// ParamGeneratorInterface<T> is the binary interface to access generators
|
// ParamGeneratorInterface<T> is the binary interface to access generators
|
||||||
// defined in other translation units.
|
// defined in other translation units.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ParamGeneratorInterface {
|
class [[nodiscard]] ParamGeneratorInterface {
|
||||||
public:
|
public:
|
||||||
typedef T ParamType;
|
typedef T ParamType;
|
||||||
|
|
||||||
@@ -184,7 +186,7 @@ class ParamGeneratorInterface {
|
|||||||
// ParamGeneratorInterface<T> instance is shared among all copies
|
// ParamGeneratorInterface<T> instance is shared among all copies
|
||||||
// of the original object. This is possible because that instance is immutable.
|
// of the original object. This is possible because that instance is immutable.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ParamGenerator {
|
class [[nodiscard]] ParamGenerator {
|
||||||
public:
|
public:
|
||||||
typedef ParamIterator<T> iterator;
|
typedef ParamIterator<T> iterator;
|
||||||
|
|
||||||
@@ -208,7 +210,7 @@ class ParamGenerator {
|
|||||||
// operator<().
|
// operator<().
|
||||||
// This class is used in the Range() function.
|
// This class is used in the Range() function.
|
||||||
template <typename T, typename IncrementT>
|
template <typename T, typename IncrementT>
|
||||||
class RangeGenerator : public ParamGeneratorInterface<T> {
|
class [[nodiscard]] RangeGenerator : public ParamGeneratorInterface<T> {
|
||||||
public:
|
public:
|
||||||
RangeGenerator(T begin, T end, IncrementT step)
|
RangeGenerator(T begin, T end, IncrementT step)
|
||||||
: begin_(begin),
|
: begin_(begin),
|
||||||
@@ -294,7 +296,8 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
// since the source can be located on the stack, and the generator
|
// since the source can be located on the stack, and the generator
|
||||||
// is likely to persist beyond that stack frame.
|
// is likely to persist beyond that stack frame.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
class [[nodiscard]] ValuesInIteratorRangeGenerator
|
||||||
|
: public ParamGeneratorInterface<T> {
|
||||||
public:
|
public:
|
||||||
template <typename ForwardIterator>
|
template <typename ForwardIterator>
|
||||||
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
||||||
@@ -379,9 +382,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
// integer test parameter index.
|
// integer test parameter index.
|
||||||
template <class ParamType>
|
template <class ParamType>
|
||||||
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
||||||
Message name_stream;
|
return std::to_string(info.index);
|
||||||
name_stream << info.index;
|
|
||||||
return name_stream.GetString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = int>
|
template <typename T = int>
|
||||||
@@ -396,7 +397,7 @@ void TestNotEmpty(const T&) {}
|
|||||||
// Stores a parameter value and later creates tests parameterized with that
|
// Stores a parameter value and later creates tests parameterized with that
|
||||||
// value.
|
// value.
|
||||||
template <class TestClass>
|
template <class TestClass>
|
||||||
class ParameterizedTestFactory : public TestFactoryBase {
|
class [[nodiscard]] ParameterizedTestFactory : public TestFactoryBase {
|
||||||
public:
|
public:
|
||||||
typedef typename TestClass::ParamType ParamType;
|
typedef typename TestClass::ParamType ParamType;
|
||||||
explicit ParameterizedTestFactory(ParamType parameter)
|
explicit ParameterizedTestFactory(ParamType parameter)
|
||||||
@@ -418,7 +419,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
|
|||||||
// TestMetaFactoryBase is a base class for meta-factories that create
|
// TestMetaFactoryBase is a base class for meta-factories that create
|
||||||
// test factories for passing into MakeAndRegisterTestInfo function.
|
// test factories for passing into MakeAndRegisterTestInfo function.
|
||||||
template <class ParamType>
|
template <class ParamType>
|
||||||
class TestMetaFactoryBase {
|
class [[nodiscard]] TestMetaFactoryBase {
|
||||||
public:
|
public:
|
||||||
virtual ~TestMetaFactoryBase() = default;
|
virtual ~TestMetaFactoryBase() = default;
|
||||||
|
|
||||||
@@ -434,7 +435,7 @@ class TestMetaFactoryBase {
|
|||||||
// it for each Test/Parameter value combination. Thus it needs meta factory
|
// it for each Test/Parameter value combination. Thus it needs meta factory
|
||||||
// creator class.
|
// creator class.
|
||||||
template <class TestSuite>
|
template <class TestSuite>
|
||||||
class TestMetaFactory
|
class [[nodiscard]] TestMetaFactory
|
||||||
: public TestMetaFactoryBase<typename TestSuite::ParamType> {
|
: public TestMetaFactoryBase<typename TestSuite::ParamType> {
|
||||||
public:
|
public:
|
||||||
using ParamType = typename TestSuite::ParamType;
|
using ParamType = typename TestSuite::ParamType;
|
||||||
@@ -460,7 +461,7 @@ class TestMetaFactory
|
|||||||
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
|
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
|
||||||
// a collection of pointers to the ParameterizedTestSuiteInfo objects
|
// a collection of pointers to the ParameterizedTestSuiteInfo objects
|
||||||
// and calls RegisterTests() on each of them when asked.
|
// and calls RegisterTests() on each of them when asked.
|
||||||
class ParameterizedTestSuiteInfoBase {
|
class [[nodiscard]] ParameterizedTestSuiteInfoBase {
|
||||||
public:
|
public:
|
||||||
virtual ~ParameterizedTestSuiteInfoBase() = default;
|
virtual ~ParameterizedTestSuiteInfoBase() = default;
|
||||||
|
|
||||||
@@ -503,7 +504,8 @@ GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
|
|||||||
// test suite. It registers tests with all values generated by all
|
// test suite. It registers tests with all values generated by all
|
||||||
// generators when asked.
|
// generators when asked.
|
||||||
template <class TestSuite>
|
template <class TestSuite>
|
||||||
class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
class [[nodiscard]] ParameterizedTestSuiteInfo
|
||||||
|
: public ParameterizedTestSuiteInfoBase {
|
||||||
public:
|
public:
|
||||||
// ParamType and GeneratorCreationFunc are private types but are required
|
// ParamType and GeneratorCreationFunc are private types but are required
|
||||||
// for declarations of public methods AddTestPattern() and
|
// for declarations of public methods AddTestPattern() and
|
||||||
@@ -513,9 +515,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||||
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
||||||
|
|
||||||
explicit ParameterizedTestSuiteInfo(const char* name,
|
explicit ParameterizedTestSuiteInfo(std::string name,
|
||||||
CodeLocation code_location)
|
CodeLocation code_location)
|
||||||
: test_suite_name_(name), code_location_(code_location) {}
|
: test_suite_name_(std::move(name)),
|
||||||
|
code_location_(std::move(code_location)) {}
|
||||||
|
|
||||||
// Test suite base name for display purposes.
|
// Test suite base name for display purposes.
|
||||||
const std::string& GetTestSuiteName() const override {
|
const std::string& GetTestSuiteName() const override {
|
||||||
@@ -529,20 +532,20 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// prefix). test_base_name is the name of an individual test without
|
// prefix). test_base_name is the name of an individual test without
|
||||||
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||||
// test suite base name and DoBar is test base name.
|
// test suite base name and DoBar is test base name.
|
||||||
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
|
void AddTestPattern(const char*, const char* test_base_name,
|
||||||
TestMetaFactoryBase<ParamType>* meta_factory,
|
TestMetaFactoryBase<ParamType>* meta_factory,
|
||||||
CodeLocation code_location) {
|
CodeLocation code_location) {
|
||||||
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
|
tests_.emplace_back(
|
||||||
test_suite_name, test_base_name, meta_factory, code_location)));
|
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
|
||||||
}
|
}
|
||||||
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
||||||
// about a generator.
|
// about a generator.
|
||||||
int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
int AddTestSuiteInstantiation(std::string instantiation_name,
|
||||||
GeneratorCreationFunc* func,
|
GeneratorCreationFunc* func,
|
||||||
ParamNameGeneratorFunc* name_func,
|
ParamNameGeneratorFunc* name_func,
|
||||||
const char* file, int line) {
|
const char* file, int line) {
|
||||||
instantiations_.push_back(
|
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
|
||||||
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
file, line);
|
||||||
return 0; // Return value used only to run this method in namespace scope.
|
return 0; // Return value used only to run this method in namespace scope.
|
||||||
}
|
}
|
||||||
// UnitTest class invokes this method to register tests in this test suite
|
// UnitTest class invokes this method to register tests in this test suite
|
||||||
@@ -553,60 +556,61 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
void RegisterTests() override {
|
void RegisterTests() override {
|
||||||
bool generated_instantiations = false;
|
bool generated_instantiations = false;
|
||||||
|
|
||||||
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
std::string test_suite_name;
|
||||||
test_it != tests_.end(); ++test_it) {
|
std::string test_name;
|
||||||
std::shared_ptr<TestInfo> test_info = *test_it;
|
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
|
||||||
for (typename InstantiationContainer::iterator gen_it =
|
for (const InstantiationInfo& instantiation : instantiations_) {
|
||||||
instantiations_.begin();
|
const std::string& instantiation_name = instantiation.name;
|
||||||
gen_it != instantiations_.end(); ++gen_it) {
|
ParamGenerator<ParamType> generator((*instantiation.generator)());
|
||||||
const std::string& instantiation_name = gen_it->name;
|
ParamNameGeneratorFunc* name_func = instantiation.name_func;
|
||||||
ParamGenerator<ParamType> generator((*gen_it->generator)());
|
const char* file = instantiation.file;
|
||||||
ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
int line = instantiation.line;
|
||||||
const char* file = gen_it->file;
|
|
||||||
int line = gen_it->line;
|
|
||||||
|
|
||||||
std::string test_suite_name;
|
|
||||||
if (!instantiation_name.empty())
|
if (!instantiation_name.empty())
|
||||||
test_suite_name = instantiation_name + "/";
|
test_suite_name = instantiation_name + "/";
|
||||||
test_suite_name += test_info->test_suite_base_name;
|
else
|
||||||
|
test_suite_name.clear();
|
||||||
|
test_suite_name += test_suite_name_;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
std::set<std::string> test_param_names;
|
std::set<std::string> test_param_names;
|
||||||
for (typename ParamGenerator<ParamType>::iterator param_it =
|
for (const auto& param : generator) {
|
||||||
generator.begin();
|
|
||||||
param_it != generator.end(); ++param_it, ++i) {
|
|
||||||
generated_instantiations = true;
|
generated_instantiations = true;
|
||||||
|
|
||||||
Message test_name_stream;
|
test_name.clear();
|
||||||
|
|
||||||
std::string param_name =
|
std::string param_name =
|
||||||
name_func(TestParamInfo<ParamType>(*param_it, i));
|
name_func(TestParamInfo<ParamType>(param, i));
|
||||||
|
|
||||||
GTEST_CHECK_(IsValidParamName(param_name))
|
GTEST_CHECK_(IsValidParamName(param_name))
|
||||||
<< "Parameterized test name '" << param_name
|
<< "Parameterized test name '" << param_name
|
||||||
<< "' is invalid, in " << file << " line " << line << std::endl;
|
<< "' is invalid (contains spaces, dashes, or any "
|
||||||
|
"non-alphanumeric characters other than underscores), in "
|
||||||
|
<< file << " line " << line << "" << std::endl;
|
||||||
|
|
||||||
GTEST_CHECK_(test_param_names.count(param_name) == 0)
|
GTEST_CHECK_(test_param_names.count(param_name) == 0)
|
||||||
<< "Duplicate parameterized test name '" << param_name << "', in "
|
<< "Duplicate parameterized test name '" << param_name << "', in "
|
||||||
<< file << " line " << line << std::endl;
|
<< file << " line " << line << std::endl;
|
||||||
|
|
||||||
test_param_names.insert(param_name);
|
|
||||||
|
|
||||||
if (!test_info->test_base_name.empty()) {
|
if (!test_info->test_base_name.empty()) {
|
||||||
test_name_stream << test_info->test_base_name << "/";
|
test_name.append(test_info->test_base_name).append("/");
|
||||||
}
|
}
|
||||||
test_name_stream << param_name;
|
test_name += param_name;
|
||||||
|
|
||||||
|
test_param_names.insert(std::move(param_name));
|
||||||
|
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
|
test_suite_name, test_name.c_str(),
|
||||||
nullptr, // No type parameter.
|
nullptr, // No type parameter.
|
||||||
PrintToString(*param_it).c_str(), test_info->code_location,
|
PrintToString(param).c_str(), test_info->code_location,
|
||||||
GetTestSuiteTypeId(),
|
GetTestSuiteTypeId(),
|
||||||
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||||
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
||||||
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
test_info->test_meta_factory->CreateTestFactory(param));
|
||||||
} // for param_it
|
++i;
|
||||||
} // for gen_it
|
} // for param
|
||||||
} // for test_it
|
} // for instantiation
|
||||||
|
} // for test_info
|
||||||
|
|
||||||
if (!generated_instantiations) {
|
if (!generated_instantiations) {
|
||||||
// There are no generaotrs, or they all generate nothing ...
|
// There are no generaotrs, or they all generate nothing ...
|
||||||
@@ -619,15 +623,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// LocalTestInfo structure keeps information about a single test registered
|
// LocalTestInfo structure keeps information about a single test registered
|
||||||
// with TEST_P macro.
|
// with TEST_P macro.
|
||||||
struct TestInfo {
|
struct TestInfo {
|
||||||
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
|
TestInfo(const char* a_test_base_name,
|
||||||
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
|
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
|
||||||
CodeLocation a_code_location)
|
CodeLocation a_code_location)
|
||||||
: test_suite_base_name(a_test_suite_base_name),
|
: test_base_name(a_test_base_name),
|
||||||
test_base_name(a_test_base_name),
|
|
||||||
test_meta_factory(a_test_meta_factory),
|
test_meta_factory(a_test_meta_factory),
|
||||||
code_location(a_code_location) {}
|
code_location(std::move(a_code_location)) {}
|
||||||
|
|
||||||
const std::string test_suite_base_name;
|
|
||||||
const std::string test_base_name;
|
const std::string test_base_name;
|
||||||
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
|
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
|
||||||
const CodeLocation code_location;
|
const CodeLocation code_location;
|
||||||
@@ -637,11 +639,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// <Instantiation name, Sequence generator creation function,
|
// <Instantiation name, Sequence generator creation function,
|
||||||
// Name generator function, Source file, Source line>
|
// Name generator function, Source file, Source line>
|
||||||
struct InstantiationInfo {
|
struct InstantiationInfo {
|
||||||
InstantiationInfo(const std::string& name_in,
|
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
|
||||||
GeneratorCreationFunc* generator_in,
|
|
||||||
ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
||||||
int line_in)
|
int line_in)
|
||||||
: name(name_in),
|
: name(std::move(name_in)),
|
||||||
generator(generator_in),
|
generator(generator_in),
|
||||||
name_func(name_func_in),
|
name_func(name_func_in),
|
||||||
file(file_in),
|
file(file_in),
|
||||||
@@ -689,7 +690,7 @@ using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
|
|||||||
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
|
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
|
||||||
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
|
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
|
||||||
// ParameterizedTestSuiteInfo descriptors.
|
// ParameterizedTestSuiteInfo descriptors.
|
||||||
class ParameterizedTestSuiteRegistry {
|
class [[nodiscard]] ParameterizedTestSuiteRegistry {
|
||||||
public:
|
public:
|
||||||
ParameterizedTestSuiteRegistry() = default;
|
ParameterizedTestSuiteRegistry() = default;
|
||||||
~ParameterizedTestSuiteRegistry() {
|
~ParameterizedTestSuiteRegistry() {
|
||||||
@@ -702,29 +703,32 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
// tests and instantiations of a particular test suite.
|
// tests and instantiations of a particular test suite.
|
||||||
template <class TestSuite>
|
template <class TestSuite>
|
||||||
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
||||||
const char* test_suite_name, CodeLocation code_location) {
|
std::string test_suite_name, CodeLocation code_location) {
|
||||||
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
||||||
for (auto& test_suite_info : test_suite_infos_) {
|
|
||||||
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
auto item_it = suite_name_to_info_index_.find(test_suite_name);
|
||||||
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
if (item_it != suite_name_to_info_index_.end()) {
|
||||||
// Complain about incorrect usage of Google Test facilities
|
auto* test_suite_info = test_suite_infos_[item_it->second];
|
||||||
// and terminate the program since we cannot guaranty correct
|
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||||
// test suite setup and tear-down in this case.
|
// Complain about incorrect usage of Google Test facilities
|
||||||
ReportInvalidTestSuiteType(test_suite_name, code_location);
|
// and terminate the program since we cannot guaranty correct
|
||||||
posix::Abort();
|
// test suite setup and tear-down in this case.
|
||||||
} else {
|
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
|
||||||
// At this point we are sure that the object we found is of the same
|
posix::Abort();
|
||||||
// type we are looking for, so we downcast it to that type
|
} else {
|
||||||
// without further checks.
|
// At this point we are sure that the object we found is of the same
|
||||||
typed_test_info = CheckedDowncastToActualType<
|
// type we are looking for, so we downcast it to that type
|
||||||
ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
|
// without further checks.
|
||||||
}
|
typed_test_info =
|
||||||
break;
|
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
|
||||||
|
test_suite_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typed_test_info == nullptr) {
|
if (typed_test_info == nullptr) {
|
||||||
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
||||||
test_suite_name, code_location);
|
test_suite_name, std::move(code_location));
|
||||||
|
suite_name_to_info_index_.emplace(std::move(test_suite_name),
|
||||||
|
test_suite_infos_.size());
|
||||||
test_suite_infos_.push_back(typed_test_info);
|
test_suite_infos_.push_back(typed_test_info);
|
||||||
}
|
}
|
||||||
return typed_test_info;
|
return typed_test_info;
|
||||||
@@ -738,8 +742,9 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
template <class TestCase>
|
template <class TestCase>
|
||||||
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||||
const char* test_case_name, CodeLocation code_location) {
|
std::string test_case_name, CodeLocation code_location) {
|
||||||
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
|
||||||
|
std::move(code_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
@@ -748,6 +753,7 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
||||||
|
|
||||||
TestSuiteInfoContainer test_suite_infos_;
|
TestSuiteInfoContainer test_suite_infos_;
|
||||||
|
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
|
||||||
|
|
||||||
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
||||||
delete;
|
delete;
|
||||||
@@ -758,7 +764,7 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
// Keep track of what type-parameterized test suite are defined and
|
// Keep track of what type-parameterized test suite are defined and
|
||||||
// where as well as which are intatiated. This allows susequently
|
// where as well as which are intatiated. This allows susequently
|
||||||
// identifying suits that are defined but never used.
|
// identifying suits that are defined but never used.
|
||||||
class TypeParameterizedTestSuiteRegistry {
|
class [[nodiscard]] TypeParameterizedTestSuiteRegistry {
|
||||||
public:
|
public:
|
||||||
// Add a suite definition
|
// Add a suite definition
|
||||||
void RegisterTestSuite(const char* test_suite_name,
|
void RegisterTestSuite(const char* test_suite_name,
|
||||||
@@ -774,7 +780,7 @@ class TypeParameterizedTestSuiteRegistry {
|
|||||||
private:
|
private:
|
||||||
struct TypeParameterizedTestSuiteInfo {
|
struct TypeParameterizedTestSuiteInfo {
|
||||||
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
||||||
: code_location(c), instantiated(false) {}
|
: code_location(std::move(c)), instantiated(false) {}
|
||||||
|
|
||||||
CodeLocation code_location;
|
CodeLocation code_location;
|
||||||
bool instantiated;
|
bool instantiated;
|
||||||
@@ -797,18 +803,18 @@ namespace internal {
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
class ValueArray {
|
class [[nodiscard]] ValueArray {
|
||||||
public:
|
public:
|
||||||
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
|
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const { // NOLINT
|
operator ParamGenerator<T>() const { // NOLINT
|
||||||
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
|
return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T, size_t... I>
|
template <typename T, size_t... I>
|
||||||
std::vector<T> MakeVector(IndexSequence<I...>) const {
|
std::vector<T> MakeVector(std::index_sequence<I...>) const {
|
||||||
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
|
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,7 +824,7 @@ class ValueArray {
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class CartesianProductGenerator
|
class [[nodiscard]] CartesianProductGenerator
|
||||||
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
||||||
public:
|
public:
|
||||||
typedef ::std::tuple<T...> ParamType;
|
typedef ::std::tuple<T...> ParamType;
|
||||||
@@ -838,7 +844,7 @@ class CartesianProductGenerator
|
|||||||
template <class I>
|
template <class I>
|
||||||
class IteratorImpl;
|
class IteratorImpl;
|
||||||
template <size_t... I>
|
template <size_t... I>
|
||||||
class IteratorImpl<IndexSequence<I...>>
|
class IteratorImpl<std::index_sequence<I...>>
|
||||||
: public ParamIteratorInterface<ParamType> {
|
: public ParamIteratorInterface<ParamType> {
|
||||||
public:
|
public:
|
||||||
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
||||||
@@ -929,13 +935,13 @@ class CartesianProductGenerator
|
|||||||
std::shared_ptr<ParamType> current_value_;
|
std::shared_ptr<ParamType> current_value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
|
using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;
|
||||||
|
|
||||||
std::tuple<ParamGenerator<T>...> generators_;
|
std::tuple<ParamGenerator<T>...> generators_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class... Gen>
|
template <class... Gen>
|
||||||
class CartesianProductHolder {
|
class [[nodiscard]] CartesianProductHolder {
|
||||||
public:
|
public:
|
||||||
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
|
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
@@ -948,11 +954,12 @@ class CartesianProductHolder {
|
|||||||
std::tuple<Gen...> generators_;
|
std::tuple<Gen...> generators_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename From, typename To>
|
template <typename From, typename To, typename Func>
|
||||||
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
class [[nodiscard]] ParamGeneratorConverter
|
||||||
|
: public ParamGeneratorInterface<To> {
|
||||||
public:
|
public:
|
||||||
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
|
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
|
||||||
: generator_(std::move(gen)) {}
|
: generator_(std::move(gen)), converter_(std::move(converter)) {}
|
||||||
|
|
||||||
ParamIteratorInterface<To>* Begin() const override {
|
ParamIteratorInterface<To>* Begin() const override {
|
||||||
return new Iterator(this, generator_.begin(), generator_.end());
|
return new Iterator(this, generator_.begin(), generator_.end());
|
||||||
@@ -961,13 +968,21 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
|||||||
return new Iterator(this, generator_.end(), generator_.end());
|
return new Iterator(this, generator_.end(), generator_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the std::function wrapping the user-supplied converter callable. It
|
||||||
|
// is used by the iterator (see class Iterator below) to convert the object
|
||||||
|
// (of type FROM) returned by the ParamGenerator to an object of a type that
|
||||||
|
// can be static_cast to type TO.
|
||||||
|
const Func& TypeConverter() const { return converter_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Iterator : public ParamIteratorInterface<To> {
|
class Iterator : public ParamIteratorInterface<To> {
|
||||||
public:
|
public:
|
||||||
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
|
Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
|
||||||
ParamIterator<From> end)
|
ParamIterator<From> end)
|
||||||
: base_(base), it_(it), end_(end) {
|
: base_(base), it_(it), end_(end) {
|
||||||
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
|
if (it_ != end_)
|
||||||
|
value_ =
|
||||||
|
std::make_shared<To>(static_cast<To>(base->TypeConverter()(*it_)));
|
||||||
}
|
}
|
||||||
~Iterator() override = default;
|
~Iterator() override = default;
|
||||||
|
|
||||||
@@ -976,7 +991,9 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
|||||||
}
|
}
|
||||||
void Advance() override {
|
void Advance() override {
|
||||||
++it_;
|
++it_;
|
||||||
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
|
if (it_ != end_)
|
||||||
|
value_ =
|
||||||
|
std::make_shared<To>(static_cast<To>(base_->TypeConverter()(*it_)));
|
||||||
}
|
}
|
||||||
ParamIteratorInterface<To>* Clone() const override {
|
ParamIteratorInterface<To>* Clone() const override {
|
||||||
return new Iterator(*this);
|
return new Iterator(*this);
|
||||||
@@ -996,30 +1013,54 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
|||||||
private:
|
private:
|
||||||
Iterator(const Iterator& other) = default;
|
Iterator(const Iterator& other) = default;
|
||||||
|
|
||||||
const ParamGeneratorInterface<To>* const base_;
|
const ParamGeneratorConverter* const base_;
|
||||||
ParamIterator<From> it_;
|
ParamIterator<From> it_;
|
||||||
ParamIterator<From> end_;
|
ParamIterator<From> end_;
|
||||||
std::shared_ptr<To> value_;
|
std::shared_ptr<To> value_;
|
||||||
}; // class ParamGeneratorConverter::Iterator
|
}; // class ParamGeneratorConverter::Iterator
|
||||||
|
|
||||||
ParamGenerator<From> generator_;
|
ParamGenerator<From> generator_;
|
||||||
|
Func converter_;
|
||||||
}; // class ParamGeneratorConverter
|
}; // class ParamGeneratorConverter
|
||||||
|
|
||||||
template <class Gen>
|
template <class GeneratedT,
|
||||||
class ParamConverterGenerator {
|
typename StdFunction =
|
||||||
|
std::function<const GeneratedT&(const GeneratedT&)>>
|
||||||
|
class [[nodiscard]] ParamConverterGenerator {
|
||||||
public:
|
public:
|
||||||
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
|
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
|
||||||
: generator_(std::move(g)) {}
|
: generator_(std::move(g)), converter_(Identity) {}
|
||||||
|
|
||||||
|
ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
|
||||||
|
: generator_(std::move(g)), converter_(std::move(converter)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const { // NOLINT
|
operator ParamGenerator<T>() const { // NOLINT
|
||||||
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
|
return ParamGenerator<T>(
|
||||||
|
new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
|
||||||
|
converter_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParamGenerator<Gen> generator_;
|
static const GeneratedT& Identity(const GeneratedT& v) { return v; }
|
||||||
|
|
||||||
|
ParamGenerator<GeneratedT> generator_;
|
||||||
|
StdFunction converter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Template to determine the param type of a single-param std::function.
|
||||||
|
template <typename T>
|
||||||
|
struct FuncSingleParamType;
|
||||||
|
template <typename R, typename P>
|
||||||
|
struct FuncSingleParamType<std::function<R(P)>> {
|
||||||
|
using type = std::remove_cv_t<std::remove_reference_t<P>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsSingleArgStdFunction : public std::false_type {};
|
||||||
|
template <typename R, typename P>
|
||||||
|
struct IsSingleArgStdFunction<std::function<R(P)>> : public std::true_type {};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,8 @@
|
|||||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
||||||
#define GTEST_OS_WINDOWS_PHONE 1
|
#define GTEST_OS_WINDOWS_PHONE 1
|
||||||
#define GTEST_OS_WINDOWS_TV_TITLE 1
|
#define GTEST_OS_WINDOWS_TV_TITLE 1
|
||||||
|
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
|
||||||
|
#define GTEST_OS_WINDOWS_GAMES 1
|
||||||
#else
|
#else
|
||||||
// WINAPI_FAMILY defined but no known partition matched.
|
// WINAPI_FAMILY defined but no known partition matched.
|
||||||
// Default to desktop.
|
// Default to desktop.
|
||||||
@@ -117,6 +119,8 @@
|
|||||||
#define GTEST_OS_NXP_QN9090 1
|
#define GTEST_OS_NXP_QN9090 1
|
||||||
#elif defined(NRF52)
|
#elif defined(NRF52)
|
||||||
#define GTEST_OS_NRF52 1
|
#define GTEST_OS_NRF52 1
|
||||||
|
#elif defined(__EMSCRIPTEN__)
|
||||||
|
#define GTEST_OS_EMSCRIPTEN 1
|
||||||
#endif // __CYGWIN__
|
#endif // __CYGWIN__
|
||||||
|
|
||||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||||
|
|||||||
@@ -194,26 +194,12 @@
|
|||||||
//
|
//
|
||||||
// Macros for basic C++ coding:
|
// Macros for basic C++ coding:
|
||||||
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
||||||
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
|
|
||||||
// variable don't have to be used.
|
|
||||||
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
|
|
||||||
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
|
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
|
||||||
// suppressed (constant conditional).
|
// suppressed (constant conditional).
|
||||||
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
||||||
// is suppressed.
|
// is suppressed.
|
||||||
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
|
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
|
||||||
// UniversalPrinter<absl::any> specializations.
|
// specializations. Always defined to 0 or 1
|
||||||
// Always defined to 0 or 1.
|
|
||||||
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>
|
|
||||||
// or
|
|
||||||
// UniversalPrinter<absl::optional>
|
|
||||||
// specializations. Always defined to 0 or 1.
|
|
||||||
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
|
|
||||||
// Matcher<absl::string_view>
|
|
||||||
// specializations. Always defined to 0 or 1.
|
|
||||||
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
|
|
||||||
// UniversalPrinter<absl::variant>
|
|
||||||
// specializations. Always defined to 0 or 1.
|
|
||||||
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
|
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
|
||||||
// GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
|
// GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
|
||||||
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
|
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
|
||||||
@@ -260,11 +246,6 @@
|
|||||||
// BoolFromGTestEnv() - parses a bool environment variable.
|
// BoolFromGTestEnv() - parses a bool environment variable.
|
||||||
// Int32FromGTestEnv() - parses an int32_t environment variable.
|
// Int32FromGTestEnv() - parses an int32_t environment variable.
|
||||||
// StringFromGTestEnv() - parses a string environment variable.
|
// StringFromGTestEnv() - parses a string environment variable.
|
||||||
//
|
|
||||||
// Deprecation warnings:
|
|
||||||
// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as
|
|
||||||
// deprecated; calling a marked function
|
|
||||||
// should generate a compiler warning
|
|
||||||
|
|
||||||
// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can
|
// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can
|
||||||
// potentially be used as an #include guard.
|
// potentially be used as an #include guard.
|
||||||
@@ -275,8 +256,28 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L
|
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
|
||||||
#error C++ versions less than C++14 are not supported.
|
#error C++ versions less than C++17 are not supported.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
|
||||||
|
#ifdef __has_include
|
||||||
|
#define GTEST_INTERNAL_HAS_INCLUDE __has_include
|
||||||
|
#else
|
||||||
|
#define GTEST_INTERNAL_HAS_INCLUDE(...) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Detect C++ feature test macros as gracefully as possible.
|
||||||
|
// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
|
||||||
|
//
|
||||||
|
// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
|
||||||
|
// <version> instead, even though <version> is not available in C++17 mode prior
|
||||||
|
// to GCC9.
|
||||||
|
#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
|
||||||
|
GTEST_INTERNAL_HAS_INCLUDE(<version>)
|
||||||
|
#include <version> // C++20 or <version> support.
|
||||||
|
#else
|
||||||
|
#include <ciso646> // Pre-C++20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h> // for isspace, etc
|
#include <ctype.h> // for isspace, etc
|
||||||
@@ -320,7 +321,8 @@
|
|||||||
#define GTEST_HAS_NOTIFICATION_ 0
|
#define GTEST_HAS_NOTIFICATION_ 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||||
|
#define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file.
|
||||||
#include "absl/flags/declare.h"
|
#include "absl/flags/declare.h"
|
||||||
#include "absl/flags/flag.h"
|
#include "absl/flags/flag.h"
|
||||||
#include "absl/flags/reflection.h"
|
#include "absl/flags/reflection.h"
|
||||||
@@ -590,7 +592,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
|
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
|
||||||
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
|
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
|
||||||
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \
|
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \
|
||||||
defined(GTEST_OS_GNU_HURD))
|
defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \
|
||||||
|
defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS))
|
||||||
#define GTEST_HAS_PTHREAD 1
|
#define GTEST_HAS_PTHREAD 1
|
||||||
#else
|
#else
|
||||||
#define GTEST_HAS_PTHREAD 0
|
#define GTEST_HAS_PTHREAD 0
|
||||||
@@ -609,7 +612,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// Determines whether clone(2) is supported.
|
// Determines whether clone(2) is supported.
|
||||||
// Usually it will only be available on Linux, excluding
|
// Usually it will only be available on Linux, excluding
|
||||||
// Linux on the Itanium architecture.
|
// Linux on the Itanium architecture.
|
||||||
// Also see http://linux.die.net/man/2/clone.
|
// Also see https://linux.die.net/man/2/clone.
|
||||||
#ifndef GTEST_HAS_CLONE
|
#ifndef GTEST_HAS_CLONE
|
||||||
// The user didn't tell us, so we need to figure it out.
|
// The user didn't tell us, so we need to figure it out.
|
||||||
|
|
||||||
@@ -640,9 +643,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// platforms except known mobile / embedded ones. Also, if the port doesn't have
|
// platforms except known mobile / embedded ones. Also, if the port doesn't have
|
||||||
// a file system, stream redirection is not supported.
|
// a file system, stream redirection is not supported.
|
||||||
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
|
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
|
||||||
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \
|
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \
|
||||||
defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \
|
defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
|
||||||
!GTEST_HAS_FILE_SYSTEM
|
defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM
|
||||||
#define GTEST_HAS_STREAM_REDIRECTION 0
|
#define GTEST_HAS_STREAM_REDIRECTION 0
|
||||||
#else
|
#else
|
||||||
#define GTEST_HAS_STREAM_REDIRECTION 1
|
#define GTEST_HAS_STREAM_REDIRECTION 1
|
||||||
@@ -652,7 +655,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// Determines whether to support death tests.
|
// Determines whether to support death tests.
|
||||||
// pops up a dialog window that cannot be suppressed programmatically.
|
// pops up a dialog window that cannot be suppressed programmatically.
|
||||||
#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) || \
|
#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) || \
|
||||||
defined(GTEST_OS_SOLARIS) || \
|
defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_ZOS) || \
|
||||||
(defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) || \
|
(defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) || \
|
||||||
(defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) || \
|
(defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) || \
|
||||||
defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) || \
|
defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) || \
|
||||||
@@ -661,12 +664,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
|
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
|
||||||
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
|
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
|
||||||
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))
|
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))
|
||||||
|
|
||||||
// Death tests require a file system to work properly.
|
// Death tests require a file system to work properly.
|
||||||
#if GTEST_HAS_FILE_SYSTEM
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
#define GTEST_HAS_DEATH_TEST 1
|
#define GTEST_HAS_DEATH_TEST 1
|
||||||
#endif // GTEST_HAS_FILE_SYSTEM
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Determines whether the Premature Exit file can be created.
|
||||||
|
// Created by default when Death tests are supported, but other platforms can
|
||||||
|
// use the Premature exit file without Death test support (e.g. for detecting
|
||||||
|
// crashes).
|
||||||
|
#if GTEST_HAS_DEATH_TEST || \
|
||||||
|
(defined(GTEST_OS_EMSCRIPTEN) && GTEST_HAS_FILE_SYSTEM)
|
||||||
|
#define GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// Determines whether to support type-driven tests.
|
// Determines whether to support type-driven tests.
|
||||||
|
|
||||||
// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
|
// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
|
||||||
@@ -730,6 +743,20 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#define GTEST_HAVE_ATTRIBUTE_(x) 0
|
#define GTEST_HAVE_ATTRIBUTE_(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE
|
||||||
|
//
|
||||||
|
// A function-like feature checking macro that accepts C++11 style attributes.
|
||||||
|
// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
|
||||||
|
// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
|
||||||
|
// find `__has_cpp_attribute`, will evaluate to 0.
|
||||||
|
#if defined(__has_cpp_attribute)
|
||||||
|
// NOTE: requiring __cplusplus above should not be necessary, but
|
||||||
|
// works around https://bugs.llvm.org/show_bug.cgi?id=23435.
|
||||||
|
#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||||
|
#else
|
||||||
|
#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
// GTEST_HAVE_FEATURE_
|
// GTEST_HAVE_FEATURE_
|
||||||
//
|
//
|
||||||
// A function-like feature checking macro that is a wrapper around
|
// A function-like feature checking macro that is a wrapper around
|
||||||
@@ -740,17 +767,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#define GTEST_HAVE_FEATURE_(x) 0
|
#define GTEST_HAVE_FEATURE_(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use this annotation after a variable or parameter declaration to tell the
|
|
||||||
// compiler the variable/parameter does not have to be used.
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// GTEST_ATTRIBUTE_UNUSED_ int foo = bar();
|
|
||||||
#if GTEST_HAVE_ATTRIBUTE_(unused)
|
|
||||||
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
|
|
||||||
#else
|
|
||||||
#define GTEST_ATTRIBUTE_UNUSED_
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Use this annotation before a function that takes a printf format string.
|
// Use this annotation before a function that takes a printf format string.
|
||||||
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
||||||
// MinGW has two different printf implementations. Ensure the format macro
|
// MinGW has two different printf implementations. Ensure the format macro
|
||||||
@@ -765,17 +781,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Tell the compiler to warn about unused return values for functions declared
|
|
||||||
// with this macro. The macro should be used on function declarations
|
|
||||||
// following the argument list:
|
|
||||||
//
|
|
||||||
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
|
|
||||||
#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)
|
|
||||||
#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
|
|
||||||
#else
|
|
||||||
#define GTEST_MUST_USE_RESULT_
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MS C++ compiler emits warning when a conditional expression is compile time
|
// MS C++ compiler emits warning when a conditional expression is compile time
|
||||||
// constant. In some contexts this warning is false positive and needs to be
|
// constant. In some contexts this warning is false positive and needs to be
|
||||||
// suppressed. Use the following two macros in such cases:
|
// suppressed. Use the following two macros in such cases:
|
||||||
@@ -827,11 +832,13 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#ifndef GTEST_API_
|
#ifndef GTEST_API_
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#if GTEST_LINKED_AS_SHARED_LIBRARY
|
#if defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
|
||||||
#define GTEST_API_ __declspec(dllimport)
|
|
||||||
#elif GTEST_CREATE_SHARED_LIBRARY
|
|
||||||
#define GTEST_API_ __declspec(dllexport)
|
#define GTEST_API_ __declspec(dllexport)
|
||||||
|
#elif defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
|
||||||
|
#define GTEST_API_ __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
|
#elif GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(gnu::visibility)
|
||||||
|
#define GTEST_API_ [[gnu::visibility("default")]]
|
||||||
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
|
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
|
||||||
#define GTEST_API_ __attribute__((visibility("default")))
|
#define GTEST_API_ __attribute__((visibility("default")))
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
@@ -922,7 +929,7 @@ namespace internal {
|
|||||||
// A secret type that Google Test users don't know about. It has no
|
// A secret type that Google Test users don't know about. It has no
|
||||||
// accessible constructors on purpose. Therefore it's impossible to create a
|
// accessible constructors on purpose. Therefore it's impossible to create a
|
||||||
// Secret object, which is what we want.
|
// Secret object, which is what we want.
|
||||||
class Secret {
|
class [[nodiscard]] Secret {
|
||||||
Secret(const Secret&) = delete;
|
Secret(const Secret&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -937,7 +944,7 @@ GTEST_API_ bool IsTrue(bool condition);
|
|||||||
// This is almost `using RE = ::RE2`, except it is copy-constructible, and it
|
// This is almost `using RE = ::RE2`, except it is copy-constructible, and it
|
||||||
// needs to disambiguate the `std::string`, `absl::string_view`, and `const
|
// needs to disambiguate the `std::string`, `absl::string_view`, and `const
|
||||||
// char*` constructors.
|
// char*` constructors.
|
||||||
class GTEST_API_ RE {
|
class GTEST_API_ [[nodiscard]] RE {
|
||||||
public:
|
public:
|
||||||
RE(absl::string_view regex) : regex_(regex) {} // NOLINT
|
RE(absl::string_view regex) : regex_(regex) {} // NOLINT
|
||||||
RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT
|
RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT
|
||||||
@@ -963,7 +970,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|||||||
|
|
||||||
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
|
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
|
||||||
// Regular Expression syntax.
|
// Regular Expression syntax.
|
||||||
class GTEST_API_ RE {
|
class GTEST_API_ [[nodiscard]] RE {
|
||||||
public:
|
public:
|
||||||
// A copy constructor is required by the Standard to initialize object
|
// A copy constructor is required by the Standard to initialize object
|
||||||
// references from r-values.
|
// references from r-values.
|
||||||
@@ -1032,7 +1039,7 @@ enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };
|
|||||||
// Formats log entry severity, provides a stream object for streaming the
|
// Formats log entry severity, provides a stream object for streaming the
|
||||||
// log message, and terminates the message with a newline when going out of
|
// log message, and terminates the message with a newline when going out of
|
||||||
// scope.
|
// scope.
|
||||||
class GTEST_API_ GTestLog {
|
class GTEST_API_ [[nodiscard]] GTestLog {
|
||||||
public:
|
public:
|
||||||
GTestLog(GTestLogSeverity severity, const char* file, int line);
|
GTestLog(GTestLogSeverity severity, const char* file, int line);
|
||||||
|
|
||||||
@@ -1195,7 +1202,7 @@ void ClearInjectableArgvs();
|
|||||||
#ifdef GTEST_OS_WINDOWS
|
#ifdef GTEST_OS_WINDOWS
|
||||||
// Provides leak-safe Windows kernel handle ownership.
|
// Provides leak-safe Windows kernel handle ownership.
|
||||||
// Used in death tests and in threading support.
|
// Used in death tests and in threading support.
|
||||||
class GTEST_API_ AutoHandle {
|
class GTEST_API_ [[nodiscard]] AutoHandle {
|
||||||
public:
|
public:
|
||||||
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
|
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
|
||||||
// avoid including <windows.h> in this header file. Including <windows.h> is
|
// avoid including <windows.h> in this header file. Including <windows.h> is
|
||||||
@@ -1229,9 +1236,6 @@ class GTEST_API_ AutoHandle {
|
|||||||
// Nothing to do here.
|
// Nothing to do here.
|
||||||
|
|
||||||
#else
|
#else
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
||||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
|
||||||
|
|
||||||
// Allows a controller thread to pause execution of newly created
|
// Allows a controller thread to pause execution of newly created
|
||||||
// threads until notified. Instances of this class must be created
|
// threads until notified. Instances of this class must be created
|
||||||
// and destroyed in the controller thread.
|
// and destroyed in the controller thread.
|
||||||
@@ -1239,7 +1243,40 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|||||||
// This class is only for testing Google Test's own constructs. Do not
|
// This class is only for testing Google Test's own constructs. Do not
|
||||||
// use it in user tests, either directly or indirectly.
|
// use it in user tests, either directly or indirectly.
|
||||||
// TODO(b/203539622): Replace unconditionally with absl::Notification.
|
// TODO(b/203539622): Replace unconditionally with absl::Notification.
|
||||||
class GTEST_API_ Notification {
|
#ifdef GTEST_OS_WINDOWS_MINGW
|
||||||
|
// GCC version < 13 with the win32 thread model does not provide std::mutex and
|
||||||
|
// std::condition_variable in the <mutex> and <condition_variable> headers. So
|
||||||
|
// we implement the Notification class using a Windows manual-reset event. See
|
||||||
|
// https://gcc.gnu.org/gcc-13/changes.html#windows.
|
||||||
|
class GTEST_API_ [[nodiscard]] Notification {
|
||||||
|
public:
|
||||||
|
Notification();
|
||||||
|
Notification(const Notification&) = delete;
|
||||||
|
Notification& operator=(const Notification&) = delete;
|
||||||
|
~Notification();
|
||||||
|
|
||||||
|
// Notifies all threads created with this notification to start. Must
|
||||||
|
// be called from the controller thread.
|
||||||
|
void Notify();
|
||||||
|
|
||||||
|
// Blocks until the controller thread notifies. Must be called from a test
|
||||||
|
// thread.
|
||||||
|
void WaitForNotification();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
|
||||||
|
// avoid including <windows.h> in this header file. Including <windows.h> is
|
||||||
|
// undesirable because it defines a lot of symbols and macros that tend to
|
||||||
|
// conflict with client code. This assumption is verified by
|
||||||
|
// WindowsTypesTest.HANDLEIsVoidStar.
|
||||||
|
typedef void* Handle;
|
||||||
|
Handle event_;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
class GTEST_API_ [[nodiscard]] Notification {
|
||||||
public:
|
public:
|
||||||
Notification() : notified_(false) {}
|
Notification() : notified_(false) {}
|
||||||
Notification(const Notification&) = delete;
|
Notification(const Notification&) = delete;
|
||||||
@@ -1266,6 +1303,7 @@ class GTEST_API_ Notification {
|
|||||||
bool notified_;
|
bool notified_;
|
||||||
};
|
};
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
#endif // GTEST_OS_WINDOWS_MINGW
|
||||||
#endif // GTEST_HAS_NOTIFICATION_
|
#endif // GTEST_HAS_NOTIFICATION_
|
||||||
|
|
||||||
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
|
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
|
||||||
@@ -1278,7 +1316,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|||||||
// in order to call its Run(). Introducing ThreadWithParamBase as a
|
// in order to call its Run(). Introducing ThreadWithParamBase as a
|
||||||
// non-templated base class for ThreadWithParam allows us to bypass this
|
// non-templated base class for ThreadWithParam allows us to bypass this
|
||||||
// problem.
|
// problem.
|
||||||
class ThreadWithParamBase {
|
class [[nodiscard]] ThreadWithParamBase {
|
||||||
public:
|
public:
|
||||||
virtual ~ThreadWithParamBase() = default;
|
virtual ~ThreadWithParamBase() = default;
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
@@ -1308,7 +1346,7 @@ extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
|
|||||||
// These classes are only for testing Google Test's own constructs. Do
|
// These classes are only for testing Google Test's own constructs. Do
|
||||||
// not use them in user tests, either directly or indirectly.
|
// not use them in user tests, either directly or indirectly.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadWithParam : public ThreadWithParamBase {
|
class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
|
||||||
public:
|
public:
|
||||||
typedef void UserThreadFunc(T);
|
typedef void UserThreadFunc(T);
|
||||||
|
|
||||||
@@ -1374,7 +1412,7 @@ class ThreadWithParam : public ThreadWithParamBase {
|
|||||||
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
||||||
//
|
//
|
||||||
// (A non-static Mutex is defined/declared in the usual way).
|
// (A non-static Mutex is defined/declared in the usual way).
|
||||||
class GTEST_API_ Mutex {
|
class GTEST_API_ [[nodiscard]] Mutex {
|
||||||
public:
|
public:
|
||||||
enum MutexType { kStatic = 0, kDynamic = 1 };
|
enum MutexType { kStatic = 0, kDynamic = 1 };
|
||||||
// We rely on kStaticMutex being 0 as it is to what the linker initializes
|
// We rely on kStaticMutex being 0 as it is to what the linker initializes
|
||||||
@@ -1390,9 +1428,9 @@ class GTEST_API_ Mutex {
|
|||||||
Mutex();
|
Mutex();
|
||||||
~Mutex();
|
~Mutex();
|
||||||
|
|
||||||
void Lock();
|
void lock();
|
||||||
|
|
||||||
void Unlock();
|
void unlock();
|
||||||
|
|
||||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
||||||
// with high probability.
|
// with high probability.
|
||||||
@@ -1427,14 +1465,13 @@ class GTEST_API_ Mutex {
|
|||||||
// platforms. That macro is used as a defensive measure to prevent against
|
// platforms. That macro is used as a defensive measure to prevent against
|
||||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||||
class GTestMutexLock {
|
class [[nodiscard]] GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||||
|
~GTestMutexLock() { mutex_.unlock(); }
|
||||||
~GTestMutexLock() { mutex_->Unlock(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex* const mutex_;
|
Mutex& mutex_;
|
||||||
|
|
||||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||||
@@ -1444,14 +1481,14 @@ typedef GTestMutexLock MutexLock;
|
|||||||
|
|
||||||
// Base class for ValueHolder<T>. Allows a caller to hold and delete a value
|
// Base class for ValueHolder<T>. Allows a caller to hold and delete a value
|
||||||
// without knowing its type.
|
// without knowing its type.
|
||||||
class ThreadLocalValueHolderBase {
|
class [[nodiscard]] ThreadLocalValueHolderBase {
|
||||||
public:
|
public:
|
||||||
virtual ~ThreadLocalValueHolderBase() {}
|
virtual ~ThreadLocalValueHolderBase() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Provides a way for a thread to send notifications to a ThreadLocal
|
// Provides a way for a thread to send notifications to a ThreadLocal
|
||||||
// regardless of its parameter type.
|
// regardless of its parameter type.
|
||||||
class ThreadLocalBase {
|
class [[nodiscard]] ThreadLocalBase {
|
||||||
public:
|
public:
|
||||||
// Creates a new ValueHolder<T> object holding a default value passed to
|
// Creates a new ValueHolder<T> object holding a default value passed to
|
||||||
// this ThreadLocal<T>'s constructor and returns it. It is the caller's
|
// this ThreadLocal<T>'s constructor and returns it. It is the caller's
|
||||||
@@ -1460,8 +1497,8 @@ class ThreadLocalBase {
|
|||||||
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
|
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ThreadLocalBase() {}
|
ThreadLocalBase() = default;
|
||||||
virtual ~ThreadLocalBase() {}
|
virtual ~ThreadLocalBase() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThreadLocalBase(const ThreadLocalBase&) = delete;
|
ThreadLocalBase(const ThreadLocalBase&) = delete;
|
||||||
@@ -1471,7 +1508,7 @@ class ThreadLocalBase {
|
|||||||
// Maps a thread to a set of ThreadLocals that have values instantiated on that
|
// Maps a thread to a set of ThreadLocals that have values instantiated on that
|
||||||
// thread and notifies them when the thread exits. A ThreadLocal instance is
|
// thread and notifies them when the thread exits. A ThreadLocal instance is
|
||||||
// expected to persist until all threads it has values on have terminated.
|
// expected to persist until all threads it has values on have terminated.
|
||||||
class GTEST_API_ ThreadLocalRegistry {
|
class GTEST_API_ [[nodiscard]] ThreadLocalRegistry {
|
||||||
public:
|
public:
|
||||||
// Registers thread_local_instance as having value on the current thread.
|
// Registers thread_local_instance as having value on the current thread.
|
||||||
// Returns a value that can be used to identify the thread from other threads.
|
// Returns a value that can be used to identify the thread from other threads.
|
||||||
@@ -1483,14 +1520,14 @@ class GTEST_API_ ThreadLocalRegistry {
|
|||||||
const ThreadLocalBase* thread_local_instance);
|
const ThreadLocalBase* thread_local_instance);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GTEST_API_ ThreadWithParamBase {
|
class GTEST_API_ [[nodiscard]] ThreadWithParamBase {
|
||||||
public:
|
public:
|
||||||
void Join();
|
void Join();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Runnable {
|
class Runnable {
|
||||||
public:
|
public:
|
||||||
virtual ~Runnable() {}
|
virtual ~Runnable() = default;
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1503,20 +1540,20 @@ class GTEST_API_ ThreadWithParamBase {
|
|||||||
|
|
||||||
// Helper class for testing Google Test's multi-threading constructs.
|
// Helper class for testing Google Test's multi-threading constructs.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadWithParam : public ThreadWithParamBase {
|
class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
|
||||||
public:
|
public:
|
||||||
typedef void UserThreadFunc(T);
|
typedef void UserThreadFunc(T);
|
||||||
|
|
||||||
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
||||||
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
|
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
|
||||||
virtual ~ThreadWithParam() {}
|
~ThreadWithParam() override = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class RunnableImpl : public Runnable {
|
class RunnableImpl : public Runnable {
|
||||||
public:
|
public:
|
||||||
RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
|
RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
|
||||||
virtual ~RunnableImpl() {}
|
~RunnableImpl() override = default;
|
||||||
virtual void Run() { func_(param_); }
|
void Run() override { func_(param_); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UserThreadFunc* const func_;
|
UserThreadFunc* const func_;
|
||||||
@@ -1558,7 +1595,7 @@ class ThreadWithParam : public ThreadWithParamBase {
|
|||||||
// object managed by Google Test will be leaked as long as all threads
|
// object managed by Google Test will be leaked as long as all threads
|
||||||
// using Google Test have exited when main() returns.
|
// using Google Test have exited when main() returns.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadLocal : public ThreadLocalBase {
|
class [[nodiscard]] ThreadLocal : public ThreadLocalBase {
|
||||||
public:
|
public:
|
||||||
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
|
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
|
||||||
explicit ThreadLocal(const T& value)
|
explicit ThreadLocal(const T& value)
|
||||||
@@ -1599,8 +1636,8 @@ class ThreadLocal : public ThreadLocalBase {
|
|||||||
|
|
||||||
class ValueHolderFactory {
|
class ValueHolderFactory {
|
||||||
public:
|
public:
|
||||||
ValueHolderFactory() {}
|
ValueHolderFactory() = default;
|
||||||
virtual ~ValueHolderFactory() {}
|
virtual ~ValueHolderFactory() = default;
|
||||||
virtual ValueHolder* MakeNewHolder() const = 0;
|
virtual ValueHolder* MakeNewHolder() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1610,7 +1647,7 @@ class ThreadLocal : public ThreadLocalBase {
|
|||||||
|
|
||||||
class DefaultValueHolderFactory : public ValueHolderFactory {
|
class DefaultValueHolderFactory : public ValueHolderFactory {
|
||||||
public:
|
public:
|
||||||
DefaultValueHolderFactory() {}
|
DefaultValueHolderFactory() = default;
|
||||||
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
|
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1643,17 +1680,17 @@ class ThreadLocal : public ThreadLocalBase {
|
|||||||
#elif GTEST_HAS_PTHREAD
|
#elif GTEST_HAS_PTHREAD
|
||||||
|
|
||||||
// MutexBase and Mutex implement mutex on pthreads-based platforms.
|
// MutexBase and Mutex implement mutex on pthreads-based platforms.
|
||||||
class MutexBase {
|
class [[nodiscard]] MutexBase {
|
||||||
public:
|
public:
|
||||||
// Acquires this mutex.
|
// Acquires this mutex.
|
||||||
void Lock() {
|
void lock() {
|
||||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
||||||
owner_ = pthread_self();
|
owner_ = pthread_self();
|
||||||
has_owner_ = true;
|
has_owner_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Releases this mutex.
|
// Releases this mutex.
|
||||||
void Unlock() {
|
void unlock() {
|
||||||
// Since the lock is being released the owner_ field should no longer be
|
// Since the lock is being released the owner_ field should no longer be
|
||||||
// considered valid. We don't protect writing to has_owner_ here, as it's
|
// considered valid. We don't protect writing to has_owner_ here, as it's
|
||||||
// the caller's responsibility to ensure that the current thread holds the
|
// the caller's responsibility to ensure that the current thread holds the
|
||||||
@@ -1701,7 +1738,7 @@ class MutexBase {
|
|||||||
|
|
||||||
// The Mutex class can only be used for mutexes created at runtime. It
|
// The Mutex class can only be used for mutexes created at runtime. It
|
||||||
// shares its API with MutexBase otherwise.
|
// shares its API with MutexBase otherwise.
|
||||||
class Mutex : public MutexBase {
|
class [[nodiscard]] Mutex : public MutexBase {
|
||||||
public:
|
public:
|
||||||
Mutex() {
|
Mutex() {
|
||||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
|
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
|
||||||
@@ -1719,14 +1756,13 @@ class Mutex : public MutexBase {
|
|||||||
// platforms. That macro is used as a defensive measure to prevent against
|
// platforms. That macro is used as a defensive measure to prevent against
|
||||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||||
class GTestMutexLock {
|
class [[nodiscard]] GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||||
|
~GTestMutexLock() { mutex_.unlock(); }
|
||||||
~GTestMutexLock() { mutex_->Unlock(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutexBase* const mutex_;
|
MutexBase& mutex_;
|
||||||
|
|
||||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||||
@@ -1740,7 +1776,7 @@ typedef GTestMutexLock MutexLock;
|
|||||||
// C-linkage. Therefore it cannot be templatized to access
|
// C-linkage. Therefore it cannot be templatized to access
|
||||||
// ThreadLocal<T>. Hence the need for class
|
// ThreadLocal<T>. Hence the need for class
|
||||||
// ThreadLocalValueHolderBase.
|
// ThreadLocalValueHolderBase.
|
||||||
class GTEST_API_ ThreadLocalValueHolderBase {
|
class GTEST_API_ [[nodiscard]] ThreadLocalValueHolderBase {
|
||||||
public:
|
public:
|
||||||
virtual ~ThreadLocalValueHolderBase() = default;
|
virtual ~ThreadLocalValueHolderBase() = default;
|
||||||
};
|
};
|
||||||
@@ -1753,7 +1789,7 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
|
|||||||
|
|
||||||
// Implements thread-local storage on pthreads-based systems.
|
// Implements thread-local storage on pthreads-based systems.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class GTEST_API_ ThreadLocal {
|
class GTEST_API_ [[nodiscard]] ThreadLocal {
|
||||||
public:
|
public:
|
||||||
ThreadLocal()
|
ThreadLocal()
|
||||||
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
|
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
|
||||||
@@ -1866,11 +1902,11 @@ class GTEST_API_ ThreadLocal {
|
|||||||
// mutex is not supported - using Google Test in multiple threads is not
|
// mutex is not supported - using Google Test in multiple threads is not
|
||||||
// supported on such platforms.
|
// supported on such platforms.
|
||||||
|
|
||||||
class Mutex {
|
class [[nodiscard]] Mutex {
|
||||||
public:
|
public:
|
||||||
Mutex() {}
|
Mutex() {}
|
||||||
void Lock() {}
|
void lock() {}
|
||||||
void Unlock() {}
|
void unlock() {}
|
||||||
void AssertHeld() const {}
|
void AssertHeld() const {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1884,15 +1920,15 @@ class Mutex {
|
|||||||
// platforms. That macro is used as a defensive measure to prevent against
|
// platforms. That macro is used as a defensive measure to prevent against
|
||||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||||
class GTestMutexLock {
|
class [[nodiscard]] GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
explicit GTestMutexLock(Mutex&) {} // NOLINT
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GTestMutexLock MutexLock;
|
typedef GTestMutexLock MutexLock;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class GTEST_API_ ThreadLocal {
|
class GTEST_API_ [[nodiscard]] ThreadLocal {
|
||||||
public:
|
public:
|
||||||
ThreadLocal() : value_() {}
|
ThreadLocal() : value_() {}
|
||||||
explicit ThreadLocal(const T& value) : value_(value) {}
|
explicit ThreadLocal(const T& value) : value_(value) {}
|
||||||
@@ -1987,7 +2023,9 @@ inline std::string StripTrailingSpaces(std::string str) {
|
|||||||
namespace posix {
|
namespace posix {
|
||||||
|
|
||||||
// File system porting.
|
// File system porting.
|
||||||
#if GTEST_HAS_FILE_SYSTEM
|
// Note: Not every I/O-related function is related to file systems, so don't
|
||||||
|
// just disable all of them here. For example, fileno() and isatty(), etc. must
|
||||||
|
// always be available in order to detect if a pipe points to a terminal.
|
||||||
#ifdef GTEST_OS_WINDOWS
|
#ifdef GTEST_OS_WINDOWS
|
||||||
|
|
||||||
typedef struct _stat StatStruct;
|
typedef struct _stat StatStruct;
|
||||||
@@ -1998,27 +2036,32 @@ inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
|
|||||||
// time and thus not defined there.
|
// time and thus not defined there.
|
||||||
#else
|
#else
|
||||||
inline int FileNo(FILE* file) { return _fileno(file); }
|
inline int FileNo(FILE* file) { return _fileno(file); }
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
|
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
|
||||||
inline int RmDir(const char* dir) { return _rmdir(dir); }
|
inline int RmDir(const char* dir) { return _rmdir(dir); }
|
||||||
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
|
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
|
||||||
|
#endif
|
||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
#elif defined(GTEST_OS_ESP8266)
|
#elif defined(GTEST_OS_ESP8266)
|
||||||
typedef struct stat StatStruct;
|
typedef struct stat StatStruct;
|
||||||
|
|
||||||
inline int FileNo(FILE* file) { return fileno(file); }
|
inline int FileNo(FILE* file) { return fileno(file); }
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
inline int Stat(const char* path, StatStruct* buf) {
|
inline int Stat(const char* path, StatStruct* buf) {
|
||||||
// stat function not implemented on ESP8266
|
// stat function not implemented on ESP8266
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inline int RmDir(const char* dir) { return rmdir(dir); }
|
inline int RmDir(const char* dir) { return rmdir(dir); }
|
||||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef struct stat StatStruct;
|
typedef struct stat StatStruct;
|
||||||
|
|
||||||
inline int FileNo(FILE* file) { return fileno(file); }
|
inline int FileNo(FILE* file) { return fileno(file); }
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
|
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
|
||||||
#ifdef GTEST_OS_QURT
|
#ifdef GTEST_OS_QURT
|
||||||
// QuRT doesn't support any directory functions, including rmdir
|
// QuRT doesn't support any directory functions, including rmdir
|
||||||
@@ -2027,9 +2070,9 @@ inline int RmDir(const char*) { return 0; }
|
|||||||
inline int RmDir(const char* dir) { return rmdir(dir); }
|
inline int RmDir(const char* dir) { return rmdir(dir); }
|
||||||
#endif
|
#endif
|
||||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
#endif // GTEST_HAS_FILE_SYSTEM
|
|
||||||
|
|
||||||
// Other functions with a different name on Windows.
|
// Other functions with a different name on Windows.
|
||||||
|
|
||||||
@@ -2082,8 +2125,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
|
|||||||
// defined there.
|
// defined there.
|
||||||
#if GTEST_HAS_FILE_SYSTEM
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
|
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
|
||||||
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \
|
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \
|
||||||
!defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT)
|
!defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \
|
||||||
|
!defined(GTEST_OS_QURT)
|
||||||
inline int ChDir(const char* dir) { return chdir(dir); }
|
inline int ChDir(const char* dir) { return chdir(dir); }
|
||||||
#endif
|
#endif
|
||||||
inline FILE* FOpen(const char* path, const char* mode) {
|
inline FILE* FOpen(const char* path, const char* mode) {
|
||||||
@@ -2192,7 +2236,7 @@ constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();
|
|||||||
// needs. Other types can be easily added in the future if need
|
// needs. Other types can be easily added in the future if need
|
||||||
// arises.
|
// arises.
|
||||||
template <size_t size>
|
template <size_t size>
|
||||||
class TypeWithSize {
|
class [[nodiscard]] TypeWithSize {
|
||||||
public:
|
public:
|
||||||
// This prevents the user from using TypeWithSize<N> with incorrect
|
// This prevents the user from using TypeWithSize<N> with incorrect
|
||||||
// values of N.
|
// values of N.
|
||||||
@@ -2201,7 +2245,7 @@ class TypeWithSize {
|
|||||||
|
|
||||||
// The specialization for size 4.
|
// The specialization for size 4.
|
||||||
template <>
|
template <>
|
||||||
class TypeWithSize<4> {
|
class [[nodiscard]] TypeWithSize<4> {
|
||||||
public:
|
public:
|
||||||
using Int = std::int32_t;
|
using Int = std::int32_t;
|
||||||
using UInt = std::uint32_t;
|
using UInt = std::uint32_t;
|
||||||
@@ -2209,7 +2253,7 @@ class TypeWithSize<4> {
|
|||||||
|
|
||||||
// The specialization for size 8.
|
// The specialization for size 8.
|
||||||
template <>
|
template <>
|
||||||
class TypeWithSize<8> {
|
class [[nodiscard]] TypeWithSize<8> {
|
||||||
public:
|
public:
|
||||||
using Int = std::int64_t;
|
using Int = std::int64_t;
|
||||||
using UInt = std::uint64_t;
|
using UInt = std::uint64_t;
|
||||||
@@ -2227,7 +2271,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
|||||||
#endif // !defined(GTEST_FLAG)
|
#endif // !defined(GTEST_FLAG)
|
||||||
|
|
||||||
// Pick a command line flags implementation.
|
// Pick a command line flags implementation.
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS
|
||||||
|
|
||||||
// Macros for defining flags.
|
// Macros for defining flags.
|
||||||
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||||
@@ -2239,11 +2283,11 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
|||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
#define GTEST_DECLARE_bool_(name) \
|
#define GTEST_DECLARE_bool_(name) \
|
||||||
ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
|
GTEST_API_ ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
|
||||||
#define GTEST_DECLARE_int32_(name) \
|
#define GTEST_DECLARE_int32_(name) \
|
||||||
ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
|
GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
|
||||||
#define GTEST_DECLARE_string_(name) \
|
#define GTEST_DECLARE_string_(name) \
|
||||||
ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
|
GTEST_API_ ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
|
||||||
|
|
||||||
#define GTEST_FLAG_SAVER_ ::absl::FlagSaver
|
#define GTEST_FLAG_SAVER_ ::absl::FlagSaver
|
||||||
|
|
||||||
@@ -2252,7 +2296,8 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
|||||||
(void)(::absl::SetFlag(>EST_FLAG(name), value))
|
(void)(::absl::SetFlag(>EST_FLAG(name), value))
|
||||||
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
|
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
|
||||||
|
|
||||||
#else // GTEST_HAS_ABSL
|
#undef GTEST_INTERNAL_HAS_ABSL_FLAGS
|
||||||
|
#else // ndef GTEST_INTERNAL_HAS_ABSL_FLAGS
|
||||||
|
|
||||||
// Macros for defining flags.
|
// Macros for defining flags.
|
||||||
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||||
@@ -2294,7 +2339,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
|||||||
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
|
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
|
||||||
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
|
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
|
||||||
|
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_INTERNAL_HAS_ABSL_FLAGS
|
||||||
|
|
||||||
// Thread annotations
|
// Thread annotations
|
||||||
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
||||||
@@ -2318,93 +2363,20 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#if !defined(GTEST_INTERNAL_DEPRECATED)
|
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate)
|
||||||
|
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \
|
||||||
// Internal Macro to mark an API deprecated, for googletest usage only
|
[[deprecated(msg), clang::annotate("inline-me")]]
|
||||||
// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or
|
|
||||||
// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of
|
|
||||||
// a deprecated entity will trigger a warning when compiled with
|
|
||||||
// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).
|
|
||||||
// For msvc /W3 option will need to be used
|
|
||||||
// Note that for 'other' compilers this macro evaluates to nothing to prevent
|
|
||||||
// compilations errors.
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))
|
|
||||||
#else
|
#else
|
||||||
#define GTEST_INTERNAL_DEPRECATED(message)
|
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
|
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
|
||||||
|
GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)
|
||||||
|
#define GTEST_INTERNAL_HAS_STD_SPAN 1
|
||||||
|
#endif // __cpp_lib_span
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifndef GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
#define GTEST_INTERNAL_HAS_STD_SPAN 0
|
||||||
// is built with absl support.
|
|
||||||
#define GTEST_INTERNAL_HAS_ANY 1
|
|
||||||
#include "absl/types/any.h"
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
using Any = ::absl::any;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
#else
|
|
||||||
#ifdef __has_include
|
|
||||||
#if __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
|
|
||||||
(!defined(_MSC_VER) || GTEST_HAS_RTTI)
|
|
||||||
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
|
|
||||||
// specializations.
|
|
||||||
#define GTEST_INTERNAL_HAS_ANY 1
|
|
||||||
#include <any>
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
using Any = ::std::any;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
// The case where absl is configured NOT to alias std::any is not
|
|
||||||
// supported.
|
|
||||||
#endif // __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
|
||||||
#endif // __has_include
|
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_ANY
|
|
||||||
#define GTEST_INTERNAL_HAS_ANY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
|
||||||
// Always use absl::optional for UniversalPrinter<> specializations if
|
|
||||||
// googletest is built with absl support.
|
|
||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 1
|
|
||||||
#include "absl/types/optional.h"
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename T>
|
|
||||||
using Optional = ::absl::optional<T>;
|
|
||||||
inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
#else
|
|
||||||
#ifdef __has_include
|
|
||||||
#if __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
|
||||||
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
|
|
||||||
// specializations.
|
|
||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 1
|
|
||||||
#include <optional>
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename T>
|
|
||||||
using Optional = ::std::optional<T>;
|
|
||||||
inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
// The case where absl is configured NOT to alias std::optional is not
|
|
||||||
// supported.
|
|
||||||
#endif // __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
|
||||||
#endif // __has_include
|
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_OPTIONAL
|
|
||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
@@ -2418,8 +2390,9 @@ using StringView = ::absl::string_view;
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
#else
|
#else
|
||||||
#ifdef __has_include
|
#if defined(__cpp_lib_string_view) || \
|
||||||
#if __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
(GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \
|
||||||
|
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
|
||||||
// Otherwise for C++17 and higher use std::string_view for Matcher<>
|
// Otherwise for C++17 and higher use std::string_view for Matcher<>
|
||||||
// specializations.
|
// specializations.
|
||||||
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
|
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
|
||||||
@@ -2431,51 +2404,19 @@ using StringView = ::std::string_view;
|
|||||||
} // namespace testing
|
} // namespace testing
|
||||||
// The case where absl is configured NOT to alias std::string_view is not
|
// The case where absl is configured NOT to alias std::string_view is not
|
||||||
// supported.
|
// supported.
|
||||||
#endif // __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >=
|
#endif // __cpp_lib_string_view
|
||||||
// 201703L
|
|
||||||
#endif // __has_include
|
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW
|
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
|
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#if (defined(__cpp_lib_three_way_comparison) || \
|
||||||
// Always use absl::variant for UniversalPrinter<> specializations if googletest
|
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
||||||
// is built with absl support.
|
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
||||||
#define GTEST_INTERNAL_HAS_VARIANT 1
|
#define GTEST_INTERNAL_HAS_COMPARE_LIB 1
|
||||||
#include "absl/types/variant.h"
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename... T>
|
|
||||||
using Variant = ::absl::variant<T...>;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
#else
|
#else
|
||||||
#ifdef __has_include
|
#define GTEST_INTERNAL_HAS_COMPARE_LIB 0
|
||||||
#if __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
|
||||||
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
|
|
||||||
// specializations.
|
|
||||||
#define GTEST_INTERNAL_HAS_VARIANT 1
|
|
||||||
#include <variant>
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename... T>
|
|
||||||
using Variant = ::std::variant<T...>;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
// The case where absl is configured NOT to alias std::variant is not supported.
|
|
||||||
#endif // __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
|
||||||
#endif // __has_include
|
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
#define GTEST_INTERNAL_HAS_VARIANT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
|
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
|
|
||||||
#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace testing {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// String - an abstract class holding static string utilities.
|
// String - an abstract class holding static string utilities.
|
||||||
class GTEST_API_ String {
|
class GTEST_API_ [[nodiscard]] String {
|
||||||
public:
|
public:
|
||||||
// Static utility methods
|
// Static utility methods
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ class GTEST_API_ String {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
String(); // Not meant to be instantiated.
|
String(); // Not meant to be instantiated.
|
||||||
}; // class String
|
}; // class String
|
||||||
|
|
||||||
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
||||||
// character in the buffer is replaced with "\\0".
|
// character in the buffer is replaced with "\\0".
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
|||||||
// Strip redundant spaces in typename to match MSVC
|
// Strip redundant spaces in typename to match MSVC
|
||||||
// For example, std::pair<int, bool> -> std::pair<int,bool>
|
// For example, std::pair<int, bool> -> std::pair<int,bool>
|
||||||
static const char to_search[] = ", ";
|
static const char to_search[] = ", ";
|
||||||
static const char replace_str[] = ",";
|
const char replace_char = ',';
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
// Get the next occurrence from the current position
|
// Get the next occurrence from the current position
|
||||||
@@ -80,8 +80,8 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Replace this occurrence of substring
|
// Replace this occurrence of substring
|
||||||
s.replace(pos, strlen(to_search), replace_str);
|
s.replace(pos, strlen(to_search), 1, replace_char);
|
||||||
pos += strlen(replace_str);
|
++pos;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,12 +53,12 @@ class BetweenCardinalityImpl : public CardinalityInterface {
|
|||||||
: min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {
|
: min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if (min < 0) {
|
if (min < 0) {
|
||||||
ss << "The invocation lower bound must be >= 0, "
|
ss << "The invocation lower bound must be >= 0, " << "but is actually "
|
||||||
<< "but is actually " << min << ".";
|
<< min << ".";
|
||||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||||
} else if (max < 0) {
|
} else if (max < 0) {
|
||||||
ss << "The invocation upper bound must be >= 0, "
|
ss << "The invocation upper bound must be >= 0, " << "but is actually "
|
||||||
<< "but is actually " << max << ".";
|
<< max << ".";
|
||||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||||
} else if (min > max) {
|
} else if (min > max) {
|
||||||
ss << "The invocation upper bound (" << max
|
ss << "The invocation upper bound (" << max
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
@@ -155,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||||||
if (!LogIsVisible(severity)) return;
|
if (!LogIsVisible(severity)) return;
|
||||||
|
|
||||||
// Ensures that logs from different threads don't interleave.
|
// Ensures that logs from different threads don't interleave.
|
||||||
MutexLock l(&g_log_mutex);
|
MutexLock l(g_log_mutex);
|
||||||
|
|
||||||
if (severity == kWarning) {
|
if (severity == kWarning) {
|
||||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||||
@@ -187,7 +188,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||||||
std::cout << ::std::flush;
|
std::cout << ::std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
|
GTEST_API_ WithoutMatchers WithoutMatchers::Get() { return WithoutMatchers(); }
|
||||||
|
|
||||||
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
||||||
internal::Assert(
|
internal::Assert(
|
||||||
@@ -211,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <size_t... I>
|
template <size_t... I>
|
||||||
constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>,
|
constexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,
|
||||||
const char* const base64) {
|
const char* const base64) {
|
||||||
return {
|
return {
|
||||||
{UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
|
{UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::array<char, 256> UnBase64(const char* const base64) {
|
constexpr std::array<char, 256> UnBase64(const char* const base64) {
|
||||||
return UnBase64Impl(MakeIndexSequence<256>{}, base64);
|
return UnBase64Impl(std::make_index_sequence<256>{}, base64);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr char kBase64[] =
|
static constexpr char kBase64[] =
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ GTEST_API_ std::string FormatMatcherDescription(
|
|||||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
|
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
|
||||||
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
|
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
|
||||||
// [2] "Ford-Fulkerson algorithm", Wikipedia,
|
// [2] "Ford-Fulkerson algorithm", Wikipedia,
|
||||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
// 'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||||
class MaxBipartiteMatchState {
|
class MaxBipartiteMatchState {
|
||||||
public:
|
public:
|
||||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||||
@@ -236,9 +236,8 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
|||||||
os << "{";
|
os << "{";
|
||||||
const char* sep = "";
|
const char* sep = "";
|
||||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||||
os << sep << "\n ("
|
os << sep << "\n (" << "element #" << it->first << ", " << "matcher #"
|
||||||
<< "element #" << it->first << ", "
|
<< it->second << ")";
|
||||||
<< "matcher #" << it->second << ")";
|
|
||||||
sep = ",";
|
sep = ",";
|
||||||
}
|
}
|
||||||
os << "\n}";
|
os << "\n}";
|
||||||
@@ -374,20 +373,20 @@ bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
const bool is_exact_match_with_size_discrepency =
|
||||||
if (matrix.LhsSize() != matrix.RhsSize()) {
|
match_flags() == UnorderedMatcherRequire::ExactMatch &&
|
||||||
// The element count doesn't match. If the container is empty,
|
matrix.LhsSize() != matrix.RhsSize();
|
||||||
// there's no need to explain anything as Google Mock already
|
if (is_exact_match_with_size_discrepency) {
|
||||||
// prints the empty container. Otherwise we just need to show
|
// The element count doesn't match. If the container is empty,
|
||||||
// how many elements there actually are.
|
// there's no need to explain anything as Google Mock already
|
||||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
// prints the empty container. Otherwise we just need to show
|
||||||
*listener << "which has " << Elements(matrix.LhsSize());
|
// how many elements there actually are.
|
||||||
}
|
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||||
return false;
|
*listener << "which has " << Elements(matrix.LhsSize()) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = true;
|
bool result = !is_exact_match_with_size_discrepency;
|
||||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
|
|||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
bool should_check = false;
|
bool should_check = false;
|
||||||
{
|
{
|
||||||
MutexLock l(&mutex_);
|
MutexLock l(mutex_);
|
||||||
if (!action_count_checked_) {
|
if (!action_count_checked_) {
|
||||||
action_count_checked_ = true;
|
action_count_checked_ = true;
|
||||||
should_check = true;
|
should_check = true;
|
||||||
@@ -293,7 +293,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
|||||||
Log(kWarning,
|
Log(kWarning,
|
||||||
msg +
|
msg +
|
||||||
"\nNOTE: You can safely ignore the above warning unless this "
|
"\nNOTE: You can safely ignore the above warning unless this "
|
||||||
"call should not happen. Do not suppress it by blindly adding "
|
"call should not happen. Do not suppress it by adding "
|
||||||
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
||||||
"See "
|
"See "
|
||||||
"https://github.com/google/googletest/blob/main/docs/"
|
"https://github.com/google/googletest/blob/main/docs/"
|
||||||
@@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
|
|||||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
{
|
{
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
mock_obj_ = mock_obj;
|
mock_obj_ = mock_obj;
|
||||||
}
|
}
|
||||||
Mock::Register(mock_obj, this);
|
Mock::Register(mock_obj, this);
|
||||||
@@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
|||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
// We protect name_ under g_gmock_mutex in case this mock function
|
// We protect name_ under g_gmock_mutex in case this mock function
|
||||||
// is called from two threads concurrently.
|
// is called from two threads concurrently.
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
mock_obj_ = mock_obj;
|
mock_obj_ = mock_obj;
|
||||||
name_ = name;
|
name_ = name;
|
||||||
}
|
}
|
||||||
@@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
|
|||||||
{
|
{
|
||||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||||
// function is called from two threads concurrently.
|
// function is called from two threads concurrently.
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
||||||
"MockObject() must not be called before RegisterOwner() or "
|
"MockObject() must not be called before RegisterOwner() or "
|
||||||
"SetOwnerAndName() has been called.");
|
"SetOwnerAndName() has been called.");
|
||||||
@@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
|
|||||||
{
|
{
|
||||||
// We protect name_ under g_gmock_mutex in case this mock
|
// We protect name_ under g_gmock_mutex in case this mock
|
||||||
// function is called from two threads concurrently.
|
// function is called from two threads concurrently.
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
Assert(name_ != nullptr, __FILE__, __LINE__,
|
Assert(name_ != nullptr, __FILE__, __LINE__,
|
||||||
"Name() must not be called before SetOwnerAndName() has "
|
"Name() must not be called before SetOwnerAndName() has "
|
||||||
"been called.");
|
"been called.");
|
||||||
@@ -436,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
|||||||
UntypedExpectations expectations_to_delete;
|
UntypedExpectations expectations_to_delete;
|
||||||
untyped_expectations_.swap(expectations_to_delete);
|
untyped_expectations_.swap(expectations_to_delete);
|
||||||
|
|
||||||
g_gmock_mutex.Unlock();
|
g_gmock_mutex.unlock();
|
||||||
expectations_to_delete.clear();
|
expectations_to_delete.clear();
|
||||||
g_gmock_mutex.Lock();
|
g_gmock_mutex.lock();
|
||||||
|
|
||||||
return expectations_met;
|
return expectations_met;
|
||||||
}
|
}
|
||||||
@@ -490,6 +490,7 @@ class MockObjectRegistry {
|
|||||||
// failure, unless the user explicitly asked us to ignore it.
|
// failure, unless the user explicitly asked us to ignore it.
|
||||||
~MockObjectRegistry() {
|
~MockObjectRegistry() {
|
||||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||||
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
|
|
||||||
int leaked_count = 0;
|
int leaked_count = 0;
|
||||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||||
@@ -530,7 +531,7 @@ class MockObjectRegistry {
|
|||||||
#ifdef GTEST_OS_QURT
|
#ifdef GTEST_OS_QURT
|
||||||
qurt_exception_raise_fatal();
|
qurt_exception_raise_fatal();
|
||||||
#else
|
#else
|
||||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
_Exit(1); // We cannot call exit() as it is not reentrant and
|
||||||
// may already have been called.
|
// may already have been called.
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -558,7 +559,7 @@ UninterestingCallReactionMap() {
|
|||||||
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
||||||
internal::CallReaction reaction)
|
internal::CallReaction reaction)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
UninterestingCallReactionMap()[mock_obj] = reaction;
|
UninterestingCallReactionMap()[mock_obj] = reaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
|
|||||||
// entry in the call-reaction table should be removed.
|
// entry in the call-reaction table should be removed.
|
||||||
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
|
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
|||||||
// made on the given mock object.
|
// made on the given mock object.
|
||||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||||
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
return (UninterestingCallReactionMap().count(
|
return (UninterestingCallReactionMap().count(
|
||||||
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
||||||
? internal::intToCallReaction(
|
? internal::intToCallReaction(
|
||||||
@@ -610,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
|||||||
// objects.
|
// objects.
|
||||||
void Mock::AllowLeak(const void* mock_obj)
|
void Mock::AllowLeak(const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj)
|
|||||||
// Test non-fatal failures and returns false.
|
// Test non-fatal failures and returns false.
|
||||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
|||||||
// verification was successful.
|
// verification was successful.
|
||||||
bool Mock::VerifyAndClear(void* mock_obj)
|
bool Mock::VerifyAndClear(void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
ClearDefaultActionsLocked(mock_obj);
|
ClearDefaultActionsLocked(mock_obj);
|
||||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||||
}
|
}
|
||||||
@@ -678,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
|
|||||||
void Mock::Register(const void* mock_obj,
|
void Mock::Register(const void* mock_obj,
|
||||||
internal::UntypedFunctionMockerBase* mocker)
|
internal::UntypedFunctionMockerBase* mocker)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +689,7 @@ void Mock::Register(const void* mock_obj,
|
|||||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||||
const char* file, int line)
|
const char* file, int line)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||||
if (state.first_used_file == nullptr) {
|
if (state.first_used_file == nullptr) {
|
||||||
state.first_used_file = file;
|
state.first_used_file = file;
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-death-test.h"
|
#include "gtest/gtest-death-test.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -115,7 +117,7 @@ GTEST_DEFINE_string_(
|
|||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
death_test_use_fork,
|
death_test_use_fork,
|
||||||
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
|
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
|
||||||
"Instructs to use fork()/_exit() instead of clone() in death tests. "
|
"Instructs to use fork()/_Exit() instead of clone() in death tests. "
|
||||||
"Ignored and always uses fork() on POSIX systems where clone() is not "
|
"Ignored and always uses fork() on POSIX systems where clone() is not "
|
||||||
"implemented. Useful when running under valgrind or similar tools if "
|
"implemented. Useful when running under valgrind or similar tools if "
|
||||||
"those do not support clone(). Valgrind 3.3.1 will just fail if "
|
"those do not support clone(). Valgrind 3.3.1 will just fail if "
|
||||||
@@ -299,7 +301,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
|
|||||||
fputc(kDeathTestInternalError, parent);
|
fputc(kDeathTestInternalError, parent);
|
||||||
fprintf(parent, "%s", message.c_str());
|
fprintf(parent, "%s", message.c_str());
|
||||||
fflush(parent);
|
fflush(parent);
|
||||||
_exit(1);
|
_Exit(1);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s", message.c_str());
|
fprintf(stderr, "%s", message.c_str());
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
@@ -511,7 +513,7 @@ std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
|
|||||||
// Signals that the death test code which should have exited, didn't.
|
// Signals that the death test code which should have exited, didn't.
|
||||||
// Should be called only in a death test child process.
|
// Should be called only in a death test child process.
|
||||||
// Writes a status byte to the child's status file descriptor, then
|
// Writes a status byte to the child's status file descriptor, then
|
||||||
// calls _exit(1).
|
// calls _Exit(1).
|
||||||
void DeathTestImpl::Abort(AbortReason reason) {
|
void DeathTestImpl::Abort(AbortReason reason) {
|
||||||
// The parent process considers the death test to be a failure if
|
// The parent process considers the death test to be a failure if
|
||||||
// it finds any data in our pipe. So, here we write a single flag byte
|
// it finds any data in our pipe. So, here we write a single flag byte
|
||||||
@@ -523,13 +525,13 @@ void DeathTestImpl::Abort(AbortReason reason) {
|
|||||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
|
||||||
// We are leaking the descriptor here because on some platforms (i.e.,
|
// We are leaking the descriptor here because on some platforms (i.e.,
|
||||||
// when built as Windows DLL), destructors of global objects will still
|
// when built as Windows DLL), destructors of global objects will still
|
||||||
// run after calling _exit(). On such systems, write_fd_ will be
|
// run after calling _Exit(). On such systems, write_fd_ will be
|
||||||
// indirectly closed from the destructor of UnitTestImpl, causing double
|
// indirectly closed from the destructor of UnitTestImpl, causing double
|
||||||
// close if it is also closed here. On debug configurations, double close
|
// close if it is also closed here. On debug configurations, double close
|
||||||
// may assert. As there are no in-process buffers to flush here, we are
|
// may assert. As there are no in-process buffers to flush here, we are
|
||||||
// relying on the OS to close the descriptor after the process terminates
|
// relying on the OS to close the descriptor after the process terminates
|
||||||
// when the destructors are not run.
|
// when the destructors are not run.
|
||||||
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
_Exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an indented copy of stderr output for a death test.
|
// Returns an indented copy of stderr output for a death test.
|
||||||
@@ -628,13 +630,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
|
|||||||
#ifndef GTEST_OS_WINDOWS
|
#ifndef GTEST_OS_WINDOWS
|
||||||
// Note: The return value points into args, so the return value's lifetime is
|
// Note: The return value points into args, so the return value's lifetime is
|
||||||
// bound to that of args.
|
// bound to that of args.
|
||||||
static std::unique_ptr<char*[]> CreateArgvFromArgs(
|
static std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {
|
||||||
std::vector<std::string>& args) {
|
std::vector<char*> result;
|
||||||
auto result = std::make_unique<char*[]>(args.size() + 1);
|
result.reserve(args.size() + 1);
|
||||||
for (size_t i = 0; i < args.size(); ++i) {
|
for (auto& arg : args) {
|
||||||
result[i] = &args[i][0];
|
result.push_back(&arg[0]);
|
||||||
}
|
}
|
||||||
result[args.size()] = nullptr; // extra null terminator
|
result.push_back(nullptr); // Extra null terminator.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -783,7 +785,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
|||||||
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
||||||
// size_t has the same width as pointers on both 32-bit and 64-bit
|
// size_t has the same width as pointers on both 32-bit and 64-bit
|
||||||
// Windows platforms.
|
// Windows platforms.
|
||||||
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
// See https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
||||||
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
|
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
|
||||||
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
||||||
|
|
||||||
@@ -1034,8 +1036,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
|||||||
// "Fuchsia Test Component" which contains a "Fuchsia Component Manifest")
|
// "Fuchsia Test Component" which contains a "Fuchsia Component Manifest")
|
||||||
// Launching processes is a privileged operation in Fuchsia, and the
|
// Launching processes is a privileged operation in Fuchsia, and the
|
||||||
// declaration indicates that the ability is required for the component.
|
// declaration indicates that the ability is required for the component.
|
||||||
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
|
std::vector<char*> argv = CreateArgvFromArgs(args);
|
||||||
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(),
|
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),
|
||||||
nullptr, 2, spawn_actions,
|
nullptr, 2, spawn_actions,
|
||||||
child_process_.reset_and_get_address(), nullptr);
|
child_process_.reset_and_get_address(), nullptr);
|
||||||
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
||||||
@@ -1333,7 +1335,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
|||||||
#endif // GTEST_HAS_CLONE
|
#endif // GTEST_HAS_CLONE
|
||||||
|
|
||||||
if (use_fork && (child_pid = fork()) == 0) {
|
if (use_fork && (child_pid = fork()) == 0) {
|
||||||
_exit(ExecDeathTestChildMain(&args));
|
_Exit(ExecDeathTestChildMain(&args));
|
||||||
}
|
}
|
||||||
#endif // GTEST_OS_QNX
|
#endif // GTEST_OS_QNX
|
||||||
#ifdef GTEST_OS_LINUX
|
#ifdef GTEST_OS_LINUX
|
||||||
@@ -1386,8 +1388,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
|||||||
// is necessary.
|
// is necessary.
|
||||||
FlushInfoLog();
|
FlushInfoLog();
|
||||||
|
|
||||||
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
|
std::vector<char*> argv = CreateArgvFromArgs(args);
|
||||||
const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]);
|
const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);
|
||||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||||
set_child_pid(child_pid);
|
set_child_pid(child_pid);
|
||||||
set_read_fd(pipe_fd[0]);
|
set_read_fd(pipe_fd[0]);
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
if (pathname_.empty() || this->DirectoryExists()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
@@ -245,15 +246,12 @@ GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);
|
|||||||
// be created, prints an error and exits.
|
// be created, prints an error and exits.
|
||||||
void WriteToShardStatusFileIfNeeded();
|
void WriteToShardStatusFileIfNeeded();
|
||||||
|
|
||||||
// Checks whether sharding is enabled by examining the relevant
|
// Checks whether sharding is enabled by examining the relevant flag values.
|
||||||
// environment variable values. If the variables are present,
|
// If the flags are set, but inconsistent (e.g., shard_index >= total_shards),
|
||||||
// but inconsistent (e.g., shard_index >= total_shards), prints
|
// prints an error and exits. If in_subprocess_for_death_test, sharding is
|
||||||
// an error and exits. If in_subprocess_for_death_test, sharding is
|
|
||||||
// disabled because it must only be applied to the original test
|
// disabled because it must only be applied to the original test
|
||||||
// process. Otherwise, we could filter out death tests we intended to execute.
|
// process. Otherwise, we could filter out death tests we intended to execute.
|
||||||
GTEST_API_ bool ShouldShard(const char* total_shards_str,
|
GTEST_API_ bool ShouldShard(bool in_subprocess_for_death_test);
|
||||||
const char* shard_index_str,
|
|
||||||
bool in_subprocess_for_death_test);
|
|
||||||
|
|
||||||
// Parses the environment variable var as a 32-bit integer. If it is unset,
|
// Parses the environment variable var as a 32-bit integer. If it is unset,
|
||||||
// returns default_val. If it is not a 32-bit integer, prints an error and
|
// returns default_val. If it is not a 32-bit integer, prints an error and
|
||||||
@@ -312,7 +310,7 @@ void ShuffleRange(internal::Random* random, int begin, int end,
|
|||||||
<< begin << ", " << size << "].";
|
<< begin << ", " << size << "].";
|
||||||
|
|
||||||
// Fisher-Yates shuffle, from
|
// Fisher-Yates shuffle, from
|
||||||
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
|
// https://en.wikipedia.org/wiki/Fisher-Yates_shuffle
|
||||||
for (int range_width = end - begin; range_width >= 2; range_width--) {
|
for (int range_width = end - begin; range_width >= 2; range_width--) {
|
||||||
const int last_in_range = begin + range_width - 1;
|
const int last_in_range = begin + range_width - 1;
|
||||||
const int selected =
|
const int selected =
|
||||||
@@ -649,13 +647,15 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// this is not a typed or a type-parameterized test.
|
// this is not a typed or a type-parameterized test.
|
||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test suite
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
|
TestSuite* GetTestSuite(const std::string& test_suite_name,
|
||||||
|
const char* type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc);
|
internal::TearDownTestSuiteFunc tear_down_tc);
|
||||||
|
|
||||||
// Legacy API is deprecated but still available
|
// Legacy API is deprecated but still available
|
||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
TestCase* GetTestCase(const char* test_case_name, const char* type_param,
|
TestCase* GetTestCase(const std::string& test_case_name,
|
||||||
|
const char* type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc) {
|
internal::TearDownTestSuiteFunc tear_down_tc) {
|
||||||
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
|
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
|
||||||
@@ -681,13 +681,13 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// AddTestInfo(), which is called to register a TEST or TEST_F
|
// AddTestInfo(), which is called to register a TEST or TEST_F
|
||||||
// before main() is reached.
|
// before main() is reached.
|
||||||
if (original_working_dir_.IsEmpty()) {
|
if (original_working_dir_.IsEmpty()) {
|
||||||
original_working_dir_.Set(FilePath::GetCurrentDir());
|
original_working_dir_ = FilePath::GetCurrentDir();
|
||||||
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
||||||
<< "Failed to get the current working directory.";
|
<< "Failed to get the current working directory.";
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_FILE_SYSTEM
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
|
GetTestSuite(test_info->test_suite_name_, test_info->type_param(),
|
||||||
set_up_tc, tear_down_tc)
|
set_up_tc, tear_down_tc)
|
||||||
->AddTestInfo(test_info);
|
->AddTestInfo(test_info);
|
||||||
}
|
}
|
||||||
@@ -709,18 +709,6 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
return type_parameterized_test_registry_;
|
return type_parameterized_test_registry_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the TestSuite object for the test that's currently running.
|
|
||||||
void set_current_test_suite(TestSuite* a_current_test_suite) {
|
|
||||||
current_test_suite_ = a_current_test_suite;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the TestInfo object for the test that's currently running. If
|
|
||||||
// current_test_info is NULL, the assertion results will be stored in
|
|
||||||
// ad_hoc_test_result_.
|
|
||||||
void set_current_test_info(TestInfo* a_current_test_info) {
|
|
||||||
current_test_info_ = a_current_test_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers all parameterized tests defined using TEST_P and
|
// Registers all parameterized tests defined using TEST_P and
|
||||||
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
|
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
|
||||||
// combination. This method can be called more then once; it has guards
|
// combination. This method can be called more then once; it has guards
|
||||||
@@ -835,12 +823,34 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
bool catch_exceptions() const { return catch_exceptions_; }
|
bool catch_exceptions() const { return catch_exceptions_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Returns true if a warning should be issued if no tests match the test
|
||||||
|
// filter flag.
|
||||||
|
bool ShouldWarnIfNoTestsMatchFilter() const;
|
||||||
|
|
||||||
|
struct CompareTestSuitesByPointer {
|
||||||
|
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
|
||||||
|
return lhs->name_ < rhs->name_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
friend class ::testing::UnitTest;
|
friend class ::testing::UnitTest;
|
||||||
|
|
||||||
// Used by UnitTest::Run() to capture the state of
|
// Used by UnitTest::Run() to capture the state of
|
||||||
// GTEST_FLAG(catch_exceptions) at the moment it starts.
|
// GTEST_FLAG(catch_exceptions) at the moment it starts.
|
||||||
void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
|
void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
|
||||||
|
|
||||||
|
// Sets the TestSuite object for the test that's currently running.
|
||||||
|
void set_current_test_suite(TestSuite* a_current_test_suite) {
|
||||||
|
current_test_suite_ = a_current_test_suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the TestInfo object for the test that's currently running. If
|
||||||
|
// current_test_info is NULL, the assertion results will be stored in
|
||||||
|
// ad_hoc_test_result_.
|
||||||
|
void set_current_test_info(TestInfo* a_current_test_info) {
|
||||||
|
current_test_info_ = a_current_test_info;
|
||||||
|
}
|
||||||
|
|
||||||
// The UnitTest object that owns this implementation object.
|
// The UnitTest object that owns this implementation object.
|
||||||
UnitTest* const parent_;
|
UnitTest* const parent_;
|
||||||
|
|
||||||
@@ -873,6 +883,9 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// elements in the vector.
|
// elements in the vector.
|
||||||
std::vector<TestSuite*> test_suites_;
|
std::vector<TestSuite*> test_suites_;
|
||||||
|
|
||||||
|
// The set of TestSuites by name.
|
||||||
|
std::unordered_map<std::string, TestSuite*> test_suites_by_name_;
|
||||||
|
|
||||||
// Provides a level of indirection for the test suite list to allow
|
// Provides a level of indirection for the test suite list to allow
|
||||||
// easy shuffling and restoring the test suite order. The i-th
|
// easy shuffling and restoring the test suite order. The i-th
|
||||||
// element of this vector is the index of the i-th test suite in the
|
// element of this vector is the index of the i-th test suite in the
|
||||||
|
|||||||
@@ -89,6 +89,7 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-string.h"
|
#include "gtest/internal/gtest-string.h"
|
||||||
#include "src/gtest-internal-inl.h"
|
#include "src/gtest-internal-inl.h"
|
||||||
@@ -158,13 +159,13 @@ size_t GetThreadCount() {
|
|||||||
// we cannot detect it.
|
// we cannot detect it.
|
||||||
size_t GetThreadCount() {
|
size_t GetThreadCount() {
|
||||||
int mib[] = {
|
int mib[] = {
|
||||||
CTL_KERN,
|
CTL_KERN,
|
||||||
KERN_PROC,
|
KERN_PROC,
|
||||||
KERN_PROC_PID,
|
KERN_PROC_PID,
|
||||||
getpid(),
|
getpid(),
|
||||||
#ifdef GTEST_OS_NETBSD
|
#ifdef GTEST_OS_NETBSD
|
||||||
sizeof(struct kinfo_proc),
|
sizeof(struct kinfo_proc),
|
||||||
1,
|
1,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
u_int miblen = sizeof(mib) / sizeof(mib[0]);
|
u_int miblen = sizeof(mib) / sizeof(mib[0]);
|
||||||
@@ -302,6 +303,22 @@ bool AutoHandle::IsCloseable() const {
|
|||||||
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
|
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
|
||||||
|
Notification::Notification() {
|
||||||
|
// Create a manual-reset event object.
|
||||||
|
event_ = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||||
|
GTEST_CHECK_(event_ != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification::~Notification() { ::CloseHandle(event_); }
|
||||||
|
|
||||||
|
void Notification::Notify() { GTEST_CHECK_(::SetEvent(event_)); }
|
||||||
|
|
||||||
|
void Notification::WaitForNotification() {
|
||||||
|
GTEST_CHECK_(::WaitForSingleObject(event_, INFINITE) == WAIT_OBJECT_0);
|
||||||
|
}
|
||||||
|
#endif // !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
|
||||||
|
|
||||||
Mutex::Mutex()
|
Mutex::Mutex()
|
||||||
: owner_thread_id_(0),
|
: owner_thread_id_(0),
|
||||||
type_(kDynamic),
|
type_(kDynamic),
|
||||||
@@ -320,13 +337,13 @@ Mutex::~Mutex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Lock() {
|
void Mutex::lock() {
|
||||||
ThreadSafeLazyInit();
|
ThreadSafeLazyInit();
|
||||||
::EnterCriticalSection(critical_section_);
|
::EnterCriticalSection(critical_section_);
|
||||||
owner_thread_id_ = ::GetCurrentThreadId();
|
owner_thread_id_ = ::GetCurrentThreadId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Unlock() {
|
void Mutex::unlock() {
|
||||||
ThreadSafeLazyInit();
|
ThreadSafeLazyInit();
|
||||||
// We don't protect writing to owner_thread_id_ here, as it's the
|
// We don't protect writing to owner_thread_id_ here, as it's the
|
||||||
// caller's responsibility to ensure that the current thread holds the
|
// caller's responsibility to ensure that the current thread holds the
|
||||||
@@ -499,7 +516,7 @@ class ThreadLocalRegistryImpl {
|
|||||||
MemoryIsNotDeallocated memory_is_not_deallocated;
|
MemoryIsNotDeallocated memory_is_not_deallocated;
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
DWORD current_thread = ::GetCurrentThreadId();
|
DWORD current_thread = ::GetCurrentThreadId();
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||||
GetThreadLocalsMapLocked();
|
GetThreadLocalsMapLocked();
|
||||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||||
@@ -532,7 +549,7 @@ class ThreadLocalRegistryImpl {
|
|||||||
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
||||||
// defer the destruction of the ThreadLocalValueHolderBases.
|
// defer the destruction of the ThreadLocalValueHolderBases.
|
||||||
{
|
{
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||||
GetThreadLocalsMapLocked();
|
GetThreadLocalsMapLocked();
|
||||||
for (ThreadIdToThreadLocals::iterator it =
|
for (ThreadIdToThreadLocals::iterator it =
|
||||||
@@ -559,7 +576,7 @@ class ThreadLocalRegistryImpl {
|
|||||||
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
||||||
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
||||||
{
|
{
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||||
GetThreadLocalsMapLocked();
|
GetThreadLocalsMapLocked();
|
||||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||||
@@ -587,9 +604,11 @@ class ThreadLocalRegistryImpl {
|
|||||||
// thread's ID.
|
// thread's ID.
|
||||||
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
|
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
|
||||||
|
|
||||||
// Holds the thread id and thread handle that we pass from
|
struct WatcherThreadParams {
|
||||||
// StartWatcherThreadFor to WatcherThreadFunc.
|
DWORD thread_id;
|
||||||
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
|
HANDLE handle;
|
||||||
|
Notification has_initialized;
|
||||||
|
};
|
||||||
|
|
||||||
static void StartWatcherThreadFor(DWORD thread_id) {
|
static void StartWatcherThreadFor(DWORD thread_id) {
|
||||||
// The returned handle will be kept in thread_map and closed by
|
// The returned handle will be kept in thread_map and closed by
|
||||||
@@ -597,15 +616,20 @@ class ThreadLocalRegistryImpl {
|
|||||||
HANDLE thread =
|
HANDLE thread =
|
||||||
::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
|
::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
|
||||||
GTEST_CHECK_(thread != nullptr);
|
GTEST_CHECK_(thread != nullptr);
|
||||||
|
|
||||||
|
WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;
|
||||||
|
watcher_thread_params->thread_id = thread_id;
|
||||||
|
watcher_thread_params->handle = thread;
|
||||||
|
|
||||||
// We need to pass a valid thread ID pointer into CreateThread for it
|
// We need to pass a valid thread ID pointer into CreateThread for it
|
||||||
// to work correctly under Win98.
|
// to work correctly under Win98.
|
||||||
DWORD watcher_thread_id;
|
DWORD watcher_thread_id;
|
||||||
HANDLE watcher_thread = ::CreateThread(
|
HANDLE watcher_thread =
|
||||||
nullptr, // Default security.
|
::CreateThread(nullptr, // Default security.
|
||||||
0, // Default stack size
|
0, // Default stack size
|
||||||
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
||||||
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
reinterpret_cast<LPVOID>(watcher_thread_params),
|
||||||
CREATE_SUSPENDED, &watcher_thread_id);
|
CREATE_SUSPENDED, &watcher_thread_id);
|
||||||
GTEST_CHECK_(watcher_thread != nullptr)
|
GTEST_CHECK_(watcher_thread != nullptr)
|
||||||
<< "CreateThread failed with error " << ::GetLastError() << ".";
|
<< "CreateThread failed with error " << ::GetLastError() << ".";
|
||||||
// Give the watcher thread the same priority as ours to avoid being
|
// Give the watcher thread the same priority as ours to avoid being
|
||||||
@@ -614,17 +638,25 @@ class ThreadLocalRegistryImpl {
|
|||||||
::GetThreadPriority(::GetCurrentThread()));
|
::GetThreadPriority(::GetCurrentThread()));
|
||||||
::ResumeThread(watcher_thread);
|
::ResumeThread(watcher_thread);
|
||||||
::CloseHandle(watcher_thread);
|
::CloseHandle(watcher_thread);
|
||||||
|
|
||||||
|
// Wait for the watcher thread to start to avoid race conditions.
|
||||||
|
// One specific race condition that can happen is that we have returned
|
||||||
|
// from main and have started to tear down, the newly spawned watcher
|
||||||
|
// thread may access already-freed variables, like global shared_ptrs.
|
||||||
|
watcher_thread_params->has_initialized.WaitForNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monitors exit from a given thread and notifies those
|
// Monitors exit from a given thread and notifies those
|
||||||
// ThreadIdToThreadLocals about thread termination.
|
// ThreadIdToThreadLocals about thread termination.
|
||||||
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
|
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
|
||||||
const ThreadIdAndHandle* tah =
|
WatcherThreadParams* watcher_thread_params =
|
||||||
reinterpret_cast<const ThreadIdAndHandle*>(param);
|
reinterpret_cast<WatcherThreadParams*>(param);
|
||||||
GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
|
watcher_thread_params->has_initialized.Notify();
|
||||||
OnThreadExit(tah->first);
|
GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle,
|
||||||
::CloseHandle(tah->second);
|
INFINITE) == WAIT_OBJECT_0);
|
||||||
delete tah;
|
OnThreadExit(watcher_thread_params->thread_id);
|
||||||
|
::CloseHandle(watcher_thread_params->handle);
|
||||||
|
delete watcher_thread_params;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,13 +729,24 @@ bool RE::PartialMatch(const char* str, const RE& re) {
|
|||||||
void RE::Init(const char* regex) {
|
void RE::Init(const char* regex) {
|
||||||
pattern_ = regex;
|
pattern_ = regex;
|
||||||
|
|
||||||
|
// NetBSD (and Android, which takes its regex implemntation from NetBSD) does
|
||||||
|
// not include the GNU regex extensions (such as Perl style character classes
|
||||||
|
// like \w) in REG_EXTENDED. REG_EXTENDED is only specified to include the
|
||||||
|
// [[:alpha:]] style character classes. Enable REG_GNU wherever it is defined
|
||||||
|
// so users can use those extensions.
|
||||||
|
#if defined(REG_GNU)
|
||||||
|
constexpr int reg_flags = REG_EXTENDED | REG_GNU;
|
||||||
|
#else
|
||||||
|
constexpr int reg_flags = REG_EXTENDED;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reserves enough bytes to hold the regular expression used for a
|
// Reserves enough bytes to hold the regular expression used for a
|
||||||
// full match.
|
// full match.
|
||||||
const size_t full_regex_len = strlen(regex) + 10;
|
const size_t full_regex_len = strlen(regex) + 10;
|
||||||
char* const full_pattern = new char[full_regex_len];
|
char* const full_pattern = new char[full_regex_len];
|
||||||
|
|
||||||
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
|
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
|
||||||
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
|
int error = regcomp(&full_regex_, full_pattern, reg_flags);
|
||||||
// We want to call regcomp(&partial_regex_, ...) even if the
|
// We want to call regcomp(&partial_regex_, ...) even if the
|
||||||
// previous expression returns false. Otherwise partial_regex_ may
|
// previous expression returns false. Otherwise partial_regex_ may
|
||||||
// not be properly initialized can may cause trouble when it's
|
// not be properly initialized can may cause trouble when it's
|
||||||
@@ -712,13 +755,13 @@ void RE::Init(const char* regex) {
|
|||||||
// Some implementation of POSIX regex (e.g. on at least some
|
// Some implementation of POSIX regex (e.g. on at least some
|
||||||
// versions of Cygwin) doesn't accept the empty string as a valid
|
// versions of Cygwin) doesn't accept the empty string as a valid
|
||||||
// regex. We change it to an equivalent form "()" to be safe.
|
// regex. We change it to an equivalent form "()" to be safe.
|
||||||
if (is_valid_) {
|
if (!error) {
|
||||||
const char* const partial_regex = (*regex == '\0') ? "()" : regex;
|
const char* const partial_regex = (*regex == '\0') ? "()" : regex;
|
||||||
is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
|
error = regcomp(&partial_regex_, partial_regex, reg_flags);
|
||||||
}
|
}
|
||||||
EXPECT_TRUE(is_valid_)
|
is_valid_ = error == 0;
|
||||||
<< "Regular expression \"" << regex
|
EXPECT_EQ(error, 0) << "Regular expression \"" << regex
|
||||||
<< "\" is not a valid POSIX Extended regular expression.";
|
<< "\" is not a valid POSIX Extended regular expression.";
|
||||||
|
|
||||||
delete[] full_pattern;
|
delete[] full_pattern;
|
||||||
}
|
}
|
||||||
@@ -1022,11 +1065,21 @@ GTestLog::~GTestLog() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_STREAM_REDIRECTION
|
||||||
|
|
||||||
// Disable Microsoft deprecation warnings for POSIX functions called from
|
// Disable Microsoft deprecation warnings for POSIX functions called from
|
||||||
// this class (creat, dup, dup2, and close)
|
// this class (creat, dup, dup2, and close)
|
||||||
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
|
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
|
||||||
|
|
||||||
#if GTEST_HAS_STREAM_REDIRECTION
|
namespace {
|
||||||
|
|
||||||
|
#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)
|
||||||
|
bool EndsWithPathSeparator(const std::string& path) {
|
||||||
|
return !path.empty() && path.back() == GTEST_PATH_SEP_[0];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// Object that captures an output stream (stdout/stderr).
|
// Object that captures an output stream (stdout/stderr).
|
||||||
class CapturedStream {
|
class CapturedStream {
|
||||||
@@ -1064,7 +1117,13 @@ class CapturedStream {
|
|||||||
// The location /data/local/tmp is directly accessible from native code.
|
// The location /data/local/tmp is directly accessible from native code.
|
||||||
// '/sdcard' and other variants cannot be relied on, as they are not
|
// '/sdcard' and other variants cannot be relied on, as they are not
|
||||||
// guaranteed to be mounted, or may have a delay in mounting.
|
// guaranteed to be mounted, or may have a delay in mounting.
|
||||||
name_template = "/data/local/tmp/";
|
//
|
||||||
|
// However, prefer using the TMPDIR environment variable if set, as newer
|
||||||
|
// devices may have /data/local/tmp read-only.
|
||||||
|
name_template = TempDir();
|
||||||
|
if (!EndsWithPathSeparator(name_template))
|
||||||
|
name_template.push_back(GTEST_PATH_SEP_[0]);
|
||||||
|
|
||||||
#elif defined(GTEST_OS_IOS)
|
#elif defined(GTEST_OS_IOS)
|
||||||
char user_temp_dir[PATH_MAX + 1];
|
char user_temp_dir[PATH_MAX + 1];
|
||||||
|
|
||||||
@@ -1084,7 +1143,7 @@ class CapturedStream {
|
|||||||
::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));
|
::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));
|
||||||
|
|
||||||
name_template = user_temp_dir;
|
name_template = user_temp_dir;
|
||||||
if (name_template.back() != GTEST_PATH_SEP_[0])
|
if (!EndsWithPathSeparator(name_template))
|
||||||
name_template.push_back(GTEST_PATH_SEP_[0]);
|
name_template.push_back(GTEST_PATH_SEP_[0]);
|
||||||
#else
|
#else
|
||||||
name_template = "/tmp/";
|
name_template = "/tmp/";
|
||||||
@@ -1306,8 +1365,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
|
|||||||
) {
|
) {
|
||||||
Message msg;
|
Message msg;
|
||||||
msg << "WARNING: " << src_text
|
msg << "WARNING: " << src_text
|
||||||
<< " is expected to be a 32-bit integer, but actually"
|
<< " is expected to be a 32-bit integer, but actually" << " has value "
|
||||||
<< " has value " << str << ", which overflows.\n";
|
<< str << ", which overflows.\n";
|
||||||
printf("%s", msg.GetString().c_str());
|
printf("%s", msg.GetString().c_str());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
@@ -333,14 +333,14 @@ void PrintTo(__int128_t v, ::std::ostream* os) {
|
|||||||
|
|
||||||
// Prints the given array of characters to the ostream. CharType must be either
|
// Prints the given array of characters to the ostream. CharType must be either
|
||||||
// char, char8_t, char16_t, char32_t, or wchar_t.
|
// char, char8_t, char16_t, char32_t, or wchar_t.
|
||||||
// The array starts at begin, the length is len, it may include '\0' characters
|
// The array starts at begin (which may be nullptr) and contains len characters.
|
||||||
// and may not be NUL-terminated.
|
// The array may include '\0' characters and may not be NUL-terminated.
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
|
||||||
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
|
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
|
||||||
const char* const quote_prefix = GetCharWidthPrefix(*begin);
|
const char* const quote_prefix = GetCharWidthPrefix(CharType());
|
||||||
*os << quote_prefix << "\"";
|
*os << quote_prefix << "\"";
|
||||||
bool is_previous_hex = false;
|
bool is_previous_hex = false;
|
||||||
CharFormat print_format = kAsIs;
|
CharFormat print_format = kAsIs;
|
||||||
@@ -516,13 +516,13 @@ bool IsValidUTF8(const char* str, size_t length) {
|
|||||||
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
||||||
if (!ContainsUnprintableControlCodes(str, length) &&
|
if (!ContainsUnprintableControlCodes(str, length) &&
|
||||||
IsValidUTF8(str, length)) {
|
IsValidUTF8(str, length)) {
|
||||||
*os << "\n As Text: \"" << str << "\"";
|
*os << "\n As Text: \"" << ::std::string_view(str, length) << "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
void PrintStringTo(::std::string_view s, ostream* os) {
|
||||||
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||||
if (GTEST_FLAG_GET(print_utf8)) {
|
if (GTEST_FLAG_GET(print_utf8)) {
|
||||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||||
@@ -531,21 +531,21 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
|
void PrintU8StringTo(::std::u8string_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
|
void PrintU16StringTo(::std::u16string_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
|
void PrintU32StringTo(::std::u32string_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
void PrintWideStringTo(::std::wstring_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|||||||
@@ -34,7 +34,9 @@
|
|||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "src/gtest-internal-inl.h"
|
#include "src/gtest-internal-inl.h"
|
||||||
|
|
||||||
@@ -42,9 +44,9 @@ namespace testing {
|
|||||||
|
|
||||||
// Gets the summary of the failure message by omitting the stack trace
|
// Gets the summary of the failure message by omitting the stack trace
|
||||||
// in it.
|
// in it.
|
||||||
std::string TestPartResult::ExtractSummary(const char* message) {
|
std::string TestPartResult::ExtractSummary(const std::string_view message) {
|
||||||
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
|
auto stack_trace = message.find(internal::kStackTraceMarker);
|
||||||
return stack_trace == nullptr ? message : std::string(message, stack_trace);
|
return std::string(message.substr(0, stack_trace));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a TestPartResult object.
|
// Prints a TestPartResult object.
|
||||||
|
|||||||
654
thirdparty/googletest/src/googletest/src/gtest.cpp
vendored
654
thirdparty/googletest/src/googletest/src/gtest.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -54,7 +54,8 @@ def copy_upstream_src(wpilib_root: Path):
|
|||||||
def main():
|
def main():
|
||||||
name = "googletest"
|
name = "googletest"
|
||||||
url = "https://github.com/google/googletest.git"
|
url = "https://github.com/google/googletest.git"
|
||||||
tag = "v1.14.0"
|
# main on 2026-04-11
|
||||||
|
tag = "d72f9c8aea6817cdf1ca0ac10887f328de7f3da2"
|
||||||
|
|
||||||
googletest = Lib(name, url, tag, copy_upstream_src)
|
googletest = Lib(name, url, tag, copy_upstream_src)
|
||||||
googletest.main()
|
googletest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user