dep/googletest: Update to v1.18.0

Note: std::any support is disabled because it depends on RTTI support in
MSVC, which we have disabled.
wip3-rebase
Stenzek 2 days ago
parent 60a798cdce
commit 42cf88c4b5
No known key found for this signature in database

@ -5,34 +5,62 @@
Ajay Joshi <jaj@google.com> Ajay Joshi <jaj@google.com>
Balázs Dán <balazs.dan@gmail.com> Balázs Dán <balazs.dan@gmail.com>
Benoit Sigoure <tsuna@google.com>
Bharat Mediratta <bharat@menalto.com> Bharat Mediratta <bharat@menalto.com>
Bogdan Piloca <boo@google.com>
Chandler Carruth <chandlerc@google.com> Chandler Carruth <chandlerc@google.com>
Chris Prince <cprince@google.com> Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com> Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com> Dan Egnor <egnor@google.com>
Dave MacLachlan <dmaclach@gmail.com>
David Anderson <danderson@google.com>
Dean Sturtevant
Eric Roman <eroman@chromium.org> Eric Roman <eroman@chromium.org>
Gene Volovich <gv@cite.com>
Hady Zalek <hady.zalek@gmail.com> Hady Zalek <hady.zalek@gmail.com>
Hal Burch <gmock@hburch.com>
Jeffrey Yasskin <jyasskin@google.com> Jeffrey Yasskin <jyasskin@google.com>
Jim Keller <jimkeller@google.com>
Joe Walnes <joe@truemesh.com>
Jon Wray <jwray@google.com>
Jói Sigurðsson <joi@google.com> Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com> Keir Mierle <mierle@gmail.com>
Keith Ray <keith.ray@gmail.com> Keith Ray <keith.ray@gmail.com>
Kenton Varda <kenton@google.com> Kenton Varda <kenton@google.com>
Kostya Serebryany <kcc@google.com>
Krystian Kuzniarek <krystian.kuzniarek@gmail.com> Krystian Kuzniarek <krystian.kuzniarek@gmail.com>
Lev Makhlis
Manuel Klimek <klimek@google.com> Manuel Klimek <klimek@google.com>
Mario Tanev <radix@google.com>
Mark Paskin
Markus Heule <markus.heule@gmail.com> Markus Heule <markus.heule@gmail.com>
Martijn Vels <mvels@google.com>
Matthew Simmons <simmonmt@acm.org>
Mika Raento <mikie@iki.fi> Mika Raento <mikie@iki.fi>
Mike Bland <mbland@google.com>
Miklós Fazekas <mfazekas@szemafor.com> Miklós Fazekas <mfazekas@szemafor.com>
Neal Norwitz <nnorwitz@gmail.com>
Nermin Ozkiranartli <nermin@google.com>
Owen Carlsen <ocarlsen@google.com>
Paneendra Ba <paneendra@google.com>
Pasi Valminen <pasi.valminen@gmail.com> Pasi Valminen <pasi.valminen@gmail.com>
Patrick Hanna <phanna@google.com> Patrick Hanna <phanna@google.com>
Patrick Riley <pfr@google.com> Patrick Riley <pfr@google.com>
Paul Menage <menage@google.com>
Peter Kaminski <piotrk@google.com> Peter Kaminski <piotrk@google.com>
Piotr Kaminski <piotrk@google.com>
Preston Jackson <preston.a.jackson@gmail.com> Preston Jackson <preston.a.jackson@gmail.com>
Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com> Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
Russ Cox <rsc@google.com> Russ Cox <rsc@google.com>
Russ Rufer <russ@pentad.com> Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com> Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com> Sigurður Ásgeirsson <siggi@google.com>
Soyeon Kim <sxshx818@naver.com>
Sverre Sundsdal <sundsdal@gmail.com>
Szymon Sobik <sobik.szymon@gmail.com>
Takeshi Yoshino <tyoshino@google.com>
Tracy Bialik <tracy@pentad.com> Tracy Bialik <tracy@pentad.com>
Vadim Berman <vadimb@google.com> Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com> Vlad Losev <vladl@google.com>
Wolfgang Klier <wklier@google.com>
Zhanyong Wan <wan@google.com> Zhanyong Wan <wan@google.com>

