make UniversalPrinter<std::any> support RTTI
This commit is contained in:
parent
c7858b7f33
commit
5ac7646e96
@ -688,13 +688,20 @@ class UniversalPrinter<Any> {
|
|||||||
public:
|
public:
|
||||||
static void Print(const Any& value, ::std::ostream* os) {
|
static void Print(const Any& value, ::std::ostream* os) {
|
||||||
if (value.has_value())
|
if (value.has_value())
|
||||||
*os << "'any' type with value of type " << GetTypeName();
|
*os << "'any' type with value of type " << GetTypeName(value);
|
||||||
else
|
else
|
||||||
*os << "'any' type with no value";
|
*os << "'any' type with no value";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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
|
#endif // GTEST_INTERNAL_HAS_ANY
|
||||||
|
@ -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
|
||||||
|
@ -1532,22 +1532,34 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_ANY
|
#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;
|
internal::Any any;
|
||||||
EXPECT_EQ("'any' type with no value", PrintToString(any));
|
EXPECT_EQ("'any' type with no value", PrintToString(any));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PrintAnyTest, NonEmpty) {
|
TEST_F(PrintAnyTest, NonEmpty) {
|
||||||
internal::Any any;
|
internal::Any any;
|
||||||
constexpr int val1 = 10;
|
constexpr int val1 = 10;
|
||||||
const std::string val2 = "content";
|
const std::string val2 = "content";
|
||||||
|
|
||||||
any = val1;
|
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));
|
PrintToString(any));
|
||||||
|
|
||||||
any = val2;
|
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));
|
PrintToString(any));
|
||||||
}
|
}
|
||||||
#endif // GTEST_INTERNAL_HAS_ANY
|
#endif // GTEST_INTERNAL_HAS_ANY
|
||||||
|
Loading…
x
Reference in New Issue
Block a user