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
This commit is contained in:
Abseil Team 2021-01-13 10:57:58 -05:00 committed by Derek Mauro
parent 50ce520161
commit 6b2e74905e
2 changed files with 92 additions and 2 deletions

View File

@ -101,6 +101,7 @@
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <functional>
#include <memory>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
@ -108,6 +109,7 @@
#include <type_traits>
#include <utility>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
@ -573,6 +575,43 @@ void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
UniversalPrinter<T&>::Print(ref.get(), os);
}
inline const void* VoidifyPointer(const void* p) { return p; }
inline const void* VoidifyPointer(volatile const void* p) {
return const_cast<const void*>(p);
}
template <typename T, typename Ptr>
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 <typename T, typename Ptr,
typename = typename std::enable_if<!std::is_void<T>::value &&
!std::is_array<T>::value>::type>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
if (ptr == nullptr) {
*os << "(nullptr)";
} else {
*os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
UniversalPrinter<T>::Print(*ptr, os);
*os << ")";
}
}
template <typename T, typename D>
void PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
template <typename T>
void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>

View File

@ -32,15 +32,16 @@
//
// This file tests the universal value printer.
#include <ctype.h>
#include <string.h>
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <deque>
#include <forward_list>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
@ -1702,6 +1703,56 @@ TEST(UniversalPrintTest, IncompleteType) {
PrintToString(reinterpret_cast<Incomplete&>(some_object)));
}
TEST(UniversalPrintTest, SmartPointers) {
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int>()));
std::unique_ptr<int> p(new int(17));
EXPECT_EQ("(ptr = " + PrintPointer(p.get()) + ", value = 17)",
PrintToString(p));
std::unique_ptr<int[]> p2(new int[2]);
EXPECT_EQ("(" + PrintPointer(p2.get()) + ")", PrintToString(p2));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int>()));
std::shared_ptr<int> p3(new int(1979));
EXPECT_EQ("(ptr = " + PrintPointer(p3.get()) + ", value = 1979)",
PrintToString(p3));
#if __cpp_lib_shared_ptr_arrays >= 201611L
std::shared_ptr<int[]> p4(new int[2]);
EXPECT_EQ("(" + PrintPointer(p4.get()) + ")", PrintToString(p4));
#endif
// modifiers
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<const int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile const int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<const int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile int[]>()));
EXPECT_EQ("(nullptr)",
PrintToString(std::unique_ptr<volatile const int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<const int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile const int>()));
#if __cpp_lib_shared_ptr_arrays >= 201611L
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<const int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile int[]>()));
EXPECT_EQ("(nullptr)",
PrintToString(std::shared_ptr<volatile const int[]>()));
#endif
// void
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<void, void (*)(void*)>(
nullptr, nullptr)));
EXPECT_EQ("(" + PrintPointer(p.get()) + ")",
PrintToString(
std::unique_ptr<void, void (*)(void*)>(p.get(), [](void*) {})));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<void>()));
EXPECT_EQ("(" + PrintPointer(p.get()) + ")",
PrintToString(std::shared_ptr<void>(p.get(), [](void*) {})));
}
TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) {
Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple());
EXPECT_EQ(0u, result.size());