Skip to content

Commit c7858b7

Browse files
committed
specialize UniversalPrinter<> for std::any (without support for RTTI)
1 parent 6e5ee43 commit c7858b7

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ cc_library(
103103
"@com_google_absl//absl/debugging:stacktrace",
104104
"@com_google_absl//absl/debugging:symbolize",
105105
"@com_google_absl//absl/strings",
106+
"@com_google_absl//absl/types:any",
106107
"@com_google_absl//absl/types:optional",
107108
"@com_google_absl//absl/types:variant",
108109
],

googletest/include/gtest/gtest-printers.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,26 @@ class UniversalPrinter {
679679
GTEST_DISABLE_MSC_WARNINGS_POP_()
680680
};
681681

682+
#if GTEST_INTERNAL_HAS_ANY
683+
684+
// Printer for std::any / absl::any
685+
686+
template <>
687+
class UniversalPrinter<Any> {
688+
public:
689+
static void Print(const Any& value, ::std::ostream* os) {
690+
if (value.has_value())
691+
*os << "'any' type with value of type " << GetTypeName();
692+
else
693+
*os << "'any' type with no value";
694+
}
695+
696+
private:
697+
static std::string GetTypeName() { return "the element type"; }
698+
};
699+
700+
#endif // GTEST_INTERNAL_HAS_ANY
701+
682702
#if GTEST_INTERNAL_HAS_OPTIONAL
683703

684704
// Printer for std::optional / absl::optional

googletest/include/gtest/internal/gtest-port.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@
199199
// suppressed (constant conditional).
200200
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
201201
// is suppressed.
202+
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
203+
// UniversalPrinter<absl::any> specializations.
202204
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional> or
203205
// UniversalPrinter<absl::optional> specializations.
204206
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
@@ -2227,6 +2229,34 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
22272229

22282230
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
22292231

2232+
#if GTEST_HAS_ABSL
2233+
// Always use absl::any for UniversalPrinter<> specializations if googletest
2234+
// is built with absl support.
2235+
# define GTEST_INTERNAL_HAS_ANY 1
2236+
#include "absl/types/any.h"
2237+
namespace testing {
2238+
namespace internal {
2239+
using Any = ::absl::any;
2240+
} // namespace internal
2241+
} // namespace testing
2242+
#else
2243+
# ifdef __has_include
2244+
# if __has_include(<any>) && __cplusplus >= 201703L
2245+
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
2246+
// specializations.
2247+
# define GTEST_INTERNAL_HAS_ANY 1
2248+
#include <any>
2249+
namespace testing {
2250+
namespace internal {
2251+
using Any = ::std::any;
2252+
} // namespace internal
2253+
} // namespace testing
2254+
// The case where absl is configured NOT to alias std::any is not
2255+
// supported.
2256+
# endif // __has_include(<any>) && __cplusplus >= 201703L
2257+
# endif // __has_include
2258+
#endif // GTEST_HAS_ABSL
2259+
22302260
#if GTEST_HAS_ABSL
22312261
// Always use absl::optional for UniversalPrinter<> specializations if googletest
22322262
// is built with absl support.

googletest/test/googletest-printers-test.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,27 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
15311531
EXPECT_EQ("\"a\"", result[1]);
15321532
}
15331533

1534+
#if GTEST_INTERNAL_HAS_ANY
1535+
TEST(PrintAnyTest, Empty) {
1536+
internal::Any any;
1537+
EXPECT_EQ("'any' type with no value", PrintToString(any));
1538+
}
1539+
1540+
TEST(PrintAnyTest, NonEmpty) {
1541+
internal::Any any;
1542+
constexpr int val1 = 10;
1543+
const std::string val2 = "content";
1544+
1545+
any = val1;
1546+
EXPECT_EQ("'any' type with value of type the element type",
1547+
PrintToString(any));
1548+
1549+
any = val2;
1550+
EXPECT_EQ("'any' type with value of type the element type",
1551+
PrintToString(any));
1552+
}
1553+
#endif // GTEST_INTERNAL_HAS_ANY
1554+
15341555
#if GTEST_INTERNAL_HAS_OPTIONAL
15351556
TEST(PrintOptionalTest, Basic) {
15361557
internal::Optional<int> value;

0 commit comments

Comments
 (0)