googletest: Add universal printer for std::span
Fixes #4318 PiperOrigin-RevId: 560089120 Change-Id: I9d0d098140033520266747a1689e953ee8307c47
This commit is contained in:
parent
460ae98267
commit
8a6feabf04
@ -122,6 +122,10 @@
|
|||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
#include <span> // NOLINT
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Definitions in the internal* namespaces are subject to change without notice.
|
// Definitions in the internal* namespaces are subject to change without notice.
|
||||||
@ -131,13 +135,32 @@ namespace internal {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void UniversalPrint(const T& value, ::std::ostream* os);
|
void UniversalPrint(const T& value, ::std::ostream* os);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsStdSpan {
|
||||||
|
static constexpr bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
template <typename E>
|
||||||
|
struct IsStdSpan<std::span<E>> {
|
||||||
|
static constexpr bool value = true;
|
||||||
|
};
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
|
||||||
// Used to print an STL-style container when the user doesn't define
|
// Used to print an STL-style container when the user doesn't define
|
||||||
// a PrintTo() for it.
|
// a PrintTo() for it.
|
||||||
|
//
|
||||||
|
// NOTE: Since std::span does not have const_iterator until C++23, it would
|
||||||
|
// fail IsContainerTest before C++23. However, IsContainerTest only uses
|
||||||
|
// the presence of const_iterator to avoid treating iterators as containers
|
||||||
|
// because of iterator::iterator. Which means std::span satisfies the *intended*
|
||||||
|
// condition of IsContainerTest.
|
||||||
struct ContainerPrinter {
|
struct ContainerPrinter {
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if<
|
typename = typename std::enable_if<
|
||||||
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||||
!IsRecursiveContainer<T>::value>::type>
|
!IsRecursiveContainer<T>::value) ||
|
||||||
|
IsStdSpan<T>::value>::type>
|
||||||
static void PrintValue(const T& container, std::ostream* os) {
|
static void PrintValue(const T& container, std::ostream* os) {
|
||||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||||
*os << '{';
|
*os << '{';
|
||||||
|
@ -208,6 +208,8 @@
|
|||||||
// or
|
// or
|
||||||
// UniversalPrinter<absl::optional>
|
// UniversalPrinter<absl::optional>
|
||||||
// specializations. Always defined to 0 or 1.
|
// specializations. Always defined to 0 or 1.
|
||||||
|
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
|
||||||
|
// specializations. Always defined to 0 or 1
|
||||||
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
|
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
|
||||||
// Matcher<absl::string_view>
|
// Matcher<absl::string_view>
|
||||||
// specializations. Always defined to 0 or 1.
|
// specializations. Always defined to 0 or 1.
|
||||||
@ -2407,6 +2409,16 @@ inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
|
|||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 0
|
#define GTEST_INTERNAL_HAS_OPTIONAL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include(<span>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
||||||
|
#define GTEST_INTERNAL_HAS_STD_SPAN 1
|
||||||
|
#endif // __has_include(<span>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
||||||
|
#endif // __has_include
|
||||||
|
|
||||||
|
#ifndef GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
#define GTEST_INTERNAL_HAS_STD_SPAN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
// Always use absl::string_view for Matcher<> specializations if googletest
|
// Always use absl::string_view for Matcher<> specializations if googletest
|
||||||
// is built with absl support.
|
// is built with absl support.
|
||||||
|
@ -54,11 +54,16 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-printers.h"
|
#include "gtest/gtest-printers.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
#include <span> // NOLINT
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
|
||||||
// Some user-defined types for testing the universal value printer.
|
// Some user-defined types for testing the universal value printer.
|
||||||
|
|
||||||
// An anonymous enum type.
|
// An anonymous enum type.
|
||||||
@ -1179,6 +1184,17 @@ TEST(PrintStlContainerTest, Vector) {
|
|||||||
EXPECT_EQ("{ 1, 2 }", Print(v));
|
EXPECT_EQ("{ 1, 2 }", Print(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintStlContainerTest, StdSpan) {
|
||||||
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
int a[] = {3, 6, 5};
|
||||||
|
std::span<int> s = a;
|
||||||
|
|
||||||
|
EXPECT_EQ("{ 3, 6, 5 }", Print(s));
|
||||||
|
#else
|
||||||
|
GTEST_SKIP() << "Does not have std::span.";
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PrintStlContainerTest, LongSequence) {
|
TEST(PrintStlContainerTest, LongSequence) {
|
||||||
const int a[100] = {1, 2, 3};
|
const int a[100] = {1, 2, 3};
|
||||||
const vector<int> v(a, a + 100);
|
const vector<int> v(a, a + 100);
|
||||||
|
Loading…
Reference in New Issue
Block a user