Merge 5ac7646e961b1c629d661e2a4960cec580726e3d into 67cc66080d64e3fa5124fe57ed0cf15e2cecfdeb
This commit is contained in:
commit
798ebab26a
@ -103,6 +103,7 @@ cc_library(
|
|||||||
"@com_google_absl//absl/debugging:stacktrace",
|
"@com_google_absl//absl/debugging:stacktrace",
|
||||||
"@com_google_absl//absl/debugging:symbolize",
|
"@com_google_absl//absl/debugging:symbolize",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
|
"@com_google_absl//absl/types:any",
|
||||||
"@com_google_absl//absl/types:optional",
|
"@com_google_absl//absl/types:optional",
|
||||||
"@com_google_absl//absl/types:variant",
|
"@com_google_absl//absl/types:variant",
|
||||||
],
|
],
|
||||||
|
@ -113,8 +113,6 @@
|
|||||||
|
|
||||||
#if GTEST_HAS_ABSL
|
#if GTEST_HAS_ABSL
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/types/optional.h"
|
|
||||||
#include "absl/types/variant.h"
|
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@ -596,14 +594,41 @@ class UniversalPrinter {
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||||
};
|
};
|
||||||
|
|
||||||
#if GTEST_HAS_ABSL
|
#if GTEST_INTERNAL_HAS_ANY
|
||||||
|
|
||||||
// Printer for absl::optional
|
// Printer for std::any / absl::any
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class UniversalPrinter<Any> {
|
||||||
|
public:
|
||||||
|
static void Print(const Any& value, ::std::ostream* os) {
|
||||||
|
if (value.has_value())
|
||||||
|
*os << "'any' type with value of type " << GetTypeName(value);
|
||||||
|
else
|
||||||
|
*os << "'any' type with no value";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string GetTypeName(const Any& value) {
|
||||||
|
#if GTEST_HAS_RTTI
|
||||||
|
return internal::GetTypeName(value.type());
|
||||||
|
#else
|
||||||
|
static_cast<void>(value); // possibly unused
|
||||||
|
return "the element type";
|
||||||
|
#endif // GTEST_HAS_RTTI
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GTEST_INTERNAL_HAS_ANY
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_OPTIONAL
|
||||||
|
|
||||||
|
// Printer for std::optional / absl::optional
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter<::absl::optional<T>> {
|
class UniversalPrinter<Optional<T>> {
|
||||||
public:
|
public:
|
||||||
static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
|
static void Print(const Optional<T>& value, ::std::ostream* os) {
|
||||||
*os << '(';
|
*os << '(';
|
||||||
if (!value) {
|
if (!value) {
|
||||||
*os << "nullopt";
|
*os << "nullopt";
|
||||||
@ -614,14 +639,22 @@ class UniversalPrinter<::absl::optional<T>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Printer for absl::variant
|
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_VARIANT
|
||||||
|
|
||||||
|
// Printer for std::variant / absl::variant
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class UniversalPrinter<::absl::variant<T...>> {
|
class UniversalPrinter<Variant<T...>> {
|
||||||
public:
|
public:
|
||||||
static void Print(const ::absl::variant<T...>& value, ::std::ostream* os) {
|
static void Print(const Variant<T...>& value, ::std::ostream* os) {
|
||||||
*os << '(';
|
*os << '(';
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
std::visit(Visitor{os}, value);
|
||||||
|
#else
|
||||||
absl::visit(Visitor{os}, value);
|
absl::visit(Visitor{os}, value);
|
||||||
|
#endif // __cplusplus >= 201703L
|
||||||
*os << ')';
|
*os << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,7 +669,7 @@ class UniversalPrinter<::absl::variant<T...>> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_INTERNAL_HAS_VARIANT
|
||||||
|
|
||||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||||
// elements, starting at address 'begin'.
|
// elements, starting at address 'begin'.
|
||||||
|
@ -199,9 +199,15 @@
|
|||||||
// 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.
|
||||||
|
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional> or
|
||||||
|
// UniversalPrinter<absl::optional> specializations.
|
||||||
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
|
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
|
||||||
// Matcher<absl::string_view>
|
// Matcher<absl::string_view>
|
||||||
// specializations.
|
// specializations.
|
||||||
|
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
|
||||||
|
// UniversalPrinter<absl::variant> specializations.
|
||||||
//
|
//
|
||||||
// Synchronization:
|
// Synchronization:
|
||||||
// Mutex, MutexLock, ThreadLocal, GetThreadCount()
|
// Mutex, MutexLock, ThreadLocal, GetThreadCount()
|
||||||
@ -2236,6 +2242,64 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
|||||||
|
|
||||||
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
|
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
|
||||||
|
|
||||||
|
#if GTEST_HAS_ABSL
|
||||||
|
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
||||||
|
// is built with absl support.
|
||||||
|
# define GTEST_INTERNAL_HAS_ANY 1
|
||||||
|
#include "absl/types/any.h"
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
using Any = ::absl::any;
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
#else
|
||||||
|
# ifdef __has_include
|
||||||
|
# if __has_include(<any>) && __cplusplus >= 201703L
|
||||||
|
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
|
||||||
|
// specializations.
|
||||||
|
# define GTEST_INTERNAL_HAS_ANY 1
|
||||||
|
#include <any>
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
using Any = ::std::any;
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
// The case where absl is configured NOT to alias std::any is not
|
||||||
|
// supported.
|
||||||
|
# endif // __has_include(<any>) && __cplusplus >= 201703L
|
||||||
|
# endif // __has_include
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
#if 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>;
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
#else
|
||||||
|
# ifdef __has_include
|
||||||
|
# if __has_include(<optional>) && __cplusplus >= 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>;
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
// The case where absl is configured NOT to alias std::optional is not
|
||||||
|
// supported.
|
||||||
|
# endif // __has_include(<optional>) && __cplusplus >= 201703L
|
||||||
|
# endif // __has_include
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
#if GTEST_HAS_ABSL
|
#if 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.
|
||||||
@ -2264,4 +2328,34 @@ using StringView = ::std::string_view;
|
|||||||
# endif // __has_include
|
# endif // __has_include
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
#if 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
|
||||||
|
# ifdef __has_include
|
||||||
|
# if __has_include(<variant>) && __cplusplus >= 201703L
|
||||||
|
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
|
||||||
|
// specializations.
|
||||||
|
# define GTEST_INTERNAL_HAS_VARIANT 1
|
||||||
|
#include <variant>
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
template <typename... T>
|
||||||
|
using Variant = ::std::variant<T...>;
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
// The case where absl is configured NOT to alias std::variant is not
|
||||||
|
// supported.
|
||||||
|
# endif // __has_include(<variant>) && __cplusplus >= 201703L
|
||||||
|
# endif // __has_include
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
|
@ -64,34 +64,40 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTypeName<T>() returns a human-readable name of type T.
|
#if GTEST_HAS_RTTI
|
||||||
|
// GetTypeName(const std::type_info&) returns a human-readable name of type T.
|
||||||
// NB: This function is also used in Google Mock, so don't move it inside of
|
// NB: This function is also used in Google Mock, so don't move it inside of
|
||||||
// the typed-test-only section below.
|
// the typed-test-only section below.
|
||||||
template <typename T>
|
inline std::string GetTypeName(const std::type_info& type) {
|
||||||
std::string GetTypeName() {
|
const char* const name = type.name();
|
||||||
# if GTEST_HAS_RTTI
|
#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
||||||
|
|
||||||
const char* const name = typeid(T).name();
|
|
||||||
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
// gcc's implementation of typeid(T).name() mangles the type name,
|
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||||
// so we have to demangle it.
|
// so we have to demangle it.
|
||||||
# if GTEST_HAS_CXXABI_H_
|
#if GTEST_HAS_CXXABI_H_
|
||||||
using abi::__cxa_demangle;
|
using abi::__cxa_demangle;
|
||||||
# endif // GTEST_HAS_CXXABI_H_
|
#endif // GTEST_HAS_CXXABI_H_
|
||||||
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
||||||
const std::string name_str(status == 0 ? readable_name : name);
|
const std::string name_str(status == 0 ? readable_name : name);
|
||||||
free(readable_name);
|
free(readable_name);
|
||||||
return CanonicalizeForStdLibVersioning(name_str);
|
return CanonicalizeForStdLibVersioning(name_str);
|
||||||
# else
|
#else
|
||||||
return name;
|
return name;
|
||||||
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||||
|
}
|
||||||
# else
|
#endif // GTEST_HAS_RTTI
|
||||||
|
|
||||||
|
// GetTypeName<T>() returns a human-readable name of type T if and only if
|
||||||
|
// RTTI is enabled, otherwise it returns a dummy type name.
|
||||||
|
// NB: This function is also used in Google Mock, so don't move it inside of
|
||||||
|
// the typed-test-only section below.
|
||||||
|
template <typename T>
|
||||||
|
std::string GetTypeName() {
|
||||||
|
#if GTEST_HAS_RTTI
|
||||||
|
return GetTypeName(typeid(T));
|
||||||
|
#else
|
||||||
return "<type>";
|
return "<type>";
|
||||||
|
#endif // GTEST_HAS_RTTI
|
||||||
# endif // GTEST_HAS_RTTI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||||
|
@ -1531,23 +1531,57 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
|
|||||||
EXPECT_EQ("\"a\"", result[1]);
|
EXPECT_EQ("\"a\"", result[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_ABSL
|
#if GTEST_INTERNAL_HAS_ANY
|
||||||
|
class PrintAnyTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
template <typename T>
|
||||||
|
static std::string ExpectedTypeName() {
|
||||||
|
#if GTEST_HAS_RTTI
|
||||||
|
return internal::GetTypeName<T>();
|
||||||
|
#else
|
||||||
|
return "the element type";
|
||||||
|
#endif // GTEST_HAS_RTTI
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(PrintAnyTest, Empty) {
|
||||||
|
internal::Any any;
|
||||||
|
EXPECT_EQ("'any' type with no value", PrintToString(any));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PrintAnyTest, NonEmpty) {
|
||||||
|
internal::Any any;
|
||||||
|
constexpr int val1 = 10;
|
||||||
|
const std::string val2 = "content";
|
||||||
|
|
||||||
|
any = val1;
|
||||||
|
EXPECT_EQ("'any' type with value of type " + ExpectedTypeName<int>(),
|
||||||
|
PrintToString(any));
|
||||||
|
|
||||||
|
any = val2;
|
||||||
|
EXPECT_EQ("'any' type with value of type " + ExpectedTypeName<std::string>(),
|
||||||
|
PrintToString(any));
|
||||||
|
}
|
||||||
|
#endif // GTEST_INTERNAL_HAS_ANY
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_OPTIONAL
|
||||||
TEST(PrintOptionalTest, Basic) {
|
TEST(PrintOptionalTest, Basic) {
|
||||||
absl::optional<int> value;
|
internal::Optional<int> value;
|
||||||
EXPECT_EQ("(nullopt)", PrintToString(value));
|
EXPECT_EQ("(nullopt)", PrintToString(value));
|
||||||
value = {7};
|
value = {7};
|
||||||
EXPECT_EQ("(7)", PrintToString(value));
|
EXPECT_EQ("(7)", PrintToString(value));
|
||||||
EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1}));
|
EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1}));
|
||||||
EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"}));
|
EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"}));
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_VARIANT
|
||||||
struct NonPrintable {
|
struct NonPrintable {
|
||||||
unsigned char contents = 17;
|
unsigned char contents = 17;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(PrintOneofTest, Basic) {
|
TEST(PrintOneofTest, Basic) {
|
||||||
using Type = absl::variant<int, StreamableInGlobal, NonPrintable>;
|
using Type = internal::Variant<int, StreamableInGlobal, NonPrintable>;
|
||||||
EXPECT_EQ("('int' with value 7)", PrintToString(Type(7)));
|
EXPECT_EQ("('int' with value 7)", PrintToString(Type(7)));
|
||||||
EXPECT_EQ("('StreamableInGlobal' with value StreamableInGlobal)",
|
EXPECT_EQ("('StreamableInGlobal' with value StreamableInGlobal)",
|
||||||
PrintToString(Type(StreamableInGlobal{})));
|
PrintToString(Type(StreamableInGlobal{})));
|
||||||
@ -1556,7 +1590,7 @@ TEST(PrintOneofTest, Basic) {
|
|||||||
"<11>)",
|
"<11>)",
|
||||||
PrintToString(Type(NonPrintable{})));
|
PrintToString(Type(NonPrintable{})));
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_INTERNAL_HAS_VARIANT
|
||||||
namespace {
|
namespace {
|
||||||
class string_ref;
|
class string_ref;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user