diff --git a/BUILD.bazel b/BUILD.bazel index 9b48aee5..7e227aa0 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -103,6 +103,7 @@ cc_library( "@com_google_absl//absl/debugging:stacktrace", "@com_google_absl//absl/debugging:symbolize", "@com_google_absl//absl/strings", + "@com_google_absl//absl/types:any", "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:variant", ], diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 4260e4f7..67c87f47 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -679,6 +679,26 @@ class UniversalPrinter { GTEST_DISABLE_MSC_WARNINGS_POP_() }; +#if GTEST_INTERNAL_HAS_ANY + +// Printer for std::any / absl::any + +template <> +class UniversalPrinter { + public: + static void Print(const Any& value, ::std::ostream* os) { + if (value.has_value()) + *os << "'any' type with value of type " << GetTypeName(); + else + *os << "'any' type with no value"; + } + + private: + static std::string GetTypeName() { return "the element type"; } +}; + +#endif // GTEST_INTERNAL_HAS_ANY + #if GTEST_INTERNAL_HAS_OPTIONAL // Printer for std::optional / absl::optional diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 377c77fb..75e00ccb 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -199,6 +199,8 @@ // suppressed (constant conditional). // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 // is suppressed. +// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter or +// UniversalPrinter specializations. // GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter or // UniversalPrinter specializations. // GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher or @@ -2227,6 +2229,34 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val); #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() && __cplusplus >= 201703L +// Otherwise for C++17 and higher use std::any for UniversalPrinter<> +// specializations. +# define GTEST_INTERNAL_HAS_ANY 1 +#include +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() && __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. diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index d71c1871..33050352 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -1531,6 +1531,27 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { EXPECT_EQ("\"a\"", result[1]); } +#if GTEST_INTERNAL_HAS_ANY +TEST(PrintAnyTest, Empty) { + internal::Any any; + EXPECT_EQ("'any' type with no value", PrintToString(any)); +} + +TEST(PrintAnyTest, NonEmpty) { + internal::Any any; + constexpr int val1 = 10; + const std::string val2 = "content"; + + any = val1; + EXPECT_EQ("'any' type with value of type the element type", + PrintToString(any)); + + any = val2; + EXPECT_EQ("'any' type with value of type the element type", + PrintToString(any)); +} +#endif // GTEST_INTERNAL_HAS_ANY + #if GTEST_INTERNAL_HAS_OPTIONAL TEST(PrintOptionalTest, Basic) { internal::Optional value;