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
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -175,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
|
||||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
return internal::Invalid<T>();
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#else
|
||||
return Invalid<T>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -189,7 +196,7 @@ struct BuiltInDefaultValueGetter<T, false> {
|
||||
// other type T, the built-in default T value is undefined, and the
|
||||
// function will abort the process.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue {
|
||||
class [[nodiscard]] BuiltInDefaultValue {
|
||||
public:
|
||||
// This function returns true if and only if type T has a built-in default
|
||||
// value.
|
||||
@@ -204,7 +211,7 @@ class BuiltInDefaultValue {
|
||||
// This partial specialization says that we use the same built-in
|
||||
// default value for T and const T.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<const T> {
|
||||
class [[nodiscard]] BuiltInDefaultValue<const T> {
|
||||
public:
|
||||
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||
@@ -213,7 +220,7 @@ class BuiltInDefaultValue<const T> {
|
||||
// This partial specialization defines the default values for pointer
|
||||
// types.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<T*> {
|
||||
class [[nodiscard]] BuiltInDefaultValue<T*> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static T* Get() { return nullptr; }
|
||||
@@ -376,7 +383,7 @@ typename std::add_const<T>::type& as_const(T& t) {
|
||||
|
||||
// Specialized for function types below.
|
||||
template <typename F>
|
||||
class OnceAction;
|
||||
class [[nodiscard]] OnceAction;
|
||||
|
||||
// An action that can only be used once.
|
||||
//
|
||||
@@ -414,7 +421,7 @@ class OnceAction;
|
||||
// A less-contrived example would be an action that returns an arbitrary type,
|
||||
// whose &&-qualified call operator is capable of dealing with move-only types.
|
||||
template <typename Result, typename... Args>
|
||||
class OnceAction<Result(Args...)> final {
|
||||
class [[nodiscard]] OnceAction<Result(Args...)> final {
|
||||
private:
|
||||
// True iff we can use the given callable type (or lvalue reference) directly
|
||||
// via StdFunctionAdaptor.
|
||||
@@ -567,7 +574,7 @@ class OnceAction<Result(Args...)> final {
|
||||
// // Sets the default value for type T to be foo.
|
||||
// DefaultValue<T>::Set(foo);
|
||||
template <typename T>
|
||||
class DefaultValue {
|
||||
class [[nodiscard]] DefaultValue {
|
||||
public:
|
||||
// Sets the default value for type T; requires T to be
|
||||
// copy-constructable and have a public destructor.
|
||||
@@ -644,7 +651,7 @@ class DefaultValue {
|
||||
// This partial specialization allows a user to set default values for
|
||||
// reference types.
|
||||
template <typename T>
|
||||
class DefaultValue<T&> {
|
||||
class [[nodiscard]] DefaultValue<T&> {
|
||||
public:
|
||||
// Sets the default value for type T&.
|
||||
static void Set(T& x) { // NOLINT
|
||||
@@ -678,7 +685,7 @@ class DefaultValue<T&> {
|
||||
// This specialization allows DefaultValue<void>::Get() to
|
||||
// compile.
|
||||
template <>
|
||||
class DefaultValue<void> {
|
||||
class [[nodiscard]] DefaultValue<void> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static void Get() {}
|
||||
@@ -694,7 +701,7 @@ T* DefaultValue<T&>::address_ = nullptr;
|
||||
|
||||
// Implement this interface to define an action for function type F.
|
||||
template <typename F>
|
||||
class ActionInterface {
|
||||
class [[nodiscard]] ActionInterface {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
@@ -714,7 +721,7 @@ class ActionInterface {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class Action;
|
||||
class [[nodiscard]] Action;
|
||||
|
||||
// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that represents an action to be taken when a mock function of type
|
||||
@@ -723,7 +730,7 @@ class Action;
|
||||
// can view an object implementing ActionInterface<F> as a concrete action
|
||||
// (including its current state), and an Action<F> object as a handle to it.
|
||||
template <typename R, typename... Args>
|
||||
class Action<R(Args...)> {
|
||||
class [[nodiscard]] Action<R(Args...)> {
|
||||
private:
|
||||
using F = R(Args...);
|
||||
|
||||
@@ -828,6 +835,10 @@ class Action<R(Args...)> {
|
||||
Result operator()(const InArgs&...) const {
|
||||
return function_impl();
|
||||
}
|
||||
template <typename... InArgs>
|
||||
Result operator()(const InArgs&...) {
|
||||
return function_impl();
|
||||
}
|
||||
|
||||
FunctionImpl function_impl;
|
||||
};
|
||||
@@ -858,7 +869,7 @@ class Action<R(Args...)> {
|
||||
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
||||
// complete examples.
|
||||
template <typename Impl>
|
||||
class PolymorphicAction {
|
||||
class [[nodiscard]] PolymorphicAction {
|
||||
public:
|
||||
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
@@ -918,7 +929,7 @@ struct ByMoveWrapper {
|
||||
|
||||
// The general implementation of Return(R). Specializations follow below.
|
||||
template <typename R>
|
||||
class ReturnAction final {
|
||||
class [[nodiscard]] ReturnAction final {
|
||||
public:
|
||||
explicit ReturnAction(R value) : value_(std::move(value)) {}
|
||||
|
||||
@@ -1084,7 +1095,7 @@ class ReturnAction final {
|
||||
// the const call operator, checking at runtime that it isn't called more than
|
||||
// once, since the user has declared their intent to do so by using ByMove.
|
||||
template <typename T>
|
||||
class ReturnAction<ByMoveWrapper<T>> final {
|
||||
class [[nodiscard]] ReturnAction<ByMoveWrapper<T>> final {
|
||||
public:
|
||||
explicit ReturnAction(ByMoveWrapper<T> wrapper)
|
||||
: state_(new State(std::move(wrapper.payload))) {}
|
||||
@@ -1111,7 +1122,7 @@ class ReturnAction<ByMoveWrapper<T>> final {
|
||||
};
|
||||
|
||||
// Implements the ReturnNull() action.
|
||||
class ReturnNullAction {
|
||||
class [[nodiscard]] ReturnNullAction {
|
||||
public:
|
||||
// Allows ReturnNull() to be used in any pointer-returning function. In C++11
|
||||
// this is enforced by returning nullptr, and in non-C++11 by asserting a
|
||||
@@ -1123,7 +1134,7 @@ class ReturnNullAction {
|
||||
};
|
||||
|
||||
// Implements the Return() action.
|
||||
class ReturnVoidAction {
|
||||
class [[nodiscard]] ReturnVoidAction {
|
||||
public:
|
||||
// Allows Return() to be used in any void-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
@@ -1136,7 +1147,7 @@ class ReturnVoidAction {
|
||||
// in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefAction {
|
||||
class [[nodiscard]] ReturnRefAction {
|
||||
public:
|
||||
// Constructs a ReturnRefAction object from the reference to be returned.
|
||||
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
||||
@@ -1177,7 +1188,7 @@ class ReturnRefAction {
|
||||
// used in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefOfCopyAction {
|
||||
class [[nodiscard]] ReturnRefOfCopyAction {
|
||||
public:
|
||||
// Constructs a ReturnRefOfCopyAction object from the reference to
|
||||
// be returned.
|
||||
@@ -1218,7 +1229,7 @@ class ReturnRefOfCopyAction {
|
||||
// Implements the polymorphic ReturnRoundRobin(v) action, which can be
|
||||
// used in any function that returns the element_type of v.
|
||||
template <typename T>
|
||||
class ReturnRoundRobinAction {
|
||||
class [[nodiscard]] ReturnRoundRobinAction {
|
||||
public:
|
||||
explicit ReturnRoundRobinAction(std::vector<T> values) {
|
||||
GTEST_CHECK_(!values.empty())
|
||||
@@ -1246,7 +1257,7 @@ class ReturnRoundRobinAction {
|
||||
};
|
||||
|
||||
// Implements the polymorphic DoDefault() action.
|
||||
class DoDefaultAction {
|
||||
class [[nodiscard]] DoDefaultAction {
|
||||
public:
|
||||
// This template type conversion operator allows DoDefault() to be
|
||||
// used in any function.
|
||||
@@ -1259,7 +1270,7 @@ class DoDefaultAction {
|
||||
// Implements the Assign action to set a given pointer referent to a
|
||||
// particular value.
|
||||
template <typename T1, typename T2>
|
||||
class AssignAction {
|
||||
class [[nodiscard]] AssignAction {
|
||||
public:
|
||||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
||||
|
||||
@@ -1278,7 +1289,7 @@ class AssignAction {
|
||||
// Implements the SetErrnoAndReturn action to simulate return from
|
||||
// various system calls and libc functions.
|
||||
template <typename T>
|
||||
class SetErrnoAndReturnAction {
|
||||
class [[nodiscard]] SetErrnoAndReturnAction {
|
||||
public:
|
||||
SetErrnoAndReturnAction(int errno_value, T result)
|
||||
: errno_(errno_value), result_(result) {}
|
||||
@@ -1386,7 +1397,7 @@ class IgnoreResultAction {
|
||||
|
||||
void Perform(const ArgumentTuple& args) override {
|
||||
// Performs the action and ignores its result.
|
||||
action_.Perform(args);
|
||||
(void)action_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1444,6 +1455,30 @@ struct WithArgsAction {
|
||||
return OA{std::move(inner_action)};
|
||||
}
|
||||
|
||||
// As above, but in the case where we want to create a OnceAction from a const
|
||||
// WithArgsAction. This is fine as long as the inner action doesn't need to
|
||||
// move any of its state to create a OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const InnerAction&,
|
||||
OnceAction<R(internal::TupleElement<
|
||||
I, std::tuple<Args...>>...)>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() const& { // NOLINT
|
||||
struct OA {
|
||||
OnceAction<InnerSignature<R, Args...>> inner_action;
|
||||
|
||||
R operator()(Args&&... args) && {
|
||||
return std::move(inner_action)
|
||||
.Call(std::get<I>(
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))...);
|
||||
}
|
||||
};
|
||||
|
||||
return OA{inner_action};
|
||||
}
|
||||
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
@@ -1468,11 +1503,11 @@ struct WithArgsAction {
|
||||
};
|
||||
|
||||
template <typename... Actions>
|
||||
class DoAllAction;
|
||||
class [[nodiscard]] DoAllAction;
|
||||
|
||||
// Base case: only a single action.
|
||||
template <typename FinalAction>
|
||||
class DoAllAction<FinalAction> {
|
||||
class [[nodiscard]] DoAllAction<FinalAction> {
|
||||
public:
|
||||
struct UserConstructorTag {};
|
||||
|
||||
@@ -1486,6 +1521,7 @@ class DoAllAction<FinalAction> {
|
||||
// providing a call operator because even with a particular set of arguments
|
||||
// they don't have a fixed return type.
|
||||
|
||||
// We support conversion to OnceAction whenever the sub-action does.
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
|
||||
@@ -1494,6 +1530,21 @@ class DoAllAction<FinalAction> {
|
||||
return std::move(final_action_);
|
||||
}
|
||||
|
||||
// We also support conversion to OnceAction whenever the sub-action supports
|
||||
// conversion to Action (since any Action can also be a OnceAction).
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
negation<
|
||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>>,
|
||||
std::is_convertible<FinalAction, Action<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
return Action<R(Args...)>(std::move(final_action_));
|
||||
}
|
||||
|
||||
// We support conversion to Action whenever the sub-action does.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
@@ -1510,7 +1561,7 @@ class DoAllAction<FinalAction> {
|
||||
// Recursive case: support N actions by calling the initial action and then
|
||||
// calling through to the base class containing N-1 actions.
|
||||
template <typename InitialAction, typename... OtherActions>
|
||||
class DoAllAction<InitialAction, OtherActions...>
|
||||
class [[nodiscard]] DoAllAction<InitialAction, OtherActions...>
|
||||
: private DoAllAction<OtherActions...> {
|
||||
private:
|
||||
using Base = DoAllAction<OtherActions...>;
|
||||
@@ -1573,16 +1624,16 @@ class DoAllAction<InitialAction, OtherActions...>
|
||||
: Base({}, std::forward<U>(other_actions)...),
|
||||
initial_action_(std::forward<T>(initial_action)) {}
|
||||
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
// Both the initial action and the rest must support
|
||||
// conversion to OnceAction.
|
||||
std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
// We support conversion to OnceAction whenever both the initial action and
|
||||
// the rest support conversion to OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
// Return an action that first calls the initial action with arguments
|
||||
// filtered through InitialActionArgType, then forwards arguments directly
|
||||
@@ -1605,12 +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 <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
// Both the initial action and the rest must support conversion to
|
||||
// Action.
|
||||
std::is_convertible<const InitialAction&,
|
||||
Action<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<const Base&, Action<R(Args...)>>>::value,
|
||||
@@ -1674,6 +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>
|
||||
struct SaveArgPointeeAction {
|
||||
Ptr pointer;
|
||||
@@ -1713,11 +1796,24 @@ struct SetArrayArgumentAction {
|
||||
};
|
||||
|
||||
template <size_t k>
|
||||
struct DeleteArgAction {
|
||||
class [[nodiscard]] DeleteArgAction {
|
||||
public:
|
||||
template <typename... Args>
|
||||
void operator()(const Args&... args) const {
|
||||
delete std::get<k>(std::tie(args...));
|
||||
DoDelete(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static void DoDelete(T* ptr) {
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[deprecated(
|
||||
"DeleteArg<N> used for a non-pointer argument, it was likely migrated "
|
||||
"to a smart pointer type. This action should be removed.")]]
|
||||
static void DoDelete(T&) {}
|
||||
};
|
||||
|
||||
template <typename Ptr>
|
||||
@@ -1740,6 +1836,13 @@ struct ThrowAction {
|
||||
return [copy](Args...) -> R { throw copy; };
|
||||
}
|
||||
};
|
||||
struct RethrowAction {
|
||||
std::exception_ptr exception;
|
||||
template <typename R, typename... Args>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
|
||||
}
|
||||
};
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace internal
|
||||
@@ -1776,6 +1879,13 @@ struct ThrowAction {
|
||||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
typedef internal::IgnoredValue Unused;
|
||||
|
||||
// Deprecated single-argument DoAll.
|
||||
template <typename Action>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
|
||||
typename std::decay<Action>::type DoAll(Action&& action) {
|
||||
return std::forward<Action>(action);
|
||||
}
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation. All but the last action will have a readonly view of the
|
||||
// arguments.
|
||||
@@ -1941,10 +2051,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Legacy function.
|
||||
// Actions can now be implicitly constructed from callables. No need to create
|
||||
// wrapper objects.
|
||||
// This function exists for backwards compatibility.
|
||||
template <typename FunctionImpl>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||
"Actions can now be implicitly constructed from callables. No need to "
|
||||
"create wrapper objects using Invoke().")
|
||||
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||
return std::forward<FunctionImpl>(function_impl);
|
||||
}
|
||||
@@ -2017,6 +2128,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
|
||||
// mock function into *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
@@ -2056,13 +2174,23 @@ internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown,
|
||||
// except for std::exception_ptr, which is likely a mistake if
|
||||
// thrown directly.
|
||||
template <typename T>
|
||||
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
|
||||
typename std::enable_if<
|
||||
!std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
|
||||
internal::ThrowAction<typename std::decay<T>::type>>::type
|
||||
Throw(T&& exception) {
|
||||
return {std::forward<T>(exception)};
|
||||
}
|
||||
// Action Rethrow(exception_ptr) can be used in a mock function of any type
|
||||
// to rethrow any exception_ptr. Note that the same object is thrown each time.
|
||||
inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
|
||||
return {std::move(exception)};
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
namespace internal {
|
||||
@@ -2111,13 +2239,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
|
||||
R operator()(Args&&... arg) const {
|
||||
static constexpr size_t kMaxArgs =
|
||||
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
|
||||
return Apply(MakeIndexSequence<kMaxArgs>{},
|
||||
MakeIndexSequence<10 - kMaxArgs>{},
|
||||
return Apply(std::make_index_sequence<kMaxArgs>{},
|
||||
std::make_index_sequence<10 - kMaxArgs>{},
|
||||
args_type{std::forward<Args>(arg)...});
|
||||
}
|
||||
|
||||
template <std::size_t... arg_id, std::size_t... excess_id>
|
||||
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
|
||||
R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,
|
||||
const args_type& args) const {
|
||||
// Impl need not be specific to the signature of action being implemented;
|
||||
// only the implementing function body needs to have all of the specific
|
||||
@@ -2150,9 +2278,9 @@ template <typename F, typename Impl>
|
||||
}
|
||||
|
||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
||||
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
|
||||
, [[maybe_unused]] const arg##i##_type& arg##i
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
[[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||
|
||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
||||
@@ -2217,8 +2345,8 @@ template <typename F, typename Impl>
|
||||
std::shared_ptr<const gmock_Impl> impl_; \
|
||||
}; \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
||||
@@ -2253,7 +2381,7 @@ template <typename F, typename Impl>
|
||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||
}; \
|
||||
}; \
|
||||
inline name##Action name() GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline name##Action name(); \
|
||||
inline name##Action name() { return name##Action(); } \
|
||||
template <typename function_type, typename return_type, typename args_type, \
|
||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace testing {
|
||||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
class [[nodiscard]] CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() = default;
|
||||
|
||||
@@ -88,7 +88,7 @@ class CardinalityInterface {
|
||||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||
class GTEST_API_ Cardinality {
|
||||
class GTEST_API_ [[nodiscard]] Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#include <utility> // IWYU pragma: keep
|
||||
|
||||
@@ -69,22 +70,22 @@ constexpr bool PrefixOf(const char* a, const char* b) {
|
||||
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(prefix, str);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||
return N == M && internal::PrefixOf(a, b);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||
return internal::Equals("const", spec) ||
|
||||
internal::Equals("override", spec) ||
|
||||
|
||||
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_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||
= default; \
|
||||
, \
|
||||
: impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
, : impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params \
|
||||
@@ -551,10 +550,10 @@
|
||||
}; \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
GMOCK_ACTION_CLASS_( \
|
||||
[[nodiscard]] GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params); \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
inline GMOCK_ACTION_CLASS_( \
|
||||
@@ -592,21 +591,23 @@ namespace internal {
|
||||
// Overloads for other custom-callables are provided in the
|
||||
// internal/custom/gmock-generated-actions.h header.
|
||||
template <typename F, typename... Args>
|
||||
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
|
||||
return f(args...);
|
||||
auto InvokeArgument(F &&f,
|
||||
Args... args) -> decltype(std::forward<F>(f)(args...)) {
|
||||
return std::forward<F>(f)(args...);
|
||||
}
|
||||
|
||||
template <std::size_t index, typename... Params>
|
||||
struct InvokeArgumentAction {
|
||||
template <typename... Args,
|
||||
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
||||
auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params &>()...)) {
|
||||
auto operator()(Args &&...args) const
|
||||
-> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params &>()...)) {
|
||||
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
|
||||
std::forward<Args>(args)...);
|
||||
return params.Apply([&](const Params &...unpacked_params) {
|
||||
auto &&callable = args_tuple.template Get<index>();
|
||||
auto &&callable = std::move(args_tuple.template Get<index>());
|
||||
return internal::InvokeArgument(
|
||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace internal {
|
||||
// Implements the polymorphic IsEmpty matcher, which
|
||||
// can be used as a Matcher<T> as long as T is either a container that defines
|
||||
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
|
||||
class IsEmptyMatcher {
|
||||
class [[nodiscard]] IsEmptyMatcher {
|
||||
public:
|
||||
// Matches anything that defines empty() and size().
|
||||
template <typename MatcheeContainerType>
|
||||
|
||||
@@ -71,11 +71,11 @@
|
||||
|
||||
namespace testing {
|
||||
template <class MockClass>
|
||||
class NiceMock;
|
||||
class [[nodiscard]] NiceMock;
|
||||
template <class MockClass>
|
||||
class NaggyMock;
|
||||
class [[nodiscard]] NaggyMock;
|
||||
template <class MockClass>
|
||||
class StrictMock;
|
||||
class [[nodiscard]] StrictMock;
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
@@ -108,7 +108,7 @@ constexpr bool HasStrictnessModifier() {
|
||||
#endif
|
||||
|
||||
template <typename Base>
|
||||
class NiceMockImpl {
|
||||
class [[nodiscard]] NiceMockImpl {
|
||||
public:
|
||||
NiceMockImpl() {
|
||||
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
@@ -120,7 +120,7 @@ class NiceMockImpl {
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class NaggyMockImpl {
|
||||
class [[nodiscard]] NaggyMockImpl {
|
||||
public:
|
||||
NaggyMockImpl() {
|
||||
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
@@ -132,7 +132,7 @@ class NaggyMockImpl {
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class StrictMockImpl {
|
||||
class [[nodiscard]] StrictMockImpl {
|
||||
public:
|
||||
StrictMockImpl() {
|
||||
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
@@ -146,7 +146,7 @@ class StrictMockImpl {
|
||||
} // namespace internal
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
: private internal::NiceMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
@@ -187,7 +187,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
: private internal::NaggyMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
@@ -229,7 +229,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
: private internal::StrictMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
|
||||
@@ -868,7 +868,7 @@ class GTEST_API_ ExpectationBase {
|
||||
Clause last_clause_;
|
||||
mutable bool action_count_checked_; // Under mutex_.
|
||||
mutable Mutex mutex_; // Protects action_count_checked_.
|
||||
}; // class ExpectationBase
|
||||
}; // class ExpectationBase
|
||||
|
||||
template <typename F>
|
||||
class TypedExpectation;
|
||||
@@ -1292,10 +1292,10 @@ class MockSpec {
|
||||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||
|
||||
// Adds a new default action spec to the function mocker and returns
|
||||
// the newly created spec.
|
||||
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
|
||||
int line, const char* obj,
|
||||
const char* call) {
|
||||
// the newly created spec. .WillByDefault() must be called on the returned
|
||||
// object.
|
||||
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
|
||||
const char* file, int line, const char* obj, const char* call) {
|
||||
LogWithLocation(internal::kInfo, file, line,
|
||||
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
||||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
||||
@@ -1467,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
// function have been satisfied. If not, it will report Google Test
|
||||
// non-fatal failures for the violations.
|
||||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
VerifyAndClearExpectationsLocked();
|
||||
Mock::UnregisterLocked(this);
|
||||
ClearDefaultActionsLocked();
|
||||
@@ -1530,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
UntypedOnCallSpecs specs_to_delete;
|
||||
untyped_on_call_specs_.swap(specs_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
||||
it != specs_to_delete.end(); ++it) {
|
||||
delete static_cast<const OnCallSpec<F>*>(*it);
|
||||
@@ -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
|
||||
// return.
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
const ArgumentTuple& args =
|
||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||
if (exp == nullptr) { // A match wasn't found.
|
||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||
@@ -1838,9 +1838,8 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const UninterestingCallCleanupHandler report_uninteresting_call = {
|
||||
reaction, ss
|
||||
};
|
||||
const UninterestingCallCleanupHandler report_uninteresting_call = {reaction,
|
||||
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
|
||||
// parameters each time.
|
||||
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(),
|
||||
ss);
|
||||
@@ -2134,9 +2132,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
// second argument is an internal type derived from the method signature. The
|
||||
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
||||
// is how we block callers from setting expectations on overloaded methods.
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
|
||||
nullptr) \
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::WithoutMatchers::Get(), \
|
||||
nullptr) \
|
||||
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
||||
|
||||
#define ON_CALL(obj, call) \
|
||||
|
||||
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.
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
#include "gmock/gmock-nice-strict.h"
|
||||
#include "gmock/gmock-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-nice-strict.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-spec-builders.h" // IWYU pragma: export
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
|
||||
@@ -41,9 +41,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
@@ -219,7 +221,7 @@ using LosslessArithmeticConvertible =
|
||||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
class [[nodiscard]] FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType { kNonfatal, kFatal };
|
||||
@@ -295,14 +297,13 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
//
|
||||
// ON_CALL(mock, Method({}, nullptr))...
|
||||
//
|
||||
class WithoutMatchers {
|
||||
class [[nodiscard]] WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
WithoutMatchers() = default;
|
||||
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
public:
|
||||
GTEST_API_ static WithoutMatchers Get();
|
||||
};
|
||||
|
||||
// Invalid<T>() is usable as an expression of type T, but will terminate
|
||||
// the program with an assertion failure if actually run. This is useful
|
||||
@@ -322,6 +323,24 @@ inline T Invalid() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetValueType(const void*);
|
||||
|
||||
template <class T>
|
||||
typename std::iterator_traits<
|
||||
decltype(std::begin(std::declval<T&>()))>::value_type
|
||||
GetValueType(T*);
|
||||
|
||||
template <class T, class = void>
|
||||
struct RangeTraits {
|
||||
typedef decltype(internal::GetValueType(
|
||||
static_cast<std::remove_reference_t<T>*>(nullptr))) value_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct RangeTraits<T, std::conditional_t<true, void, typename T::value_type>> {
|
||||
typedef typename T::value_type value_type;
|
||||
};
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
@@ -339,7 +358,7 @@ inline T Invalid() {
|
||||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
class [[nodiscard]] StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
@@ -354,7 +373,7 @@ class StlContainerView {
|
||||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
class [[nodiscard]] StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef typename std::remove_const<Element>::type RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
@@ -378,7 +397,7 @@ class StlContainerView<Element[N]> {
|
||||
// This specialization is used when RawContainer is a native array
|
||||
// represented as a (pointer, size) tuple.
|
||||
template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
class [[nodiscard]] StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef typename std::remove_const<
|
||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||
@@ -420,7 +439,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
||||
auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
|
||||
-> decltype(std::forward<F>(f)(
|
||||
std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||
@@ -428,12 +447,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
||||
|
||||
// Apply the function to a tuple of arguments.
|
||||
template <typename F, typename Tuple>
|
||||
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
|
||||
std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
auto Apply(F&& f, Tuple&& args)
|
||||
-> decltype(ApplyImpl(
|
||||
std::forward<F>(f), std::forward<Tuple>(args),
|
||||
std::make_index_sequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
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>());
|
||||
}
|
||||
|
||||
@@ -465,11 +485,6 @@ struct Function<R(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'
|
||||
// when std::tuple_element is used.
|
||||
// See: https://github.com/google/googletest/issues/3931
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
@@ -56,7 +57,7 @@
|
||||
#include "gmock/internal/custom/gmock-port.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#endif
|
||||
@@ -73,7 +74,7 @@
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Pick a command line flags implementation.
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
@@ -85,17 +86,17 @@
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
|
||||
|
||||
#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
|
||||
#define GMOCK_FLAG_SET(name, value) \
|
||||
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
|
||||
|
||||
#else // GTEST_HAS_ABSL
|
||||
#else // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
@@ -134,6 +135,6 @@
|
||||
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#endif // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
@@ -130,7 +130,14 @@ namespace testing {
|
||||
// Expected: Foo() is even
|
||||
// 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:
|
||||
// Copy constructor.
|
||||
// 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*:
|
||||
|
||||
// Tests that an exit code describes a normal exit with a given exit code.
|
||||
class GTEST_API_ ExitedWithCode {
|
||||
class GTEST_API_ [[nodiscard]] ExitedWithCode {
|
||||
public:
|
||||
explicit ExitedWithCode(int exit_code);
|
||||
ExitedWithCode(const ExitedWithCode&) = default;
|
||||
@@ -206,7 +206,7 @@ class GTEST_API_ ExitedWithCode {
|
||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
class GTEST_API_ KilledBySignal {
|
||||
class GTEST_API_ [[nodiscard]] KilledBySignal {
|
||||
public:
|
||||
explicit KilledBySignal(int signum);
|
||||
bool operator()(int exit_status) const;
|
||||
@@ -293,8 +293,8 @@ class GTEST_API_ KilledBySignal {
|
||||
// statement is compiled but not executed, to ensure that
|
||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||
// parameter if and only if EXPECT_DEATH compiles with it.
|
||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||
// the output of statement. This parameter has to be
|
||||
// regex_or_matcher - A regex that a macro such as EXPECT_DEATH would use
|
||||
// to test the output of statement. This parameter has to be
|
||||
// compiled but not evaluated by this macro, to ensure that
|
||||
// this macro only accepts expressions that a macro such as
|
||||
// EXPECT_DEATH would accept.
|
||||
@@ -311,13 +311,13 @@ class GTEST_API_ KilledBySignal {
|
||||
// statement unconditionally returns or throws. The Message constructor at
|
||||
// the end allows the syntax of streaming additional messages into the
|
||||
// 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_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
|
||||
<< "Statement '" #statement "' cannot be verified."; \
|
||||
} else if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
||||
(void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
terminator; \
|
||||
} 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_
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
@@ -67,15 +68,15 @@ namespace testing {
|
||||
// To implement a matcher Foo for type T, define:
|
||||
// 1. a class FooMatcherMatcher that implements the matcher interface:
|
||||
// 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*)
|
||||
// void DescribeTo(std::ostream*);
|
||||
// void DescribeNegationTo(std::ostream*);
|
||||
// void DescribeTo(std::ostream*) const;
|
||||
// void DescribeNegationTo(std::ostream*) const;
|
||||
//
|
||||
// 2. a factory function that creates a Matcher<T> object from a
|
||||
// FooMatcherMatcher.
|
||||
|
||||
class MatchResultListener {
|
||||
class [[nodiscard]] MatchResultListener {
|
||||
public:
|
||||
// Creates a listener object with the given underlying ostream. The
|
||||
// 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
|
||||
// matcher.
|
||||
class GTEST_API_ MatcherDescriberInterface {
|
||||
class GTEST_API_ [[nodiscard]] MatcherDescriberInterface {
|
||||
public:
|
||||
virtual ~MatcherDescriberInterface() = default;
|
||||
|
||||
@@ -137,7 +138,7 @@ class GTEST_API_ MatcherDescriberInterface {
|
||||
|
||||
// The implementation of a matcher.
|
||||
template <typename T>
|
||||
class MatcherInterface : public MatcherDescriberInterface {
|
||||
class [[nodiscard]] MatcherInterface : public MatcherDescriberInterface {
|
||||
public:
|
||||
// Returns true if and only if the matcher matches x; also explains the
|
||||
// match result to 'listener' if necessary (see the next paragraph), in
|
||||
@@ -180,7 +181,7 @@ class MatcherInterface : public MatcherDescriberInterface {
|
||||
namespace internal {
|
||||
|
||||
// A match result listener that ignores the explanation.
|
||||
class DummyMatchResultListener : public MatchResultListener {
|
||||
class [[nodiscard]] DummyMatchResultListener : public MatchResultListener {
|
||||
public:
|
||||
DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
||||
|
||||
@@ -192,7 +193,7 @@ class DummyMatchResultListener : public MatchResultListener {
|
||||
// A match result listener that forwards the explanation to a given
|
||||
// ostream. The difference between this and MatchResultListener is
|
||||
// that the former is concrete.
|
||||
class StreamMatchResultListener : public MatchResultListener {
|
||||
class [[nodiscard]] StreamMatchResultListener : public MatchResultListener {
|
||||
public:
|
||||
explicit StreamMatchResultListener(::std::ostream* os)
|
||||
: MatchResultListener(os) {}
|
||||
@@ -225,7 +226,7 @@ struct SharedPayload : SharedPayloadBase {
|
||||
// from it. We put functionalities common to all Matcher<T>
|
||||
// specializations here to avoid code duplication.
|
||||
template <typename T>
|
||||
class MatcherBase : private MatcherDescriberInterface {
|
||||
class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
|
||||
public:
|
||||
// Returns true if and only if the matcher matches x; also explains the
|
||||
// match result to 'listener'.
|
||||
@@ -296,12 +297,12 @@ class MatcherBase : private MatcherDescriberInterface {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MatcherBase(MatcherBase&& other)
|
||||
MatcherBase(MatcherBase&& other) noexcept
|
||||
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
||||
other.vtable_ = nullptr;
|
||||
}
|
||||
|
||||
MatcherBase& operator=(MatcherBase&& other) {
|
||||
MatcherBase& operator=(MatcherBase&& other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
Destroy();
|
||||
vtable_ = other.vtable_;
|
||||
@@ -460,7 +461,7 @@ class MatcherBase : private MatcherDescriberInterface {
|
||||
// implementation of Matcher<T> is just a std::shared_ptr to const
|
||||
// MatcherInterface<T>. Don't inherit from Matcher!
|
||||
template <typename T>
|
||||
class Matcher : public internal::MatcherBase<T> {
|
||||
class [[nodiscard]] Matcher : public internal::MatcherBase<T> {
|
||||
public:
|
||||
// Constructs a null matcher. Needed for storing Matcher objects in STL
|
||||
// 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
|
||||
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
||||
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
|
||||
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
||||
// matcher is expected.
|
||||
template <>
|
||||
class GTEST_API_ Matcher<const std::string&>
|
||||
: public internal::MatcherBase<const std::string&> {
|
||||
class GTEST_API_ [[nodiscard]]
|
||||
Matcher<const std::string&> : public internal::MatcherBase<const std::string&> {
|
||||
public:
|
||||
Matcher() = default;
|
||||
|
||||
@@ -513,8 +523,8 @@ class GTEST_API_ Matcher<const std::string&>
|
||||
};
|
||||
|
||||
template <>
|
||||
class GTEST_API_ Matcher<std::string>
|
||||
: public internal::MatcherBase<std::string> {
|
||||
class GTEST_API_ [[nodiscard]]
|
||||
Matcher<std::string> : public internal::MatcherBase<std::string> {
|
||||
public:
|
||||
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
|
||||
// matcher is expected.
|
||||
template <>
|
||||
class GTEST_API_ Matcher<const internal::StringView&>
|
||||
class GTEST_API_ [[nodiscard]] Matcher<const internal::StringView&>
|
||||
: public internal::MatcherBase<const internal::StringView&> {
|
||||
public:
|
||||
Matcher() = default;
|
||||
@@ -567,7 +577,7 @@ class GTEST_API_ Matcher<const internal::StringView&>
|
||||
};
|
||||
|
||||
template <>
|
||||
class GTEST_API_ Matcher<internal::StringView>
|
||||
class GTEST_API_ [[nodiscard]] Matcher<internal::StringView>
|
||||
: public internal::MatcherBase<internal::StringView> {
|
||||
public:
|
||||
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.
|
||||
template <class Impl>
|
||||
class PolymorphicMatcher {
|
||||
class [[nodiscard]] PolymorphicMatcher {
|
||||
public:
|
||||
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
|
||||
// a "bare" type (i.e. neither 'const T' nor 'T&').
|
||||
template <typename D, typename Rhs, typename Op>
|
||||
class ComparisonBase {
|
||||
class [[nodiscard]] ComparisonBase {
|
||||
public:
|
||||
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
||||
|
||||
@@ -722,7 +732,8 @@ class ComparisonBase {
|
||||
};
|
||||
|
||||
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:
|
||||
explicit EqMatcher(const Rhs& 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"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class NeMatcher
|
||||
class [[nodiscard]] NeMatcher
|
||||
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
|
||||
public:
|
||||
explicit NeMatcher(const Rhs& rhs)
|
||||
@@ -739,7 +750,8 @@ class NeMatcher
|
||||
static const char* NegatedDesc() { return "is equal to"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
||||
class [[nodiscard]] LtMatcher
|
||||
: public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
||||
public:
|
||||
explicit LtMatcher(const Rhs& 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 <"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
||||
class [[nodiscard]] GtMatcher
|
||||
: public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
||||
public:
|
||||
explicit GtMatcher(const Rhs& 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 >"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class LeMatcher
|
||||
class [[nodiscard]] LeMatcher
|
||||
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
|
||||
public:
|
||||
explicit LeMatcher(const Rhs& rhs)
|
||||
@@ -764,7 +777,7 @@ class LeMatcher
|
||||
static const char* NegatedDesc() { return "isn't <="; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class GeMatcher
|
||||
class [[nodiscard]] GeMatcher
|
||||
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
|
||||
public:
|
||||
explicit GeMatcher(const Rhs& rhs)
|
||||
@@ -773,6 +786,35 @@ class GeMatcher
|
||||
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<
|
||||
std::is_constructible<std::string, T>::value>::type>
|
||||
using StringLike = T;
|
||||
@@ -780,7 +822,7 @@ using StringLike = T;
|
||||
// Implements polymorphic matchers MatchesRegex(regex) and
|
||||
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
||||
// T can be converted to a string.
|
||||
class MatchesRegexMatcher {
|
||||
class [[nodiscard]] MatchesRegexMatcher {
|
||||
public:
|
||||
MatchesRegexMatcher(const RE* regex, bool full_match)
|
||||
: regex_(regex), full_match_(full_match) {}
|
||||
@@ -863,13 +905,21 @@ inline internal::EqMatcher<T> Eq(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'.
|
||||
template <typename T>
|
||||
Matcher<T>::Matcher(T 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
|
||||
// and equal to rhs. A user may need to use this instead of Eq(...)
|
||||
// in order to resolve an overloading ambiguity.
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/strings/internal/has_absl_stringify.h"
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#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
|
||||
// GoogleTest with ABSL, this overload is only enabled if the value does not
|
||||
// have an AbslStringify definition.
|
||||
template <typename T
|
||||
template <
|
||||
typename T
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
,
|
||||
typename std::enable_if<
|
||||
!absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0
|
||||
,
|
||||
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0
|
||||
#endif // GTEST_HAS_ABSL
|
||||
>
|
||||
>
|
||||
inline Message& operator<<(const T& val) {
|
||||
// Some libraries overload << for STL containers. These
|
||||
// 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
|
||||
// object.
|
||||
template <typename T,
|
||||
typename std::enable_if<
|
||||
absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0>
|
||||
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0>
|
||||
inline Message& operator<<(const T& val) {
|
||||
// ::operator<< is needed here for a similar reason as with the non-Abseil
|
||||
// version above
|
||||
|
||||
@@ -174,11 +174,12 @@ TEST_P(DerivedTest, DoesBlah) {
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#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"
|
||||
|
||||
namespace testing {
|
||||
@@ -413,7 +414,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
// Synopsis:
|
||||
// ConvertGenerator<T>(gen)
|
||||
// - 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
|
||||
// parameters in a custom type instead of std::tuple
|
||||
@@ -441,10 +443,65 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE))));
|
||||
//
|
||||
template <typename T>
|
||||
internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
internal::ParamGenerator<T> gen) {
|
||||
return internal::ParamConverterGenerator<T>(gen);
|
||||
template <typename RequestedT>
|
||||
internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
|
||||
internal::ParamGenerator<RequestedT> 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) \
|
||||
@@ -469,7 +526,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
||||
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, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
@@ -493,39 +550,38 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
#define GTEST_GET_FIRST_(first, ...) first
|
||||
#define GTEST_GET_SECOND_(first, second, ...) second
|
||||
|
||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||
if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))); \
|
||||
auto t = std::make_tuple(__VA_ARGS__); \
|
||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||
"Too Many Args!"); \
|
||||
} \
|
||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))))(info); \
|
||||
} \
|
||||
static int gtest_##prefix##test_suite_name##_dummy_ \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
GTEST_STRINGIFY_(test_suite_name), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestSuiteInstantiation( \
|
||||
GTEST_STRINGIFY_(prefix), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
||||
__FILE__, __LINE__)
|
||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||
if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))); \
|
||||
auto t = std::make_tuple(__VA_ARGS__); \
|
||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||
"Too Many Args!"); \
|
||||
} \
|
||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))))(info); \
|
||||
} \
|
||||
[[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
GTEST_STRINGIFY_(test_suite_name), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestSuiteInstantiation( \
|
||||
GTEST_STRINGIFY_(prefix), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
|
||||
__LINE__)
|
||||
|
||||
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
||||
#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_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream> // NOLINT
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#include "gtest/internal/gtest-internal.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 {
|
||||
|
||||
// Definitions in the internal* namespaces are subject to change without notice.
|
||||
@@ -131,13 +143,32 @@ namespace internal {
|
||||
template <typename T>
|
||||
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
|
||||
// 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 {
|
||||
template <typename T,
|
||||
typename = typename std::enable_if<
|
||||
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||
!IsRecursiveContainer<T>::value>::type>
|
||||
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||
!IsRecursiveContainer<T>::value) ||
|
||||
IsStdSpan<T>::value>::type>
|
||||
static void PrintValue(const T& container, std::ostream* os) {
|
||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||
*os << '{';
|
||||
@@ -269,10 +300,9 @@ struct ConvertibleToStringViewPrinter {
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
struct ConvertibleToAbslStringifyPrinter {
|
||||
template <
|
||||
typename T,
|
||||
typename = typename std::enable_if<
|
||||
absl::strings_internal::HasAbslStringify<T>::value>::type> // NOLINT
|
||||
template <typename T,
|
||||
typename = typename std::enable_if<
|
||||
absl::HasAbslStringify<T>::value>::type> // NOLINT
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
*os << absl::StrCat(value);
|
||||
}
|
||||
@@ -352,7 +382,7 @@ void PrintWithFallback(const T& value, ::std::ostream* os) {
|
||||
|
||||
// The default case.
|
||||
template <typename ToPrint, typename OtherOperand>
|
||||
class FormatForComparison {
|
||||
class [[nodiscard]] FormatForComparison {
|
||||
public:
|
||||
static ::std::string Format(const ToPrint& value) {
|
||||
return ::testing::PrintToString(value);
|
||||
@@ -361,7 +391,7 @@ class FormatForComparison {
|
||||
|
||||
// Array.
|
||||
template <typename ToPrint, size_t N, typename OtherOperand>
|
||||
class FormatForComparison<ToPrint[N], OtherOperand> {
|
||||
class [[nodiscard]] FormatForComparison<ToPrint[N], OtherOperand> {
|
||||
public:
|
||||
static ::std::string Format(const ToPrint* 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
|
||||
// reference types, which cannot be done with function templates.
|
||||
template <typename T>
|
||||
class UniversalPrinter;
|
||||
class [[nodiscard]] UniversalPrinter;
|
||||
|
||||
// Prints the given value using the << operator if it has one;
|
||||
// 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);
|
||||
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
|
||||
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
|
||||
|
||||
@@ -530,49 +564,63 @@ int AppropriateResolution(FloatType val) {
|
||||
int full = std::numeric_limits<FloatType>::max_digits10;
|
||||
if (val < 0) val = -val;
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
if (val < 1000000) {
|
||||
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;
|
||||
} else if (val >= 10000.0) {
|
||||
} else if (val >= static_cast<FloatType>(10000.0)) {
|
||||
mulfor6 = 1e1;
|
||||
} else if (val >= 1000.0) {
|
||||
} else if (val >= static_cast<FloatType>(1000.0)) {
|
||||
mulfor6 = 1e2;
|
||||
} else if (val >= 100.0) {
|
||||
} else if (val >= static_cast<FloatType>(100.0)) {
|
||||
mulfor6 = 1e3;
|
||||
} else if (val >= 10.0) {
|
||||
} else if (val >= static_cast<FloatType>(10.0)) {
|
||||
mulfor6 = 1e4;
|
||||
} else if (val >= 1.0) {
|
||||
} else if (val >= static_cast<FloatType>(1.0)) {
|
||||
mulfor6 = 1e5;
|
||||
} else if (val >= 0.1) {
|
||||
} else if (val >= static_cast<FloatType>(0.1)) {
|
||||
mulfor6 = 1e6;
|
||||
} else if (val >= 0.01) {
|
||||
} else if (val >= static_cast<FloatType>(0.01)) {
|
||||
mulfor6 = 1e7;
|
||||
} else if (val >= 0.001) {
|
||||
} else if (val >= static_cast<FloatType>(0.001)) {
|
||||
mulfor6 = 1e8;
|
||||
} else if (val >= 0.0001) {
|
||||
} else if (val >= static_cast<FloatType>(0.0001)) {
|
||||
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 ==
|
||||
val)
|
||||
return 6;
|
||||
} else if (val < 1e10) {
|
||||
FloatType divfor6 = 1.0;
|
||||
if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999
|
||||
} else if (val < static_cast<FloatType>(1e10)) {
|
||||
FloatType divfor6 = static_cast<FloatType>(1.0);
|
||||
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
}
|
||||
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 ==
|
||||
val)
|
||||
return 6;
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
return full;
|
||||
}
|
||||
|
||||
@@ -655,44 +703,63 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
||||
}
|
||||
}
|
||||
|
||||
// Overloads for ::std::string.
|
||||
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
|
||||
// Overloads for ::std::string and ::std::string_view
|
||||
GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::string& s, ::std::ostream* 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
|
||||
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) {
|
||||
PrintU8StringTo(s, os);
|
||||
}
|
||||
inline void PrintTo(::std::u8string_view s, ::std::ostream* os) {
|
||||
PrintU8StringTo(s, os);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Overloads for ::std::u16string
|
||||
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
|
||||
// Overloads for ::std::u16string and ::std::u16string_view
|
||||
GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
|
||||
PrintU16StringTo(s, os);
|
||||
}
|
||||
inline void PrintTo(::std::u16string_view s, ::std::ostream* os) {
|
||||
PrintU16StringTo(s, os);
|
||||
}
|
||||
|
||||
// Overloads for ::std::u32string
|
||||
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
|
||||
// Overloads for ::std::u32string and ::std::u32string_view
|
||||
GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::u32string& s, ::std::ostream* 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
|
||||
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) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
inline void PrintTo(::std::wstring_view s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#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) {
|
||||
PrintTo(::std::string(sp), os);
|
||||
PrintStringTo(sp, os);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
#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
|
||||
// a tuple type.
|
||||
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
|
||||
// pick the right overload of PrintTo() for T.
|
||||
template <typename T>
|
||||
class UniversalPrinter {
|
||||
class [[nodiscard]] UniversalPrinter {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
@@ -813,16 +915,13 @@ class UniversalPrinter {
|
||||
|
||||
// Remove any const-qualifiers before passing a type to UniversalPrinter.
|
||||
template <typename T>
|
||||
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
||||
|
||||
#if GTEST_INTERNAL_HAS_ANY
|
||||
|
||||
// Printer for std::any / absl::any
|
||||
class [[nodiscard]] UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
||||
|
||||
// Printer for std::any
|
||||
template <>
|
||||
class UniversalPrinter<Any> {
|
||||
class [[nodiscard]] UniversalPrinter<std::any> {
|
||||
public:
|
||||
static void Print(const Any& value, ::std::ostream* os) {
|
||||
static void Print(const std::any& value, ::std::ostream* os) {
|
||||
if (value.has_value()) {
|
||||
*os << "value of type " << GetTypeName(value);
|
||||
} else {
|
||||
@@ -831,7 +930,7 @@ class UniversalPrinter<Any> {
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string GetTypeName(const Any& value) {
|
||||
static std::string GetTypeName(const std::any& value) {
|
||||
#if GTEST_HAS_RTTI
|
||||
return internal::GetTypeName(value.type());
|
||||
#else
|
||||
@@ -841,16 +940,11 @@ class UniversalPrinter<Any> {
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GTEST_INTERNAL_HAS_ANY
|
||||
|
||||
#if GTEST_INTERNAL_HAS_OPTIONAL
|
||||
|
||||
// Printer for std::optional / absl::optional
|
||||
|
||||
// Printer for std::optional
|
||||
template <typename T>
|
||||
class UniversalPrinter<Optional<T>> {
|
||||
class [[nodiscard]] UniversalPrinter<std::optional<T>> {
|
||||
public:
|
||||
static void Print(const Optional<T>& value, ::std::ostream* os) {
|
||||
static void Print(const std::optional<T>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
if (!value) {
|
||||
*os << "nullopt";
|
||||
@@ -862,29 +956,18 @@ class UniversalPrinter<Optional<T>> {
|
||||
};
|
||||
|
||||
template <>
|
||||
class UniversalPrinter<decltype(Nullopt())> {
|
||||
class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
|
||||
public:
|
||||
static void Print(decltype(Nullopt()), ::std::ostream* os) {
|
||||
*os << "(nullopt)";
|
||||
}
|
||||
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
|
||||
};
|
||||
|
||||
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
||||
|
||||
#if GTEST_INTERNAL_HAS_VARIANT
|
||||
|
||||
// Printer for std::variant / absl::variant
|
||||
|
||||
// Printer for std::variant
|
||||
template <typename... T>
|
||||
class UniversalPrinter<Variant<T...>> {
|
||||
class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
|
||||
public:
|
||||
static void Print(const Variant<T...>& value, ::std::ostream* os) {
|
||||
static void Print(const std::variant<T...>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
absl::visit(Visitor{os, value.index()}, value);
|
||||
#else
|
||||
std::visit(Visitor{os, value.index()}, value);
|
||||
#endif // GTEST_HAS_ABSL
|
||||
*os << ')';
|
||||
}
|
||||
|
||||
@@ -901,8 +984,6 @@ class UniversalPrinter<Variant<T...>> {
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GTEST_INTERNAL_HAS_VARIANT
|
||||
|
||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||
// elements, starting at address 'begin'.
|
||||
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].
|
||||
template <typename T, size_t N>
|
||||
class UniversalPrinter<T[N]> {
|
||||
class [[nodiscard]] UniversalPrinter<T[N]> {
|
||||
public:
|
||||
// Prints the given array, omitting some elements when there are too
|
||||
// many.
|
||||
@@ -961,7 +1042,7 @@ class UniversalPrinter<T[N]> {
|
||||
|
||||
// Implements printing a reference type T&.
|
||||
template <typename T>
|
||||
class UniversalPrinter<T&> {
|
||||
class [[nodiscard]] UniversalPrinter<T&> {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
@@ -984,35 +1065,35 @@ class UniversalPrinter<T&> {
|
||||
// NUL-terminated string (but not the pointer) is printed.
|
||||
|
||||
template <typename T>
|
||||
class UniversalTersePrinter {
|
||||
class [[nodiscard]] UniversalTersePrinter {
|
||||
public:
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
UniversalPrint(value, os);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
class UniversalTersePrinter<T&> {
|
||||
class [[nodiscard]] UniversalTersePrinter<T&> {
|
||||
public:
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
UniversalPrint(value, os);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
class UniversalTersePrinter<std::reference_wrapper<T>> {
|
||||
class [[nodiscard]] UniversalTersePrinter<std::reference_wrapper<T>> {
|
||||
public:
|
||||
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
|
||||
UniversalTersePrinter<T>::Print(value.get(), os);
|
||||
}
|
||||
};
|
||||
template <typename T, size_t N>
|
||||
class UniversalTersePrinter<T[N]> {
|
||||
class [[nodiscard]] UniversalTersePrinter<T[N]> {
|
||||
public:
|
||||
static void Print(const T (&value)[N], ::std::ostream* os) {
|
||||
UniversalPrinter<T[N]>::Print(value, os);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<const char*> {
|
||||
class [[nodiscard]] UniversalTersePrinter<const char*> {
|
||||
public:
|
||||
static void Print(const char* str, ::std::ostream* os) {
|
||||
if (str == nullptr) {
|
||||
@@ -1023,12 +1104,12 @@ class UniversalTersePrinter<const char*> {
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
|
||||
};
|
||||
class [[nodiscard]]
|
||||
UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {};
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template <>
|
||||
class UniversalTersePrinter<const char8_t*> {
|
||||
class [[nodiscard]] UniversalTersePrinter<const char8_t*> {
|
||||
public:
|
||||
static void Print(const char8_t* str, ::std::ostream* os) {
|
||||
if (str == nullptr) {
|
||||
@@ -1039,12 +1120,12 @@ class UniversalTersePrinter<const char8_t*> {
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<char8_t*>
|
||||
class [[nodiscard]] UniversalTersePrinter<char8_t*>
|
||||
: public UniversalTersePrinter<const char8_t*> {};
|
||||
#endif
|
||||
|
||||
template <>
|
||||
class UniversalTersePrinter<const char16_t*> {
|
||||
class [[nodiscard]] UniversalTersePrinter<const char16_t*> {
|
||||
public:
|
||||
static void Print(const char16_t* str, ::std::ostream* os) {
|
||||
if (str == nullptr) {
|
||||
@@ -1055,11 +1136,11 @@ class UniversalTersePrinter<const char16_t*> {
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<char16_t*>
|
||||
class [[nodiscard]] UniversalTersePrinter<char16_t*>
|
||||
: public UniversalTersePrinter<const char16_t*> {};
|
||||
|
||||
template <>
|
||||
class UniversalTersePrinter<const char32_t*> {
|
||||
class [[nodiscard]] UniversalTersePrinter<const char32_t*> {
|
||||
public:
|
||||
static void Print(const char32_t* str, ::std::ostream* os) {
|
||||
if (str == nullptr) {
|
||||
@@ -1070,12 +1151,12 @@ class UniversalTersePrinter<const char32_t*> {
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<char32_t*>
|
||||
class [[nodiscard]] UniversalTersePrinter<char32_t*>
|
||||
: public UniversalTersePrinter<const char32_t*> {};
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
template <>
|
||||
class UniversalTersePrinter<const wchar_t*> {
|
||||
class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
|
||||
public:
|
||||
static void Print(const wchar_t* str, ::std::ostream* os) {
|
||||
if (str == nullptr) {
|
||||
@@ -1088,7 +1169,7 @@ class UniversalTersePrinter<const wchar_t*> {
|
||||
#endif
|
||||
|
||||
template <>
|
||||
class UniversalTersePrinter<wchar_t*> {
|
||||
class [[nodiscard]] UniversalTersePrinter<wchar_t*> {
|
||||
public:
|
||||
static void Print(wchar_t* str, ::std::ostream* 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
|
||||
// all generated failures. The scope of this mock object can be controlled with
|
||||
// the second argument to the two arguments constructor.
|
||||
class GTEST_API_ ScopedFakeTestPartResultReporter
|
||||
class GTEST_API_ [[nodiscard]] ScopedFakeTestPartResultReporter
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
// The two possible mocking modes of this object.
|
||||
@@ -100,7 +100,7 @@ namespace internal {
|
||||
// TestPartResultArray contains exactly one failure that has the given
|
||||
// type and contains the given substring. If that's not the case, a
|
||||
// non-fatal failure will be generated.
|
||||
class GTEST_API_ SingleFailureChecker {
|
||||
class GTEST_API_ [[nodiscard]] SingleFailureChecker {
|
||||
public:
|
||||
// The constructor remembers the arguments.
|
||||
SingleFailureChecker(const TestPartResultArray* results,
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
@@ -51,7 +52,7 @@ namespace testing {
|
||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
//
|
||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
class GTEST_API_ TestPartResult {
|
||||
class GTEST_API_ [[nodiscard]] TestPartResult {
|
||||
public:
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
@@ -65,10 +66,10 @@ class GTEST_API_ TestPartResult {
|
||||
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestPartResult object.
|
||||
TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
|
||||
const char* a_message)
|
||||
TestPartResult(Type a_type, std::string_view a_file_name, int a_line_number,
|
||||
std::string_view a_message)
|
||||
: type_(a_type),
|
||||
file_name_(a_file_name == nullptr ? "" : a_file_name),
|
||||
file_name_(a_file_name),
|
||||
line_number_(a_line_number),
|
||||
summary_(ExtractSummary(a_message)),
|
||||
message_(a_message) {}
|
||||
@@ -112,7 +113,7 @@ class GTEST_API_ TestPartResult {
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack
|
||||
// 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
|
||||
// "" 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
|
||||
// virtual.
|
||||
class GTEST_API_ TestPartResultArray {
|
||||
class GTEST_API_ [[nodiscard]] TestPartResultArray {
|
||||
public:
|
||||
TestPartResultArray() = default;
|
||||
|
||||
@@ -152,7 +153,7 @@ class GTEST_API_ TestPartResultArray {
|
||||
};
|
||||
|
||||
// This interface knows how to report a test part result.
|
||||
class GTEST_API_ TestPartResultReporterInterface {
|
||||
class GTEST_API_ [[nodiscard]] TestPartResultReporterInterface {
|
||||
public:
|
||||
virtual ~TestPartResultReporterInterface() = default;
|
||||
|
||||
@@ -167,7 +168,7 @@ namespace internal {
|
||||
// reported, it only delegates the reporting to the former result reporter.
|
||||
// The original result reporter is restored in the destructor.
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
class GTEST_API_ HasNewFatalFailureHelper
|
||||
class GTEST_API_ [[nodiscard]] HasNewFatalFailureHelper
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
HasNewFatalFailureHelper();
|
||||
|
||||
@@ -45,18 +45,18 @@
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
class [[nodiscard]] FooTest : public testing::Test {
|
||||
public:
|
||||
...
|
||||
typedef std::list<T> List;
|
||||
using List = ::std::list<T>;
|
||||
static T shared_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
// 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.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
using MyTypes = ::testing::Types<char, int, unsigned int>;
|
||||
TYPED_TEST_SUITE(FooTest, MyTypes);
|
||||
|
||||
// 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
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
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
|
||||
// to the actual test suite name. Remember to pick unique prefixes for
|
||||
// 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);
|
||||
|
||||
// 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; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
static bool gtest_##CaseName##_##TestName##_registered_ \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
|
||||
[[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)>, \
|
||||
@@ -267,22 +267,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// 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) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
[[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||
SuiteName) = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||
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, ...) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||
"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< \
|
||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||
::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 <cstdint>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest-assertion-result.h"
|
||||
#include "gtest/gtest-death-test.h"
|
||||
#include "gtest/gtest-matchers.h"
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/gtest-param-test.h"
|
||||
#include "gtest/gtest-printers.h"
|
||||
#include "gtest/gtest-test-part.h"
|
||||
#include "gtest/gtest-typed-test.h"
|
||||
#include "gtest/gtest_pred_impl.h"
|
||||
#include "gtest/gtest_prod.h"
|
||||
#include "gtest/gtest-assertion-result.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-death-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-matchers.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-message.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-param-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-printers.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-test-part.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-typed-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest_pred_impl.h" // IWYU pragma: export
|
||||
#include "gtest/gtest_prod.h" // IWYU pragma: export
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
@@ -137,6 +137,10 @@ GTEST_DECLARE_int32_(repeat);
|
||||
// only torn down once, for the last.
|
||||
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
|
||||
// stack frames in failure stack traces.
|
||||
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.
|
||||
// We do this instead of using '= delete' so as to avoid triggering warnings
|
||||
// inside user code regarding any of our declarations.
|
||||
class GTestNonCopyable {
|
||||
class [[nodiscard]] GTestNonCopyable {
|
||||
public:
|
||||
GTestNonCopyable() = default;
|
||||
GTestNonCopyable(const GTestNonCopyable&) = delete;
|
||||
@@ -207,15 +211,15 @@ class GTestNonCopyable {
|
||||
// The friend relationship of some of these classes is cyclic.
|
||||
// If we don't forward declare them the compiler might confuse the classes
|
||||
// in friendship clauses with same named classes on the scope.
|
||||
class Test;
|
||||
class TestSuite;
|
||||
class [[nodiscard]] Test;
|
||||
class [[nodiscard]] TestSuite;
|
||||
|
||||
// Old API is still available but deprecated
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
using TestCase = TestSuite;
|
||||
#endif
|
||||
class TestInfo;
|
||||
class UnitTest;
|
||||
class [[nodiscard]] TestInfo;
|
||||
class [[nodiscard]] UnitTest;
|
||||
|
||||
// The abstract class that all tests inherit from.
|
||||
//
|
||||
@@ -240,7 +244,7 @@ class UnitTest;
|
||||
// TEST_F(FooTest, Baz) { ... }
|
||||
//
|
||||
// Test is not copyable.
|
||||
class GTEST_API_ Test {
|
||||
class GTEST_API_ [[nodiscard]] Test {
|
||||
public:
|
||||
friend class TestInfo;
|
||||
|
||||
@@ -367,7 +371,7 @@ typedef internal::TimeInMillis TimeInMillis;
|
||||
// output as a key/value string pair.
|
||||
//
|
||||
// Don't inherit from TestProperty as its destructor is not virtual.
|
||||
class TestProperty {
|
||||
class [[nodiscard]] TestProperty {
|
||||
public:
|
||||
// C'tor. TestProperty does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
@@ -397,7 +401,7 @@ class TestProperty {
|
||||
// the Test.
|
||||
//
|
||||
// TestResult is not copyable.
|
||||
class GTEST_API_ TestResult {
|
||||
class GTEST_API_ [[nodiscard]] TestResult {
|
||||
public:
|
||||
// Creates an empty TestResult.
|
||||
TestResult();
|
||||
@@ -531,7 +535,7 @@ class GTEST_API_ TestResult {
|
||||
// The constructor of TestInfo registers itself with the UnitTest
|
||||
// singleton such that the RUN_ALL_TESTS() macro knows which tests to
|
||||
// run.
|
||||
class GTEST_API_ TestInfo {
|
||||
class GTEST_API_ [[nodiscard]] TestInfo {
|
||||
public:
|
||||
// Destructs a TestInfo object. This function is not virtual, so
|
||||
// don't inherit from TestInfo.
|
||||
@@ -608,7 +612,7 @@ class GTEST_API_ TestInfo {
|
||||
friend class internal::UnitTestImpl;
|
||||
friend class internal::StreamingListenerTest;
|
||||
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,
|
||||
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
||||
internal::TearDownTestSuiteFunc tear_down_tc,
|
||||
@@ -616,7 +620,7 @@ class GTEST_API_ TestInfo {
|
||||
|
||||
// Constructs a TestInfo object. The newly constructed instance assumes
|
||||
// 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_value_param, // NULL if not a value-parameterized test
|
||||
internal::CodeLocation a_code_location,
|
||||
@@ -670,7 +674,7 @@ class GTEST_API_ TestInfo {
|
||||
// A test suite, which consists of a vector of TestInfos.
|
||||
//
|
||||
// TestSuite is not copyable.
|
||||
class GTEST_API_ TestSuite {
|
||||
class GTEST_API_ [[nodiscard]] TestSuite {
|
||||
public:
|
||||
// Creates a TestSuite with the given name.
|
||||
//
|
||||
@@ -684,7 +688,7 @@ class GTEST_API_ TestSuite {
|
||||
// this is not a type-parameterized test.
|
||||
// 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
|
||||
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::TearDownTestSuiteFunc tear_down_tc);
|
||||
|
||||
@@ -891,7 +895,7 @@ class GTEST_API_ TestSuite {
|
||||
// available.
|
||||
// 2. You cannot use ASSERT_* directly in a constructor or
|
||||
// destructor.
|
||||
class Environment {
|
||||
class [[nodiscard]] Environment {
|
||||
public:
|
||||
// The d'tor is virtual as we need to subclass Environment.
|
||||
virtual ~Environment() = default;
|
||||
@@ -912,7 +916,7 @@ class Environment {
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Exception which can be thrown from TestEventListener::OnTestPartResult.
|
||||
class GTEST_API_ AssertionException
|
||||
class GTEST_API_ [[nodiscard]] AssertionException
|
||||
: public internal::GoogleTestFailureException {
|
||||
public:
|
||||
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 order the corresponding events are fired.
|
||||
class TestEventListener {
|
||||
class [[nodiscard]] TestEventListener {
|
||||
public:
|
||||
virtual ~TestEventListener() = default;
|
||||
|
||||
@@ -990,7 +994,7 @@ class TestEventListener {
|
||||
// the methods they override will not be caught during the build. For
|
||||
// comments about each method please see the definition of TestEventListener
|
||||
// above.
|
||||
class EmptyTestEventListener : public TestEventListener {
|
||||
class [[nodiscard]] EmptyTestEventListener : public TestEventListener {
|
||||
public:
|
||||
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
|
||||
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.
|
||||
class GTEST_API_ TestEventListeners {
|
||||
class GTEST_API_ [[nodiscard]] TestEventListeners {
|
||||
public:
|
||||
TestEventListeners();
|
||||
~TestEventListeners();
|
||||
@@ -1111,7 +1115,7 @@ class GTEST_API_ TestEventListeners {
|
||||
//
|
||||
// This class is thread-safe as long as the methods are called
|
||||
// according to their specification.
|
||||
class GTEST_API_ UnitTest {
|
||||
class GTEST_API_ [[nodiscard]] UnitTest {
|
||||
public:
|
||||
// Gets the singleton UnitTest object. The first time this method
|
||||
// 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.
|
||||
//
|
||||
// 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()
|
||||
// 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
|
||||
// should use the assertion macros instead of calling this directly.
|
||||
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& os_stack_trace)
|
||||
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.
|
||||
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.
|
||||
internal::UnitTestImpl* impl() { return impl_; }
|
||||
const internal::UnitTestImpl* impl() const { return impl_; }
|
||||
@@ -1271,6 +1289,8 @@ class GTEST_API_ UnitTest {
|
||||
// members of UnitTest.
|
||||
friend class ScopedTrace;
|
||||
friend class Test;
|
||||
friend class TestInfo;
|
||||
friend class TestSuite;
|
||||
friend class internal::AssertHelper;
|
||||
friend class internal::StreamingListenerTest;
|
||||
friend class internal::UnitTestRecordPropertyTestHelper;
|
||||
@@ -1383,7 +1403,7 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
|
||||
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
|
||||
}
|
||||
|
||||
class EqHelper {
|
||||
class [[nodiscard]] EqHelper {
|
||||
public:
|
||||
// This templatized version is for the general case.
|
||||
template <
|
||||
@@ -1574,12 +1594,12 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
|
||||
}
|
||||
|
||||
::std::stringstream lhs_ss;
|
||||
lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
||||
<< lhs_value;
|
||||
lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
|
||||
lhs_ss << lhs_value;
|
||||
|
||||
::std::stringstream rhs_ss;
|
||||
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
||||
<< rhs_value;
|
||||
rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
|
||||
rhs_ss << rhs_value;
|
||||
|
||||
return EqFailure(lhs_expression, rhs_expression,
|
||||
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
|
||||
@@ -1595,18 +1615,23 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
|
||||
double val1, double val2,
|
||||
double abs_error);
|
||||
|
||||
using GoogleTest_NotSupported_OnFunctionReturningNonVoid = void;
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
// A class that enables one to stream messages to assertion macros
|
||||
class GTEST_API_ AssertHelper {
|
||||
class GTEST_API_ [[nodiscard]] AssertHelper {
|
||||
public:
|
||||
// Constructor.
|
||||
AssertHelper(TestPartResult::Type type, const char* file, int line,
|
||||
const char* message);
|
||||
AssertHelper(TestPartResult::Type type, std::string_view file, int line,
|
||||
std::string_view message);
|
||||
~AssertHelper();
|
||||
|
||||
// Message assignment is a semantic trick to enable assertion
|
||||
// streaming; see the GTEST_MESSAGE_ macro below.
|
||||
void operator=(const Message& message) const;
|
||||
GoogleTest_NotSupported_OnFunctionReturningNonVoid operator=(
|
||||
const Message& message) const;
|
||||
|
||||
private:
|
||||
// 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
|
||||
// reserves stack space for another AssertHelper.
|
||||
struct AssertHelperData {
|
||||
AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,
|
||||
const char* msg)
|
||||
AssertHelperData(TestPartResult::Type t, std::string_view srcfile,
|
||||
int line_num, std::string_view msg)
|
||||
: type(t), file(srcfile), line(line_num), message(msg) {}
|
||||
|
||||
TestPartResult::Type const type;
|
||||
const char* const file;
|
||||
const std::string_view file;
|
||||
int const line;
|
||||
std::string const message;
|
||||
|
||||
@@ -1671,14 +1696,14 @@ class GTEST_API_ AssertHelper {
|
||||
// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
|
||||
|
||||
template <typename T>
|
||||
class WithParamInterface {
|
||||
class [[nodiscard]] WithParamInterface {
|
||||
public:
|
||||
typedef T ParamType;
|
||||
virtual ~WithParamInterface() = default;
|
||||
|
||||
// The current parameter value. Is also available in the test fixture's
|
||||
// constructor.
|
||||
static const ParamType& GetParam() {
|
||||
[[nodiscard]] static const ParamType& GetParam() {
|
||||
GTEST_CHECK_(parameter_ != nullptr)
|
||||
<< "GetParam() can only be called inside a value-parameterized test "
|
||||
<< "-- 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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -1752,6 +1778,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
||||
// generic name and clashes with some other libraries.
|
||||
#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
|
||||
#define FAIL() GTEST_FAIL()
|
||||
#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)
|
||||
#endif
|
||||
|
||||
// Generates a success with a generic message.
|
||||
@@ -2052,7 +2079,7 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
|
||||
// Example:
|
||||
// testing::ScopedTrace trace("file.cc", 123, "message");
|
||||
//
|
||||
class GTEST_API_ ScopedTrace {
|
||||
class GTEST_API_ [[nodiscard]] ScopedTrace {
|
||||
public:
|
||||
// The c'tor pushes the given source file location and message onto
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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(); }
|
||||
|
||||
|
||||
@@ -46,17 +46,38 @@
|
||||
|
||||
#include "gtest/gtest-matchers.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
GTEST_DECLARE_string_(internal_run_death_test);
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Names of the flags (needed for parsing Google Test flags).
|
||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||
// Name of the flag (needed for parsing Google Test flag).
|
||||
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
|
||||
|
||||
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
|
||||
// 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()
|
||||
class GTEST_API_ DeathTest {
|
||||
class GTEST_API_ [[nodiscard]] DeathTest {
|
||||
public:
|
||||
// Create returns false if there was an error determining the
|
||||
// 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
|
||||
|
||||
// Factory interface for death tests. May be mocked out for testing.
|
||||
class DeathTestFactory {
|
||||
class [[nodiscard]] DeathTestFactory {
|
||||
public:
|
||||
virtual ~DeathTestFactory() = default;
|
||||
virtual bool Create(const char* statement,
|
||||
@@ -160,7 +181,7 @@ class DeathTestFactory {
|
||||
};
|
||||
|
||||
// A concrete DeathTestFactory implementation for normal use.
|
||||
class DefaultDeathTestFactory : public DeathTestFactory {
|
||||
class [[nodiscard]] DefaultDeathTestFactory : public DeathTestFactory {
|
||||
public:
|
||||
bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||
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.
|
||||
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
|
||||
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||
#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.
|
||||
// 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.
|
||||
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} else if (!::testing::internal::AlwaysTrue()) { \
|
||||
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||
} else \
|
||||
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} else if (!::testing::internal::AlwaysTrue()) { \
|
||||
(void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
// A class representing the parsed contents of the
|
||||
// --gtest_internal_run_death_test flag, as it existed when
|
||||
// RUN_ALL_TESTS was called.
|
||||
class InternalRunDeathTestFlag {
|
||||
class [[nodiscard]] InternalRunDeathTestFlag {
|
||||
public:
|
||||
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
|
||||
int a_write_fd)
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
@@ -66,12 +67,13 @@ namespace internal {
|
||||
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||
// characters, malformed paths, etc.
|
||||
|
||||
class GTEST_API_ FilePath {
|
||||
class GTEST_API_ [[nodiscard]] FilePath {
|
||||
public:
|
||||
FilePath() : 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();
|
||||
}
|
||||
|
||||
@@ -79,6 +81,10 @@ class GTEST_API_ FilePath {
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
FilePath& operator=(FilePath&& rhs) noexcept {
|
||||
pathname_ = std::move(rhs.pathname_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
@@ -79,7 +78,7 @@
|
||||
//
|
||||
// will result in the token foo__LINE__, instead of foo followed by
|
||||
// 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_IMPL_(foo, bar) foo##bar
|
||||
|
||||
@@ -96,7 +95,7 @@
|
||||
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
|
||||
|
||||
namespace proto2 {
|
||||
class MessageLite;
|
||||
class [[nodiscard]] MessageLite;
|
||||
}
|
||||
|
||||
namespace testing {
|
||||
@@ -116,15 +115,15 @@ template <typename T>
|
||||
namespace internal {
|
||||
|
||||
struct TraceInfo; // Information about a trace point.
|
||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
||||
class [[nodiscard]] TestInfoImpl; // Opaque implementation of TestInfo
|
||||
class [[nodiscard]] UnitTestImpl; // Opaque implementation of UnitTest
|
||||
|
||||
// The text used in failure messages to indicate the start of the
|
||||
// stack trace.
|
||||
GTEST_API_ extern const char kStackTraceMarker[];
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
class IgnoredValue {
|
||||
class [[nodiscard]] IgnoredValue {
|
||||
struct Sink {};
|
||||
|
||||
public:
|
||||
@@ -156,7 +155,8 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
||||
// errors presumably detectable only at run time. Since
|
||||
// std::runtime_error inherits from std::exception, many testing
|
||||
// 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:
|
||||
explicit GoogleTestFailureException(const TestPartResult& failure);
|
||||
};
|
||||
@@ -170,7 +170,7 @@ namespace edit_distance {
|
||||
// All edits cost the same, with replace having lower priority than
|
||||
// add/remove.
|
||||
// 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 };
|
||||
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
||||
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.
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// RawType: the raw floating-point type (either float or double)
|
||||
template <typename RawType>
|
||||
class FloatingPoint {
|
||||
class [[nodiscard]] FloatingPoint {
|
||||
public:
|
||||
// Defines the unsigned integer type that has the same size as the
|
||||
// floating point number.
|
||||
@@ -282,7 +282,7 @@ class FloatingPoint {
|
||||
// bits. Therefore, 4 should be enough for ordinary use.
|
||||
//
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
// to be also a NAN. Therefore, don't expect this constructor to
|
||||
// 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
|
||||
|
||||
// Reinterprets a bit pattern as a floating-point number.
|
||||
//
|
||||
// This function is needed to test the AlmostEquals() method.
|
||||
static RawType ReinterpretBits(const Bits bits) {
|
||||
FloatingPoint fp(0);
|
||||
fp.u_.bits_ = bits;
|
||||
return fp.u_.value_;
|
||||
static RawType ReinterpretBits(Bits bits) {
|
||||
RawType fp;
|
||||
memcpy(&fp, &bits, sizeof(fp));
|
||||
return fp;
|
||||
}
|
||||
|
||||
// Returns the floating-point number that represent positive infinity.
|
||||
@@ -310,16 +310,16 @@ class FloatingPoint {
|
||||
// Non-static methods
|
||||
|
||||
// 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.
|
||||
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
|
||||
Bits exponent_bits() const { return kExponentBitMask & bits_; }
|
||||
|
||||
// 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.
|
||||
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).
|
||||
bool is_nan() const {
|
||||
@@ -333,23 +333,16 @@ class FloatingPoint {
|
||||
//
|
||||
// - returns false if either number is (or both are) NAN.
|
||||
// - 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 {
|
||||
// The IEEE standard says that any comparison operation involving
|
||||
// a NAN must return false.
|
||||
if (is_nan() || rhs.is_nan()) return false;
|
||||
|
||||
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
|
||||
kMaxUlps;
|
||||
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
|
||||
}
|
||||
|
||||
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
|
||||
// the biased representation. More precisely, let N be 2 to 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
|
||||
// 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.
|
||||
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
||||
static Bits SignAndMagnitudeToBiased(Bits sam) {
|
||||
if (kSignBitMask & sam) {
|
||||
// sam represents a negative number.
|
||||
return ~sam + 1;
|
||||
@@ -377,14 +370,13 @@ class FloatingPoint {
|
||||
|
||||
// Given two numbers in the sign-and-magnitude representation,
|
||||
// returns the distance between them as an unsigned number.
|
||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
|
||||
const Bits& sam2) {
|
||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
|
||||
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
||||
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
||||
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
|
||||
@@ -401,7 +393,7 @@ typedef FloatingPoint<double> Double;
|
||||
typedef const void* TypeId;
|
||||
|
||||
template <typename T>
|
||||
class TypeIdHelper {
|
||||
class [[nodiscard]] TypeIdHelper {
|
||||
public:
|
||||
// dummy_ must not have a const type. Otherwise an overly eager
|
||||
// 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
|
||||
// of a Test object.
|
||||
class TestFactoryBase {
|
||||
class [[nodiscard]] TestFactoryBase {
|
||||
public:
|
||||
virtual ~TestFactoryBase() = default;
|
||||
|
||||
@@ -452,7 +444,7 @@ class TestFactoryBase {
|
||||
// This class provides implementation of TestFactoryBase interface.
|
||||
// It is used in TEST and TEST_F macros.
|
||||
template <class TestClass>
|
||||
class TestFactoryImpl : public TestFactoryBase {
|
||||
class [[nodiscard]] TestFactoryImpl : public TestFactoryBase {
|
||||
public:
|
||||
Test* CreateTest() override { return new TestClass; }
|
||||
};
|
||||
@@ -475,8 +467,8 @@ using SetUpTestSuiteFunc = void (*)();
|
||||
using TearDownTestSuiteFunc = void (*)();
|
||||
|
||||
struct CodeLocation {
|
||||
CodeLocation(const std::string& a_file, int a_line)
|
||||
: file(a_file), line(a_line) {}
|
||||
CodeLocation(std::string a_file, int a_line)
|
||||
: file(std::move(a_file)), line(a_line) {}
|
||||
|
||||
std::string file;
|
||||
int line;
|
||||
@@ -556,7 +548,7 @@ struct SuiteApiResolver : T {
|
||||
// type_param: the name of the test's type parameter, or NULL if
|
||||
// this is not a typed or a type-parameterized test.
|
||||
// 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
|
||||
// fixture_class_id: ID of the test fixture class
|
||||
// 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
|
||||
// ownership of the factory object.
|
||||
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,
|
||||
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
||||
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 */)
|
||||
|
||||
// State of the definition of a type-parameterized test suite.
|
||||
class GTEST_API_ TypedTestSuitePState {
|
||||
class GTEST_API_ [[nodiscard]] TypedTestSuitePState {
|
||||
public:
|
||||
TypedTestSuitePState() : registered_(false) {}
|
||||
|
||||
@@ -596,8 +588,7 @@ class GTEST_API_ TypedTestSuitePState {
|
||||
fflush(stderr);
|
||||
posix::Abort();
|
||||
}
|
||||
registered_tests_.insert(
|
||||
::std::make_pair(test_name, CodeLocation(file, line)));
|
||||
registered_tests_.emplace(test_name, CodeLocation(file, line));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -695,13 +686,13 @@ std::vector<std::string> GenerateNames() {
|
||||
// Implementation note: The GTEST_TEMPLATE_ macro declares a template
|
||||
// template parameter. It's defined in gtest-type-util.h.
|
||||
template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
|
||||
class TypeParameterizedTest {
|
||||
class [[nodiscard]] TypeParameterizedTest {
|
||||
public:
|
||||
// 'index' is the index of the test in the type list 'Types'
|
||||
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||
// 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 std::vector<std::string>& type_names =
|
||||
GenerateNames<DefaultNameGenerator, Types>()) {
|
||||
@@ -713,8 +704,7 @@ class TypeParameterizedTest {
|
||||
// list.
|
||||
MakeAndRegisterTestInfo(
|
||||
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
||||
"/" + type_names[static_cast<size_t>(index)])
|
||||
.c_str(),
|
||||
"/" + type_names[static_cast<size_t>(index)]),
|
||||
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
||||
GetTypeName<Type>().c_str(),
|
||||
nullptr, // No value parameter.
|
||||
@@ -726,21 +716,17 @@ class TypeParameterizedTest {
|
||||
new TestFactoryImpl<TestClass>);
|
||||
|
||||
// Next, recurses (at compile time) with the tail of the type list.
|
||||
return TypeParameterizedTest<Fixture, TestSel,
|
||||
typename Types::Tail>::Register(prefix,
|
||||
code_location,
|
||||
case_name,
|
||||
test_names,
|
||||
index + 1,
|
||||
type_names);
|
||||
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
|
||||
Register(prefix, std::move(code_location), case_name, test_names,
|
||||
index + 1, type_names);
|
||||
}
|
||||
};
|
||||
|
||||
// The base case for the compile time recursion.
|
||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
||||
class [[nodiscard]] TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
||||
public:
|
||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||
const char* /*case_name*/, const char* /*test_names*/,
|
||||
int /*index*/,
|
||||
const std::vector<std::string>& =
|
||||
@@ -759,7 +745,7 @@ GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
|
||||
// Test. The return value is insignificant - we just need to return
|
||||
// something such that we can call this function in a namespace scope.
|
||||
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
||||
class TypeParameterizedTestSuite {
|
||||
class [[nodiscard]] TypeParameterizedTestSuite {
|
||||
public:
|
||||
static bool Register(const char* prefix, CodeLocation code_location,
|
||||
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.
|
||||
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
||||
Types>::Register(prefix, code_location,
|
||||
Types>::Register(prefix,
|
||||
std::move(code_location),
|
||||
state, case_name,
|
||||
SkipComma(test_names),
|
||||
type_names);
|
||||
@@ -796,7 +783,7 @@ class TypeParameterizedTestSuite {
|
||||
|
||||
// The base case for the compile time recursion.
|
||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||
class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
|
||||
class [[nodiscard]] TypeParameterizedTestSuite<Fixture, internal::None, Types> {
|
||||
public:
|
||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||
const TypedTestSuitePState* /*state*/,
|
||||
@@ -852,7 +839,7 @@ struct TrueWithString {
|
||||
// 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,
|
||||
// but it's good enough for our purposes.
|
||||
class GTEST_API_ Random {
|
||||
class GTEST_API_ [[nodiscard]] Random {
|
||||
public:
|
||||
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 return std::string.
|
||||
template <typename T>
|
||||
class HasDebugStringAndShortDebugString {
|
||||
class [[nodiscard]] HasDebugStringAndShortDebugString {
|
||||
private:
|
||||
template <typename C>
|
||||
static auto CheckDebugString(C*) -> typename std::is_same<
|
||||
@@ -900,11 +887,6 @@ class HasDebugStringAndShortDebugString {
|
||||
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
|
||||
// STL-style container class, the first overload of IsContainerTest
|
||||
// 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
|
||||
// multi-dimensional arrays are supported).
|
||||
template <typename Element>
|
||||
class NativeArray {
|
||||
class [[nodiscard]] NativeArray {
|
||||
public:
|
||||
// STL-style container typedefs.
|
||||
typedef Element value_type;
|
||||
@@ -1143,40 +1125,6 @@ class NativeArray {
|
||||
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>
|
||||
struct Ignore {
|
||||
Ignore(...); // NOLINT
|
||||
@@ -1185,7 +1133,7 @@ struct Ignore {
|
||||
template <typename>
|
||||
struct ElemFromListImpl;
|
||||
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.
|
||||
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
|
||||
// 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>
|
||||
struct ElemFromList {
|
||||
using type =
|
||||
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
|
||||
static_cast<T (*)()>(nullptr)...));
|
||||
using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(
|
||||
static_cast<T (*)()>(nullptr)...));
|
||||
};
|
||||
|
||||
struct FlatTupleConstructTag {};
|
||||
|
||||
template <typename... T>
|
||||
class FlatTuple;
|
||||
class [[nodiscard]] FlatTuple;
|
||||
|
||||
template <typename Derived, size_t I>
|
||||
struct FlatTupleElemBase;
|
||||
@@ -1223,9 +1170,9 @@ template <typename Derived, typename Idx>
|
||||
struct FlatTupleBase;
|
||||
|
||||
template <size_t... Idx, typename... T>
|
||||
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
||||
struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
|
||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
||||
using Indices = IndexSequence<Idx...>;
|
||||
using Indices = std::index_sequence<Idx...>;
|
||||
FlatTupleBase() = default;
|
||||
template <typename... Args>
|
||||
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
|
||||
@@ -1260,14 +1207,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
||||
// implementations.
|
||||
// FlatTuple and ElemFromList are not recursive and have a fixed depth
|
||||
// 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)).
|
||||
template <typename... T>
|
||||
class FlatTuple
|
||||
class [[nodiscard]] FlatTuple
|
||||
: private FlatTupleBase<FlatTuple<T...>,
|
||||
typename MakeIndexSequence<sizeof...(T)>::type> {
|
||||
using Indices = typename FlatTupleBase<
|
||||
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
|
||||
std::make_index_sequence<sizeof...(T)>> {
|
||||
using Indices =
|
||||
typename FlatTupleBase<FlatTuple<T...>,
|
||||
std::make_index_sequence<sizeof...(T)>>::Indices;
|
||||
|
||||
public:
|
||||
FlatTuple() = default;
|
||||
@@ -1281,30 +1229,40 @@ class FlatTuple
|
||||
|
||||
// Utility functions to be called with static_assert to induce deprecation
|
||||
// warnings.
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
||||
"INSTANTIATE_TEST_SUITE_P")
|
||||
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
|
||||
"INSTANTIATE_TEST_SUITE_P")]]
|
||||
constexpr bool InstantiateTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"TYPED_TEST_CASE_P is deprecated, please use "
|
||||
"TYPED_TEST_SUITE_P")
|
||||
constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
|
||||
"TYPED_TEST_SUITE_P")]]
|
||||
constexpr bool TypedTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"TYPED_TEST_CASE is deprecated, please use "
|
||||
"TYPED_TEST_SUITE")
|
||||
constexpr bool TypedTestCaseIsDeprecated() { return true; }
|
||||
"TYPED_TEST_SUITE")]]
|
||||
constexpr bool TypedTestCaseIsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
||||
"REGISTER_TYPED_TEST_SUITE_P")
|
||||
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
|
||||
"REGISTER_TYPED_TEST_SUITE_P")]]
|
||||
constexpr bool RegisterTypedTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
||||
"INSTANTIATE_TYPED_TEST_SUITE_P")
|
||||
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
|
||||
"INSTANTIATE_TYPED_TEST_SUITE_P")]]
|
||||
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
@@ -1360,7 +1318,7 @@ struct tuple_size<testing::internal::FlatTuple<Ts...>>
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
class NeverThrown {
|
||||
class [[nodiscard]] NeverThrown {
|
||||
public:
|
||||
const char* what() const noexcept {
|
||||
return "this exception should never be thrown";
|
||||
@@ -1494,8 +1452,7 @@ class NeverThrown {
|
||||
; \
|
||||
else \
|
||||
fail(::testing::internal::GetBoolAssertionFailureMessage( \
|
||||
gtest_ar_, text, #actual, #expected) \
|
||||
.c_str())
|
||||
gtest_ar_, text, #actual, #expected))
|
||||
|
||||
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
@@ -1541,7 +1498,7 @@ class NeverThrown {
|
||||
\
|
||||
private: \
|
||||
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, \
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -47,6 +48,7 @@
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -85,17 +87,17 @@ namespace internal {
|
||||
// TEST_P macro is used to define two tests with the same name
|
||||
// but in different namespaces.
|
||||
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||
CodeLocation code_location);
|
||||
const CodeLocation& code_location);
|
||||
|
||||
template <typename>
|
||||
class ParamGeneratorInterface;
|
||||
class [[nodiscard]] ParamGeneratorInterface;
|
||||
template <typename>
|
||||
class ParamGenerator;
|
||||
class [[nodiscard]] ParamGenerator;
|
||||
|
||||
// Interface for iterating over elements provided by an implementation
|
||||
// of ParamGeneratorInterface<T>.
|
||||
template <typename T>
|
||||
class ParamIteratorInterface {
|
||||
class [[nodiscard]] ParamIteratorInterface {
|
||||
public:
|
||||
virtual ~ParamIteratorInterface() = default;
|
||||
// A pointer to the base generator instance.
|
||||
@@ -125,7 +127,7 @@ class ParamIteratorInterface {
|
||||
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
|
||||
// and implements the const forward iterator concept.
|
||||
template <typename T>
|
||||
class ParamIterator {
|
||||
class [[nodiscard]] ParamIterator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef const T& reference;
|
||||
@@ -167,7 +169,7 @@ class ParamIterator {
|
||||
// ParamGeneratorInterface<T> is the binary interface to access generators
|
||||
// defined in other translation units.
|
||||
template <typename T>
|
||||
class ParamGeneratorInterface {
|
||||
class [[nodiscard]] ParamGeneratorInterface {
|
||||
public:
|
||||
typedef T ParamType;
|
||||
|
||||
@@ -184,7 +186,7 @@ class ParamGeneratorInterface {
|
||||
// ParamGeneratorInterface<T> instance is shared among all copies
|
||||
// of the original object. This is possible because that instance is immutable.
|
||||
template <typename T>
|
||||
class ParamGenerator {
|
||||
class [[nodiscard]] ParamGenerator {
|
||||
public:
|
||||
typedef ParamIterator<T> iterator;
|
||||
|
||||
@@ -208,7 +210,7 @@ class ParamGenerator {
|
||||
// operator<().
|
||||
// This class is used in the Range() function.
|
||||
template <typename T, typename IncrementT>
|
||||
class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
class [[nodiscard]] RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
public:
|
||||
RangeGenerator(T begin, T end, IncrementT step)
|
||||
: begin_(begin),
|
||||
@@ -294,7 +296,8 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
// since the source can be located on the stack, and the generator
|
||||
// is likely to persist beyond that stack frame.
|
||||
template <typename T>
|
||||
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||
class [[nodiscard]] ValuesInIteratorRangeGenerator
|
||||
: public ParamGeneratorInterface<T> {
|
||||
public:
|
||||
template <typename ForwardIterator>
|
||||
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
||||
@@ -379,9 +382,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||
// integer test parameter index.
|
||||
template <class ParamType>
|
||||
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
||||
Message name_stream;
|
||||
name_stream << info.index;
|
||||
return name_stream.GetString();
|
||||
return std::to_string(info.index);
|
||||
}
|
||||
|
||||
template <typename T = int>
|
||||
@@ -396,7 +397,7 @@ void TestNotEmpty(const T&) {}
|
||||
// Stores a parameter value and later creates tests parameterized with that
|
||||
// value.
|
||||
template <class TestClass>
|
||||
class ParameterizedTestFactory : public TestFactoryBase {
|
||||
class [[nodiscard]] ParameterizedTestFactory : public TestFactoryBase {
|
||||
public:
|
||||
typedef typename TestClass::ParamType ParamType;
|
||||
explicit ParameterizedTestFactory(ParamType parameter)
|
||||
@@ -418,7 +419,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
|
||||
// TestMetaFactoryBase is a base class for meta-factories that create
|
||||
// test factories for passing into MakeAndRegisterTestInfo function.
|
||||
template <class ParamType>
|
||||
class TestMetaFactoryBase {
|
||||
class [[nodiscard]] TestMetaFactoryBase {
|
||||
public:
|
||||
virtual ~TestMetaFactoryBase() = default;
|
||||
|
||||
@@ -434,7 +435,7 @@ class TestMetaFactoryBase {
|
||||
// it for each Test/Parameter value combination. Thus it needs meta factory
|
||||
// creator class.
|
||||
template <class TestSuite>
|
||||
class TestMetaFactory
|
||||
class [[nodiscard]] TestMetaFactory
|
||||
: public TestMetaFactoryBase<typename TestSuite::ParamType> {
|
||||
public:
|
||||
using ParamType = typename TestSuite::ParamType;
|
||||
@@ -460,7 +461,7 @@ class TestMetaFactory
|
||||
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
|
||||
// a collection of pointers to the ParameterizedTestSuiteInfo objects
|
||||
// and calls RegisterTests() on each of them when asked.
|
||||
class ParameterizedTestSuiteInfoBase {
|
||||
class [[nodiscard]] ParameterizedTestSuiteInfoBase {
|
||||
public:
|
||||
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
|
||||
// generators when asked.
|
||||
template <class TestSuite>
|
||||
class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
class [[nodiscard]] ParameterizedTestSuiteInfo
|
||||
: public ParameterizedTestSuiteInfoBase {
|
||||
public:
|
||||
// ParamType and GeneratorCreationFunc are private types but are required
|
||||
// for declarations of public methods AddTestPattern() and
|
||||
@@ -513,9 +515,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
||||
|
||||
explicit ParameterizedTestSuiteInfo(const char* name,
|
||||
explicit ParameterizedTestSuiteInfo(std::string name,
|
||||
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.
|
||||
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
|
||||
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||
// 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,
|
||||
CodeLocation code_location) {
|
||||
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
|
||||
test_suite_name, test_base_name, meta_factory, code_location)));
|
||||
tests_.emplace_back(
|
||||
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
|
||||
}
|
||||
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
||||
// about a generator.
|
||||
int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
||||
int AddTestSuiteInstantiation(std::string instantiation_name,
|
||||
GeneratorCreationFunc* func,
|
||||
ParamNameGeneratorFunc* name_func,
|
||||
const char* file, int line) {
|
||||
instantiations_.push_back(
|
||||
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
||||
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
|
||||
file, line);
|
||||
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
|
||||
@@ -553,60 +556,61 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
void RegisterTests() override {
|
||||
bool generated_instantiations = false;
|
||||
|
||||
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
||||
test_it != tests_.end(); ++test_it) {
|
||||
std::shared_ptr<TestInfo> test_info = *test_it;
|
||||
for (typename InstantiationContainer::iterator gen_it =
|
||||
instantiations_.begin();
|
||||
gen_it != instantiations_.end(); ++gen_it) {
|
||||
const std::string& instantiation_name = gen_it->name;
|
||||
ParamGenerator<ParamType> generator((*gen_it->generator)());
|
||||
ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
||||
const char* file = gen_it->file;
|
||||
int line = gen_it->line;
|
||||
std::string test_suite_name;
|
||||
std::string test_name;
|
||||
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
|
||||
for (const InstantiationInfo& instantiation : instantiations_) {
|
||||
const std::string& instantiation_name = instantiation.name;
|
||||
ParamGenerator<ParamType> generator((*instantiation.generator)());
|
||||
ParamNameGeneratorFunc* name_func = instantiation.name_func;
|
||||
const char* file = instantiation.file;
|
||||
int line = instantiation.line;
|
||||
|
||||
std::string test_suite_name;
|
||||
if (!instantiation_name.empty())
|
||||
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;
|
||||
std::set<std::string> test_param_names;
|
||||
for (typename ParamGenerator<ParamType>::iterator param_it =
|
||||
generator.begin();
|
||||
param_it != generator.end(); ++param_it, ++i) {
|
||||
for (const auto& param : generator) {
|
||||
generated_instantiations = true;
|
||||
|
||||
Message test_name_stream;
|
||||
test_name.clear();
|
||||
|
||||
std::string param_name =
|
||||
name_func(TestParamInfo<ParamType>(*param_it, i));
|
||||
name_func(TestParamInfo<ParamType>(param, i));
|
||||
|
||||
GTEST_CHECK_(IsValidParamName(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)
|
||||
<< "Duplicate parameterized test name '" << param_name << "', in "
|
||||
<< file << " line " << line << std::endl;
|
||||
|
||||
test_param_names.insert(param_name);
|
||||
|
||||
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(
|
||||
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
|
||||
test_suite_name, test_name.c_str(),
|
||||
nullptr, // No type parameter.
|
||||
PrintToString(*param_it).c_str(), test_info->code_location,
|
||||
PrintToString(param).c_str(), test_info->code_location,
|
||||
GetTestSuiteTypeId(),
|
||||
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
||||
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
||||
} // for param_it
|
||||
} // for gen_it
|
||||
} // for test_it
|
||||
test_info->test_meta_factory->CreateTestFactory(param));
|
||||
++i;
|
||||
} // for param
|
||||
} // for instantiation
|
||||
} // for test_info
|
||||
|
||||
if (!generated_instantiations) {
|
||||
// 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
|
||||
// with TEST_P macro.
|
||||
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,
|
||||
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),
|
||||
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::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
|
||||
const CodeLocation code_location;
|
||||
@@ -637,11 +639,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
// <Instantiation name, Sequence generator creation function,
|
||||
// Name generator function, Source file, Source line>
|
||||
struct InstantiationInfo {
|
||||
InstantiationInfo(const std::string& name_in,
|
||||
GeneratorCreationFunc* generator_in,
|
||||
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
|
||||
ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
||||
int line_in)
|
||||
: name(name_in),
|
||||
: name(std::move(name_in)),
|
||||
generator(generator_in),
|
||||
name_func(name_func_in),
|
||||
file(file_in),
|
||||
@@ -689,7 +690,7 @@ using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
|
||||
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
|
||||
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
|
||||
// ParameterizedTestSuiteInfo descriptors.
|
||||
class ParameterizedTestSuiteRegistry {
|
||||
class [[nodiscard]] ParameterizedTestSuiteRegistry {
|
||||
public:
|
||||
ParameterizedTestSuiteRegistry() = default;
|
||||
~ParameterizedTestSuiteRegistry() {
|
||||
@@ -702,29 +703,32 @@ class ParameterizedTestSuiteRegistry {
|
||||
// tests and instantiations of a particular test suite.
|
||||
template <class TestSuite>
|
||||
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;
|
||||
for (auto& test_suite_info : test_suite_infos_) {
|
||||
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
||||
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||
// Complain about incorrect usage of Google Test facilities
|
||||
// and terminate the program since we cannot guaranty correct
|
||||
// test suite setup and tear-down in this case.
|
||||
ReportInvalidTestSuiteType(test_suite_name, code_location);
|
||||
posix::Abort();
|
||||
} else {
|
||||
// At this point we are sure that the object we found is of the same
|
||||
// type we are looking for, so we downcast it to that type
|
||||
// without further checks.
|
||||
typed_test_info = CheckedDowncastToActualType<
|
||||
ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
|
||||
}
|
||||
break;
|
||||
|
||||
auto item_it = suite_name_to_info_index_.find(test_suite_name);
|
||||
if (item_it != suite_name_to_info_index_.end()) {
|
||||
auto* test_suite_info = test_suite_infos_[item_it->second];
|
||||
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||
// Complain about incorrect usage of Google Test facilities
|
||||
// and terminate the program since we cannot guaranty correct
|
||||
// test suite setup and tear-down in this case.
|
||||
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
|
||||
posix::Abort();
|
||||
} else {
|
||||
// At this point we are sure that the object we found is of the same
|
||||
// type we are looking for, so we downcast it to that type
|
||||
// without further checks.
|
||||
typed_test_info =
|
||||
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
|
||||
test_suite_info);
|
||||
}
|
||||
}
|
||||
if (typed_test_info == nullptr) {
|
||||
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);
|
||||
}
|
||||
return typed_test_info;
|
||||
@@ -738,8 +742,9 @@ class ParameterizedTestSuiteRegistry {
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
template <class TestCase>
|
||||
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||
const char* test_case_name, CodeLocation code_location) {
|
||||
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
||||
std::string test_case_name, CodeLocation code_location) {
|
||||
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
|
||||
std::move(code_location));
|
||||
}
|
||||
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
@@ -748,6 +753,7 @@ class ParameterizedTestSuiteRegistry {
|
||||
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
||||
|
||||
TestSuiteInfoContainer test_suite_infos_;
|
||||
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
|
||||
|
||||
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
||||
delete;
|
||||
@@ -758,7 +764,7 @@ class ParameterizedTestSuiteRegistry {
|
||||
// Keep track of what type-parameterized test suite are defined and
|
||||
// where as well as which are intatiated. This allows susequently
|
||||
// identifying suits that are defined but never used.
|
||||
class TypeParameterizedTestSuiteRegistry {
|
||||
class [[nodiscard]] TypeParameterizedTestSuiteRegistry {
|
||||
public:
|
||||
// Add a suite definition
|
||||
void RegisterTestSuite(const char* test_suite_name,
|
||||
@@ -774,7 +780,7 @@ class TypeParameterizedTestSuiteRegistry {
|
||||
private:
|
||||
struct TypeParameterizedTestSuiteInfo {
|
||||
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
||||
: code_location(c), instantiated(false) {}
|
||||
: code_location(std::move(c)), instantiated(false) {}
|
||||
|
||||
CodeLocation code_location;
|
||||
bool instantiated;
|
||||
@@ -797,18 +803,18 @@ namespace internal {
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
template <typename... Ts>
|
||||
class ValueArray {
|
||||
class [[nodiscard]] ValueArray {
|
||||
public:
|
||||
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { // NOLINT
|
||||
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
|
||||
return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
|
||||
}
|
||||
|
||||
private:
|
||||
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>())...};
|
||||
}
|
||||
|
||||
@@ -818,7 +824,7 @@ class ValueArray {
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
template <typename... T>
|
||||
class CartesianProductGenerator
|
||||
class [[nodiscard]] CartesianProductGenerator
|
||||
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
||||
public:
|
||||
typedef ::std::tuple<T...> ParamType;
|
||||
@@ -838,7 +844,7 @@ class CartesianProductGenerator
|
||||
template <class I>
|
||||
class IteratorImpl;
|
||||
template <size_t... I>
|
||||
class IteratorImpl<IndexSequence<I...>>
|
||||
class IteratorImpl<std::index_sequence<I...>>
|
||||
: public ParamIteratorInterface<ParamType> {
|
||||
public:
|
||||
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
||||
@@ -929,13 +935,13 @@ class CartesianProductGenerator
|
||||
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_;
|
||||
};
|
||||
|
||||
template <class... Gen>
|
||||
class CartesianProductHolder {
|
||||
class [[nodiscard]] CartesianProductHolder {
|
||||
public:
|
||||
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
|
||||
template <typename... T>
|
||||
@@ -948,11 +954,12 @@ class CartesianProductHolder {
|
||||
std::tuple<Gen...> generators_;
|
||||
};
|
||||
|
||||
template <typename From, typename To>
|
||||
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
template <typename From, typename To, typename Func>
|
||||
class [[nodiscard]] ParamGeneratorConverter
|
||||
: public ParamGeneratorInterface<To> {
|
||||
public:
|
||||
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
|
||||
: generator_(std::move(gen)) {}
|
||||
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
|
||||
: generator_(std::move(gen)), converter_(std::move(converter)) {}
|
||||
|
||||
ParamIteratorInterface<To>* Begin() const override {
|
||||
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());
|
||||
}
|
||||
|
||||
// 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:
|
||||
class Iterator : public ParamIteratorInterface<To> {
|
||||
public:
|
||||
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
|
||||
Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
|
||||
ParamIterator<From> 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;
|
||||
|
||||
@@ -976,7 +991,9 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
}
|
||||
void Advance() override {
|
||||
++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 {
|
||||
return new Iterator(*this);
|
||||
@@ -996,30 +1013,54 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
private:
|
||||
Iterator(const Iterator& other) = default;
|
||||
|
||||
const ParamGeneratorInterface<To>* const base_;
|
||||
const ParamGeneratorConverter* const base_;
|
||||
ParamIterator<From> it_;
|
||||
ParamIterator<From> end_;
|
||||
std::shared_ptr<To> value_;
|
||||
}; // class ParamGeneratorConverter::Iterator
|
||||
|
||||
ParamGenerator<From> generator_;
|
||||
Func converter_;
|
||||
}; // class ParamGeneratorConverter
|
||||
|
||||
template <class Gen>
|
||||
class ParamConverterGenerator {
|
||||
template <class GeneratedT,
|
||||
typename StdFunction =
|
||||
std::function<const GeneratedT&(const GeneratedT&)>>
|
||||
class [[nodiscard]] ParamConverterGenerator {
|
||||
public:
|
||||
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
|
||||
: generator_(std::move(g)) {}
|
||||
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
|
||||
: generator_(std::move(g)), converter_(Identity) {}
|
||||
|
||||
ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
|
||||
: generator_(std::move(g)), converter_(std::move(converter)) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { // NOLINT
|
||||
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
|
||||
return ParamGenerator<T>(
|
||||
new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
|
||||
converter_));
|
||||
}
|
||||
|
||||
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 testing
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
||||
#define GTEST_OS_WINDOWS_PHONE 1
|
||||
#define GTEST_OS_WINDOWS_TV_TITLE 1
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
|
||||
#define GTEST_OS_WINDOWS_GAMES 1
|
||||
#else
|
||||
// WINAPI_FAMILY defined but no known partition matched.
|
||||
// Default to desktop.
|
||||
@@ -117,6 +119,8 @@
|
||||
#define GTEST_OS_NXP_QN9090 1
|
||||
#elif defined(NRF52)
|
||||
#define GTEST_OS_NRF52 1
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#define GTEST_OS_EMSCRIPTEN 1
|
||||
#endif // __CYGWIN__
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||
|
||||
@@ -194,26 +194,12 @@
|
||||
//
|
||||
// Macros for basic C++ coding:
|
||||
// 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
|
||||
// suppressed (constant conditional).
|
||||
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
||||
// is suppressed.
|
||||
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
|
||||
// UniversalPrinter<absl::any> specializations.
|
||||
// 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_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
|
||||
// specializations. 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_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
|
||||
@@ -260,11 +246,6 @@
|
||||
// BoolFromGTestEnv() - parses a bool environment variable.
|
||||
// Int32FromGTestEnv() - parses an int32_t 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
|
||||
// potentially be used as an #include guard.
|
||||
@@ -275,8 +256,28 @@
|
||||
#endif
|
||||
|
||||
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L
|
||||
#error C++ versions less than C++14 are not supported.
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
|
||||
#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
|
||||
|
||||
#include <ctype.h> // for isspace, etc
|
||||
@@ -320,7 +321,8 @@
|
||||
#define GTEST_HAS_NOTIFICATION_ 0
|
||||
#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/flag.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_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
|
||||
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
|
||||
#else
|
||||
#define GTEST_HAS_PTHREAD 0
|
||||
@@ -609,7 +612,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
// Determines whether clone(2) is supported.
|
||||
// Usually it will only be available on Linux, excluding
|
||||
// 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
|
||||
// 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
|
||||
// a file system, stream redirection is not supported.
|
||||
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
|
||||
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \
|
||||
defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \
|
||||
!GTEST_HAS_FILE_SYSTEM
|
||||
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \
|
||||
defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
|
||||
defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM
|
||||
#define GTEST_HAS_STREAM_REDIRECTION 0
|
||||
#else
|
||||
#define GTEST_HAS_STREAM_REDIRECTION 1
|
||||
@@ -652,7 +655,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
// Determines whether to support death tests.
|
||||
// pops up a dialog window that cannot be suppressed programmatically.
|
||||
#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_WINDOWS_DESKTOP) && _MSC_VER) || \
|
||||
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_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
|
||||
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))
|
||||
|
||||
// Death tests require a file system to work properly.
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
#define GTEST_HAS_DEATH_TEST 1
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
#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.
|
||||
|
||||
// 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
|
||||
#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_
|
||||
//
|
||||
// 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
|
||||
#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.
|
||||
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
||||
// 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)
|
||||
#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
|
||||
// constant. In some contexts this warning is false positive and needs to be
|
||||
// suppressed. Use the following two macros in such cases:
|
||||
@@ -827,11 +832,13 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#ifndef GTEST_API_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if GTEST_LINKED_AS_SHARED_LIBRARY
|
||||
#define GTEST_API_ __declspec(dllimport)
|
||||
#elif GTEST_CREATE_SHARED_LIBRARY
|
||||
#if defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
|
||||
#define GTEST_API_ __declspec(dllexport)
|
||||
#elif defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
|
||||
#define GTEST_API_ __declspec(dllimport)
|
||||
#endif
|
||||
#elif GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(gnu::visibility)
|
||||
#define GTEST_API_ [[gnu::visibility("default")]]
|
||||
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
|
||||
#define GTEST_API_ __attribute__((visibility("default")))
|
||||
#endif // _MSC_VER
|
||||
@@ -922,7 +929,7 @@ namespace internal {
|
||||
// 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
|
||||
// Secret object, which is what we want.
|
||||
class Secret {
|
||||
class [[nodiscard]] Secret {
|
||||
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
|
||||
// needs to disambiguate the `std::string`, `absl::string_view`, and `const
|
||||
// char*` constructors.
|
||||
class GTEST_API_ RE {
|
||||
class GTEST_API_ [[nodiscard]] RE {
|
||||
public:
|
||||
RE(absl::string_view regex) : regex_(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
|
||||
// Regular Expression syntax.
|
||||
class GTEST_API_ RE {
|
||||
class GTEST_API_ [[nodiscard]] RE {
|
||||
public:
|
||||
// A copy constructor is required by the Standard to initialize object
|
||||
// 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
|
||||
// log message, and terminates the message with a newline when going out of
|
||||
// scope.
|
||||
class GTEST_API_ GTestLog {
|
||||
class GTEST_API_ [[nodiscard]] GTestLog {
|
||||
public:
|
||||
GTestLog(GTestLogSeverity severity, const char* file, int line);
|
||||
|
||||
@@ -1195,7 +1202,7 @@ void ClearInjectableArgvs();
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Provides leak-safe Windows kernel handle ownership.
|
||||
// Used in death tests and in threading support.
|
||||
class GTEST_API_ AutoHandle {
|
||||
class GTEST_API_ [[nodiscard]] AutoHandle {
|
||||
public:
|
||||
// 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
|
||||
@@ -1229,9 +1236,6 @@ class GTEST_API_ AutoHandle {
|
||||
// Nothing to do here.
|
||||
|
||||
#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
|
||||
// threads until notified. Instances of this class must be created
|
||||
// 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
|
||||
// use it in user tests, either directly or indirectly.
|
||||
// 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:
|
||||
Notification() : notified_(false) {}
|
||||
Notification(const Notification&) = delete;
|
||||
@@ -1266,6 +1303,7 @@ class GTEST_API_ Notification {
|
||||
bool notified_;
|
||||
};
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
#endif // GTEST_OS_WINDOWS_MINGW
|
||||
#endif // GTEST_HAS_NOTIFICATION_
|
||||
|
||||
// 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
|
||||
// non-templated base class for ThreadWithParam allows us to bypass this
|
||||
// problem.
|
||||
class ThreadWithParamBase {
|
||||
class [[nodiscard]] ThreadWithParamBase {
|
||||
public:
|
||||
virtual ~ThreadWithParamBase() = default;
|
||||
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
|
||||
// not use them in user tests, either directly or indirectly.
|
||||
template <typename T>
|
||||
class ThreadWithParam : public ThreadWithParamBase {
|
||||
class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
|
||||
public:
|
||||
typedef void UserThreadFunc(T);
|
||||
|
||||
@@ -1374,7 +1412,7 @@ class ThreadWithParam : public ThreadWithParamBase {
|
||||
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
||||
//
|
||||
// (A non-static Mutex is defined/declared in the usual way).
|
||||
class GTEST_API_ Mutex {
|
||||
class GTEST_API_ [[nodiscard]] Mutex {
|
||||
public:
|
||||
enum MutexType { kStatic = 0, kDynamic = 1 };
|
||||
// We rely on kStaticMutex being 0 as it is to what the linker initializes
|
||||
@@ -1390,9 +1428,9 @@ class GTEST_API_ Mutex {
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void Lock();
|
||||
void lock();
|
||||
|
||||
void Unlock();
|
||||
void unlock();
|
||||
|
||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
||||
// with high probability.
|
||||
@@ -1427,14 +1465,13 @@ class GTEST_API_ Mutex {
|
||||
// platforms. That macro is used as a defensive measure to prevent against
|
||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
class [[nodiscard]] GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
||||
|
||||
~GTestMutexLock() { mutex_->Unlock(); }
|
||||
explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||
~GTestMutexLock() { mutex_.unlock(); }
|
||||
|
||||
private:
|
||||
Mutex* const mutex_;
|
||||
Mutex& mutex_;
|
||||
|
||||
GTestMutexLock(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
|
||||
// without knowing its type.
|
||||
class ThreadLocalValueHolderBase {
|
||||
class [[nodiscard]] ThreadLocalValueHolderBase {
|
||||
public:
|
||||
virtual ~ThreadLocalValueHolderBase() {}
|
||||
virtual ~ThreadLocalValueHolderBase() = default;
|
||||
};
|
||||
|
||||
// Provides a way for a thread to send notifications to a ThreadLocal
|
||||
// regardless of its parameter type.
|
||||
class ThreadLocalBase {
|
||||
class [[nodiscard]] ThreadLocalBase {
|
||||
public:
|
||||
// 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
|
||||
@@ -1460,8 +1497,8 @@ class ThreadLocalBase {
|
||||
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
|
||||
|
||||
protected:
|
||||
ThreadLocalBase() {}
|
||||
virtual ~ThreadLocalBase() {}
|
||||
ThreadLocalBase() = default;
|
||||
virtual ~ThreadLocalBase() = default;
|
||||
|
||||
private:
|
||||
ThreadLocalBase(const ThreadLocalBase&) = delete;
|
||||
@@ -1471,7 +1508,7 @@ class ThreadLocalBase {
|
||||
// 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
|
||||
// expected to persist until all threads it has values on have terminated.
|
||||
class GTEST_API_ ThreadLocalRegistry {
|
||||
class GTEST_API_ [[nodiscard]] ThreadLocalRegistry {
|
||||
public:
|
||||
// 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.
|
||||
@@ -1483,14 +1520,14 @@ class GTEST_API_ ThreadLocalRegistry {
|
||||
const ThreadLocalBase* thread_local_instance);
|
||||
};
|
||||
|
||||
class GTEST_API_ ThreadWithParamBase {
|
||||
class GTEST_API_ [[nodiscard]] ThreadWithParamBase {
|
||||
public:
|
||||
void Join();
|
||||
|
||||
protected:
|
||||
class Runnable {
|
||||
public:
|
||||
virtual ~Runnable() {}
|
||||
virtual ~Runnable() = default;
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
@@ -1503,20 +1540,20 @@ class GTEST_API_ ThreadWithParamBase {
|
||||
|
||||
// Helper class for testing Google Test's multi-threading constructs.
|
||||
template <typename T>
|
||||
class ThreadWithParam : public ThreadWithParamBase {
|
||||
class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
|
||||
public:
|
||||
typedef void UserThreadFunc(T);
|
||||
|
||||
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
||||
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
|
||||
virtual ~ThreadWithParam() {}
|
||||
~ThreadWithParam() override = default;
|
||||
|
||||
private:
|
||||
class RunnableImpl : public Runnable {
|
||||
public:
|
||||
RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
|
||||
virtual ~RunnableImpl() {}
|
||||
virtual void Run() { func_(param_); }
|
||||
~RunnableImpl() override = default;
|
||||
void Run() override { func_(param_); }
|
||||
|
||||
private:
|
||||
UserThreadFunc* const func_;
|
||||
@@ -1558,7 +1595,7 @@ class ThreadWithParam : public ThreadWithParamBase {
|
||||
// object managed by Google Test will be leaked as long as all threads
|
||||
// using Google Test have exited when main() returns.
|
||||
template <typename T>
|
||||
class ThreadLocal : public ThreadLocalBase {
|
||||
class [[nodiscard]] ThreadLocal : public ThreadLocalBase {
|
||||
public:
|
||||
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
|
||||
explicit ThreadLocal(const T& value)
|
||||
@@ -1599,8 +1636,8 @@ class ThreadLocal : public ThreadLocalBase {
|
||||
|
||||
class ValueHolderFactory {
|
||||
public:
|
||||
ValueHolderFactory() {}
|
||||
virtual ~ValueHolderFactory() {}
|
||||
ValueHolderFactory() = default;
|
||||
virtual ~ValueHolderFactory() = default;
|
||||
virtual ValueHolder* MakeNewHolder() const = 0;
|
||||
|
||||
private:
|
||||
@@ -1610,7 +1647,7 @@ class ThreadLocal : public ThreadLocalBase {
|
||||
|
||||
class DefaultValueHolderFactory : public ValueHolderFactory {
|
||||
public:
|
||||
DefaultValueHolderFactory() {}
|
||||
DefaultValueHolderFactory() = default;
|
||||
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
|
||||
|
||||
private:
|
||||
@@ -1643,17 +1680,17 @@ class ThreadLocal : public ThreadLocalBase {
|
||||
#elif GTEST_HAS_PTHREAD
|
||||
|
||||
// MutexBase and Mutex implement mutex on pthreads-based platforms.
|
||||
class MutexBase {
|
||||
class [[nodiscard]] MutexBase {
|
||||
public:
|
||||
// Acquires this mutex.
|
||||
void Lock() {
|
||||
void lock() {
|
||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
||||
owner_ = pthread_self();
|
||||
has_owner_ = true;
|
||||
}
|
||||
|
||||
// Releases this mutex.
|
||||
void Unlock() {
|
||||
void unlock() {
|
||||
// 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
|
||||
// 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
|
||||
// shares its API with MutexBase otherwise.
|
||||
class Mutex : public MutexBase {
|
||||
class [[nodiscard]] Mutex : public MutexBase {
|
||||
public:
|
||||
Mutex() {
|
||||
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
|
||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
class [[nodiscard]] GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
||||
|
||||
~GTestMutexLock() { mutex_->Unlock(); }
|
||||
explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||
~GTestMutexLock() { mutex_.unlock(); }
|
||||
|
||||
private:
|
||||
MutexBase* const mutex_;
|
||||
MutexBase& mutex_;
|
||||
|
||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||
@@ -1740,7 +1776,7 @@ typedef GTestMutexLock MutexLock;
|
||||
// C-linkage. Therefore it cannot be templatized to access
|
||||
// ThreadLocal<T>. Hence the need for class
|
||||
// ThreadLocalValueHolderBase.
|
||||
class GTEST_API_ ThreadLocalValueHolderBase {
|
||||
class GTEST_API_ [[nodiscard]] ThreadLocalValueHolderBase {
|
||||
public:
|
||||
virtual ~ThreadLocalValueHolderBase() = default;
|
||||
};
|
||||
@@ -1753,7 +1789,7 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
|
||||
|
||||
// Implements thread-local storage on pthreads-based systems.
|
||||
template <typename T>
|
||||
class GTEST_API_ ThreadLocal {
|
||||
class GTEST_API_ [[nodiscard]] ThreadLocal {
|
||||
public:
|
||||
ThreadLocal()
|
||||
: 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
|
||||
// supported on such platforms.
|
||||
|
||||
class Mutex {
|
||||
class [[nodiscard]] Mutex {
|
||||
public:
|
||||
Mutex() {}
|
||||
void Lock() {}
|
||||
void Unlock() {}
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
void AssertHeld() const {}
|
||||
};
|
||||
|
||||
@@ -1884,15 +1920,15 @@ class Mutex {
|
||||
// platforms. That macro is used as a defensive measure to prevent against
|
||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
class [[nodiscard]] GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
||||
explicit GTestMutexLock(Mutex&) {} // NOLINT
|
||||
};
|
||||
|
||||
typedef GTestMutexLock MutexLock;
|
||||
|
||||
template <typename T>
|
||||
class GTEST_API_ ThreadLocal {
|
||||
class GTEST_API_ [[nodiscard]] ThreadLocal {
|
||||
public:
|
||||
ThreadLocal() : value_() {}
|
||||
explicit ThreadLocal(const T& value) : value_(value) {}
|
||||
@@ -1987,7 +2023,9 @@ inline std::string StripTrailingSpaces(std::string str) {
|
||||
namespace posix {
|
||||
|
||||
// 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
|
||||
|
||||
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.
|
||||
#else
|
||||
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 RmDir(const char* dir) { return _rmdir(dir); }
|
||||
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
|
||||
#endif
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
#elif defined(GTEST_OS_ESP8266)
|
||||
typedef struct stat StatStruct;
|
||||
|
||||
inline int FileNo(FILE* file) { return fileno(file); }
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
inline int Stat(const char* path, StatStruct* buf) {
|
||||
// stat function not implemented on ESP8266
|
||||
return 0;
|
||||
}
|
||||
inline int RmDir(const char* dir) { return rmdir(dir); }
|
||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
typedef struct stat StatStruct;
|
||||
|
||||
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); }
|
||||
#ifdef GTEST_OS_QURT
|
||||
// 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); }
|
||||
#endif
|
||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||
#endif
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
|
||||
// Other functions with a different name on Windows.
|
||||
|
||||
@@ -2082,8 +2125,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
|
||||
// defined there.
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
|
||||
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \
|
||||
!defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT)
|
||||
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \
|
||||
!defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \
|
||||
!defined(GTEST_OS_QURT)
|
||||
inline int ChDir(const char* dir) { return chdir(dir); }
|
||||
#endif
|
||||
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
|
||||
// arises.
|
||||
template <size_t size>
|
||||
class TypeWithSize {
|
||||
class [[nodiscard]] TypeWithSize {
|
||||
public:
|
||||
// This prevents the user from using TypeWithSize<N> with incorrect
|
||||
// values of N.
|
||||
@@ -2201,7 +2245,7 @@ class TypeWithSize {
|
||||
|
||||
// The specialization for size 4.
|
||||
template <>
|
||||
class TypeWithSize<4> {
|
||||
class [[nodiscard]] TypeWithSize<4> {
|
||||
public:
|
||||
using Int = std::int32_t;
|
||||
using UInt = std::uint32_t;
|
||||
@@ -2209,7 +2253,7 @@ class TypeWithSize<4> {
|
||||
|
||||
// The specialization for size 8.
|
||||
template <>
|
||||
class TypeWithSize<8> {
|
||||
class [[nodiscard]] TypeWithSize<8> {
|
||||
public:
|
||||
using Int = std::int64_t;
|
||||
using UInt = std::uint64_t;
|
||||
@@ -2227,7 +2271,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
||||
#endif // !defined(GTEST_FLAG)
|
||||
|
||||
// Pick a command line flags implementation.
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||
@@ -2239,11 +2283,11 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
||||
|
||||
// Macros for declaring flags.
|
||||
#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) \
|
||||
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) \
|
||||
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
|
||||
|
||||
@@ -2252,7 +2296,8 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
||||
(void)(::absl::SetFlag(>EST_FLAG(name), value))
|
||||
#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.
|
||||
#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_USE_OWN_FLAGFILE_FLAG_ 1
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#endif // GTEST_INTERNAL_HAS_ABSL_FLAGS
|
||||
|
||||
// Thread annotations
|
||||
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
||||
@@ -2318,93 +2363,20 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#if !defined(GTEST_INTERNAL_DEPRECATED)
|
||||
|
||||
// Internal Macro to mark an API deprecated, for googletest usage only
|
||||
// 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)))
|
||||
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate)
|
||||
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \
|
||||
[[deprecated(msg), clang::annotate("inline-me")]]
|
||||
#else
|
||||
#define GTEST_INTERNAL_DEPRECATED(message)
|
||||
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]]
|
||||
#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
|
||||
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
||||
// 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
|
||||
#ifndef GTEST_INTERNAL_HAS_STD_SPAN
|
||||
#define GTEST_INTERNAL_HAS_STD_SPAN 0
|
||||
#endif
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
@@ -2418,8 +2390,9 @@ using StringView = ::absl::string_view;
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
#else
|
||||
#ifdef __has_include
|
||||
#if __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
#if defined(__cpp_lib_string_view) || \
|
||||
(GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
|
||||
// Otherwise for C++17 and higher use std::string_view for Matcher<>
|
||||
// specializations.
|
||||
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
|
||||
@@ -2431,51 +2404,19 @@ using StringView = ::std::string_view;
|
||||
} // namespace testing
|
||||
// The case where absl is configured NOT to alias std::string_view is not
|
||||
// supported.
|
||||
#endif // __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >=
|
||||
// 201703L
|
||||
#endif // __has_include
|
||||
#endif // __cpp_lib_string_view
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
|
||||
#endif
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
// Always use absl::variant for UniversalPrinter<> specializations if googletest
|
||||
// is built with absl support.
|
||||
#define GTEST_INTERNAL_HAS_VARIANT 1
|
||||
#include "absl/types/variant.h"
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
template <typename... T>
|
||||
using Variant = ::absl::variant<T...>;
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
#if (defined(__cpp_lib_three_way_comparison) || \
|
||||
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
||||
#define GTEST_INTERNAL_HAS_COMPARE_LIB 1
|
||||
#else
|
||||
#ifdef __has_include
|
||||
#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
|
||||
#define GTEST_INTERNAL_HAS_COMPARE_LIB 0
|
||||
#endif
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// String - an abstract class holding static string utilities.
|
||||
class GTEST_API_ String {
|
||||
class GTEST_API_ [[nodiscard]] String {
|
||||
public:
|
||||
// Static utility methods
|
||||
|
||||
@@ -166,7 +166,7 @@ class GTEST_API_ String {
|
||||
|
||||
private:
|
||||
String(); // Not meant to be instantiated.
|
||||
}; // class String
|
||||
}; // class String
|
||||
|
||||
// Gets the content of the stringstream's buffer as an std::string. Each '\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
|
||||
// For example, std::pair<int, bool> -> std::pair<int,bool>
|
||||
static const char to_search[] = ", ";
|
||||
static const char replace_str[] = ",";
|
||||
const char replace_char = ',';
|
||||
size_t pos = 0;
|
||||
while (true) {
|
||||
// Get the next occurrence from the current position
|
||||
@@ -80,8 +80,8 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
||||
break;
|
||||
}
|
||||
// Replace this occurrence of substring
|
||||
s.replace(pos, strlen(to_search), replace_str);
|
||||
pos += strlen(replace_str);
|
||||
s.replace(pos, strlen(to_search), 1, replace_char);
|
||||
++pos;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
: min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {
|
||||
std::stringstream ss;
|
||||
if (min < 0) {
|
||||
ss << "The invocation lower bound must be >= 0, "
|
||||
<< "but is actually " << min << ".";
|
||||
ss << "The invocation lower bound must be >= 0, " << "but is actually "
|
||||
<< min << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (max < 0) {
|
||||
ss << "The invocation upper bound must be >= 0, "
|
||||
<< "but is actually " << max << ".";
|
||||
ss << "The invocation upper bound must be >= 0, " << "but is actually "
|
||||
<< max << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (min > max) {
|
||||
ss << "The invocation upper bound (" << max
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <iostream>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
@@ -155,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
if (!LogIsVisible(severity)) return;
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
MutexLock l(g_log_mutex);
|
||||
|
||||
if (severity == kWarning) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
|
||||
GTEST_API_ WithoutMatchers WithoutMatchers::Get() { return WithoutMatchers(); }
|
||||
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
||||
internal::Assert(
|
||||
@@ -211,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
||||
}
|
||||
|
||||
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) {
|
||||
return {
|
||||
{UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
|
||||
}
|
||||
|
||||
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[] =
|
||||
|
||||
@@ -120,7 +120,7 @@ GTEST_API_ std::string FormatMatcherDescription(
|
||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
|
||||
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
|
||||
// [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 {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
@@ -236,9 +236,8 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
os << "{";
|
||||
const char* sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
<< "matcher #" << it->second << ")";
|
||||
os << sep << "\n (" << "element #" << it->first << ", " << "matcher #"
|
||||
<< it->second << ")";
|
||||
sep = ",";
|
||||
}
|
||||
os << "\n}";
|
||||
@@ -374,20 +373,20 @@ bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
if (matrix.LhsSize() != matrix.RhsSize()) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||
*listener << "which has " << Elements(matrix.LhsSize());
|
||||
}
|
||||
return false;
|
||||
const bool is_exact_match_with_size_discrepency =
|
||||
match_flags() == UnorderedMatcherRequire::ExactMatch &&
|
||||
matrix.LhsSize() != matrix.RhsSize();
|
||||
if (is_exact_match_with_size_discrepency) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||
*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> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
MutexLock l(mutex_);
|
||||
if (!action_count_checked_) {
|
||||
action_count_checked_ = true;
|
||||
should_check = true;
|
||||
@@ -293,7 +293,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||
Log(kWarning,
|
||||
msg +
|
||||
"\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. "
|
||||
"See "
|
||||
"https://github.com/google/googletest/blob/main/docs/"
|
||||
@@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
}
|
||||
Mock::Register(mock_obj, this);
|
||||
@@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// We protect name_ under g_gmock_mutex in case this mock function
|
||||
// is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
name_ = name;
|
||||
}
|
||||
@@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
|
||||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
||||
"MockObject() must not be called before RegisterOwner() or "
|
||||
"SetOwnerAndName() has been called.");
|
||||
@@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
|
||||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
Assert(name_ != nullptr, __FILE__, __LINE__,
|
||||
"Name() must not be called before SetOwnerAndName() has "
|
||||
"been called.");
|
||||
@@ -436,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
@@ -490,6 +490,7 @@ class MockObjectRegistry {
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
@@ -530,7 +531,7 @@ class MockObjectRegistry {
|
||||
#ifdef GTEST_OS_QURT
|
||||
qurt_exception_raise_fatal();
|
||||
#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.
|
||||
#endif
|
||||
}
|
||||
@@ -558,7 +559,7 @@ UninterestingCallReactionMap() {
|
||||
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
||||
internal::CallReaction reaction)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -589,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
|
||||
// entry in the call-reaction table should be removed.
|
||||
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -597,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
||||
// made on the given mock object.
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
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(
|
||||
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
||||
? internal::intToCallReaction(
|
||||
@@ -610,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
// objects.
|
||||
void Mock::AllowLeak(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);
|
||||
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.
|
||||
bool Mock::VerifyAndClearExpectations(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 VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
@@ -628,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
// verification was successful.
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
@@ -678,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -688,7 +689,7 @@ void Mock::Register(const void* mock_obj,
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||
const char* file, int line)
|
||||
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];
|
||||
if (state.first_used_file == nullptr) {
|
||||
state.first_used_file = file;
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#include "gtest/gtest-death-test.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
@@ -115,7 +117,7 @@ GTEST_DEFINE_string_(
|
||||
GTEST_DEFINE_bool_(
|
||||
death_test_use_fork,
|
||||
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 "
|
||||
"implemented. Useful when running under valgrind or similar tools 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);
|
||||
fprintf(parent, "%s", message.c_str());
|
||||
fflush(parent);
|
||||
_exit(1);
|
||||
_Exit(1);
|
||||
} else {
|
||||
fprintf(stderr, "%s", message.c_str());
|
||||
fflush(stderr);
|
||||
@@ -511,7 +513,7 @@ std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
|
||||
// Signals that the death test code which should have exited, didn't.
|
||||
// Should be called only in a death test child process.
|
||||
// Writes a status byte to the child's status file descriptor, then
|
||||
// calls _exit(1).
|
||||
// calls _Exit(1).
|
||||
void DeathTestImpl::Abort(AbortReason reason) {
|
||||
// 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
|
||||
@@ -523,13 +525,13 @@ void DeathTestImpl::Abort(AbortReason reason) {
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
|
||||
// We are leaking the descriptor here because on some platforms (i.e.,
|
||||
// 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
|
||||
// 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
|
||||
// relying on the OS to close the descriptor after the process terminates
|
||||
// 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.
|
||||
@@ -628,13 +630,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
|
||||
#ifndef GTEST_OS_WINDOWS
|
||||
// Note: The return value points into args, so the return value's lifetime is
|
||||
// bound to that of args.
|
||||
static std::unique_ptr<char*[]> CreateArgvFromArgs(
|
||||
std::vector<std::string>& args) {
|
||||
auto result = std::make_unique<char*[]>(args.size() + 1);
|
||||
for (size_t i = 0; i < args.size(); ++i) {
|
||||
result[i] = &args[i][0];
|
||||
static std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {
|
||||
std::vector<char*> result;
|
||||
result.reserve(args.size() + 1);
|
||||
for (auto& arg : args) {
|
||||
result.push_back(&arg[0]);
|
||||
}
|
||||
result[args.size()] = nullptr; // extra null terminator
|
||||
result.push_back(nullptr); // Extra null terminator.
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@@ -783,7 +785,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
||||
// size_t has the same width as pointers on both 32-bit and 64-bit
|
||||
// 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>(event_handle_.Get()));
|
||||
|
||||
@@ -1034,8 +1036,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
||||
// "Fuchsia Test Component" which contains a "Fuchsia Component Manifest")
|
||||
// Launching processes is a privileged operation in Fuchsia, and the
|
||||
// declaration indicates that the ability is required for the component.
|
||||
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
|
||||
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(),
|
||||
std::vector<char*> argv = CreateArgvFromArgs(args);
|
||||
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),
|
||||
nullptr, 2, spawn_actions,
|
||||
child_process_.reset_and_get_address(), nullptr);
|
||||
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
|
||||
|
||||
if (use_fork && (child_pid = fork()) == 0) {
|
||||
_exit(ExecDeathTestChildMain(&args));
|
||||
_Exit(ExecDeathTestChildMain(&args));
|
||||
}
|
||||
#endif // GTEST_OS_QNX
|
||||
#ifdef GTEST_OS_LINUX
|
||||
@@ -1386,8 +1388,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
||||
// is necessary.
|
||||
FlushInfoLog();
|
||||
|
||||
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
|
||||
const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]);
|
||||
std::vector<char*> argv = CreateArgvFromArgs(args);
|
||||
const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||
set_child_pid(child_pid);
|
||||
set_read_fd(pipe_fd[0]);
|
||||
|
||||
@@ -336,7 +336,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
||||
if (pathname_.empty() || this->DirectoryExists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#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.
|
||||
void WriteToShardStatusFileIfNeeded();
|
||||
|
||||
// Checks whether sharding is enabled by examining the relevant
|
||||
// environment variable values. If the variables are present,
|
||||
// but inconsistent (e.g., shard_index >= total_shards), prints
|
||||
// an error and exits. If in_subprocess_for_death_test, sharding is
|
||||
// Checks whether sharding is enabled by examining the relevant flag values.
|
||||
// If the flags are set, but inconsistent (e.g., shard_index >= total_shards),
|
||||
// prints an error and exits. If in_subprocess_for_death_test, sharding is
|
||||
// disabled because it must only be applied to the original test
|
||||
// process. Otherwise, we could filter out death tests we intended to execute.
|
||||
GTEST_API_ bool ShouldShard(const char* total_shards_str,
|
||||
const char* shard_index_str,
|
||||
bool in_subprocess_for_death_test);
|
||||
GTEST_API_ bool ShouldShard(bool in_subprocess_for_death_test);
|
||||
|
||||
// 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
|
||||
@@ -312,7 +310,7 @@ void ShuffleRange(internal::Random* random, int begin, int end,
|
||||
<< begin << ", " << size << "].";
|
||||
|
||||
// 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--) {
|
||||
const int last_in_range = begin + range_width - 1;
|
||||
const int selected =
|
||||
@@ -649,13 +647,15 @@ class GTEST_API_ UnitTestImpl {
|
||||
// this is not a typed or a type-parameterized test.
|
||||
// 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
|
||||
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::TearDownTestSuiteFunc tear_down_tc);
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#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::TearDownTestSuiteFunc 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
|
||||
// before main() is reached.
|
||||
if (original_working_dir_.IsEmpty()) {
|
||||
original_working_dir_.Set(FilePath::GetCurrentDir());
|
||||
original_working_dir_ = FilePath::GetCurrentDir();
|
||||
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
||||
<< "Failed to get the current working directory.";
|
||||
}
|
||||
#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)
|
||||
->AddTestInfo(test_info);
|
||||
}
|
||||
@@ -709,18 +709,6 @@ class GTEST_API_ UnitTestImpl {
|
||||
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
|
||||
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
|
||||
// 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_; }
|
||||
|
||||
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;
|
||||
|
||||
// Used by UnitTest::Run() to capture the state of
|
||||
// GTEST_FLAG(catch_exceptions) at the moment it starts.
|
||||
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.
|
||||
UnitTest* const parent_;
|
||||
|
||||
@@ -873,6 +883,9 @@ class GTEST_API_ UnitTestImpl {
|
||||
// elements in the vector.
|
||||
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
|
||||
// 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
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
#include "src/gtest-internal-inl.h"
|
||||
@@ -158,13 +159,13 @@ size_t GetThreadCount() {
|
||||
// we cannot detect it.
|
||||
size_t GetThreadCount() {
|
||||
int mib[] = {
|
||||
CTL_KERN,
|
||||
KERN_PROC,
|
||||
KERN_PROC_PID,
|
||||
getpid(),
|
||||
CTL_KERN,
|
||||
KERN_PROC,
|
||||
KERN_PROC_PID,
|
||||
getpid(),
|
||||
#ifdef GTEST_OS_NETBSD
|
||||
sizeof(struct kinfo_proc),
|
||||
1,
|
||||
sizeof(struct kinfo_proc),
|
||||
1,
|
||||
#endif
|
||||
};
|
||||
u_int miblen = sizeof(mib) / sizeof(mib[0]);
|
||||
@@ -302,6 +303,22 @@ bool AutoHandle::IsCloseable() const {
|
||||
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()
|
||||
: owner_thread_id_(0),
|
||||
type_(kDynamic),
|
||||
@@ -320,13 +337,13 @@ Mutex::~Mutex() {
|
||||
}
|
||||
}
|
||||
|
||||
void Mutex::Lock() {
|
||||
void Mutex::lock() {
|
||||
ThreadSafeLazyInit();
|
||||
::EnterCriticalSection(critical_section_);
|
||||
owner_thread_id_ = ::GetCurrentThreadId();
|
||||
}
|
||||
|
||||
void Mutex::Unlock() {
|
||||
void Mutex::unlock() {
|
||||
ThreadSafeLazyInit();
|
||||
// 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
|
||||
@@ -499,7 +516,7 @@ class ThreadLocalRegistryImpl {
|
||||
MemoryIsNotDeallocated memory_is_not_deallocated;
|
||||
#endif // _MSC_VER
|
||||
DWORD current_thread = ::GetCurrentThreadId();
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||
GetThreadLocalsMapLocked();
|
||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||
@@ -532,7 +549,7 @@ class ThreadLocalRegistryImpl {
|
||||
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
||||
// defer the destruction of the ThreadLocalValueHolderBases.
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||
GetThreadLocalsMapLocked();
|
||||
for (ThreadIdToThreadLocals::iterator it =
|
||||
@@ -559,7 +576,7 @@ class ThreadLocalRegistryImpl {
|
||||
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
||||
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||
GetThreadLocalsMapLocked();
|
||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||
@@ -587,9 +604,11 @@ class ThreadLocalRegistryImpl {
|
||||
// thread's ID.
|
||||
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
|
||||
|
||||
// Holds the thread id and thread handle that we pass from
|
||||
// StartWatcherThreadFor to WatcherThreadFunc.
|
||||
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
|
||||
struct WatcherThreadParams {
|
||||
DWORD thread_id;
|
||||
HANDLE handle;
|
||||
Notification has_initialized;
|
||||
};
|
||||
|
||||
static void StartWatcherThreadFor(DWORD thread_id) {
|
||||
// The returned handle will be kept in thread_map and closed by
|
||||
@@ -597,15 +616,20 @@ class ThreadLocalRegistryImpl {
|
||||
HANDLE thread =
|
||||
::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
|
||||
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
|
||||
// to work correctly under Win98.
|
||||
DWORD watcher_thread_id;
|
||||
HANDLE watcher_thread = ::CreateThread(
|
||||
nullptr, // Default security.
|
||||
0, // Default stack size
|
||||
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
||||
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
||||
CREATE_SUSPENDED, &watcher_thread_id);
|
||||
HANDLE watcher_thread =
|
||||
::CreateThread(nullptr, // Default security.
|
||||
0, // Default stack size
|
||||
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
||||
reinterpret_cast<LPVOID>(watcher_thread_params),
|
||||
CREATE_SUSPENDED, &watcher_thread_id);
|
||||
GTEST_CHECK_(watcher_thread != nullptr)
|
||||
<< "CreateThread failed with error " << ::GetLastError() << ".";
|
||||
// Give the watcher thread the same priority as ours to avoid being
|
||||
@@ -614,17 +638,25 @@ class ThreadLocalRegistryImpl {
|
||||
::GetThreadPriority(::GetCurrentThread()));
|
||||
::ResumeThread(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
|
||||
// ThreadIdToThreadLocals about thread termination.
|
||||
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
|
||||
const ThreadIdAndHandle* tah =
|
||||
reinterpret_cast<const ThreadIdAndHandle*>(param);
|
||||
GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
|
||||
OnThreadExit(tah->first);
|
||||
::CloseHandle(tah->second);
|
||||
delete tah;
|
||||
WatcherThreadParams* watcher_thread_params =
|
||||
reinterpret_cast<WatcherThreadParams*>(param);
|
||||
watcher_thread_params->has_initialized.Notify();
|
||||
GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle,
|
||||
INFINITE) == WAIT_OBJECT_0);
|
||||
OnThreadExit(watcher_thread_params->thread_id);
|
||||
::CloseHandle(watcher_thread_params->handle);
|
||||
delete watcher_thread_params;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -697,13 +729,24 @@ bool RE::PartialMatch(const char* str, const RE& re) {
|
||||
void RE::Init(const char* 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
|
||||
// full match.
|
||||
const size_t full_regex_len = strlen(regex) + 10;
|
||||
char* const full_pattern = new char[full_regex_len];
|
||||
|
||||
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
|
||||
// previous expression returns false. Otherwise partial_regex_ may
|
||||
// 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
|
||||
// versions of Cygwin) doesn't accept the empty string as a valid
|
||||
// regex. We change it to an equivalent form "()" to be safe.
|
||||
if (is_valid_) {
|
||||
if (!error) {
|
||||
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_)
|
||||
<< "Regular expression \"" << regex
|
||||
<< "\" is not a valid POSIX Extended regular expression.";
|
||||
is_valid_ = error == 0;
|
||||
EXPECT_EQ(error, 0) << "Regular expression \"" << regex
|
||||
<< "\" is not a valid POSIX Extended regular expression.";
|
||||
|
||||
delete[] full_pattern;
|
||||
}
|
||||
@@ -1022,11 +1065,21 @@ GTestLog::~GTestLog() {
|
||||
}
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STREAM_REDIRECTION
|
||||
|
||||
// Disable Microsoft deprecation warnings for POSIX functions called from
|
||||
// this class (creat, dup, dup2, and close)
|
||||
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).
|
||||
class CapturedStream {
|
||||
@@ -1064,7 +1117,13 @@ class CapturedStream {
|
||||
// The location /data/local/tmp is directly accessible from native code.
|
||||
// '/sdcard' and other variants cannot be relied on, as they are not
|
||||
// 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)
|
||||
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));
|
||||
|
||||
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]);
|
||||
#else
|
||||
name_template = "/tmp/";
|
||||
@@ -1306,8 +1365,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
|
||||
) {
|
||||
Message msg;
|
||||
msg << "WARNING: " << src_text
|
||||
<< " is expected to be a 32-bit integer, but actually"
|
||||
<< " has value " << str << ", which overflows.\n";
|
||||
<< " is expected to be a 32-bit integer, but actually" << " has value "
|
||||
<< str << ", which overflows.\n";
|
||||
printf("%s", msg.GetString().c_str());
|
||||
fflush(stdout);
|
||||
return false;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#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
|
||||
// char, char8_t, char16_t, char32_t, or wchar_t.
|
||||
// The array starts at begin, the length is len, it may include '\0' characters
|
||||
// and may not be NUL-terminated.
|
||||
// The array starts at begin (which may be nullptr) and contains len characters.
|
||||
// The array may include '\0' characters and may not be NUL-terminated.
|
||||
template <typename CharType>
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
|
||||
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 << "\"";
|
||||
bool is_previous_hex = false;
|
||||
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) {
|
||||
if (!ContainsUnprintableControlCodes(str, length) &&
|
||||
IsValidUTF8(str, length)) {
|
||||
*os << "\n As Text: \"" << str << "\"";
|
||||
*os << "\n As Text: \"" << ::std::string_view(str, length) << "\"";
|
||||
}
|
||||
}
|
||||
|
||||
} // 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 (GTEST_FLAG_GET(print_utf8)) {
|
||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||
@@ -531,21 +531,21 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
|
||||
void PrintU16StringTo(::std::u16string_view s, ostream* 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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-port.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
|
||||
// in it.
|
||||
std::string TestPartResult::ExtractSummary(const char* message) {
|
||||
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
|
||||
return stack_trace == nullptr ? message : std::string(message, stack_trace);
|
||||
std::string TestPartResult::ExtractSummary(const std::string_view message) {
|
||||
auto stack_trace = message.find(internal::kStackTraceMarker);
|
||||
return std::string(message.substr(0, stack_trace));
|
||||
}
|
||||
|
||||
// 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():
|
||||
name = "googletest"
|
||||
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.main()
|
||||
|
||||
Reference in New Issue
Block a user