From 6b2e74905e9a7e70c7d1017ee0dfe5a8e88a1300 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 13 Jan 2021 10:57:58 -0500 Subject: [PATCH] Googletest export Print unique_ptr/shared_ptr recursively. Given that they are smart pointers, it is unlikely that the inner object is invalid. PiperOrigin-RevId: 351586888 --- googletest/include/gtest/gtest-printers.h | 39 +++++++++++++++ googletest/test/googletest-printers-test.cc | 55 ++++++++++++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 1f72b78089..37e949b646 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -101,6 +101,7 @@ #define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #include +#include #include // NOLINT #include #include @@ -108,6 +109,7 @@ #include #include #include + #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-port.h" @@ -573,6 +575,43 @@ void PrintTo(std::reference_wrapper ref, ::std::ostream* os) { UniversalPrinter::Print(ref.get(), os); } +inline const void* VoidifyPointer(const void* p) { return p; } +inline const void* VoidifyPointer(volatile const void* p) { + return const_cast(p); +} + +template +void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) { + if (ptr == nullptr) { + *os << "(nullptr)"; + } else { + // We can't print the value. Just print the pointer.. + *os << "(" << (VoidifyPointer)(ptr.get()) << ")"; + } +} +template ::value && + !std::is_array::value>::type> +void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) { + if (ptr == nullptr) { + *os << "(nullptr)"; + } else { + *os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = "; + UniversalPrinter::Print(*ptr, os); + *os << ")"; + } +} + +template +void PrintTo(const std::unique_ptr& ptr, std::ostream* os) { + (PrintSmartPointer)(ptr, os, 0); +} + +template +void PrintTo(const std::shared_ptr& ptr, std::ostream* os) { + (PrintSmartPointer)(ptr, os, 0); +} + // Helper function for printing a tuple. T must be instantiated with // a tuple type. template diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index 24ec230312..0653d9e1ed 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -32,15 +32,16 @@ // // This file tests the universal value printer. -#include -#include #include +#include #include +#include #include #include #include #include #include +#include #include #include #include @@ -1702,6 +1703,56 @@ TEST(UniversalPrintTest, IncompleteType) { PrintToString(reinterpret_cast(some_object))); } +TEST(UniversalPrintTest, SmartPointers) { + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + std::unique_ptr p(new int(17)); + EXPECT_EQ("(ptr = " + PrintPointer(p.get()) + ", value = 17)", + PrintToString(p)); + std::unique_ptr p2(new int[2]); + EXPECT_EQ("(" + PrintPointer(p2.get()) + ")", PrintToString(p2)); + + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + std::shared_ptr p3(new int(1979)); + EXPECT_EQ("(ptr = " + PrintPointer(p3.get()) + ", value = 1979)", + PrintToString(p3)); +#if __cpp_lib_shared_ptr_arrays >= 201611L + std::shared_ptr p4(new int[2]); + EXPECT_EQ("(" + PrintPointer(p4.get()) + ")", PrintToString(p4)); +#endif + + // modifiers + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", + PrintToString(std::unique_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); +#if __cpp_lib_shared_ptr_arrays >= 201611L + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(nullptr)", + PrintToString(std::shared_ptr())); +#endif + + // void + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr( + nullptr, nullptr))); + EXPECT_EQ("(" + PrintPointer(p.get()) + ")", + PrintToString( + std::unique_ptr(p.get(), [](void*) {}))); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr())); + EXPECT_EQ("(" + PrintPointer(p.get()) + ")", + PrintToString(std::shared_ptr(p.get(), [](void*) {}))); +} + TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); EXPECT_EQ(0u, result.size());