make UniversalPrinter<std::any> support RTTI
This commit is contained in:
		@@ -688,13 +688,20 @@ 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();
 | 
			
		||||
      *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<void>(value); // possibly unused
 | 
			
		||||
    return "the element type";
 | 
			
		||||
#endif  // GTEST_HAS_RTTI
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // GTEST_INTERNAL_HAS_ANY
 | 
			
		||||
 
 | 
			
		||||
@@ -64,34 +64,38 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
 | 
			
		||||
  return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetTypeName<T>() 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 <typename T>
 | 
			
		||||
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<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>";
 | 
			
		||||
 | 
			
		||||
# endif  // GTEST_HAS_RTTI
 | 
			
		||||
#endif  // GTEST_HAS_RTTI
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
 | 
			
		||||
 
 | 
			
		||||
@@ -1532,22 +1532,34 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if GTEST_INTERNAL_HAS_ANY
 | 
			
		||||
TEST(PrintAnyTest, Empty) {
 | 
			
		||||
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(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<int>(),
 | 
			
		||||
            PrintToString(any));
 | 
			
		||||
 | 
			
		||||
  any = val2;
 | 
			
		||||
  EXPECT_EQ("'any' type with value of type the element type",
 | 
			
		||||
  EXPECT_EQ("'any' type with value of type " + ExpectedTypeName<std::string>(),
 | 
			
		||||
            PrintToString(any));
 | 
			
		||||
}
 | 
			
		||||
#endif  // GTEST_INTERNAL_HAS_ANY
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user