From eb3953f805d0ed9054dba78b8e842caba0b539c2 Mon Sep 17 00:00:00 2001 From: Krystian Kuzniarek Date: Sat, 7 Mar 2020 17:25:51 +0100 Subject: [PATCH] make UniversalPrinter support RTTI --- googletest/include/gtest/gtest-printers.h | 11 +++++- .../include/gtest/internal/gtest-type-util.h | 38 ++++++++++--------- googletest/test/googletest-printers-test.cc | 20 ++++++++-- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 67c87f47..718e6f13 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -688,13 +688,20 @@ class UniversalPrinter { public: static void Print(const Any& value, ::std::ostream* os) { if (value.has_value()) - *os << "'any' type with value of type " << GetTypeName(); + *os << "'any' type with value of type " << GetTypeName(value); else *os << "'any' type with no value"; } private: - static std::string GetTypeName() { return "the element type"; } + static std::string GetTypeName(const Any& value) { +#if GTEST_HAS_RTTI + return internal::GetTypeName(value.type()); +#else + static_cast(value); // possibly unused + return "the element type"; +#endif // GTEST_HAS_RTTI + } }; #endif // GTEST_INTERNAL_HAS_ANY diff --git a/googletest/include/gtest/internal/gtest-type-util.h b/googletest/include/gtest/internal/gtest-type-util.h index 082fdad1..c3326f2c 100644 --- a/googletest/include/gtest/internal/gtest-type-util.h +++ b/googletest/include/gtest/internal/gtest-type-util.h @@ -64,34 +64,38 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) { return s; } -// GetTypeName() returns a human-readable name of type T. -// NB: This function is also used in Google Mock, so don't move it inside of -// the typed-test-only section below. -template -std::string GetTypeName() { -# if GTEST_HAS_RTTI - - const char* const name = typeid(T).name(); -# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) +#if GTEST_HAS_RTTI +// GetTypeName(const std::type_info&) returns a human-readable name of type T. +inline std::string GetTypeName(const std::type_info& type) { + const char* const name = type.name(); +#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. -# if GTEST_HAS_CXXABI_H_ +#if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; -# endif // GTEST_HAS_CXXABI_H_ +#endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return CanonicalizeForStdLibVersioning(name_str); -# else +#else return name; -# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC - -# else +#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC +} +#endif // GTEST_HAS_RTTI +// GetTypeName() 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 +std::string GetTypeName() { +#if GTEST_HAS_RTTI + return GetTypeName(typeid(T)); +#else return ""; - -# endif // GTEST_HAS_RTTI +#endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index 33050352..1324dd6e 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -1532,22 +1532,34 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { } #if GTEST_INTERNAL_HAS_ANY -TEST(PrintAnyTest, Empty) { +class PrintAnyTest : public ::testing::Test { + protected: + template + static std::string ExpectedTypeName() { +#if GTEST_HAS_RTTI + return internal::GetTypeName(); +#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(PrintAnyTest, NonEmpty) { +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 the element type", + EXPECT_EQ("'any' type with value of type " + ExpectedTypeName(), PrintToString(any)); any = val2; - EXPECT_EQ("'any' type with value of type the element type", + EXPECT_EQ("'any' type with value of type " + ExpectedTypeName(), PrintToString(any)); } #endif // GTEST_INTERNAL_HAS_ANY