@ -137,7 +137,7 @@ namespace testing {
class [[nodiscard]] AssertionResult; class [[nodiscard]] AssertionResult;
#endif // !SWIG #endif // !SWIG
class GTEST_API_ AssertionResult { class GTEST_API_ [[nodiscard]] AssertionResult {
public: public:
// Copy constructor. // Copy constructor.
// Used in EXPECT_TRUE/FALSE(assertion_result). // Used in EXPECT_TRUE/FALSE(assertion_result).
@ -158,14 +158,18 @@ class GTEST_API_ AssertionResult {
// The second parameter prevents this overload from being considered if // The second parameter prevents this overload from being considered if
// the argument is implicitly convertible to AssertionResult. In that case // the argument is implicitly convertible to AssertionResult. In that case
// we want AssertionResult's copy constructor to be used. // we want AssertionResult's copy constructor to be used.
template <typename T> template <typename T,
explicit AssertionResult( std::enable_if_t<!std::is_convertible_v<T, AssertionResult> &&
const T& success, !std::is_trivially_constructible_v<bool, T>,
typename std::enable_if< int> = 0>
!std::is_convertible<T, AssertionResult>::value>::type* explicit AssertionResult(T&& success) : success_(std::forward<T>(success)) {}
/*enabler*/
= nullptr) // Similar to the mutable overload, but for cases where mutability is
: success_(success) {} // unnecessary or problematic (e.g., bitfields).
template <typename T,
std::enable_if_t<!std::is_convertible_v<const T&, AssertionResult>,
int> = 0>
explicit AssertionResult(const T& success) : success_(success) {}
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) #if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
@ -227,6 +231,24 @@ class GTEST_API_ AssertionResult {
std::unique_ptr< ::std::string> message_; std::unique_ptr< ::std::string> message_;
}; };
namespace internal {
// A pair containing the result that an assertion is evaluating, and the
// expected result (true, false).
//
// Contains a conversion operator that indicates whether the two match.
struct AssertionResultExpectation {
testing::AssertionResult assertion_result;
bool expected_result;
explicit operator bool() const {
bool converted(assertion_result);
return converted == expected_result;
}
};
} // namespace internal
// Makes a successful assertion result. // Makes a successful assertion result.
GTEST_API_ AssertionResult AssertionSuccess(); GTEST_API_ AssertionResult AssertionSuccess();

@ -192,7 +192,7 @@ GTEST_API_ bool InDeathTestChild();
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
// Tests that an exit code describes a normal exit with a given exit code. // Tests that an exit code describes a normal exit with a given exit code.
class GTEST_API_ ExitedWithCode { class GTEST_API_ [[nodiscard]] ExitedWithCode {
public: public:
explicit ExitedWithCode(int exit_code); explicit ExitedWithCode(int exit_code);
ExitedWithCode(const ExitedWithCode&) = default; ExitedWithCode(const ExitedWithCode&) = default;
@ -206,7 +206,7 @@ class GTEST_API_ ExitedWithCode {
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA) #if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
// Tests that an exit code describes an exit due to termination by a // Tests that an exit code describes an exit due to termination by a
// given signal. // given signal.
class GTEST_API_ KilledBySignal { class GTEST_API_ [[nodiscard]] KilledBySignal {
public: public:
explicit KilledBySignal(int signum); explicit KilledBySignal(int signum);
bool operator()(int exit_status) const; bool operator()(int exit_status) const;
@ -317,7 +317,7 @@ class GTEST_API_ KilledBySignal {
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \ GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \ << "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \ } else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \ (void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \ terminator; \
} else \ } else \

@ -40,10 +40,12 @@
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#include <atomic> #include <atomic>
#include <cstddef>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <string_view>
#include <type_traits> #include <type_traits>
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
@ -75,7 +77,7 @@ namespace testing {
// 2. a factory function that creates a Matcher<T> object from a // 2. a factory function that creates a Matcher<T> object from a
// FooMatcherMatcher. // FooMatcherMatcher.
class MatchResultListener { class [[nodiscard]] MatchResultListener {
public: public:
// Creates a listener object with the given underlying ostream. The // Creates a listener object with the given underlying ostream. The
// listener does not own the ostream, and does not dereference it // listener does not own the ostream, and does not dereference it
@ -111,7 +113,7 @@ inline MatchResultListener::~MatchResultListener() = default;
// An instance of a subclass of this knows how to describe itself as a // An instance of a subclass of this knows how to describe itself as a
// matcher. // matcher.
class GTEST_API_ MatcherDescriberInterface { class GTEST_API_ [[nodiscard]] MatcherDescriberInterface {
public: public:
virtual ~MatcherDescriberInterface() = default; virtual ~MatcherDescriberInterface() = default;
@ -137,7 +139,7 @@ class GTEST_API_ MatcherDescriberInterface {
// The implementation of a matcher. // The implementation of a matcher.
template <typename T> template <typename T>
class MatcherInterface : public MatcherDescriberInterface { class [[nodiscard]] MatcherInterface : public MatcherDescriberInterface {
public: public:
// Returns true if and only if the matcher matches x; also explains the // Returns true if and only if the matcher matches x; also explains the
// match result to 'listener' if necessary (see the next paragraph), in // match result to 'listener' if necessary (see the next paragraph), in
@ -180,7 +182,7 @@ class MatcherInterface : public MatcherDescriberInterface {
namespace internal { namespace internal {
// A match result listener that ignores the explanation. // A match result listener that ignores the explanation.
class DummyMatchResultListener : public MatchResultListener { class [[nodiscard]] DummyMatchResultListener : public MatchResultListener {
public: public:
DummyMatchResultListener() : MatchResultListener(nullptr) {} DummyMatchResultListener() : MatchResultListener(nullptr) {}
@ -192,7 +194,7 @@ class DummyMatchResultListener : public MatchResultListener {
// A match result listener that forwards the explanation to a given // A match result listener that forwards the explanation to a given
// ostream. The difference between this and MatchResultListener is // ostream. The difference between this and MatchResultListener is
// that the former is concrete. // that the former is concrete.
class StreamMatchResultListener : public MatchResultListener { class [[nodiscard]] StreamMatchResultListener : public MatchResultListener {
public: public:
explicit StreamMatchResultListener(::std::ostream* os) explicit StreamMatchResultListener(::std::ostream* os)
: MatchResultListener(os) {} : MatchResultListener(os) {}
@ -225,7 +227,7 @@ struct SharedPayload : SharedPayloadBase {
// from it. We put functionalities common to all Matcher<T> // from it. We put functionalities common to all Matcher<T>
// specializations here to avoid code duplication. // specializations here to avoid code duplication.
template <typename T> template <typename T>
class MatcherBase : private MatcherDescriberInterface { class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
public: public:
// Returns true if and only if the matcher matches x; also explains the // Returns true if and only if the matcher matches x; also explains the
// match result to 'listener'. // match result to 'listener'.
@ -276,8 +278,8 @@ class MatcherBase : private MatcherDescriberInterface {
Init(impl); Init(impl);
} }
template <typename M, typename = typename std::remove_reference< template <typename M,
M>::type::is_gtest_matcher> typename = typename std::remove_reference_t<M>::is_gtest_matcher>
MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT
Init(std::forward<M>(m)); Init(std::forward<M>(m));
} }
@ -296,12 +298,12 @@ class MatcherBase : private MatcherDescriberInterface {
return *this; return *this;
} }
MatcherBase(MatcherBase&& other) MatcherBase(MatcherBase&& other) noexcept
: vtable_(other.vtable_), buffer_(other.buffer_) { : vtable_(other.vtable_), buffer_(other.buffer_) {
other.vtable_ = nullptr; other.vtable_ = nullptr;
} }
MatcherBase& operator=(MatcherBase&& other) { MatcherBase& operator=(MatcherBase&& other) noexcept {
if (this == &other) return *this; if (this == &other) return *this;
Destroy(); Destroy();
vtable_ = other.vtable_; vtable_ = other.vtable_;
@ -362,11 +364,10 @@ class MatcherBase : private MatcherDescriberInterface {
// from the impl, but some users really want to get their impl back when // from the impl, but some users really want to get their impl back when
// they call GetDescriber(). // they call GetDescriber().
// We use std::get on a tuple as a workaround of not having `if constexpr`. // We use std::get on a tuple as a workaround of not having `if constexpr`.
return std::get<( return std::get<(std::is_convertible_v<decltype(&P::Get(m)),
std::is_convertible<decltype(&P::Get(m)), const MatcherDescriberInterface*>
const MatcherDescriberInterface*>::value ? 1
? 1 : 0)>(std::make_tuple(&m, &P::Get(m)));
: 0)>(std::make_tuple(&m, &P::Get(m)));
} }
template <typename P> template <typename P>
@ -395,8 +396,8 @@ class MatcherBase : private MatcherDescriberInterface {
template <typename M> template <typename M>
static constexpr bool IsInlined() { static constexpr bool IsInlined() {
return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) && return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
std::is_trivially_copy_constructible<M>::value && std::is_trivially_copy_constructible_v<M> &&
std::is_trivially_destructible<M>::value; std::is_trivially_destructible_v<M>;
} }
template <typename M, bool = MatcherBase::IsInlined<M>()> template <typename M, bool = MatcherBase::IsInlined<M>()>
@ -443,7 +444,7 @@ class MatcherBase : private MatcherDescriberInterface {
template <typename M> template <typename M>
void Init(M&& m) { void Init(M&& m) {
using MM = typename std::decay<M>::type; using MM = std::decay_t<M>;
using Policy = ValuePolicy<MM>; using Policy = ValuePolicy<MM>;
vtable_ = GetVTable<Policy>(); vtable_ = GetVTable<Policy>();
Policy::Init(*this, std::forward<M>(m)); Policy::Init(*this, std::forward<M>(m));
@ -460,7 +461,7 @@ class MatcherBase : private MatcherDescriberInterface {
// implementation of Matcher<T> is just a std::shared_ptr to const // implementation of Matcher<T> is just a std::shared_ptr to const
// MatcherInterface<T>. Don't inherit from Matcher! // MatcherInterface<T>. Don't inherit from Matcher!
template <typename T> template <typename T>
class Matcher : public internal::MatcherBase<T> { class [[nodiscard]] Matcher : public internal::MatcherBase<T> {
public: public:
// Constructs a null matcher. Needed for storing Matcher objects in STL // Constructs a null matcher. Needed for storing Matcher objects in STL
// containers. A default-constructed matcher is not yet initialized. You // containers. A default-constructed matcher is not yet initialized. You
@ -472,35 +473,42 @@ class Matcher : public internal::MatcherBase<T> {
: internal::MatcherBase<T>(impl) {} : internal::MatcherBase<T>(impl) {}
template <typename U> template <typename U>
explicit Matcher( explicit Matcher(const MatcherInterface<U>* impl,
const MatcherInterface<U>* impl, std::enable_if_t<!std::is_same_v<U, const U&>>* = nullptr)
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
nullptr)
: internal::MatcherBase<T>(impl) {} : internal::MatcherBase<T>(impl) {}
template <typename M, typename = typename std::remove_reference< template <typename M,
M>::type::is_gtest_matcher> typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
// Implicit constructor here allows people to write // Implicit constructor here allows people to write
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
Matcher(T value); // NOLINT Matcher(T value); // NOLINT
// Implicit constructor here allows people to write
// EXPECT_THAT(foo, nullptr) instead of EXPECT_THAT(foo, IsNull()) for smart
// pointer types.
//
// The second argument is needed to avoid capturing literal '0'.
template <typename U>
Matcher(U, // NOLINT
std::enable_if_t<std::is_same_v<U, std::nullptr_t>>* = nullptr);
}; };
// The following two specializations allow the user to write str // The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string // instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected. // matcher is expected.
template <> template <>
class GTEST_API_ Matcher<const std::string&> class GTEST_API_ [[nodiscard]]
: public internal::MatcherBase<const std::string&> { Matcher<const std::string&> : public internal::MatcherBase<const std::string&> {
public: public:
Matcher() = default; Matcher() = default;
explicit Matcher(const MatcherInterface<const std::string&>* impl) explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<const std::string&>(impl) {} : internal::MatcherBase<const std::string&>(impl) {}
template <typename M, typename = typename std::remove_reference< template <typename M,
M>::type::is_gtest_matcher> typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT Matcher(M&& m) // NOLINT
: internal::MatcherBase<const std::string&>(std::forward<M>(m)) {} : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
@ -513,8 +521,8 @@ class GTEST_API_ Matcher<const std::string&>
}; };
template <> template <>
class GTEST_API_ Matcher<std::string> class GTEST_API_ [[nodiscard]]
: public internal::MatcherBase<std::string> { Matcher<std::string> : public internal::MatcherBase<std::string> {
public: public:
Matcher() = default; Matcher() = default;
@ -523,8 +531,8 @@ class GTEST_API_ Matcher<std::string>
explicit Matcher(const MatcherInterface<std::string>* impl) explicit Matcher(const MatcherInterface<std::string>* impl)
: internal::MatcherBase<std::string>(impl) {} : internal::MatcherBase<std::string>(impl) {}
template <typename M, typename = typename std::remove_reference< template <typename M,
M>::type::is_gtest_matcher> typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT Matcher(M&& m) // NOLINT
: internal::MatcherBase<std::string>(std::forward<M>(m)) {} : internal::MatcherBase<std::string>(std::forward<M>(m)) {}
@ -536,12 +544,11 @@ class GTEST_API_ Matcher<std::string>
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
}; };
#if GTEST_INTERNAL_HAS_STRING_VIEW
// The following two specializations allow the user to write str // The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view // instead of Eq(str) and "foo" instead of Eq("foo") when a std::string_view
// matcher is expected. // matcher is expected.
template <> template <>
class GTEST_API_ Matcher<const internal::StringView&> class GTEST_API_ [[nodiscard]] Matcher<const internal::StringView&>
: public internal::MatcherBase<const internal::StringView&> { : public internal::MatcherBase<const internal::StringView&> {
public: public:
Matcher() = default; Matcher() = default;
@ -549,8 +556,8 @@ class GTEST_API_ Matcher<const internal::StringView&>
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
: internal::MatcherBase<const internal::StringView&>(impl) {} : internal::MatcherBase<const internal::StringView&>(impl) {}
template <typename M, typename = typename std::remove_reference< template <typename M,
M>::type::is_gtest_matcher> typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT Matcher(M&& m) // NOLINT
: internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) { : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
} }
@ -562,12 +569,12 @@ class GTEST_API_ Matcher<const internal::StringView&>
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly. // Allows the user to pass std::string_views directly.
Matcher(internal::StringView s); // NOLINT Matcher(internal::StringView s); // NOLINT
}; };
template <> template <>
class GTEST_API_ Matcher<internal::StringView> class GTEST_API_ [[nodiscard]] Matcher<internal::StringView>
: public internal::MatcherBase<internal::StringView> { : public internal::MatcherBase<internal::StringView> {
public: public:
Matcher() = default; Matcher() = default;
@ -577,8 +584,8 @@ class GTEST_API_ Matcher<internal::StringView>
explicit Matcher(const MatcherInterface<internal::StringView>* impl) explicit Matcher(const MatcherInterface<internal::StringView>* impl)
: internal::MatcherBase<internal::StringView>(impl) {} : internal::MatcherBase<internal::StringView>(impl) {}
template <typename M, typename = typename std::remove_reference< template <typename M,
M>::type::is_gtest_matcher> typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT Matcher(M&& m) // NOLINT
: internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {} : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
@ -589,10 +596,9 @@ class GTEST_API_ Matcher<internal::StringView>
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly. // Allows the user to pass std::string_views directly.
Matcher(internal::StringView s); // NOLINT Matcher(internal::StringView s); // NOLINT
}; };
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Prints a matcher in a human-readable format. // Prints a matcher in a human-readable format.
template <typename T> template <typename T>
@ -614,7 +620,7 @@ std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
// //
// See the definition of NotNull() for a complete example. // See the definition of NotNull() for a complete example.
template <class Impl> template <class Impl>
class PolymorphicMatcher { class [[nodiscard]] PolymorphicMatcher {
public: public:
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
@ -689,7 +695,7 @@ namespace internal {
// The following template definition assumes that the Rhs parameter is // The following template definition assumes that the Rhs parameter is
// a "bare" type (i.e. neither 'const T' nor 'T&'). // a "bare" type (i.e. neither 'const T' nor 'T&').
template <typename D, typename Rhs, typename Op> template <typename D, typename Rhs, typename Op>
class ComparisonBase { class [[nodiscard]] ComparisonBase {
public: public:
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
@ -722,7 +728,8 @@ class ComparisonBase {
}; };
template <typename Rhs> template <typename Rhs>
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> { class [[nodiscard]] EqMatcher
: public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
public: public:
explicit EqMatcher(const Rhs& rhs) explicit EqMatcher(const Rhs& rhs)
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {} : ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
@ -730,7 +737,7 @@ class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
static const char* NegatedDesc() { return "isn't equal to"; } static const char* NegatedDesc() { return "isn't equal to"; }
}; };
template <typename Rhs> template <typename Rhs>
class NeMatcher class [[nodiscard]] NeMatcher
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> { : public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
public: public:
explicit NeMatcher(const Rhs& rhs) explicit NeMatcher(const Rhs& rhs)
@ -739,7 +746,8 @@ class NeMatcher
static const char* NegatedDesc() { return "is equal to"; } static const char* NegatedDesc() { return "is equal to"; }
}; };
template <typename Rhs> template <typename Rhs>
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> { class [[nodiscard]] LtMatcher
: public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
public: public:
explicit LtMatcher(const Rhs& rhs) explicit LtMatcher(const Rhs& rhs)
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {} : ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
@ -747,7 +755,8 @@ class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
static const char* NegatedDesc() { return "isn't <"; } static const char* NegatedDesc() { return "isn't <"; }
}; };
template <typename Rhs> template <typename Rhs>
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> { class [[nodiscard]] GtMatcher
: public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
public: public:
explicit GtMatcher(const Rhs& rhs) explicit GtMatcher(const Rhs& rhs)
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {} : ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
@ -755,7 +764,7 @@ class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
static const char* NegatedDesc() { return "isn't >"; } static const char* NegatedDesc() { return "isn't >"; }
}; };
template <typename Rhs> template <typename Rhs>
class LeMatcher class [[nodiscard]] LeMatcher
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> { : public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
public: public:
explicit LeMatcher(const Rhs& rhs) explicit LeMatcher(const Rhs& rhs)
@ -764,7 +773,7 @@ class LeMatcher
static const char* NegatedDesc() { return "isn't <="; } static const char* NegatedDesc() { return "isn't <="; }
}; };
template <typename Rhs> template <typename Rhs>
class GeMatcher class [[nodiscard]] GeMatcher
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> { : public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
public: public:
explicit GeMatcher(const Rhs& rhs) explicit GeMatcher(const Rhs& rhs)
@ -773,24 +782,68 @@ class GeMatcher
static const char* NegatedDesc() { return "isn't >="; } static const char* NegatedDesc() { return "isn't >="; }
}; };
template <typename T, typename = typename std::enable_if< // Same as `EqMatcher<Rhs>`, except that the `rhs` is stored as `StoredRhs` and
std::is_constructible<std::string, T>::value>::type> // must be implicitly convertible to `Rhs`.
using StringLike = T; 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_;
};
// Dummy function (never defined) whose return type evaluates to std::string if
// the given type is a string-like type that can be converted to std::string,
// either directly or through an intermediate std::string_view.
template <class T>
extern std::enable_if_t<std::is_constructible_v<std::string, T>, std::string>
ResolveAsString(const void* /* preferred */);
#if GTEST_HAS_STD_WSTRING
// Same as above, but for std::wstring. In cases where both conversions are
// possible, this overload takes lower priority.
template <class T>
extern std::enable_if_t<std::is_constructible_v<std::wstring, T>, std::wstring>
ResolveAsString(... /* fallback */);
#endif
// Evaluates to the std::basic_string type that the given string-like type can
// be converted to. Prefers std::string over std::wstring if both are possible.
// Fails in a SFINAE-friendly way if no conversion was viable.
template <typename T>
using StringType = decltype(ResolveAsString<T>(nullptr));
// Implements polymorphic matchers MatchesRegex(regex) and // Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as // ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string. // T can be converted to a string.
class MatchesRegexMatcher { class [[nodiscard]] MatchesRegexMatcher {
public: public:
MatchesRegexMatcher(const RE* regex, bool full_match) MatchesRegexMatcher(const RE* regex, bool full_match)
: regex_(regex), full_match_(full_match) {} : regex_(regex), full_match_(full_match) {}
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
return MatchAndExplain(std::string(s), listener); return MatchAndExplain(std::string(s), listener);
} }
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
@ -805,7 +858,7 @@ class MatchesRegexMatcher {
// Matches anything that can convert to std::string. // Matches anything that can convert to std::string.
// //
// This is a template, not just a plain function with const std::string&, // This is a template, not just a plain function with const std::string&,
// because absl::string_view has some interfering non-explicit constructors. // because std::string_view has some interfering non-explicit constructors.
template <class MatcheeStringType> template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
@ -838,9 +891,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
} }
template <typename T = std::string> template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( std::enable_if_t<std::is_constructible_v<internal::RE, internal::StringType<T>>,
const internal::StringLike<T>& regex) { PolymorphicMatcher<internal::MatchesRegexMatcher>>
return MatchesRegex(new internal::RE(std::string(regex))); MatchesRegex(const T& regex) {
return MatchesRegex(new internal::RE(internal::StringType<T>(regex)));
} }
// Matches a string that contains regular expression 'regex'. // Matches a string that contains regular expression 'regex'.
@ -850,9 +904,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
} }
template <typename T = std::string> template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( std::enable_if_t<std::is_constructible_v<internal::RE, internal::StringType<T>>,
const internal::StringLike<T>& regex) { PolymorphicMatcher<internal::MatchesRegexMatcher>>
return ContainsRegex(new internal::RE(std::string(regex))); ContainsRegex(const T& regex) {
return ContainsRegex(new internal::RE(internal::StringType<T>(regex)));
} }
// Creates a polymorphic matcher that matches anything equal to x. // Creates a polymorphic matcher that matches anything equal to x.
@ -863,13 +918,21 @@ inline internal::EqMatcher<T> Eq(T x) {
return internal::EqMatcher<T>(x); return internal::EqMatcher<T>(x);
} }
// Constructs a Matcher<T> from a 'value' of type T. The constructed // Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'. // matcher matches any value that's equal to 'value'.
template <typename T> template <typename T>
Matcher<T>::Matcher(T value) { Matcher<T>::Matcher(T value) {
*this = Eq(value); *this = Eq(value);
} }
// Constructs a Matcher<T> from nullptr. The constructed matcher matches any
// value that is equal to nullptr.
template <typename T>
template <typename U>
Matcher<T>::Matcher(U, std::enable_if_t<std::is_same_v<U, std::nullptr_t>>*) {
*this = Eq(nullptr);
}
// Creates a monomorphic matcher that matches anything with type Lhs // Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...) // and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity. // in order to resolve an overloading ambiguity.

@ -129,7 +129,7 @@ class GTEST_API_ Message {
int>::type = 0 int>::type = 0
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
> >
inline Message& operator<<(const T& val) { Message& operator<<(const T& val) {
// Some libraries overload << for STL containers. These // Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std. // overloads are defined in the global namespace instead of ::std.
// //
@ -155,7 +155,7 @@ class GTEST_API_ Message {
template <typename T, template <typename T,
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0> int>::type = 0>
inline Message& operator<<(const T& val) { Message& operator<<(const T& val) {
// ::operator<< is needed here for a similar reason as with the non-Abseil // ::operator<< is needed here for a similar reason as with the non-Abseil
// version above // version above
using ::operator<<; using ::operator<<;

@ -104,15 +104,19 @@
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <any>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <optional>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <string_view>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <typeinfo> #include <typeinfo>
#include <utility> #include <utility>
#include <variant>
#include <vector> #include <vector>
#ifdef GTEST_HAS_ABSL #ifdef GTEST_HAS_ABSL
@ -245,8 +249,8 @@ struct StreamPrinter {
// ADL (possibly involving implicit conversions). // ADL (possibly involving implicit conversions).
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name // (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
// lookup properly when we do it in the template parameter list.) // lookup properly when we do it in the template parameter list.)
static auto PrintValue(const T& value, static auto PrintValue(const T& value, ::std::ostream* os)
::std::ostream* os) -> decltype((void)(*os << value)) { -> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions // Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments. // of the arguments.
*os << value; *os << value;
@ -287,11 +291,9 @@ struct ConvertibleToIntegerPrinter {
}; };
struct ConvertibleToStringViewPrinter { struct ConvertibleToStringViewPrinter {
#if GTEST_INTERNAL_HAS_STRING_VIEW
static void PrintValue(internal::StringView value, ::std::ostream* os) { static void PrintValue(internal::StringView value, ::std::ostream* os) {
internal::UniversalPrint(value, os); internal::UniversalPrint(value, os);
} }
#endif
}; };
#ifdef GTEST_HAS_ABSL #ifdef GTEST_HAS_ABSL
@ -378,7 +380,7 @@ void PrintWithFallback(const T& value, ::std::ostream* os) {
// The default case. // The default case.
template <typename ToPrint, typename OtherOperand> template <typename ToPrint, typename OtherOperand>
class FormatForComparison { class [[nodiscard]] FormatForComparison {
public: public:
static ::std::string Format(const ToPrint& value) { static ::std::string Format(const ToPrint& value) {
return ::testing::PrintToString(value); return ::testing::PrintToString(value);
@ -387,7 +389,7 @@ class FormatForComparison {
// Array. // Array.
template <typename ToPrint, size_t N, typename OtherOperand> template <typename ToPrint, size_t N, typename OtherOperand>
class FormatForComparison<ToPrint[N], OtherOperand> { class [[nodiscard]] FormatForComparison<ToPrint[N], OtherOperand> {
public: public:
static ::std::string Format(const ToPrint* value) { static ::std::string Format(const ToPrint* value) {
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value); return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
@ -473,7 +475,7 @@ std::string FormatForComparisonFailureMessage(const T1& value,
// function template), as we need to partially specialize it for // function template), as we need to partially specialize it for
// reference types, which cannot be done with function templates. // reference types, which cannot be done with function templates.
template <typename T> template <typename T>
class UniversalPrinter; class [[nodiscard]] UniversalPrinter;
// Prints the given value using the << operator if it has one; // Prints the given value using the << operator if it has one;
// otherwise prints the bytes in it. This is what // otherwise prints the bytes in it. This is what
@ -521,11 +523,15 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os); GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
inline void PrintTo(char16_t c, ::std::ostream* os) { inline void PrintTo(char16_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os); // TODO(b/418738869): Incorrect for values not representing valid codepoints.
// Also see https://github.com/google/googletest/issues/4762.
PrintTo(static_cast<char32_t>(c), os);
} }
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
inline void PrintTo(char8_t c, ::std::ostream* os) { inline void PrintTo(char8_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os); // TODO(b/418738869): Incorrect for values not representing valid codepoints.
// Also see https://github.com/google/googletest/issues/4762.
PrintTo(static_cast<char32_t>(c), os);
} }
#endif #endif
@ -695,46 +701,63 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
} }
} }
// Overloads for ::std::string. // Overloads for ::std::string and std::string_view
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os); GTEST_API_ void PrintStringTo(std::string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* os) { inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os); PrintStringTo(s, os);
} }
inline void PrintTo(std::string_view s, ::std::ostream* os) {
PrintStringTo(s, os);
}
// Overloads for ::std::u8string // Overloads for ::std::u8string and ::std::u8string_view
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os); GTEST_API_ void PrintU8StringTo(::std::u8string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) { inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
PrintU8StringTo(s, os); PrintU8StringTo(s, os);
} }
inline void PrintTo(::std::u8string_view s, ::std::ostream* os) {
PrintU8StringTo(s, os);
}
#endif #endif
// Overloads for ::std::u16string // Overloads for ::std::u16string and ::std::u16string_view
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os); GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) { inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
PrintU16StringTo(s, os); PrintU16StringTo(s, os);
} }
inline void PrintTo(::std::u16string_view s, ::std::ostream* os) {
PrintU16StringTo(s, os);
}
// Overloads for ::std::u32string // Overloads for ::std::u32string and ::std::u32string_view
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os); GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) { inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
PrintU32StringTo(s, os); PrintU32StringTo(s, os);
} }
inline void PrintTo(::std::u32string_view s, ::std::ostream* os) {
PrintU32StringTo(s, os);
}
// Overloads for ::std::wstring. // Overloads for ::std::wstring and ::std::wstring_view
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os); GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os);
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
PrintWideStringTo(s, os); PrintWideStringTo(s, os);
} }
inline void PrintTo(::std::wstring_view s, ::std::ostream* os) {
PrintWideStringTo(s, os);
}
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
#if GTEST_INTERNAL_HAS_STRING_VIEW // Overload for internal::StringView. Needed for build configurations where
// Overload for internal::StringView. // internal::StringView is an alias for absl::string_view, but absl::string_view
// is a distinct type from std::string_view.
template <int&... ExplicitArgumentBarrier, typename T = internal::StringView,
std::enable_if_t<!std::is_same_v<T, std::string_view>, int> = 0>
inline void PrintTo(internal::StringView sp, ::std::ostream* os) { inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
PrintTo(::std::string(sp), os); PrintStringTo(sp, os);
} }
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
@ -836,8 +859,8 @@ void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_INTENTIONAL_CONST_COND_POP_()
*os << ", "; *os << ", ";
} }
UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print( UniversalPrinter<std::tuple_element_t<I - 1, T>>::Print(std::get<I - 1>(t),
std::get<I - 1>(t), os); os);
} }
template <typename... Types> template <typename... Types>
@ -862,7 +885,7 @@ void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
// Implements printing a non-reference type T by letting the compiler // Implements printing a non-reference type T by letting the compiler
// pick the right overload of PrintTo() for T. // pick the right overload of PrintTo() for T.
template <typename T> template <typename T>
class UniversalPrinter { class [[nodiscard]] UniversalPrinter {
public: public:
// MSVC warns about adding const to a function type, so we want to // MSVC warns about adding const to a function type, so we want to
// disable the warning. // disable the warning.
@ -888,16 +911,15 @@ class UniversalPrinter {
// Remove any const-qualifiers before passing a type to UniversalPrinter. // Remove any const-qualifiers before passing a type to UniversalPrinter.
template <typename T> template <typename T>
class UniversalPrinter<const T> : public UniversalPrinter<T> {}; class [[nodiscard]] UniversalPrinter<const T> : public UniversalPrinter<T> {};
#if GTEST_INTERNAL_HAS_ANY
// Printer for std::any / absl::any
#if 0
// DUCKSTATION-CHANGE: Disabled because it requires RTTI on Windows/MSVC.
// Printer for std::any
template <> template <>
class UniversalPrinter<Any> { class [[nodiscard]] UniversalPrinter<std::any> {
public: public:
static void Print(const Any& value, ::std::ostream* os) { static void Print(const std::any& value, ::std::ostream* os) {
if (value.has_value()) { if (value.has_value()) {
*os << "value of type " << GetTypeName(value); *os << "value of type " << GetTypeName(value);
} else { } else {
@ -906,7 +928,7 @@ class UniversalPrinter<Any> {
} }
private: private:
static std::string GetTypeName(const Any& value) { static std::string GetTypeName(const std::any& value) {
#if GTEST_HAS_RTTI #if GTEST_HAS_RTTI
return internal::GetTypeName(value.type()); return internal::GetTypeName(value.type());
#else #else
@ -916,67 +938,61 @@ class UniversalPrinter<Any> {
} }
}; };
#endif // GTEST_INTERNAL_HAS_ANY // Printer for std::optional
#if GTEST_INTERNAL_HAS_OPTIONAL
// Printer for std::optional / absl::optional
template <typename T> template <typename T>
class UniversalPrinter<Optional<T>> { class [[nodiscard]] UniversalPrinter<std::optional<T>> {
public: public:
static void Print(const Optional<T>& value, ::std::ostream* os) { static void Print(const std::optional<T>& value, ::std::ostream* os) {
*os << '(';
if (!value) { if (!value) {
*os << "nullopt"; UniversalPrint(std::nullopt, os);
} else { } else {
*os << '(';
UniversalPrint(*value, os); UniversalPrint(*value, os);
*os << ')';
} }
*os << ')';
} }
}; };
#endif
template <> template <>
class UniversalPrinter<decltype(Nullopt())> { class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
public: public:
static void Print(decltype(Nullopt()), ::std::ostream* os) { static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
*os << "(nullopt)";
}
}; };
#endif // GTEST_INTERNAL_HAS_OPTIONAL struct UniversalPrinterVisitor {
template <typename T>
#if GTEST_INTERNAL_HAS_VARIANT void operator()(const T& arg) const {
*os << "'" << GetTypeName<T>() << "(index = " << index << ")' with value ";
// Printer for std::variant / absl::variant UniversalPrint(arg, os);
}
::std::ostream* os;
std::size_t index;
};
// Printer for std::variant
template <typename... T> template <typename... T>
class UniversalPrinter<Variant<T...>> { class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
public: public:
static void Print(const Variant<T...>& value, ::std::ostream* os) { static void Print(const std::variant<T...>& value, ::std::ostream* os) {
*os << '('; if (value.valueless_by_exception()) {
#ifdef GTEST_HAS_ABSL *os << "(valueless)";
absl::visit(Visitor{os, value.index()}, value); } else {
#else *os << '(';
std::visit(Visitor{os, value.index()}, value); std::visit(UniversalPrinterVisitor{os, value.index()}, value);
#endif // GTEST_HAS_ABSL *os << ')';
*os << ')';
}
private:
struct Visitor {
template <typename U>
void operator()(const U& u) const {
*os << "'" << GetTypeName<U>() << "(index = " << index
<< ")' with value ";
UniversalPrint(u, os);
} }
::std::ostream* os; }
std::size_t index;
};
}; };
#endif // GTEST_INTERNAL_HAS_VARIANT // Printer for std::monostate
template <>
class [[nodiscard]] UniversalPrinter<std::monostate> {
public:
static void Print(std::monostate, ::std::ostream* os) {
*os << "(monostate)";
}
};
// UniversalPrintArray(begin, len, os) prints an array of 'len' // UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'. // elements, starting at address 'begin'.
@ -1025,7 +1041,7 @@ GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
// Implements printing an array type T[N]. // Implements printing an array type T[N].
template <typename T, size_t N> template <typename T, size_t N>
class UniversalPrinter<T[N]> { class [[nodiscard]] UniversalPrinter<T[N]> {
public: public:
// Prints the given array, omitting some elements when there are too // Prints the given array, omitting some elements when there are too
// many. // many.
@ -1036,7 +1052,7 @@ class UniversalPrinter<T[N]> {
// Implements printing a reference type T&. // Implements printing a reference type T&.
template <typename T> template <typename T>
class UniversalPrinter<T&> { class [[nodiscard]] UniversalPrinter<T&> {
public: public:
// MSVC warns about adding const to a function type, so we want to // MSVC warns about adding const to a function type, so we want to
// disable the warning. // disable the warning.
@ -1059,35 +1075,35 @@ class UniversalPrinter<T&> {
// NUL-terminated string (but not the pointer) is printed. // NUL-terminated string (but not the pointer) is printed.
template <typename T> template <typename T>
class UniversalTersePrinter { class [[nodiscard]] UniversalTersePrinter {
public: public:
static void Print(const T& value, ::std::ostream* os) { static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os); UniversalPrint(value, os);
} }
}; };
template <typename T> template <typename T>
class UniversalTersePrinter<T&> { class [[nodiscard]] UniversalTersePrinter<T&> {
public: public:
static void Print(const T& value, ::std::ostream* os) { static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os); UniversalPrint(value, os);
} }
}; };
template <typename T> template <typename T>
class UniversalTersePrinter<std::reference_wrapper<T>> { class [[nodiscard]] UniversalTersePrinter<std::reference_wrapper<T>> {
public: public:
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) { static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
UniversalTersePrinter<T>::Print(value.get(), os); UniversalTersePrinter<T>::Print(value.get(), os);
} }
}; };
template <typename T, size_t N> template <typename T, size_t N>
class UniversalTersePrinter<T[N]> { class [[nodiscard]] UniversalTersePrinter<T[N]> {
public: public:
static void Print(const T (&value)[N], ::std::ostream* os) { static void Print(const T (&value)[N], ::std::ostream* os) {
UniversalPrinter<T[N]>::Print(value, os); UniversalPrinter<T[N]>::Print(value, os);
} }
}; };
template <> template <>
class UniversalTersePrinter<const char*> { class [[nodiscard]] UniversalTersePrinter<const char*> {
public: public:
static void Print(const char* str, ::std::ostream* os) { static void Print(const char* str, ::std::ostream* os) {
if (str == nullptr) { if (str == nullptr) {
@ -1098,12 +1114,12 @@ class UniversalTersePrinter<const char*> {
} }
}; };
template <> template <>
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> { class [[nodiscard]]
}; UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {};
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
template <> template <>
class UniversalTersePrinter<const char8_t*> { class [[nodiscard]] UniversalTersePrinter<const char8_t*> {
public: public:
static void Print(const char8_t* str, ::std::ostream* os) { static void Print(const char8_t* str, ::std::ostream* os) {
if (str == nullptr) { if (str == nullptr) {
@ -1114,12 +1130,12 @@ class UniversalTersePrinter<const char8_t*> {
} }
}; };
template <> template <>
class UniversalTersePrinter<char8_t*> class [[nodiscard]] UniversalTersePrinter<char8_t*>
: public UniversalTersePrinter<const char8_t*> {}; : public UniversalTersePrinter<const char8_t*> {};
#endif #endif
template <> template <>
class UniversalTersePrinter<const char16_t*> { class [[nodiscard]] UniversalTersePrinter<const char16_t*> {
public: public:
static void Print(const char16_t* str, ::std::ostream* os) { static void Print(const char16_t* str, ::std::ostream* os) {
if (str == nullptr) { if (str == nullptr) {
@ -1130,11 +1146,11 @@ class UniversalTersePrinter<const char16_t*> {
} }
}; };
template <> template <>
class UniversalTersePrinter<char16_t*> class [[nodiscard]] UniversalTersePrinter<char16_t*>
: public UniversalTersePrinter<const char16_t*> {}; : public UniversalTersePrinter<const char16_t*> {};
template <> template <>
class UniversalTersePrinter<const char32_t*> { class [[nodiscard]] UniversalTersePrinter<const char32_t*> {
public: public:
static void Print(const char32_t* str, ::std::ostream* os) { static void Print(const char32_t* str, ::std::ostream* os) {
if (str == nullptr) { if (str == nullptr) {
@ -1145,12 +1161,12 @@ class UniversalTersePrinter<const char32_t*> {
} }
}; };
template <> template <>
class UniversalTersePrinter<char32_t*> class [[nodiscard]] UniversalTersePrinter<char32_t*>
: public UniversalTersePrinter<const char32_t*> {}; : public UniversalTersePrinter<const char32_t*> {};
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
template <> template <>
class UniversalTersePrinter<const wchar_t*> { class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
public: public:
static void Print(const wchar_t* str, ::std::ostream* os) { static void Print(const wchar_t* str, ::std::ostream* os) {
if (str == nullptr) { if (str == nullptr) {
@ -1163,7 +1179,7 @@ class UniversalTersePrinter<const wchar_t*> {
#endif #endif
template <> template <>
class UniversalTersePrinter<wchar_t*> { class [[nodiscard]] UniversalTersePrinter<wchar_t*> {
public: public:
static void Print(wchar_t* str, ::std::ostream* os) { static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os); UniversalTersePrinter<const wchar_t*>::Print(str, os);
@ -1212,7 +1228,7 @@ template <typename Tuple>
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
Strings result; Strings result;
TersePrintPrefixToStrings( TersePrintPrefixToStrings(
value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(), value, std::integral_constant<size_t, std::tuple_size_v<Tuple>>(),
&result); &result);
return result; return result;
} }

@ -51,7 +51,7 @@ namespace testing {
// generated in the same thread that created this object or it can intercept // generated in the same thread that created this object or it can intercept
// all generated failures. The scope of this mock object can be controlled with // all generated failures. The scope of this mock object can be controlled with
// the second argument to the two arguments constructor. // the second argument to the two arguments constructor.
class GTEST_API_ ScopedFakeTestPartResultReporter class GTEST_API_ [[nodiscard]] ScopedFakeTestPartResultReporter
: public TestPartResultReporterInterface { : public TestPartResultReporterInterface {
public: public:
// The two possible mocking modes of this object. // The two possible mocking modes of this object.
@ -100,7 +100,7 @@ namespace internal {
// TestPartResultArray contains exactly one failure that has the given // TestPartResultArray contains exactly one failure that has the given
// type and contains the given substring. If that's not the case, a // type and contains the given substring. If that's not the case, a
// non-fatal failure will be generated. // non-fatal failure will be generated.
class GTEST_API_ SingleFailureChecker { class GTEST_API_ [[nodiscard]] SingleFailureChecker {
public: public:
// The constructor remembers the arguments. // The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results, SingleFailureChecker(const TestPartResultArray* results,

@ -37,6 +37,7 @@
#include <iosfwd> #include <iosfwd>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <string_view>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
@ -51,7 +52,7 @@ namespace testing {
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
// //
// Don't inherit from TestPartResult as its destructor is not virtual. // Don't inherit from TestPartResult as its destructor is not virtual.
class GTEST_API_ TestPartResult { class GTEST_API_ [[nodiscard]] TestPartResult {
public: public:
// The possible outcomes of a test part (i.e. an assertion or an // The possible outcomes of a test part (i.e. an assertion or an
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()). // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
@ -65,10 +66,10 @@ class GTEST_API_ TestPartResult {
// C'tor. TestPartResult does NOT have a default constructor. // C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a // Always use this constructor (with parameters) to create a
// TestPartResult object. // TestPartResult object.
TestPartResult(Type a_type, const char* a_file_name, int a_line_number, TestPartResult(Type a_type, std::string_view a_file_name, int a_line_number,
const char* a_message) std::string_view a_message)
: type_(a_type), : type_(a_type),
file_name_(a_file_name == nullptr ? "" : a_file_name), file_name_(a_file_name),
line_number_(a_line_number), line_number_(a_line_number),
summary_(ExtractSummary(a_message)), summary_(ExtractSummary(a_message)),
message_(a_message) {} message_(a_message) {}
@ -112,7 +113,7 @@ class GTEST_API_ TestPartResult {
// Gets the summary of the failure message by omitting the stack // Gets the summary of the failure message by omitting the stack
// trace in it. // trace in it.
static std::string ExtractSummary(const char* message); static std::string ExtractSummary(std::string_view message);
// The name of the source file where the test part took place, or // The name of the source file where the test part took place, or
// "" if the source file is unknown. // "" if the source file is unknown.
@ -131,7 +132,7 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
// //
// Don't inherit from TestPartResultArray as its destructor is not // Don't inherit from TestPartResultArray as its destructor is not
// virtual. // virtual.
class GTEST_API_ TestPartResultArray { class GTEST_API_ [[nodiscard]] TestPartResultArray {
public: public:
TestPartResultArray() = default; TestPartResultArray() = default;
@ -152,7 +153,7 @@ class GTEST_API_ TestPartResultArray {
}; };
// This interface knows how to report a test part result. // This interface knows how to report a test part result.
class GTEST_API_ TestPartResultReporterInterface { class GTEST_API_ [[nodiscard]] TestPartResultReporterInterface {
public: public:
virtual ~TestPartResultReporterInterface() = default; virtual ~TestPartResultReporterInterface() = default;
@ -167,7 +168,7 @@ namespace internal {
// reported, it only delegates the reporting to the former result reporter. // reported, it only delegates the reporting to the former result reporter.
// The original result reporter is restored in the destructor. // The original result reporter is restored in the destructor.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
class GTEST_API_ HasNewFatalFailureHelper class GTEST_API_ [[nodiscard]] HasNewFatalFailureHelper
: public TestPartResultReporterInterface { : public TestPartResultReporterInterface {
public: public:
HasNewFatalFailureHelper(); HasNewFatalFailureHelper();

@ -45,18 +45,18 @@
// First, define a fixture class template. It should be parameterized // First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test. // by a type. Remember to derive it from testing::Test.
template <typename T> template <typename T>
class FooTest : public testing::Test { class [[nodiscard]] FooTest : public testing::Test {
public: public:
... ...
typedef std::list<T> List; using List = ::std::list<T>;
static T shared_; static T shared_;
T value_; T value_;
}; };
// Next, associate a list of types with the test suite, which will be // Next, associate a list of types with the test suite, which will be
// repeated for each type in the list. The typedef is necessary for // repeated for each type in the list. The using-declaration is necessary for
// the macro to parse correctly. // the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes; using MyTypes = ::testing::Types<char, int, unsigned int>;
TYPED_TEST_SUITE(FooTest, MyTypes); TYPED_TEST_SUITE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type // If the type list contains only one type, you can write that type
@ -123,7 +123,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... }
// First, define a fixture class template. It should be parameterized // First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test. // by a type. Remember to derive it from testing::Test.
template <typename T> template <typename T>
class FooTest : public testing::Test { class [[nodiscard]] FooTest : public testing::Test {
... ...
}; };
@ -157,7 +157,7 @@ REGISTER_TYPED_TEST_SUITE_P(FooTest,
// argument to the INSTANTIATE_* macro is a prefix that will be added // argument to the INSTANTIATE_* macro is a prefix that will be added
// to the actual test suite name. Remember to pick unique prefixes for // to the actual test suite name. Remember to pick unique prefixes for
// different instances. // different instances.
typedef testing::Types<char, int, unsigned int> MyTypes; using MyTypes = ::testing::Types<char, int, unsigned int>;
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type // If the type list contains only one type, you can write that type

@ -57,6 +57,7 @@
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <string_view>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -136,6 +137,10 @@ GTEST_DECLARE_int32_(repeat);
// only torn down once, for the last. // only torn down once, for the last.
GTEST_DECLARE_bool_(recreate_environments_when_repeating); GTEST_DECLARE_bool_(recreate_environments_when_repeating);
// Together these flags determine which tests are run if the test is sharded.
GTEST_DECLARE_int32_(shard_index);
GTEST_DECLARE_int32_(total_shards);
// This flag controls whether Google Test includes Google Test internal // This flag controls whether Google Test includes Google Test internal
// stack frames in failure stack traces. // stack frames in failure stack traces.
GTEST_DECLARE_bool_(show_internal_stack_frames); GTEST_DECLARE_bool_(show_internal_stack_frames);
@ -193,7 +198,7 @@ std::set<std::string>* GetIgnoredParameterizedTestSuites();
// A base class that prevents subclasses from being copyable. // A base class that prevents subclasses from being copyable.
// We do this instead of using '= delete' so as to avoid triggering warnings // We do this instead of using '= delete' so as to avoid triggering warnings
// inside user code regarding any of our declarations. // inside user code regarding any of our declarations.
class GTestNonCopyable { class [[nodiscard]] GTestNonCopyable {
public: public:
GTestNonCopyable() = default; GTestNonCopyable() = default;
GTestNonCopyable(const GTestNonCopyable&) = delete; GTestNonCopyable(const GTestNonCopyable&) = delete;
@ -206,15 +211,15 @@ class GTestNonCopyable {
// The friend relationship of some of these classes is cyclic. // The friend relationship of some of these classes is cyclic.
// If we don't forward declare them the compiler might confuse the classes // If we don't forward declare them the compiler might confuse the classes
// in friendship clauses with same named classes on the scope. // in friendship clauses with same named classes on the scope.
class Test; class [[nodiscard]] Test;
class TestSuite; class [[nodiscard]] TestSuite;
// Old API is still available but deprecated // Old API is still available but deprecated
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
using TestCase = TestSuite; using TestCase = TestSuite;
#endif #endif
class TestInfo; class [[nodiscard]] TestInfo;
class UnitTest; class [[nodiscard]] UnitTest;
// The abstract class that all tests inherit from. // The abstract class that all tests inherit from.
// //
@ -239,7 +244,7 @@ class UnitTest;
// TEST_F(FooTest, Baz) { ... } // TEST_F(FooTest, Baz) { ... }
// //
// Test is not copyable. // Test is not copyable.
class GTEST_API_ Test { class GTEST_API_ [[nodiscard]] Test {
public: public:
friend class TestInfo; friend class TestInfo;
@ -366,7 +371,7 @@ typedef internal::TimeInMillis TimeInMillis;
// output as a key/value string pair. // output as a key/value string pair.
// //
// Don't inherit from TestProperty as its destructor is not virtual. // Don't inherit from TestProperty as its destructor is not virtual.
class TestProperty { class [[nodiscard]] TestProperty {
public: public:
// C'tor. TestProperty does NOT have a default constructor. // C'tor. TestProperty does NOT have a default constructor.
// Always use this constructor (with parameters) to create a // Always use this constructor (with parameters) to create a
@ -396,7 +401,7 @@ class TestProperty {
// the Test. // the Test.
// //
// TestResult is not copyable. // TestResult is not copyable.
class GTEST_API_ TestResult { class GTEST_API_ [[nodiscard]] TestResult {
public: public:
// Creates an empty TestResult. // Creates an empty TestResult.
TestResult(); TestResult();
@ -530,7 +535,7 @@ class GTEST_API_ TestResult {
// The constructor of TestInfo registers itself with the UnitTest // The constructor of TestInfo registers itself with the UnitTest
// singleton such that the RUN_ALL_TESTS() macro knows which tests to // singleton such that the RUN_ALL_TESTS() macro knows which tests to
// run. // run.
class GTEST_API_ TestInfo { class GTEST_API_ [[nodiscard]] TestInfo {
public: public:
// Destructs a TestInfo object. This function is not virtual, so // Destructs a TestInfo object. This function is not virtual, so
// don't inherit from TestInfo. // don't inherit from TestInfo.
@ -669,7 +674,7 @@ class GTEST_API_ TestInfo {
// A test suite, which consists of a vector of TestInfos. // A test suite, which consists of a vector of TestInfos.
// //
// TestSuite is not copyable. // TestSuite is not copyable.
class GTEST_API_ TestSuite { class GTEST_API_ [[nodiscard]] TestSuite {
public: public:
// Creates a TestSuite with the given name. // Creates a TestSuite with the given name.
// //
@ -890,7 +895,7 @@ class GTEST_API_ TestSuite {
// available. // available.
// 2. You cannot use ASSERT_* directly in a constructor or // 2. You cannot use ASSERT_* directly in a constructor or
// destructor. // destructor.
class Environment { class [[nodiscard]] Environment {
public: public:
// The d'tor is virtual as we need to subclass Environment. // The d'tor is virtual as we need to subclass Environment.
virtual ~Environment() = default; virtual ~Environment() = default;
@ -911,7 +916,7 @@ class Environment {
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
// Exception which can be thrown from TestEventListener::OnTestPartResult. // Exception which can be thrown from TestEventListener::OnTestPartResult.
class GTEST_API_ AssertionException class GTEST_API_ [[nodiscard]] AssertionException
: public internal::GoogleTestFailureException { : public internal::GoogleTestFailureException {
public: public:
explicit AssertionException(const TestPartResult& result) explicit AssertionException(const TestPartResult& result)
@ -922,7 +927,7 @@ class GTEST_API_ AssertionException
// The interface for tracing execution of tests. The methods are organized in // The interface for tracing execution of tests. The methods are organized in
// the order the corresponding events are fired. // the order the corresponding events are fired.
class TestEventListener { class [[nodiscard]] TestEventListener {
public: public:
virtual ~TestEventListener() = default; virtual ~TestEventListener() = default;
@ -989,7 +994,7 @@ class TestEventListener {
// the methods they override will not be caught during the build. For // the methods they override will not be caught during the build. For
// comments about each method please see the definition of TestEventListener // comments about each method please see the definition of TestEventListener
// above. // above.
class EmptyTestEventListener : public TestEventListener { class [[nodiscard]] EmptyTestEventListener : public TestEventListener {
public: public:
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
void OnTestIterationStart(const UnitTest& /*unit_test*/, void OnTestIterationStart(const UnitTest& /*unit_test*/,
@ -1019,7 +1024,7 @@ class EmptyTestEventListener : public TestEventListener {
}; };
// TestEventListeners lets users add listeners to track events in Google Test. // TestEventListeners lets users add listeners to track events in Google Test.
class GTEST_API_ TestEventListeners { class GTEST_API_ [[nodiscard]] TestEventListeners {
public: public:
TestEventListeners(); TestEventListeners();
~TestEventListeners(); ~TestEventListeners();
@ -1110,7 +1115,7 @@ class GTEST_API_ TestEventListeners {
// //
// This class is thread-safe as long as the methods are called // This class is thread-safe as long as the methods are called
// according to their specification. // according to their specification.
class GTEST_API_ UnitTest { class GTEST_API_ [[nodiscard]] UnitTest {
public: public:
// Gets the singleton UnitTest object. The first time this method // Gets the singleton UnitTest object. The first time this method
// is called, a UnitTest object is constructed and returned. // is called, a UnitTest object is constructed and returned.
@ -1246,7 +1251,7 @@ class GTEST_API_ UnitTest {
// eventually call this to report their results. The user code // eventually call this to report their results. The user code
// should use the assertion macros instead of calling this directly. // should use the assertion macros instead of calling this directly.
void AddTestPartResult(TestPartResult::Type result_type, void AddTestPartResult(TestPartResult::Type result_type,
const char* file_name, int line_number, std::string_view file_name, int line_number,
const std::string& message, const std::string& message,
const std::string& os_stack_trace) const std::string& os_stack_trace)
GTEST_LOCK_EXCLUDED_(mutex_); GTEST_LOCK_EXCLUDED_(mutex_);
@ -1398,7 +1403,7 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs); return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
} }
class EqHelper { class [[nodiscard]] EqHelper {
public: public:
// This templatized version is for the general case. // This templatized version is for the general case.
template < template <
@ -1610,18 +1615,23 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
double val1, double val2, double val1, double val2,
double abs_error); double abs_error);
using GoogleTest_NotSupported_OnFunctionReturningNonVoid = void;
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// A class that enables one to stream messages to assertion macros // A class that enables one to stream messages to assertion macros
class GTEST_API_ AssertHelper { class GTEST_API_ [[nodiscard]] AssertHelper {
public: public:
// Constructor. // Constructor.
AssertHelper(TestPartResult::Type type, const char* file, int line, AssertHelper(TestPartResult::Type type, const char* file, int line,
const char* message); const char* message);
AssertHelper(TestPartResult::Type type, std::string_view file, int line,
std::string_view message);
~AssertHelper(); ~AssertHelper();
// Message assignment is a semantic trick to enable assertion // Message assignment is a semantic trick to enable assertion
// streaming; see the GTEST_MESSAGE_ macro below. // streaming; see the GTEST_MESSAGE_ macro below.
void operator=(const Message& message) const; GoogleTest_NotSupported_OnFunctionReturningNonVoid operator=(
const Message& message) const;
private: private:
// We put our data in a struct so that the size of the AssertHelper class can // We put our data in a struct so that the size of the AssertHelper class can
@ -1629,12 +1639,12 @@ class GTEST_API_ AssertHelper {
// re-using stack space even for temporary variables, so every EXPECT_EQ // re-using stack space even for temporary variables, so every EXPECT_EQ
// reserves stack space for another AssertHelper. // reserves stack space for another AssertHelper.
struct AssertHelperData { struct AssertHelperData {
AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, AssertHelperData(TestPartResult::Type t, std::string_view srcfile,
const char* msg) int line_num, std::string_view msg)
: type(t), file(srcfile), line(line_num), message(msg) {} : type(t), file(srcfile), line(line_num), message(msg) {}
TestPartResult::Type const type; TestPartResult::Type const type;
const char* const file; const std::string_view file;
int const line; int const line;
std::string const message; std::string const message;
@ -1686,14 +1696,14 @@ class GTEST_API_ AssertHelper {
// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); // INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
template <typename T> template <typename T>
class WithParamInterface { class [[nodiscard]] WithParamInterface {
public: public:
typedef T ParamType; typedef T ParamType;
virtual ~WithParamInterface() = default; virtual ~WithParamInterface() = default;
// The current parameter value. Is also available in the test fixture's // The current parameter value. Is also available in the test fixture's
// constructor. // constructor.
static const ParamType& GetParam() { [[nodiscard]] static const ParamType& GetParam() {
GTEST_CHECK_(parameter_ != nullptr) GTEST_CHECK_(parameter_ != nullptr)
<< "GetParam() can only be called inside a value-parameterized test " << "GetParam() can only be called inside a value-parameterized test "
<< "-- did you intend to write TEST_P instead of TEST_F?"; << "-- did you intend to write TEST_P instead of TEST_F?";
@ -1720,7 +1730,8 @@ const T* WithParamInterface<T>::parameter_ = nullptr;
// WithParamInterface, and can just inherit from ::testing::TestWithParam. // WithParamInterface, and can just inherit from ::testing::TestWithParam.
template <typename T> template <typename T>
class TestWithParam : public Test, public WithParamInterface<T> {}; class [[nodiscard]] TestWithParam : public Test,
public WithParamInterface<T> {};
// Macros for indicating success/failure in test code. // Macros for indicating success/failure in test code.
@ -1807,14 +1818,13 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
#define GTEST_EXPECT_TRUE(condition) \ #define GTEST_EXPECT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_NONFATAL_FAILURE_) GTEST_NONFATAL_FAILURE_)
#define GTEST_EXPECT_FALSE(condition) \ #define GTEST_EXPECT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_TEST_BOOLEAN_(condition, #condition, true, false, \
GTEST_NONFATAL_FAILURE_) GTEST_NONFATAL_FAILURE_)
#define GTEST_ASSERT_TRUE(condition) \ #define GTEST_ASSERT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_) GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)
#define GTEST_ASSERT_FALSE(condition) \ #define GTEST_ASSERT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_TEST_BOOLEAN_(condition, #condition, true, false, GTEST_FATAL_FAILURE_)
GTEST_FATAL_FAILURE_)
// Define these macros to 1 to omit the definition of the corresponding // Define these macros to 1 to omit the definition of the corresponding
// EXPECT or ASSERT, which clashes with some users' own code. // EXPECT or ASSERT, which clashes with some users' own code.
@ -2068,7 +2078,7 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
// Example: // Example:
// testing::ScopedTrace trace("file.cc", 123, "message"); // testing::ScopedTrace trace("file.cc", 123, "message");
// //
class GTEST_API_ ScopedTrace { class GTEST_API_ [[nodiscard]] ScopedTrace {
public: public:
// The c'tor pushes the given source file location and message onto // The c'tor pushes the given source file location and message onto
// a trace stack maintained by Google Test. // a trace stack maintained by Google Test.
@ -2153,7 +2163,7 @@ class GTEST_API_ ScopedTrace {
// to cause a compiler error. // to cause a compiler error.
template <typename T1, typename T2> template <typename T1, typename T2>
constexpr bool StaticAssertTypeEq() noexcept { constexpr bool StaticAssertTypeEq() noexcept {
static_assert(std::is_same<T1, T2>::value, "T1 and T2 are not the same type"); static_assert(std::is_same_v<T1, T2>, "T1 and T2 are not the same type");
return true; return true;
} }
@ -2299,7 +2309,7 @@ template <int&... ExplicitParameterBarrier, typename Factory>
TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
const char* type_param, const char* value_param, const char* type_param, const char* value_param,
const char* file, int line, Factory factory) { const char* file, int line, Factory factory) {
using TestT = typename std::remove_pointer<decltype(factory())>::type; using TestT = std::remove_pointer_t<decltype(factory())>;
class FactoryImpl : public internal::TestFactoryBase { class FactoryImpl : public internal::TestFactoryBase {
public: public:

@ -43,6 +43,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <string_view>
#include "gtest/gtest-matchers.h" #include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
@ -63,6 +64,10 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) { ::testing::internal::RE regex) {
return ContainsRegex(regex.pattern()); return ContainsRegex(regex.pattern());
} }
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
std::string_view regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) { inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex); return ContainsRegex(regex);
} }
@ -96,7 +101,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// by wait(2) // by wait(2)
// exit code: The integer code passed to exit(3), _Exit(2), or // exit code: The integer code passed to exit(3), _Exit(2), or
// returned from main() // returned from main()
class GTEST_API_ DeathTest { class GTEST_API_ [[nodiscard]] DeathTest {
public: public:
// Create returns false if there was an error determining the // Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example, // appropriate action to take for the current death test; for example,
@ -172,7 +177,7 @@ class GTEST_API_ DeathTest {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// Factory interface for death tests. May be mocked out for testing. // Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory { class [[nodiscard]] DeathTestFactory {
public: public:
virtual ~DeathTestFactory() = default; virtual ~DeathTestFactory() = default;
virtual bool Create(const char* statement, virtual bool Create(const char* statement,
@ -181,7 +186,7 @@ class DeathTestFactory {
}; };
// A concrete DeathTestFactory implementation for normal use. // A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory { class [[nodiscard]] DefaultDeathTestFactory : public DeathTestFactory {
public: public:
bool Create(const char* statement, Matcher<const std::string&> matcher, bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test) override; const char* file, int line, DeathTest** test) override;
@ -229,7 +234,8 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \ } \
if (gtest_dt != nullptr) { \ if (gtest_dt != nullptr) { \
std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \ const std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr( \
gtest_dt); \
switch (gtest_dt->AssumeRole()) { \ switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \ case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
@ -256,19 +262,19 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// must accept a streamed message even though the message is never printed. // must accept a streamed message even though the message is never printed.
// The regex object is not evaluated, but it is used to prevent "unused" // The regex object is not evaluated, but it is used to prevent "unused"
// warnings and to avoid an expression that doesn't compile in debug mode. // warnings and to avoid an expression that doesn't compile in debug mode.
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \ #define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else if (!::testing::internal::AlwaysTrue()) { \ } else if (!::testing::internal::AlwaysTrue()) { \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \ (void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
} else \ } else \
::testing::Message() ::testing::Message()
// A class representing the parsed contents of the // A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when // --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called. // RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag { class [[nodiscard]] InternalRunDeathTestFlag {
public: public:
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
int a_write_fd) int a_write_fd)

@ -67,7 +67,7 @@ namespace internal {
// Names are NOT checked for syntax correctness -- no checking for illegal // Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc. // characters, malformed paths, etc.
class GTEST_API_ FilePath { class GTEST_API_ [[nodiscard]] FilePath {
public: public:
FilePath() : pathname_("") {} FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}

@ -95,7 +95,13 @@
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, ) #define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
namespace proto2 { namespace proto2 {
class MessageLite; class [[nodiscard]] MessageLite;
// Dummy forward declaration of `DynamicCastMessage`. Does not match any actual
// overloads of `DynamicCastMessage`, but can be used to assist name resolution
// in templates.
template <typename T>
T DynamicCastMessage() = delete;
} }
namespace testing { namespace testing {
@ -115,15 +121,15 @@ template <typename T>
namespace internal { namespace internal {
struct TraceInfo; // Information about a trace point. struct TraceInfo; // Information about a trace point.
class TestInfoImpl; // Opaque implementation of TestInfo class [[nodiscard]] TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest class [[nodiscard]] UnitTestImpl; // Opaque implementation of UnitTest
// The text used in failure messages to indicate the start of the // The text used in failure messages to indicate the start of the
// stack trace. // stack trace.
GTEST_API_ extern const char kStackTraceMarker[]; GTEST_API_ extern const char kStackTraceMarker[];
// An IgnoredValue object can be implicitly constructed from ANY value. // An IgnoredValue object can be implicitly constructed from ANY value.
class IgnoredValue { class [[nodiscard]] IgnoredValue {
struct Sink {}; struct Sink {};
public: public:
@ -155,7 +161,8 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
// errors presumably detectable only at run time. Since // errors presumably detectable only at run time. Since
// std::runtime_error inherits from std::exception, many testing // std::runtime_error inherits from std::exception, many testing
// frameworks know how to extract and print the message inside it. // frameworks know how to extract and print the message inside it.
class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { class GTEST_API_ [[nodiscard]] GoogleTestFailureException
: public ::std::runtime_error {
public: public:
explicit GoogleTestFailureException(const TestPartResult& failure); explicit GoogleTestFailureException(const TestPartResult& failure);
}; };
@ -242,7 +249,7 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage(
// //
// RawType: the raw floating-point type (either float or double) // RawType: the raw floating-point type (either float or double)
template <typename RawType> template <typename RawType>
class FloatingPoint { class [[nodiscard]] FloatingPoint {
public: public:
// Defines the unsigned integer type that has the same size as the // Defines the unsigned integer type that has the same size as the
// floating point number. // floating point number.
@ -392,7 +399,7 @@ typedef FloatingPoint<double> Double;
typedef const void* TypeId; typedef const void* TypeId;
template <typename T> template <typename T>
class TypeIdHelper { class [[nodiscard]] TypeIdHelper {
public: public:
// dummy_ must not have a const type. Otherwise an overly eager // dummy_ must not have a const type. Otherwise an overly eager
// compiler (e.g. MSVC 7.1 & 8.0) may try to merge // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
@ -424,7 +431,7 @@ GTEST_API_ TypeId GetTestTypeId();
// Defines the abstract factory interface that creates instances // Defines the abstract factory interface that creates instances
// of a Test object. // of a Test object.
class TestFactoryBase { class [[nodiscard]] TestFactoryBase {
public: public:
virtual ~TestFactoryBase() = default; virtual ~TestFactoryBase() = default;
@ -443,7 +450,7 @@ class TestFactoryBase {
// This class provides implementation of TestFactoryBase interface. // This class provides implementation of TestFactoryBase interface.
// It is used in TEST and TEST_F macros. // It is used in TEST and TEST_F macros.
template <class TestClass> template <class TestClass>
class TestFactoryImpl : public TestFactoryBase { class [[nodiscard]] TestFactoryImpl : public TestFactoryBase {
public: public:
Test* CreateTest() override { return new TestClass; } Test* CreateTest() override { return new TestClass; }
}; };
@ -570,7 +577,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
// State of the definition of a type-parameterized test suite. // State of the definition of a type-parameterized test suite.
class GTEST_API_ TypedTestSuitePState { class GTEST_API_ [[nodiscard]] TypedTestSuitePState {
public: public:
TypedTestSuitePState() : registered_(false) {} TypedTestSuitePState() : registered_(false) {}
@ -685,7 +692,7 @@ std::vector<std::string> GenerateNames() {
// Implementation note: The GTEST_TEMPLATE_ macro declares a template // Implementation note: The GTEST_TEMPLATE_ macro declares a template
// template parameter. It's defined in gtest-type-util.h. // template parameter. It's defined in gtest-type-util.h.
template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types> template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
class TypeParameterizedTest { class [[nodiscard]] TypeParameterizedTest {
public: public:
// 'index' is the index of the test in the type list 'Types' // 'index' is the index of the test in the type list 'Types'
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite, // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
@ -723,7 +730,7 @@ class TypeParameterizedTest {
// The base case for the compile time recursion. // The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, class TestSel> template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, internal::None> { class [[nodiscard]] TypeParameterizedTest<Fixture, TestSel, internal::None> {
public: public:
static bool Register(const char* /*prefix*/, CodeLocation, static bool Register(const char* /*prefix*/, CodeLocation,
const char* /*case_name*/, const char* /*test_names*/, const char* /*case_name*/, const char* /*test_names*/,
@ -744,7 +751,7 @@ GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
// Test. The return value is insignificant - we just need to return // Test. The return value is insignificant - we just need to return
// something such that we can call this function in a namespace scope. // something such that we can call this function in a namespace scope.
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
class TypeParameterizedTestSuite { class [[nodiscard]] TypeParameterizedTestSuite {
public: public:
static bool Register(const char* prefix, CodeLocation code_location, static bool Register(const char* prefix, CodeLocation code_location,
const TypedTestSuitePState* state, const char* case_name, const TypedTestSuitePState* state, const char* case_name,
@ -782,7 +789,7 @@ class TypeParameterizedTestSuite {
// The base case for the compile time recursion. // The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestSuite<Fixture, internal::None, Types> { class [[nodiscard]] TypeParameterizedTestSuite<Fixture, internal::None, Types> {
public: public:
static bool Register(const char* /*prefix*/, const CodeLocation&, static bool Register(const char* /*prefix*/, const CodeLocation&,
const TypedTestSuitePState* /*state*/, const TypedTestSuitePState* /*state*/,
@ -838,7 +845,7 @@ struct TrueWithString {
// doesn't use global state (and therefore can't interfere with user // doesn't use global state (and therefore can't interfere with user
// code). Unlike rand_r(), it's portable. An LCG isn't very random, // code). Unlike rand_r(), it's portable. An LCG isn't very random,
// but it's good enough for our purposes. // but it's good enough for our purposes.
class GTEST_API_ Random { class GTEST_API_ [[nodiscard]] Random {
public: public:
static const uint32_t kMaxRange = 1u << 31; static const uint32_t kMaxRange = 1u << 31;
@ -864,7 +871,7 @@ class GTEST_API_ Random {
// that's true if and only if T has methods DebugString() and ShortDebugString() // that's true if and only if T has methods DebugString() and ShortDebugString()
// that return std::string. // that return std::string.
template <typename T> template <typename T>
class HasDebugStringAndShortDebugString { class [[nodiscard]] HasDebugStringAndShortDebugString {
private: private:
template <typename C> template <typename C>
static auto CheckDebugString(C*) -> typename std::is_same< static auto CheckDebugString(C*) -> typename std::is_same<
@ -1064,7 +1071,7 @@ struct RelationToSourceCopy {};
// this requirement. Element can be an array type itself (hence // this requirement. Element can be an array type itself (hence
// multi-dimensional arrays are supported). // multi-dimensional arrays are supported).
template <typename Element> template <typename Element>
class NativeArray { class [[nodiscard]] NativeArray {
public: public:
// STL-style container typedefs. // STL-style container typedefs.
typedef Element value_type; typedef Element value_type;
@ -1150,7 +1157,7 @@ struct ElemFromList {
struct FlatTupleConstructTag {}; struct FlatTupleConstructTag {};
template <typename... T> template <typename... T>
class FlatTuple; class [[nodiscard]] FlatTuple;
template <typename Derived, size_t I> template <typename Derived, size_t I>
struct FlatTupleElemBase; struct FlatTupleElemBase;
@ -1209,7 +1216,7 @@ struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
// std::make_index_sequence, on the other hand, it is recursive but with an // std::make_index_sequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)). // instantiation depth of O(ln(N)).
template <typename... T> template <typename... T>
class FlatTuple class [[nodiscard]] FlatTuple
: private FlatTupleBase<FlatTuple<T...>, : private FlatTupleBase<FlatTuple<T...>,
std::make_index_sequence<sizeof...(T)>> { std::make_index_sequence<sizeof...(T)>> {
using Indices = using Indices =
@ -1317,7 +1324,7 @@ struct tuple_size<testing::internal::FlatTuple<Ts...>>
namespace testing { namespace testing {
namespace internal { namespace internal {
class NeverThrown { class [[nodiscard]] NeverThrown {
public: public:
const char* what() const noexcept { const char* what() const noexcept {
return "this exception should never be thrown"; return "this exception should never be thrown";
@ -1444,15 +1451,14 @@ class NeverThrown {
// Implements Boolean test assertions such as EXPECT_TRUE. expression can be // Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual // either a boolean expression or an AssertionResult. text is a textual
// representation of expression as it was passed into the EXPECT_TRUE. // representation of expression as it was passed into the EXPECT_TRUE.
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar_ = \ if (const ::testing::internal::AssertionResultExpectation gtest_are_ = { \
::testing::AssertionResult(expression)) \ ::testing::AssertionResult(expression), expected}) \
; \ ; \
else \ else /* NOLINT */ \
fail(::testing::internal::GetBoolAssertionFailureMessage( \ fail(::testing::internal::GetBoolAssertionFailureMessage( \
gtest_ar_, text, #actual, #expected) \ gtest_are_.assertion_result, text, #actual, #expected))
.c_str())
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \

@ -90,14 +90,14 @@ GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
const CodeLocation& code_location); const CodeLocation& code_location);
template <typename> template <typename>
class ParamGeneratorInterface; class [[nodiscard]] ParamGeneratorInterface;
template <typename> template <typename>
class ParamGenerator; class [[nodiscard]] ParamGenerator;
// Interface for iterating over elements provided by an implementation // Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>. // of ParamGeneratorInterface<T>.
template <typename T> template <typename T>
class ParamIteratorInterface { class [[nodiscard]] ParamIteratorInterface {
public: public:
virtual ~ParamIteratorInterface() = default; virtual ~ParamIteratorInterface() = default;
// A pointer to the base generator instance. // A pointer to the base generator instance.
@ -127,7 +127,7 @@ class ParamIteratorInterface {
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> // ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
// and implements the const forward iterator concept. // and implements the const forward iterator concept.
template <typename T> template <typename T>
class ParamIterator { class [[nodiscard]] ParamIterator {
public: public:
typedef T value_type; typedef T value_type;
typedef const T& reference; typedef const T& reference;
@ -169,7 +169,7 @@ class ParamIterator {
// ParamGeneratorInterface<T> is the binary interface to access generators // ParamGeneratorInterface<T> is the binary interface to access generators
// defined in other translation units. // defined in other translation units.
template <typename T> template <typename T>
class ParamGeneratorInterface { class [[nodiscard]] ParamGeneratorInterface {
public: public:
typedef T ParamType; typedef T ParamType;
@ -186,7 +186,7 @@ class ParamGeneratorInterface {
// ParamGeneratorInterface<T> instance is shared among all copies // ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable. // of the original object. This is possible because that instance is immutable.
template <typename T> template <typename T>
class ParamGenerator { class [[nodiscard]] ParamGenerator {
public: public:
typedef ParamIterator<T> iterator; typedef ParamIterator<T> iterator;
@ -210,7 +210,7 @@ class ParamGenerator {
// operator<(). // operator<().
// This class is used in the Range() function. // This class is used in the Range() function.
template <typename T, typename IncrementT> template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> { class [[nodiscard]] RangeGenerator : public ParamGeneratorInterface<T> {
public: public:
RangeGenerator(T begin, T end, IncrementT step) RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), : begin_(begin),
@ -296,7 +296,8 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
// since the source can be located on the stack, and the generator // since the source can be located on the stack, and the generator
// is likely to persist beyond that stack frame. // is likely to persist beyond that stack frame.
template <typename T> template <typename T>
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { class [[nodiscard]] ValuesInIteratorRangeGenerator
: public ParamGeneratorInterface<T> {
public: public:
template <typename ForwardIterator> template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
@ -396,7 +397,7 @@ void TestNotEmpty(const T&) {}
// Stores a parameter value and later creates tests parameterized with that // Stores a parameter value and later creates tests parameterized with that
// value. // value.
template <class TestClass> template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase { class [[nodiscard]] ParameterizedTestFactory : public TestFactoryBase {
public: public:
typedef typename TestClass::ParamType ParamType; typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) explicit ParameterizedTestFactory(ParamType parameter)
@ -418,7 +419,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
// TestMetaFactoryBase is a base class for meta-factories that create // TestMetaFactoryBase is a base class for meta-factories that create
// test factories for passing into MakeAndRegisterTestInfo function. // test factories for passing into MakeAndRegisterTestInfo function.
template <class ParamType> template <class ParamType>
class TestMetaFactoryBase { class [[nodiscard]] TestMetaFactoryBase {
public: public:
virtual ~TestMetaFactoryBase() = default; virtual ~TestMetaFactoryBase() = default;
@ -434,7 +435,7 @@ class TestMetaFactoryBase {
// it for each Test/Parameter value combination. Thus it needs meta factory // it for each Test/Parameter value combination. Thus it needs meta factory
// creator class. // creator class.
template <class TestSuite> template <class TestSuite>
class TestMetaFactory class [[nodiscard]] TestMetaFactory
: public TestMetaFactoryBase<typename TestSuite::ParamType> { : public TestMetaFactoryBase<typename TestSuite::ParamType> {
public: public:
using ParamType = typename TestSuite::ParamType; using ParamType = typename TestSuite::ParamType;
@ -460,7 +461,7 @@ class TestMetaFactory
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds // in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
// a collection of pointers to the ParameterizedTestSuiteInfo objects // a collection of pointers to the ParameterizedTestSuiteInfo objects
// and calls RegisterTests() on each of them when asked. // and calls RegisterTests() on each of them when asked.
class ParameterizedTestSuiteInfoBase { class [[nodiscard]] ParameterizedTestSuiteInfoBase {
public: public:
virtual ~ParameterizedTestSuiteInfoBase() = default; virtual ~ParameterizedTestSuiteInfoBase() = default;
@ -503,7 +504,8 @@ GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
// test suite. It registers tests with all values generated by all // test suite. It registers tests with all values generated by all
// generators when asked. // generators when asked.
template <class TestSuite> template <class TestSuite>
class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { class [[nodiscard]] ParameterizedTestSuiteInfo
: public ParameterizedTestSuiteInfoBase {
public: public:
// ParamType and GeneratorCreationFunc are private types but are required // ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and // for declarations of public methods AddTestPattern() and
@ -688,7 +690,7 @@ using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P // ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding // and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
// ParameterizedTestSuiteInfo descriptors. // ParameterizedTestSuiteInfo descriptors.
class ParameterizedTestSuiteRegistry { class [[nodiscard]] ParameterizedTestSuiteRegistry {
public: public:
ParameterizedTestSuiteRegistry() = default; ParameterizedTestSuiteRegistry() = default;
~ParameterizedTestSuiteRegistry() { ~ParameterizedTestSuiteRegistry() {
@ -762,7 +764,7 @@ class ParameterizedTestSuiteRegistry {
// Keep track of what type-parameterized test suite are defined and // Keep track of what type-parameterized test suite are defined and
// where as well as which are intatiated. This allows susequently // where as well as which are intatiated. This allows susequently
// identifying suits that are defined but never used. // identifying suits that are defined but never used.
class TypeParameterizedTestSuiteRegistry { class [[nodiscard]] TypeParameterizedTestSuiteRegistry {
public: public:
// Add a suite definition // Add a suite definition
void RegisterTestSuite(const char* test_suite_name, void RegisterTestSuite(const char* test_suite_name,
@ -801,7 +803,7 @@ namespace internal {
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
template <typename... Ts> template <typename... Ts>
class ValueArray { class [[nodiscard]] ValueArray {
public: public:
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {} explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
@ -822,7 +824,7 @@ class ValueArray {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
template <typename... T> template <typename... T>
class CartesianProductGenerator class [[nodiscard]] CartesianProductGenerator
: public ParamGeneratorInterface<::std::tuple<T...>> { : public ParamGeneratorInterface<::std::tuple<T...>> {
public: public:
typedef ::std::tuple<T...> ParamType; typedef ::std::tuple<T...> ParamType;
@ -939,7 +941,7 @@ class CartesianProductGenerator
}; };
template <class... Gen> template <class... Gen>
class CartesianProductHolder { class [[nodiscard]] CartesianProductHolder {
public: public:
CartesianProductHolder(const Gen&... g) : generators_(g...) {} CartesianProductHolder(const Gen&... g) : generators_(g...) {}
template <typename... T> template <typename... T>
@ -953,7 +955,8 @@ class CartesianProductHolder {
}; };
template <typename From, typename To, typename Func> template <typename From, typename To, typename Func>
class ParamGeneratorConverter : public ParamGeneratorInterface<To> { class [[nodiscard]] ParamGeneratorConverter
: public ParamGeneratorInterface<To> {
public: public:
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
: generator_(std::move(gen)), converter_(std::move(converter)) {} : generator_(std::move(gen)), converter_(std::move(converter)) {}
@ -1023,7 +1026,7 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
template <class GeneratedT, template <class GeneratedT,
typename StdFunction = typename StdFunction =
std::function<const GeneratedT&(const GeneratedT&)>> std::function<const GeneratedT&(const GeneratedT&)>>
class ParamConverterGenerator { class [[nodiscard]] ParamConverterGenerator {
public: public:
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
: generator_(std::move(g)), converter_(Identity) {} : generator_(std::move(g)), converter_(Identity) {}

@ -119,6 +119,8 @@
#define GTEST_OS_NXP_QN9090 1 #define GTEST_OS_NXP_QN9090 1
#elif defined(NRF52) #elif defined(NRF52)
#define GTEST_OS_NRF52 1 #define GTEST_OS_NRF52 1
#elif defined(__EMSCRIPTEN__)
#define GTEST_OS_EMSCRIPTEN 1
#endif // __CYGWIN__ #endif // __CYGWIN__
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_

@ -198,21 +198,8 @@
// suppressed (constant conditional). // suppressed (constant conditional).
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
// is suppressed. // is suppressed.
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
// 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_STD_SPAN - for enabling UniversalPrinter<std::span> // GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
// specializations. Always defined to 0 or 1 // specializations. Always defined to 0 or 1
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
// Matcher<absl::string_view>
// specializations. Always defined to 0 or 1.
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
// UniversalPrinter<absl::variant>
// specializations. Always defined to 0 or 1.
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1. // GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
// GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1. // GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1. // GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
@ -306,9 +293,10 @@
#include <limits> #include <limits>
#include <locale> #include <locale>
#include <memory> #include <memory>
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
#include <ostream> #include <ostream>
#include <string> #include <string>
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below #include <string_view>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -376,18 +364,24 @@
#define GTEST_DISABLE_MSC_WARNINGS_POP_() #define GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif #endif
// Clang on Windows does not understand MSVC's pragma warning. // Pragmas to disable function deprecation warnings.
// We need clang-specific way to disable function deprecation warning. #if defined(__clang__)
#ifdef __clang__ #define GTEST_DISABLE_DEPRECATED_PUSH_() \
#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
_Pragma("clang diagnostic push") \ _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"") _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"")
#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma("clang diagnostic pop") #define GTEST_DISABLE_DEPRECATED_POP_() _Pragma("clang diagnostic pop")
#elif defined(__GNUC__)
#define GTEST_DISABLE_DEPRECATED_PUSH_() \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define GTEST_DISABLE_DEPRECATED_POP_() _Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
#define GTEST_DISABLE_DEPRECATED_PUSH_() GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
#define GTEST_DISABLE_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
#else #else
#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ #define GTEST_DISABLE_DEPRECATED_PUSH_()
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) #define GTEST_DISABLE_DEPRECATED_POP_()
#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif #endif
// Brings in definitions for functions used in the testing::internal::posix // Brings in definitions for functions used in the testing::internal::posix
@ -606,7 +600,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \ defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \ defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \
defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \ defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS)) defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS) || \
(defined(GTEST_OS_EMSCRIPTEN) && defined(__EMSCRIPTEN_PTHREADS__)))
#define GTEST_HAS_PTHREAD 1 #define GTEST_HAS_PTHREAD 1
#else #else
#define GTEST_HAS_PTHREAD 0 #define GTEST_HAS_PTHREAD 0
@ -677,12 +672,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \ defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \ defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD)) defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))
// Death tests require a file system to work properly. // Death tests require a file system to work properly.
#if GTEST_HAS_FILE_SYSTEM #if GTEST_HAS_FILE_SYSTEM
#define GTEST_HAS_DEATH_TEST 1 #define GTEST_HAS_DEATH_TEST 1
#endif // GTEST_HAS_FILE_SYSTEM #endif // GTEST_HAS_FILE_SYSTEM
#endif #endif
// Determines whether the Premature Exit file can be created.
// Created by default when Death tests are supported, but other platforms can
// use the Premature exit file without Death test support (e.g. for detecting
// crashes).
#if GTEST_HAS_DEATH_TEST || \
(defined(GTEST_OS_EMSCRIPTEN) && GTEST_HAS_FILE_SYSTEM)
#define GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE 1
#endif
// Determines whether to support type-driven tests. // Determines whether to support type-driven tests.
// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0, // Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
@ -835,11 +840,13 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_API_ #ifndef GTEST_API_
#ifdef _MSC_VER #ifdef _MSC_VER
#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY #if defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllimport)
#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllexport) #define GTEST_API_ __declspec(dllexport)
#elif defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllimport)
#endif #endif
#elif GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(gnu::visibility)
#define GTEST_API_ [[gnu::visibility("default")]]
#elif GTEST_HAVE_ATTRIBUTE_(visibility) #elif GTEST_HAVE_ATTRIBUTE_(visibility)
#define GTEST_API_ __attribute__((visibility("default"))) #define GTEST_API_ __attribute__((visibility("default")))
#endif // _MSC_VER #endif // _MSC_VER
@ -930,7 +937,7 @@ namespace internal {
// A secret type that Google Test users don't know about. It has no // A secret type that Google Test users don't know about. It has no
// accessible constructors on purpose. Therefore it's impossible to create a // accessible constructors on purpose. Therefore it's impossible to create a
// Secret object, which is what we want. // Secret object, which is what we want.
class Secret { class [[nodiscard]] Secret {
Secret(const Secret&) = delete; Secret(const Secret&) = delete;
}; };
@ -943,21 +950,21 @@ GTEST_API_ bool IsTrue(bool condition);
#ifdef GTEST_USES_RE2 #ifdef GTEST_USES_RE2
// This is almost `using RE = ::RE2`, except it is copy-constructible, and it // This is almost `using RE = ::RE2`, except it is copy-constructible, and it
// needs to disambiguate the `std::string`, `absl::string_view`, and `const // needs to disambiguate the `std::string`, `std::string_view`, and `const
// char*` constructors. // char*` constructors.
class GTEST_API_ RE { class GTEST_API_ [[nodiscard]] RE {
public: public:
RE(absl::string_view regex) : regex_(regex) {} // NOLINT RE(std::string_view regex) : regex_(regex) {} // NOLINT
RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT RE(const char* regex) : RE(std::string_view(regex)) {} // NOLINT
RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT RE(const std::string& regex) : RE(std::string_view(regex)) {} // NOLINT
RE(const RE& other) : RE(other.pattern()) {} RE(const RE& other) : RE(other.pattern()) {}
const std::string& pattern() const { return regex_.pattern(); } const std::string& pattern() const { return regex_.pattern(); }
static bool FullMatch(absl::string_view str, const RE& re) { static bool FullMatch(std::string_view str, const RE& re) {
return RE2::FullMatch(str, re.regex_); return RE2::FullMatch(str, re.regex_);
} }
static bool PartialMatch(absl::string_view str, const RE& re) { static bool PartialMatch(std::string_view str, const RE& re) {
return RE2::PartialMatch(str, re.regex_); return RE2::PartialMatch(str, re.regex_);
} }
@ -971,7 +978,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended // A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
// Regular Expression syntax. // Regular Expression syntax.
class GTEST_API_ RE { class GTEST_API_ [[nodiscard]] RE {
public: public:
// A copy constructor is required by the Standard to initialize object // A copy constructor is required by the Standard to initialize object
// references from r-values. // references from r-values.
@ -1040,7 +1047,7 @@ enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };
// Formats log entry severity, provides a stream object for streaming the // Formats log entry severity, provides a stream object for streaming the
// log message, and terminates the message with a newline when going out of // log message, and terminates the message with a newline when going out of
// scope. // scope.
class GTEST_API_ GTestLog { class GTEST_API_ [[nodiscard]] GTestLog {
public: public:
GTestLog(GTestLogSeverity severity, const char* file, int line); GTestLog(GTestLogSeverity severity, const char* file, int line);
@ -1203,7 +1210,7 @@ void ClearInjectableArgvs();
#ifdef GTEST_OS_WINDOWS #ifdef GTEST_OS_WINDOWS
// Provides leak-safe Windows kernel handle ownership. // Provides leak-safe Windows kernel handle ownership.
// Used in death tests and in threading support. // Used in death tests and in threading support.
class GTEST_API_ AutoHandle { class GTEST_API_ [[nodiscard]] AutoHandle {
public: public:
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
// avoid including <windows.h> in this header file. Including <windows.h> is // avoid including <windows.h> in this header file. Including <windows.h> is
@ -1237,9 +1244,6 @@ class GTEST_API_ AutoHandle {
// Nothing to do here. // Nothing to do here.
#else #else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
// Allows a controller thread to pause execution of newly created // Allows a controller thread to pause execution of newly created
// threads until notified. Instances of this class must be created // threads until notified. Instances of this class must be created
// and destroyed in the controller thread. // and destroyed in the controller thread.
@ -1247,7 +1251,40 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// This class is only for testing Google Test's own constructs. Do not // This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly. // use it in user tests, either directly or indirectly.
// TODO(b/203539622): Replace unconditionally with absl::Notification. // TODO(b/203539622): Replace unconditionally with absl::Notification.
class GTEST_API_ Notification { #ifdef GTEST_OS_WINDOWS_MINGW
// GCC version < 13 with the win32 thread model does not provide std::mutex and
// std::condition_variable in the <mutex> and <condition_variable> headers. So
// we implement the Notification class using a Windows manual-reset event. See
// https://gcc.gnu.org/gcc-13/changes.html#windows.
class GTEST_API_ [[nodiscard]] Notification {
public:
Notification();
Notification(const Notification&) = delete;
Notification& operator=(const Notification&) = delete;
~Notification();
// Notifies all threads created with this notification to start. Must
// be called from the controller thread.
void Notify();
// Blocks until the controller thread notifies. Must be called from a test
// thread.
void WaitForNotification();
private:
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
// avoid including <windows.h> in this header file. Including <windows.h> is
// undesirable because it defines a lot of symbols and macros that tend to
// conflict with client code. This assumption is verified by
// WindowsTypesTest.HANDLEIsVoidStar.
typedef void* Handle;
Handle event_;
};
#else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
class GTEST_API_ [[nodiscard]] Notification {
public: public:
Notification() : notified_(false) {} Notification() : notified_(false) {}
Notification(const Notification&) = delete; Notification(const Notification&) = delete;
@ -1274,6 +1311,7 @@ class GTEST_API_ Notification {
bool notified_; bool notified_;
}; };
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_OS_WINDOWS_MINGW
#endif // GTEST_HAS_NOTIFICATION_ #endif // GTEST_HAS_NOTIFICATION_
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD // On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
@ -1286,7 +1324,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// in order to call its Run(). Introducing ThreadWithParamBase as a // in order to call its Run(). Introducing ThreadWithParamBase as a
// non-templated base class for ThreadWithParam allows us to bypass this // non-templated base class for ThreadWithParam allows us to bypass this
// problem. // problem.
class ThreadWithParamBase { class [[nodiscard]] ThreadWithParamBase {
public: public:
virtual ~ThreadWithParamBase() = default; virtual ~ThreadWithParamBase() = default;
virtual void Run() = 0; virtual void Run() = 0;
@ -1316,7 +1354,7 @@ extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
// These classes are only for testing Google Test's own constructs. Do // These classes are only for testing Google Test's own constructs. Do
// not use them in user tests, either directly or indirectly. // not use them in user tests, either directly or indirectly.
template <typename T> template <typename T>
class ThreadWithParam : public ThreadWithParamBase { class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
public: public:
typedef void UserThreadFunc(T); typedef void UserThreadFunc(T);
@ -1382,7 +1420,7 @@ class ThreadWithParam : public ThreadWithParamBase {
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
// //
// (A non-static Mutex is defined/declared in the usual way). // (A non-static Mutex is defined/declared in the usual way).
class GTEST_API_ Mutex { class GTEST_API_ [[nodiscard]] Mutex {
public: public:
enum MutexType { kStatic = 0, kDynamic = 1 }; enum MutexType { kStatic = 0, kDynamic = 1 };
// We rely on kStaticMutex being 0 as it is to what the linker initializes // We rely on kStaticMutex being 0 as it is to what the linker initializes
@ -1398,9 +1436,9 @@ class GTEST_API_ Mutex {
Mutex(); Mutex();
~Mutex(); ~Mutex();
void Lock(); void lock();
void Unlock(); void unlock();
// Does nothing if the current thread holds the mutex. Otherwise, crashes // Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability. // with high probability.
@ -1435,14 +1473,13 @@ class GTEST_API_ Mutex {
// platforms. That macro is used as a defensive measure to prevent against // platforms. That macro is used as a defensive measure to prevent against
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than // inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
// "MutexLock l(&mu)". Hence the typedef trick below. // "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock { class [[nodiscard]] GTestMutexLock {
public: public:
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
~GTestMutexLock() { mutex_.unlock(); }
~GTestMutexLock() { mutex_->Unlock(); }
private: private:
Mutex* const mutex_; Mutex& mutex_;
GTestMutexLock(const GTestMutexLock&) = delete; GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete; GTestMutexLock& operator=(const GTestMutexLock&) = delete;
@ -1452,14 +1489,14 @@ typedef GTestMutexLock MutexLock;
// Base class for ValueHolder<T>. Allows a caller to hold and delete a value // Base class for ValueHolder<T>. Allows a caller to hold and delete a value
// without knowing its type. // without knowing its type.
class ThreadLocalValueHolderBase { class [[nodiscard]] ThreadLocalValueHolderBase {
public: public:
virtual ~ThreadLocalValueHolderBase() {} virtual ~ThreadLocalValueHolderBase() = default;
}; };
// Provides a way for a thread to send notifications to a ThreadLocal // Provides a way for a thread to send notifications to a ThreadLocal
// regardless of its parameter type. // regardless of its parameter type.
class ThreadLocalBase { class [[nodiscard]] ThreadLocalBase {
public: public:
// Creates a new ValueHolder<T> object holding a default value passed to // Creates a new ValueHolder<T> object holding a default value passed to
// this ThreadLocal<T>'s constructor and returns it. It is the caller's // this ThreadLocal<T>'s constructor and returns it. It is the caller's
@ -1468,8 +1505,8 @@ class ThreadLocalBase {
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
protected: protected:
ThreadLocalBase() {} ThreadLocalBase() = default;
virtual ~ThreadLocalBase() {} virtual ~ThreadLocalBase() = default;
private: private:
ThreadLocalBase(const ThreadLocalBase&) = delete; ThreadLocalBase(const ThreadLocalBase&) = delete;
@ -1479,7 +1516,7 @@ class ThreadLocalBase {
// Maps a thread to a set of ThreadLocals that have values instantiated on that // Maps a thread to a set of ThreadLocals that have values instantiated on that
// thread and notifies them when the thread exits. A ThreadLocal instance is // thread and notifies them when the thread exits. A ThreadLocal instance is
// expected to persist until all threads it has values on have terminated. // expected to persist until all threads it has values on have terminated.
class GTEST_API_ ThreadLocalRegistry { class GTEST_API_ [[nodiscard]] ThreadLocalRegistry {
public: public:
// Registers thread_local_instance as having value on the current thread. // Registers thread_local_instance as having value on the current thread.
// Returns a value that can be used to identify the thread from other threads. // Returns a value that can be used to identify the thread from other threads.
@ -1491,14 +1528,14 @@ class GTEST_API_ ThreadLocalRegistry {
const ThreadLocalBase* thread_local_instance); const ThreadLocalBase* thread_local_instance);
}; };
class GTEST_API_ ThreadWithParamBase { class GTEST_API_ [[nodiscard]] ThreadWithParamBase {
public: public:
void Join(); void Join();
protected: protected:
class Runnable { class Runnable {
public: public:
virtual ~Runnable() {} virtual ~Runnable() = default;
virtual void Run() = 0; virtual void Run() = 0;
}; };
@ -1511,20 +1548,20 @@ class GTEST_API_ ThreadWithParamBase {
// Helper class for testing Google Test's multi-threading constructs. // Helper class for testing Google Test's multi-threading constructs.
template <typename T> template <typename T>
class ThreadWithParam : public ThreadWithParamBase { class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
public: public:
typedef void UserThreadFunc(T); typedef void UserThreadFunc(T);
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {} : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
virtual ~ThreadWithParam() {} ~ThreadWithParam() override = default;
private: private:
class RunnableImpl : public Runnable { class RunnableImpl : public Runnable {
public: public:
RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {} RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
virtual ~RunnableImpl() {} ~RunnableImpl() override = default;
virtual void Run() { func_(param_); } void Run() override { func_(param_); }
private: private:
UserThreadFunc* const func_; UserThreadFunc* const func_;
@ -1566,7 +1603,7 @@ class ThreadWithParam : public ThreadWithParamBase {
// object managed by Google Test will be leaked as long as all threads // object managed by Google Test will be leaked as long as all threads
// using Google Test have exited when main() returns. // using Google Test have exited when main() returns.
template <typename T> template <typename T>
class ThreadLocal : public ThreadLocalBase { class [[nodiscard]] ThreadLocal : public ThreadLocalBase {
public: public:
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {} ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
explicit ThreadLocal(const T& value) explicit ThreadLocal(const T& value)
@ -1607,8 +1644,8 @@ class ThreadLocal : public ThreadLocalBase {
class ValueHolderFactory { class ValueHolderFactory {
public: public:
ValueHolderFactory() {} ValueHolderFactory() = default;
virtual ~ValueHolderFactory() {} virtual ~ValueHolderFactory() = default;
virtual ValueHolder* MakeNewHolder() const = 0; virtual ValueHolder* MakeNewHolder() const = 0;
private: private:
@ -1618,7 +1655,7 @@ class ThreadLocal : public ThreadLocalBase {
class DefaultValueHolderFactory : public ValueHolderFactory { class DefaultValueHolderFactory : public ValueHolderFactory {
public: public:
DefaultValueHolderFactory() {} DefaultValueHolderFactory() = default;
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private: private:
@ -1651,17 +1688,17 @@ class ThreadLocal : public ThreadLocalBase {
#elif GTEST_HAS_PTHREAD #elif GTEST_HAS_PTHREAD
// MutexBase and Mutex implement mutex on pthreads-based platforms. // MutexBase and Mutex implement mutex on pthreads-based platforms.
class MutexBase { class [[nodiscard]] MutexBase {
public: public:
// Acquires this mutex. // Acquires this mutex.
void Lock() { void lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self(); owner_ = pthread_self();
has_owner_ = true; has_owner_ = true;
} }
// Releases this mutex. // Releases this mutex.
void Unlock() { void unlock() {
// Since the lock is being released the owner_ field should no longer be // Since the lock is being released the owner_ field should no longer be
// considered valid. We don't protect writing to has_owner_ here, as it's // considered valid. We don't protect writing to has_owner_ here, as it's
// the caller's responsibility to ensure that the current thread holds the // the caller's responsibility to ensure that the current thread holds the
@ -1709,7 +1746,7 @@ class MutexBase {
// The Mutex class can only be used for mutexes created at runtime. It // The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise. // shares its API with MutexBase otherwise.
class Mutex : public MutexBase { class [[nodiscard]] Mutex : public MutexBase {
public: public:
Mutex() { Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
@ -1727,14 +1764,13 @@ class Mutex : public MutexBase {
// platforms. That macro is used as a defensive measure to prevent against // platforms. That macro is used as a defensive measure to prevent against
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than // inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
// "MutexLock l(&mu)". Hence the typedef trick below. // "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock { class [[nodiscard]] GTestMutexLock {
public: public:
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
~GTestMutexLock() { mutex_.unlock(); }
~GTestMutexLock() { mutex_->Unlock(); }
private: private:
MutexBase* const mutex_; MutexBase& mutex_;
GTestMutexLock(const GTestMutexLock&) = delete; GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete; GTestMutexLock& operator=(const GTestMutexLock&) = delete;
@ -1748,7 +1784,7 @@ typedef GTestMutexLock MutexLock;
// C-linkage. Therefore it cannot be templatized to access // C-linkage. Therefore it cannot be templatized to access
// ThreadLocal<T>. Hence the need for class // ThreadLocal<T>. Hence the need for class
// ThreadLocalValueHolderBase. // ThreadLocalValueHolderBase.
class GTEST_API_ ThreadLocalValueHolderBase { class GTEST_API_ [[nodiscard]] ThreadLocalValueHolderBase {
public: public:
virtual ~ThreadLocalValueHolderBase() = default; virtual ~ThreadLocalValueHolderBase() = default;
}; };
@ -1761,7 +1797,7 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
// Implements thread-local storage on pthreads-based systems. // Implements thread-local storage on pthreads-based systems.
template <typename T> template <typename T>
class GTEST_API_ ThreadLocal { class GTEST_API_ [[nodiscard]] ThreadLocal {
public: public:
ThreadLocal() ThreadLocal()
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {} : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
@ -1874,11 +1910,11 @@ class GTEST_API_ ThreadLocal {
// mutex is not supported - using Google Test in multiple threads is not // mutex is not supported - using Google Test in multiple threads is not
// supported on such platforms. // supported on such platforms.
class Mutex { class [[nodiscard]] Mutex {
public: public:
Mutex() {} Mutex() {}
void Lock() {} void lock() {}
void Unlock() {} void unlock() {}
void AssertHeld() const {} void AssertHeld() const {}
}; };
@ -1892,15 +1928,15 @@ class Mutex {
// platforms. That macro is used as a defensive measure to prevent against // platforms. That macro is used as a defensive measure to prevent against
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than // inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
// "MutexLock l(&mu)". Hence the typedef trick below. // "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock { class [[nodiscard]] GTestMutexLock {
public: public:
explicit GTestMutexLock(Mutex*) {} // NOLINT explicit GTestMutexLock(Mutex&) {} // NOLINT
}; };
typedef GTestMutexLock MutexLock; typedef GTestMutexLock MutexLock;
template <typename T> template <typename T>
class GTEST_API_ ThreadLocal { class GTEST_API_ [[nodiscard]] ThreadLocal {
public: public:
ThreadLocal() : value_() {} ThreadLocal() : value_() {}
explicit ThreadLocal(const T& value) : value_(value) {} explicit ThreadLocal(const T& value) : value_(value) {}
@ -2090,7 +2126,7 @@ inline int IsATTY(int fd) {
// Functions deprecated by MSVC 8.0. // Functions deprecated by MSVC 8.0.
GTEST_DISABLE_MSC_DEPRECATED_PUSH_() GTEST_DISABLE_DEPRECATED_PUSH_()
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
// StrError() aren't needed on Windows CE at this time and thus not // StrError() aren't needed on Windows CE at this time and thus not
@ -2152,7 +2188,7 @@ inline const char* GetEnv(const char* name) {
#endif #endif
} }
GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_DEPRECATED_POP_()
#ifdef GTEST_OS_WINDOWS_MOBILE #ifdef GTEST_OS_WINDOWS_MOBILE
// Windows CE has no C library. The abort() function is used in // Windows CE has no C library. The abort() function is used in
@ -2208,7 +2244,7 @@ constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();
// needs. Other types can be easily added in the future if need // needs. Other types can be easily added in the future if need
// arises. // arises.
template <size_t size> template <size_t size>
class TypeWithSize { class [[nodiscard]] TypeWithSize {
public: public:
// This prevents the user from using TypeWithSize<N> with incorrect // This prevents the user from using TypeWithSize<N> with incorrect
// values of N. // values of N.
@ -2217,7 +2253,7 @@ class TypeWithSize {
// The specialization for size 4. // The specialization for size 4.
template <> template <>
class TypeWithSize<4> { class [[nodiscard]] TypeWithSize<4> {
public: public:
using Int = std::int32_t; using Int = std::int32_t;
using UInt = std::uint32_t; using UInt = std::uint32_t;
@ -2225,7 +2261,7 @@ class TypeWithSize<4> {
// The specialization for size 8. // The specialization for size 8.
template <> template <>
class TypeWithSize<8> { class [[nodiscard]] TypeWithSize<8> {
public: public:
using Int = std::int64_t; using Int = std::int64_t;
using UInt = std::uint64_t; using UInt = std::uint64_t;
@ -2255,11 +2291,11 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
// Macros for declaring flags. // Macros for declaring flags.
#define GTEST_DECLARE_bool_(name) \ #define GTEST_DECLARE_bool_(name) \
ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name)) GTEST_API_ ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
#define GTEST_DECLARE_int32_(name) \ #define GTEST_DECLARE_int32_(name) \
ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name)) GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
#define GTEST_DECLARE_string_(name) \ #define GTEST_DECLARE_string_(name) \
ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name)) GTEST_API_ ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
#define GTEST_FLAG_SAVER_ ::absl::FlagSaver #define GTEST_FLAG_SAVER_ ::absl::FlagSaver
@ -2273,22 +2309,29 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
// Macros for defining flags. // Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \ #define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_DECLARE_bool_(name); \
namespace testing { \ namespace testing { \
GTEST_API_ bool GTEST_FLAG(name) = (default_val); \ GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
} \ } \
static_assert(true, "no-op to require trailing semicolon") static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_int32_(name, default_val, doc) \ #define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_DECLARE_int32_(name); \
namespace testing { \ namespace testing { \
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \ GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
} \ } \
static_assert(true, "no-op to require trailing semicolon") static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_string_(name, default_val, doc) \ #define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_DECLARE_string_(name); \
namespace testing { \ namespace testing { \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
} \ } \
static_assert(true, "no-op to require trailing semicolon") static_assert(true, "no-op to require trailing semicolon")
// Macros for declaring flags. // Macros for declaring flags.
//
// We also need to declare the flag in the public namespace to avoid triggering
// -Wmissing-variable-declarations warnings, as reported here:
// https://github.com/google/googletest/issues/4897
#define GTEST_DECLARE_bool_(name) \ #define GTEST_DECLARE_bool_(name) \
namespace testing { \ namespace testing { \
GTEST_API_ extern bool GTEST_FLAG(name); \ GTEST_API_ extern bool GTEST_FLAG(name); \
@ -2335,71 +2378,11 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#ifdef GTEST_HAS_ABSL #if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate)
// Always use absl::any for UniversalPrinter<> specializations if googletest #define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \
// is built with absl support. [[deprecated(msg), clang::annotate("inline-me")]]
#define GTEST_INTERNAL_HAS_ANY 1
#include "absl/types/any.h"
namespace testing {
namespace internal {
using Any = ::absl::any;
} // namespace internal
} // namespace testing
#else
#if defined(__cpp_lib_any) || (GTEST_INTERNAL_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 // __cpp_lib_any
#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 #else
#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \ #define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]]
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 // __cpp_lib_optional
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_OPTIONAL
#define GTEST_INTERNAL_HAS_OPTIONAL 0
#endif #endif
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \ #if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
@ -2414,7 +2397,6 @@ inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
#ifdef GTEST_HAS_ABSL #ifdef GTEST_HAS_ABSL
// Always use absl::string_view for Matcher<> specializations if googletest // Always use absl::string_view for Matcher<> specializations if googletest
// is built with absl support. // is built with absl support.
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -2422,62 +2404,17 @@ using StringView = ::absl::string_view;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#else #else
#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<> // Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations. // specializations.
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include <string_view>
namespace testing { namespace testing {
namespace internal { namespace internal {
using StringView = ::std::string_view; using StringView = std::string_view;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
// The case where absl is configured NOT to alias std::string_view is not
// supported.
#endif // __cpp_lib_string_view
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW #if defined(__cpp_lib_three_way_comparison)
#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
#else
#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_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 // __cpp_lib_variant
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_VARIANT
#define GTEST_INTERNAL_HAS_VARIANT 0
#endif
#if (defined(__cpp_lib_three_way_comparison) || \
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
#define GTEST_INTERNAL_HAS_COMPARE_LIB 1 #define GTEST_INTERNAL_HAS_COMPARE_LIB 1
#else #else
#define GTEST_INTERNAL_HAS_COMPARE_LIB 0 #define GTEST_INTERNAL_HAS_COMPARE_LIB 0

@ -60,7 +60,7 @@ namespace testing {
namespace internal { namespace internal {
// String - an abstract class holding static string utilities. // String - an abstract class holding static string utilities.
class GTEST_API_ String { class GTEST_API_ [[nodiscard]] String {
public: public:
// Static utility methods // Static utility methods
@ -166,7 +166,7 @@ class GTEST_API_ String {
private: private:
String(); // Not meant to be instantiated. String(); // Not meant to be instantiated.
}; // class String }; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0' // Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0". // character in the buffer is replaced with "\\0".

@ -246,15 +246,12 @@ GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);
// be created, prints an error and exits. // be created, prints an error and exits.
void WriteToShardStatusFileIfNeeded(); void WriteToShardStatusFileIfNeeded();
// Checks whether sharding is enabled by examining the relevant // Checks whether sharding is enabled by examining the relevant flag values.
// environment variable values. If the variables are present, // If the flags are set, but inconsistent (e.g., shard_index >= total_shards),
// but inconsistent (e.g., shard_index >= total_shards), prints // prints an error and exits. If in_subprocess_for_death_test, sharding is
// an error and exits. If in_subprocess_for_death_test, sharding is
// disabled because it must only be applied to the original test // disabled because it must only be applied to the original test
// process. Otherwise, we could filter out death tests we intended to execute. // process. Otherwise, we could filter out death tests we intended to execute.
GTEST_API_ bool ShouldShard(const char* total_shards_str, GTEST_API_ bool ShouldShard(bool in_subprocess_for_death_test);
const char* shard_index_str,
bool in_subprocess_for_death_test);
// Parses the environment variable var as a 32-bit integer. If it is unset, // Parses the environment variable var as a 32-bit integer. If it is unset,
// returns default_val. If it is not a 32-bit integer, prints an error and // returns default_val. If it is not a 32-bit integer, prints an error and
@ -590,7 +587,7 @@ class GTEST_API_ UnitTestImpl {
// total_test_suite_count() - 1. If i is not in that range, returns NULL. // total_test_suite_count() - 1. If i is not in that range, returns NULL.
const TestSuite* GetTestSuite(int i) const { const TestSuite* GetTestSuite(int i) const {
const int index = GetElementOr(test_suite_indices_, i, -1); const int index = GetElementOr(test_suite_indices_, i, -1);
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)]; return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];
} }
// Legacy API is deprecated but still available // Legacy API is deprecated but still available
@ -1109,7 +1106,7 @@ class StreamingListener : public EmptyTestEventListener {
GTEST_CHECK_(sockfd_ != -1) GTEST_CHECK_(sockfd_ != -1)
<< "Send() can be called only when there is a connection."; << "Send() can be called only when there is a connection.";
const auto len = static_cast<size_t>(message.length()); const size_t len = message.length();
if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) { if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_; << host_name_ << ":" << port_num_;

@ -59,7 +59,6 @@ Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
// s. // s.
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); } Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Constructs a matcher that matches a const StringView& whose value is // Constructs a matcher that matches a const StringView& whose value is
// equal to s. // equal to s.
Matcher<const internal::StringView&>::Matcher(const std::string& s) { Matcher<const internal::StringView&>::Matcher(const std::string& s) {
@ -93,6 +92,5 @@ Matcher<internal::StringView>::Matcher(const char* s) {
Matcher<internal::StringView>::Matcher(internal::StringView s) { Matcher<internal::StringView>::Matcher(internal::StringView s) {
*this = Eq(std::string(s)); *this = Eq(std::string(s));
} }
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
} // namespace testing } // namespace testing

@ -89,6 +89,7 @@
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
@ -302,6 +303,22 @@ bool AutoHandle::IsCloseable() const {
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
} }
#if !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
Notification::Notification() {
// Create a manual-reset event object.
event_ = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
GTEST_CHECK_(event_ != nullptr);
}
Notification::~Notification() { ::CloseHandle(event_); }
void Notification::Notify() { GTEST_CHECK_(::SetEvent(event_)); }
void Notification::WaitForNotification() {
GTEST_CHECK_(::WaitForSingleObject(event_, INFINITE) == WAIT_OBJECT_0);
}
#endif // !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
Mutex::Mutex() Mutex::Mutex()
: owner_thread_id_(0), : owner_thread_id_(0),
type_(kDynamic), type_(kDynamic),
@ -320,13 +337,13 @@ Mutex::~Mutex() {
} }
} }
void Mutex::Lock() { void Mutex::lock() {
ThreadSafeLazyInit(); ThreadSafeLazyInit();
::EnterCriticalSection(critical_section_); ::EnterCriticalSection(critical_section_);
owner_thread_id_ = ::GetCurrentThreadId(); owner_thread_id_ = ::GetCurrentThreadId();
} }
void Mutex::Unlock() { void Mutex::unlock() {
ThreadSafeLazyInit(); ThreadSafeLazyInit();
// We don't protect writing to owner_thread_id_ here, as it's the // We don't protect writing to owner_thread_id_ here, as it's the
// caller's responsibility to ensure that the current thread holds the // caller's responsibility to ensure that the current thread holds the
@ -499,7 +516,7 @@ class ThreadLocalRegistryImpl {
MemoryIsNotDeallocated memory_is_not_deallocated; MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER #endif // _MSC_VER
DWORD current_thread = ::GetCurrentThreadId(); DWORD current_thread = ::GetCurrentThreadId();
MutexLock lock(&mutex_); MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals = ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked(); GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos = ThreadIdToThreadLocals::iterator thread_local_pos =
@ -532,7 +549,7 @@ class ThreadLocalRegistryImpl {
// Clean up the ThreadLocalValues data structure while holding the lock, but // Clean up the ThreadLocalValues data structure while holding the lock, but
// defer the destruction of the ThreadLocalValueHolderBases. // defer the destruction of the ThreadLocalValueHolderBases.
{ {
MutexLock lock(&mutex_); MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals = ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked(); GetThreadLocalsMapLocked();
for (ThreadIdToThreadLocals::iterator it = for (ThreadIdToThreadLocals::iterator it =
@ -559,7 +576,7 @@ class ThreadLocalRegistryImpl {
// Clean up the ThreadIdToThreadLocals data structure while holding the // Clean up the ThreadIdToThreadLocals data structure while holding the
// lock, but defer the destruction of the ThreadLocalValueHolderBases. // lock, but defer the destruction of the ThreadLocalValueHolderBases.
{ {
MutexLock lock(&mutex_); MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals = ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked(); GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos = ThreadIdToThreadLocals::iterator thread_local_pos =
@ -729,7 +746,7 @@ void RE::Init(const char* regex) {
char* const full_pattern = new char[full_regex_len]; char* const full_pattern = new char[full_regex_len];
snprintf(full_pattern, full_regex_len, "^(%s)$", regex); snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
is_valid_ = regcomp(&full_regex_, full_pattern, reg_flags) == 0; int error = regcomp(&full_regex_, full_pattern, reg_flags);
// We want to call regcomp(&partial_regex_, ...) even if the // We want to call regcomp(&partial_regex_, ...) even if the
// previous expression returns false. Otherwise partial_regex_ may // previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's // not be properly initialized can may cause trouble when it's
@ -738,13 +755,13 @@ void RE::Init(const char* regex) {
// Some implementation of POSIX regex (e.g. on at least some // Some implementation of POSIX regex (e.g. on at least some
// versions of Cygwin) doesn't accept the empty string as a valid // versions of Cygwin) doesn't accept the empty string as a valid
// regex. We change it to an equivalent form "()" to be safe. // regex. We change it to an equivalent form "()" to be safe.
if (is_valid_) { if (!error) {
const char* const partial_regex = (*regex == '\0') ? "()" : regex; const char* const partial_regex = (*regex == '\0') ? "()" : regex;
is_valid_ = regcomp(&partial_regex_, partial_regex, reg_flags) == 0; error = regcomp(&partial_regex_, partial_regex, reg_flags);
} }
EXPECT_TRUE(is_valid_) is_valid_ = error == 0;
<< "Regular expression \"" << regex EXPECT_EQ(error, 0) << "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression."; << "\" is not a valid POSIX Extended regular expression.";
delete[] full_pattern; delete[] full_pattern;
} }
@ -1052,7 +1069,7 @@ GTestLog::~GTestLog() {
// Disable Microsoft deprecation warnings for POSIX functions called from // Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close) // this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_DEPRECATED_PUSH_() GTEST_DISABLE_DEPRECATED_PUSH_()
namespace { namespace {
@ -1078,10 +1095,12 @@ class CapturedStream {
0, // Generate unique file name. 0, // Generate unique file name.
temp_file_path); temp_file_path);
GTEST_CHECK_(success != 0) GTEST_CHECK_(success != 0)
<< "Unable to create a temporary file in " << temp_dir_path; << "Failed to create temporary file in " << temp_dir_path
<< " with error " << ::GetLastError();
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
GTEST_CHECK_(captured_fd != -1) GTEST_CHECK_(captured_fd != -1)
<< "Unable to open temporary file " << temp_file_path; << "Failed to open temporary file " << temp_file_path << " with error "
<< ::GetLastError();
filename_ = temp_file_path; filename_ = temp_file_path;
#else #else
// There's no guarantee that a test has write access to the current // There's no guarantee that a test has write access to the current
@ -1183,7 +1202,7 @@ class CapturedStream {
CapturedStream& operator=(const CapturedStream&) = delete; CapturedStream& operator=(const CapturedStream&) = delete;
}; };
GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_DEPRECATED_POP_()
static CapturedStream* g_captured_stderr = nullptr; static CapturedStream* g_captured_stderr = nullptr;
static CapturedStream* g_captured_stdout = nullptr; static CapturedStream* g_captured_stdout = nullptr;

@ -50,7 +50,7 @@
#include <iomanip> #include <iomanip>
#include <ios> #include <ios>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <string> #include <string_view>
#include <type_traits> #include <type_traits>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
@ -114,8 +114,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
// char32_t. // char32_t.
template <typename CharType> template <typename CharType>
char32_t ToChar32(CharType in) { char32_t ToChar32(CharType in) {
return static_cast<char32_t>( return static_cast<char32_t>(static_cast<std::make_unsigned_t<CharType>>(in));
static_cast<typename std::make_unsigned<CharType>::type>(in));
} }
} // namespace } // namespace
@ -333,14 +332,14 @@ void PrintTo(__int128_t v, ::std::ostream* os) {
// Prints the given array of characters to the ostream. CharType must be either // Prints the given array of characters to the ostream. CharType must be either
// char, char8_t, char16_t, char32_t, or wchar_t. // char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters // The array starts at begin (which may be nullptr) and contains len characters.
// and may not be NUL-terminated. // The array may include '\0' characters and may not be NUL-terminated.
template <typename CharType> template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) { PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
const char* const quote_prefix = GetCharWidthPrefix(*begin); const char* const quote_prefix = GetCharWidthPrefix(CharType());
*os << quote_prefix << "\""; *os << quote_prefix << "\"";
bool is_previous_hex = false; bool is_previous_hex = false;
CharFormat print_format = kAsIs; CharFormat print_format = kAsIs;
@ -516,13 +515,13 @@ bool IsValidUTF8(const char* str, size_t length) {
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) { void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
if (!ContainsUnprintableControlCodes(str, length) && if (!ContainsUnprintableControlCodes(str, length) &&
IsValidUTF8(str, length)) { IsValidUTF8(str, length)) {
*os << "\n As Text: \"" << str << "\""; *os << "\n As Text: \"" << std::string_view(str, length) << "\"";
} }
} }
} // anonymous namespace } // anonymous namespace
void PrintStringTo(const ::std::string& s, ostream* os) { void PrintStringTo(std::string_view s, ostream* os) {
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG_GET(print_utf8)) { if (GTEST_FLAG_GET(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os); ConditionalPrintAsText(s.data(), s.size(), os);
@ -531,21 +530,21 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
} }
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
void PrintU8StringTo(const ::std::u8string& s, ostream* os) { void PrintU8StringTo(::std::u8string_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
#endif #endif
void PrintU16StringTo(const ::std::u16string& s, ostream* os) { void PrintU16StringTo(::std::u16string_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
void PrintU32StringTo(const ::std::u32string& s, ostream* os) { void PrintU32StringTo(::std::u32string_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) { void PrintWideStringTo(::std::wstring_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING

@ -34,7 +34,9 @@
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <string_view>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
@ -42,9 +44,9 @@ namespace testing {
// Gets the summary of the failure message by omitting the stack trace // Gets the summary of the failure message by omitting the stack trace
// in it. // in it.
std::string TestPartResult::ExtractSummary(const char* message) { std::string TestPartResult::ExtractSummary(const std::string_view message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker); auto stack_trace = message.find(internal::kStackTraceMarker);
return stack_trace == nullptr ? message : std::string(message, stack_trace); return std::string(message.substr(0, stack_trace));
} }
// Prints a TestPartResult object. // Prints a TestPartResult object.

@ -58,6 +58,7 @@
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <string_view>
#include <unordered_set> #include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -269,6 +270,13 @@ GTEST_DEFINE_bool_(
"True if and only if the test should fail if no test case (including " "True if and only if the test should fail if no test case (including "
"disabled test cases) is linked."); "disabled test cases) is linked.");
GTEST_DEFINE_bool_(
fail_if_no_test_selected,
testing::internal::BoolFromGTestEnv("fail_if_no_test_selected", false),
"True if and only if the test should fail if no test case is selected to "
"run. A test case is selected to run if it is not disabled and is matched "
"by the filter flag so that it starts executing.");
GTEST_DEFINE_bool_( GTEST_DEFINE_bool_(
also_run_disabled_tests, also_run_disabled_tests,
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false), testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
@ -399,6 +407,18 @@ GTEST_DEFINE_bool_(
"if exceptions are enabled or exit the program with a non-zero code " "if exceptions are enabled or exit the program with a non-zero code "
"otherwise. For use with an external test framework."); "otherwise. For use with an external test framework.");
GTEST_DEFINE_int32_(
shard_index,
testing::internal::Int32FromEnvOrDie(testing::kTestShardIndex, -1),
"The zero-based index of the shard to run. A value of -1 "
"(the default) indicates that sharding is disabled.");
GTEST_DEFINE_int32_(
total_shards,
testing::internal::Int32FromEnvOrDie(testing::kTestTotalShards, -1),
"The total number of shards to use when running tests in parallel. "
"A value of -1 (the default) indicates that sharding is disabled.");
#if GTEST_USE_OWN_FLAGFILE_FLAG_ #if GTEST_USE_OWN_FLAGFILE_FLAG_
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
flagfile, testing::internal::StringFromGTestEnv("flagfile", ""), flagfile, testing::internal::StringFromGTestEnv("flagfile", ""),
@ -478,6 +498,15 @@ bool ShouldEmitStackTraceForResultType(TestPartResult::Type type) {
// AssertHelper constructor. // AssertHelper constructor.
AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, AssertHelper::AssertHelper(TestPartResult::Type type, const char* file,
int line, const char* message) int line, const char* message)
: AssertHelper(
type, file == nullptr ? std::string_view() : std::string_view(file),
line,
message == nullptr ? std::string_view() : std::string_view(message)) {
}
AssertHelper::AssertHelper(TestPartResult::Type type,
const std::string_view file, int line,
const std::string_view message)
: data_(new AssertHelperData(type, file, line, message)) {} : data_(new AssertHelperData(type, file, line, message)) {}
AssertHelper::~AssertHelper() { delete data_; } AssertHelper::~AssertHelper() { delete data_; }
@ -706,7 +735,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
const char* const gtest_output_flag = s.c_str(); const char* const gtest_output_flag = s.c_str();
std::string format = GetOutputFormat(); std::string format = GetOutputFormat();
if (format.empty()) format = std::string(kDefaultOutputFormat); if (format.empty()) format = kDefaultOutputFormat;
const char* const colon = strchr(gtest_output_flag, ':'); const char* const colon = strchr(gtest_output_flag, ':');
if (colon == nullptr) if (colon == nullptr)
@ -868,7 +897,11 @@ class PositiveAndNegativeUnitTestFilter {
// and does not match the negative filter. // and does not match the negative filter.
bool MatchesTest(const std::string& test_suite_name, bool MatchesTest(const std::string& test_suite_name,
const std::string& test_name) const { const std::string& test_name) const {
#ifdef GTEST_HAS_ABSL
return MatchesName(absl::StrCat(test_suite_name, ".", test_name));
#else
return MatchesName(test_suite_name + "." + test_name); return MatchesName(test_suite_name + "." + test_name);
#endif
} }
// Returns true if and only if name matches the positive filter and does not // Returns true if and only if name matches the positive filter and does not
@ -1079,14 +1112,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
// Returns the global test part result reporter. // Returns the global test part result reporter.
TestPartResultReporterInterface* TestPartResultReporterInterface*
UnitTestImpl::GetGlobalTestPartResultReporter() { UnitTestImpl::GetGlobalTestPartResultReporter() {
internal::MutexLock lock(&global_test_part_result_reporter_mutex_); internal::MutexLock lock(global_test_part_result_reporter_mutex_);
return global_test_part_result_reporter_; return global_test_part_result_reporter_;
} }
// Sets the global test part result reporter. // Sets the global test part result reporter.
void UnitTestImpl::SetGlobalTestPartResultReporter( void UnitTestImpl::SetGlobalTestPartResultReporter(
TestPartResultReporterInterface* reporter) { TestPartResultReporterInterface* reporter) {
internal::MutexLock lock(&global_test_part_result_reporter_mutex_); internal::MutexLock lock(global_test_part_result_reporter_mutex_);
global_test_part_result_reporter_ = reporter; global_test_part_result_reporter_ = reporter;
} }
@ -1176,7 +1209,7 @@ int UnitTestImpl::test_to_run_count() const {
// trace but Bar() and CurrentOsStackTraceExceptTop() won't. // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
return os_stack_trace_getter()->CurrentStackTrace( return os_stack_trace_getter()->CurrentStackTrace(
static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1 GTEST_FLAG_GET(stack_trace_depth), skip_count + 1
// Skips the user-specified number of frames plus this function // Skips the user-specified number of frames plus this function
// itself. // itself.
); // NOLINT ); // NOLINT
@ -1488,17 +1521,17 @@ class Hunk {
// Print a unified diff header for one hunk. // Print a unified diff header for one hunk.
// The format is // The format is
// "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@" // "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
// where the left/right parts are omitted if unnecessary. // where the left/right lengths are omitted if unnecessary.
void PrintHeader(std::ostream* ss) const { void PrintHeader(std::ostream* ss) const {
*ss << "@@ "; size_t left_length = removes_ + common_;
if (removes_) { size_t right_length = adds_ + common_;
*ss << "-" << left_start_ << "," << (removes_ + common_); *ss << "@@ " << "-" << left_start_;
} if (left_length != 1) {
if (removes_ && adds_) { *ss << "," << left_length;
*ss << " ";
} }
if (adds_) { *ss << " " << "+" << right_start_;
*ss << "+" << right_start_ << "," << (adds_ + common_); if (right_length != 1) {
*ss << "," << right_length;
} }
*ss << " @@\n"; *ss << " @@\n";
} }
@ -2340,7 +2373,7 @@ void TestResult::RecordProperty(const std::string& xml_element,
if (!ValidateTestProperty(xml_element, test_property)) { if (!ValidateTestProperty(xml_element, test_property)) {
return; return;
} }
internal::MutexLock lock(&test_properties_mutex_); internal::MutexLock lock(test_properties_mutex_);
const std::vector<TestProperty>::iterator property_with_matching_key = const std::vector<TestProperty>::iterator property_with_matching_key =
std::find_if(test_properties_.begin(), test_properties_.end(), std::find_if(test_properties_.begin(), test_properties_.end(),
internal::TestPropertyKeyIs(test_property.key())); internal::TestPropertyKeyIs(test_property.key()));
@ -2540,8 +2573,9 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
// AddTestPartResult. // AddTestPartResult.
UnitTest::GetInstance()->AddTestPartResult( UnitTest::GetInstance()->AddTestPartResult(
result_type, result_type,
nullptr, // No info about the source file where the exception occurred. std::string_view(), // No info about the source file where the exception
-1, // We have no info on which line caused the exception. // occurred.
-1, // We have no info on which line caused the exception.
message, message,
""); // No stack trace, either. ""); // No stack trace, either.
} }
@ -2666,7 +2700,7 @@ Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
} }
// Runs the given method and catches and reports C++ and/or SEH-style // Runs the given method and catches and reports C++ and/or SEH-style
// exceptions, if they are supported; returns the 0-value for type // exceptions, if they are supported; returns the default-value for type
// Result in case of an SEH exception. // Result in case of an SEH exception.
template <class T, typename Result> template <class T, typename Result>
Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(), Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
@ -2714,7 +2748,7 @@ Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
TestPartResult::kFatalFailure, TestPartResult::kFatalFailure,
FormatCxxExceptionMessage(nullptr, location)); FormatCxxExceptionMessage(nullptr, location));
} }
return static_cast<Result>(0); return Result();
#else #else
return HandleSehExceptionsInMethodIfSupported(object, method, location); return HandleSehExceptionsInMethodIfSupported(object, method, location);
#endif // GTEST_HAS_EXCEPTIONS #endif // GTEST_HAS_EXCEPTIONS
@ -3298,6 +3332,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
const bool term_supports_color = const bool term_supports_color =
term != nullptr && (String::CStringEquals(term, "xterm") || term != nullptr && (String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-color") ||
String::CStringEquals(term, "xterm-ghostty") ||
String::CStringEquals(term, "xterm-kitty") || String::CStringEquals(term, "xterm-kitty") ||
String::CStringEquals(term, "alacritty") || String::CStringEquals(term, "alacritty") ||
String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen") ||
@ -3452,11 +3487,11 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
filter); filter);
} }
if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { if (internal::ShouldShard(false)) {
const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); const int32_t shard_index = GTEST_FLAG_GET(shard_index);
ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n", ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %d.\n",
static_cast<int>(shard_index) + 1, static_cast<int>(shard_index) + 1,
internal::posix::GetEnv(kTestTotalShards)); GTEST_FLAG_GET(total_shards));
} }
if (GTEST_FLAG_GET(shuffle)) { if (GTEST_FLAG_GET(shuffle)) {
@ -4204,8 +4239,7 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
for (;;) { for (;;) {
const char* const next_segment = strstr(segment, "]]>"); const char* const next_segment = strstr(segment, "]]>");
if (next_segment != nullptr) { if (next_segment != nullptr) {
stream->write(segment, stream->write(segment, next_segment - segment);
static_cast<std::streamsize>(next_segment - segment));
*stream << "]]>]]&gt;<![CDATA["; *stream << "]]>]]&gt;<![CDATA[";
segment = next_segment + strlen("]]>"); segment = next_segment + strlen("]]>");
} else { } else {
@ -4347,8 +4381,8 @@ void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,
internal::FormatCompilerIndependentFileLocation(part.file_name(), internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number()); part.line_number());
const std::string summary = location + "\n" + part.summary(); const std::string summary = location + "\n" + part.summary();
*stream << " <skipped message=\"" *stream << " <skipped message=\"" << EscapeXmlAttribute(summary)
<< EscapeXmlAttribute(summary.c_str()) << "\">"; << "\">";
const std::string detail = location + "\n" + part.message(); const std::string detail = location + "\n" + part.message();
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
*stream << "</skipped>\n"; *stream << "</skipped>\n";
@ -5080,7 +5114,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
void* caller_frame = nullptr; void* caller_frame = nullptr;
{ {
MutexLock lock(&mutex_); MutexLock lock(mutex_);
caller_frame = caller_frame_; caller_frame = caller_frame_;
} }
@ -5119,12 +5153,12 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
caller_frame = nullptr; caller_frame = nullptr;
} }
MutexLock lock(&mutex_); MutexLock lock(mutex_);
caller_frame_ = caller_frame; caller_frame_ = caller_frame;
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
} }
#ifdef GTEST_HAS_DEATH_TEST #ifdef GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
// A helper class that creates the premature-exit file in its // A helper class that creates the premature-exit file in its
// constructor and deletes the file in its destructor. // constructor and deletes the file in its destructor.
class ScopedPrematureExitFile { class ScopedPrematureExitFile {
@ -5137,9 +5171,12 @@ class ScopedPrematureExitFile {
// create the file with a single "0" character in it. I/O // create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we // errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this. // don't want to fail the test because of this.
FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w"); if (FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w")) {
fwrite("0", 1, 1, pfile); fwrite("0", 1, 1, pfile);
fclose(pfile); fclose(pfile);
} else {
premature_exit_filepath_.clear();
}
} }
} }
@ -5157,12 +5194,12 @@ class ScopedPrematureExitFile {
} }
private: private:
const std::string premature_exit_filepath_; std::string premature_exit_filepath_;
ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete; ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete; ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;
}; };
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
} // namespace internal } // namespace internal
@ -5382,13 +5419,13 @@ void UnitTest::UponLeavingGTest() {
// Sets the TestSuite object for the test that's currently running. // Sets the TestSuite object for the test that's currently running.
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) { void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
impl_->set_current_test_suite(a_current_test_suite); impl_->set_current_test_suite(a_current_test_suite);
} }
// Sets the TestInfo object for the test that's currently running. // Sets the TestInfo object for the test that's currently running.
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) { void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
impl_->set_current_test_info(a_current_test_info); impl_->set_current_test_info(a_current_test_info);
} }
@ -5420,14 +5457,14 @@ Environment* UnitTest::AddEnvironment(Environment* env) {
// this to report their results. The user code should use the // this to report their results. The user code should use the
// assertion macros instead of calling this directly. // assertion macros instead of calling this directly.
void UnitTest::AddTestPartResult(TestPartResult::Type result_type, void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
const char* file_name, int line_number, const std::string_view file_name,
const std::string& message, int line_number, const std::string& message,
const std::string& os_stack_trace) const std::string& os_stack_trace)
GTEST_LOCK_EXCLUDED_(mutex_) { GTEST_LOCK_EXCLUDED_(mutex_) {
Message msg; Message msg;
msg << message; msg << message;
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
if (!impl_->gtest_trace_stack().empty()) { if (!impl_->gtest_trace_stack().empty()) {
msg << "\n" << GTEST_NAME_ << " trace:"; msg << "\n" << GTEST_NAME_ << " trace:";
@ -5507,7 +5544,7 @@ void UnitTest::RecordProperty(const std::string& key,
// We don't protect this under mutex_, as we only support calling it // We don't protect this under mutex_, as we only support calling it
// from the main thread. // from the main thread.
int UnitTest::Run() { int UnitTest::Run() {
#ifdef GTEST_HAS_DEATH_TEST #ifdef GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
const bool in_death_test_child_process = const bool in_death_test_child_process =
!GTEST_FLAG_GET(internal_run_death_test).empty(); !GTEST_FLAG_GET(internal_run_death_test).empty();
@ -5538,7 +5575,7 @@ int UnitTest::Run() {
: internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
#else #else
const bool in_death_test_child_process = false; const bool in_death_test_child_process = false;
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be // Captures the value of GTEST_FLAG(catch_exceptions). This value will be
// used for the duration of the program. // used for the duration of the program.
@ -5610,7 +5647,7 @@ const char* UnitTest::original_working_dir() const {
// or NULL if no test is running. // or NULL if no test is running.
const TestSuite* UnitTest::current_test_suite() const const TestSuite* UnitTest::current_test_suite() const
GTEST_LOCK_EXCLUDED_(mutex_) { GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
return impl_->current_test_suite(); return impl_->current_test_suite();
} }
@ -5618,7 +5655,7 @@ const TestSuite* UnitTest::current_test_suite() const
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
const TestCase* UnitTest::current_test_case() const const TestCase* UnitTest::current_test_case() const
GTEST_LOCK_EXCLUDED_(mutex_) { GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
return impl_->current_test_suite(); return impl_->current_test_suite();
} }
#endif #endif
@ -5627,7 +5664,7 @@ const TestCase* UnitTest::current_test_case() const
// or NULL if no test is running. // or NULL if no test is running.
const TestInfo* UnitTest::current_test_info() const const TestInfo* UnitTest::current_test_info() const
GTEST_LOCK_EXCLUDED_(mutex_) { GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
return impl_->current_test_info(); return impl_->current_test_info();
} }
@ -5651,13 +5688,13 @@ UnitTest::~UnitTest() { delete impl_; }
// Google Test trace stack. // Google Test trace stack.
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
GTEST_LOCK_EXCLUDED_(mutex_) { GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
impl_->gtest_trace_stack().push_back(trace); impl_->gtest_trace_stack().push_back(trace);
} }
// Pops a trace from the per-thread Google Test trace stack. // Pops a trace from the per-thread Google Test trace stack.
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_); internal::MutexLock lock(mutex_);
impl_->gtest_trace_stack().pop_back(); impl_->gtest_trace_stack().pop_back();
} }
@ -5960,8 +5997,7 @@ bool UnitTestImpl::RunAllTests() {
#endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) #endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, const bool should_shard = ShouldShard(in_subprocess_for_death_test);
in_subprocess_for_death_test);
// Compares the full test names with the filter to decide which // Compares the full test names with the filter to decide which
// tests to run. // tests to run.
@ -6079,6 +6115,20 @@ bool UnitTestImpl::RunAllTests() {
TearDownEnvironment); TearDownEnvironment);
repeater->OnEnvironmentsTearDownEnd(*parent_); repeater->OnEnvironmentsTearDownEnd(*parent_);
} }
} else if (GTEST_FLAG_GET(fail_if_no_test_selected)) {
// If there were no tests to run, bail if we were requested to be
// strict.
constexpr char kNoTestsSelectedMessage[] =
"No tests ran. Check that tests exist and are not disabled or "
"filtered out.\n\n"
"For sharded runs, this error indicates an empty shard. This can "
"happen if you have more shards than tests, or if --gtest_filter "
"leaves a shard with no tests.\n\n"
"To permit empty shards (e.g., when debugging with a filter), "
"specify \n"
"--gtest_fail_if_no_test_selected=false.";
ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage);
return false;
} }
elapsed_time_ = timer.Elapsed(); elapsed_time_ = timer.Elapsed();
@ -6159,45 +6209,44 @@ void WriteToShardStatusFileIfNeeded() {
} }
#endif // GTEST_HAS_FILE_SYSTEM #endif // GTEST_HAS_FILE_SYSTEM
// Checks whether sharding is enabled by examining the relevant // Checks whether sharding is enabled by examining the relevant command line
// environment variable values. If the variables are present, // arguments. If the arguments are present, but inconsistent
// but inconsistent (i.e., shard_index >= total_shards), prints // (i.e., shard_index >= total_shards), prints an error and exits.
// an error and exits. If in_subprocess_for_death_test, sharding is // If in_subprocess_for_death_test, sharding is disabled because it must only
// disabled because it must only be applied to the original test // be applied to the original test process. Otherwise, we could filter out death
// process. Otherwise, we could filter out death tests we intended to execute. // tests we intended to execute.
bool ShouldShard(const char* total_shards_env, const char* shard_index_env, bool ShouldShard(bool in_subprocess_for_death_test) {
bool in_subprocess_for_death_test) {
if (in_subprocess_for_death_test) { if (in_subprocess_for_death_test) {
return false; return false;
} }
const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1); const int32_t total_shards = GTEST_FLAG_GET(total_shards);
const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1); const int32_t shard_index = GTEST_FLAG_GET(shard_index);
if (total_shards == -1 && shard_index == -1) { if (total_shards == -1 && shard_index == -1) {
return false; return false;
} else if (total_shards == -1 && shard_index != -1) { } else if (total_shards == -1 && shard_index != -1) {
const Message msg = Message() << "Invalid environment variables: you have " const Message msg = Message()
<< kTestShardIndex << " = " << shard_index << "Invalid sharding: you have " << kTestShardIndex
<< ", but have left " << kTestTotalShards << " = " << shard_index << ", but have left "
<< " unset.\n"; << kTestTotalShards << " unset.\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) { } else if (total_shards != -1 && shard_index == -1) {
const Message msg = Message() const Message msg = Message()
<< "Invalid environment variables: you have " << "Invalid sharding: you have " << kTestTotalShards
<< kTestTotalShards << " = " << total_shards << " = " << total_shards << ", but have left "
<< ", but have left " << kTestShardIndex << " unset.\n"; << kTestShardIndex << " unset.\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) { } else if (shard_index < 0 || shard_index >= total_shards) {
const Message msg = const Message msg =
Message() << "Invalid environment variables: we require 0 <= " Message() << "Invalid sharding: we require 0 <= " << kTestShardIndex
<< kTestShardIndex << " < " << kTestTotalShards << " < " << kTestTotalShards << ", but you have "
<< ", but you have " << kTestShardIndex << "=" << shard_index << kTestShardIndex << "=" << shard_index << ", "
<< ", " << kTestTotalShards << "=" << total_shards << ".\n"; << kTestTotalShards << "=" << total_shards << ".\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -6240,11 +6289,10 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
// . Returns the number of tests that should run. // . Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL
? Int32FromEnvOrDie(kTestTotalShards, -1) ? GTEST_FLAG_GET(total_shards)
: -1; : -1;
const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL const int32_t shard_index =
? Int32FromEnvOrDie(kTestShardIndex, -1) shard_tests == HONOR_SHARDING_PROTOCOL ? GTEST_FLAG_GET(shard_index) : -1;
: -1;
const PositiveAndNegativeUnitTestFilter gtest_flag_filter( const PositiveAndNegativeUnitTestFilter gtest_flag_filter(
GTEST_FLAG_GET(filter)); GTEST_FLAG_GET(filter));
@ -6686,6 +6734,12 @@ static const char kColorEncodedHelpMessage[] =
"recreate_environments_when_repeating@D\n" "recreate_environments_when_repeating@D\n"
" Sets up and tears down the global test environment on each repeat\n" " Sets up and tears down the global test environment on each repeat\n"
" of the test.\n" " of the test.\n"
" @G--" GTEST_FLAG_PREFIX_
"fail_fast@D\n"
" Stop running tests after the first failure.\n"
" @G--" GTEST_FLAG_PREFIX_
"fail_if_no_test_linked@D\n"
" Fail if no test is linked into the test program.\n"
"\n" "\n"
"Test Output:\n" "Test Output:\n"
" @G--" GTEST_FLAG_PREFIX_ " @G--" GTEST_FLAG_PREFIX_
@ -6698,6 +6752,9 @@ static const char kColorEncodedHelpMessage[] =
"print_time=0@D\n" "print_time=0@D\n"
" Don't print the elapsed time of each test.\n" " Don't print the elapsed time of each test.\n"
" @G--" GTEST_FLAG_PREFIX_ " @G--" GTEST_FLAG_PREFIX_
"print_utf8=0@D\n"
" Don't print UTF-8 characters as text.\n"
" @G--" GTEST_FLAG_PREFIX_
"output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_
"@Y|@G:@YFILE_PATH]@D\n" "@Y|@G:@YFILE_PATH]@D\n"
" Generate a JSON or XML report in the given directory or with the " " Generate a JSON or XML report in the given directory or with the "
@ -6714,6 +6771,9 @@ static const char kColorEncodedHelpMessage[] =
" @G--" GTEST_FLAG_PREFIX_ " @G--" GTEST_FLAG_PREFIX_
"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
" Set the default death test style.\n" " Set the default death test style.\n"
" @G--" GTEST_FLAG_PREFIX_
"death_test_use_fork@D\n"
" Use fork() instead of clone() to spawn death test child processes.\n"
#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS #endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ " @G--" GTEST_FLAG_PREFIX_
"break_on_failure@D\n" "break_on_failure@D\n"
@ -6726,6 +6786,9 @@ static const char kColorEncodedHelpMessage[] =
"catch_exceptions=0@D\n" "catch_exceptions=0@D\n"
" Do not report exceptions as test failures. Instead, allow them\n" " Do not report exceptions as test failures. Instead, allow them\n"
" to crash the program or throw a pop-up (on Windows).\n" " to crash the program or throw a pop-up (on Windows).\n"
" @G--" GTEST_FLAG_PREFIX_
"stack_trace_depth=@Y[NUMBER]@D\n"
" Maximum number of stack frames to print when an assertion fails.\n"
"\n" "\n"
"Except for @G--" GTEST_FLAG_PREFIX_ "Except for @G--" GTEST_FLAG_PREFIX_
"list_tests@D, you can alternatively set " "list_tests@D, you can alternatively set "
@ -6763,6 +6826,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork); GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
GTEST_INTERNAL_PARSE_FLAG(fail_fast); GTEST_INTERNAL_PARSE_FLAG(fail_fast);
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked); GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_selected);
GTEST_INTERNAL_PARSE_FLAG(filter); GTEST_INTERNAL_PARSE_FLAG(filter);
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test); GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
GTEST_INTERNAL_PARSE_FLAG(list_tests); GTEST_INTERNAL_PARSE_FLAG(list_tests);
@ -6772,6 +6836,8 @@ static bool ParseGoogleTestFlag(const char* const arg) {
GTEST_INTERNAL_PARSE_FLAG(print_utf8); GTEST_INTERNAL_PARSE_FLAG(print_utf8);
GTEST_INTERNAL_PARSE_FLAG(random_seed); GTEST_INTERNAL_PARSE_FLAG(random_seed);
GTEST_INTERNAL_PARSE_FLAG(repeat); GTEST_INTERNAL_PARSE_FLAG(repeat);
GTEST_INTERNAL_PARSE_FLAG(shard_index);
GTEST_INTERNAL_PARSE_FLAG(total_shards);
GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating); GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);
GTEST_INTERNAL_PARSE_FLAG(shuffle); GTEST_INTERNAL_PARSE_FLAG(shuffle);
GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth); GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);
@ -6864,7 +6930,7 @@ void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
std::vector<char*> positional_args; std::vector<char*> positional_args;
std::vector<absl::UnrecognizedFlag> unrecognized_flags; std::vector<absl::UnrecognizedFlag> unrecognized_flags;
absl::ParseAbseilFlagsOnly(*argc, argv, positional_args, unrecognized_flags); absl::ParseAbseilFlagsOnly(*argc, argv, positional_args, unrecognized_flags);
absl::flat_hash_set<absl::string_view> unrecognized; absl::flat_hash_set<std::string_view> unrecognized;
for (const auto& flag : unrecognized_flags) { for (const auto& flag : unrecognized_flags) {
unrecognized.insert(flag.flag_name); unrecognized.insert(flag.flag_name);
} }

Loading…
Cancel
Save