Update C++ feature detection in gtest-port.h to rely on feature test macros where possible.

This also avoids conflating C++ language versions with standard library versions, which don't always align.

PiperOrigin-RevId: 567662118
Change-Id: I7c023bd043c81c540c9430eaeb7b450feaadb206
This commit is contained in:
Abseil Team 2023-09-22 10:45:22 -07:00 committed by Copybara-Service
parent 80306a7b5e
commit e40661d89b

View File

@ -281,6 +281,22 @@
#error C++ versions less than C++14 are not supported. #error C++ versions less than C++14 are not supported.
#endif #endif
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
#ifdef __has_include
#define GTEST_INTERNAL_HAS_INCLUDE __has_include
#else
#define GTEST_INTERNAL_HAS_INCLUDE(...) 0
#endif
// Detect C++ feature test macros as gracefully as possible.
// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \
(!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))
#include <version> // C++20 and later
#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))
#include <ciso646> // Pre-C++20
#endif
#include <ctype.h> // for isspace, etc #include <ctype.h> // for isspace, etc
#include <stddef.h> // for ptrdiff_t #include <stddef.h> // for ptrdiff_t
#include <stdio.h> #include <stdio.h>
@ -2351,9 +2367,9 @@ using Any = ::absl::any;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#else #else
#ifdef __has_include #if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) && \
#if __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \ GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
(!defined(_MSC_VER) || GTEST_HAS_RTTI) (!defined(_MSC_VER) || GTEST_HAS_RTTI))
// Otherwise for C++17 and higher use std::any for UniversalPrinter<> // Otherwise for C++17 and higher use std::any for UniversalPrinter<>
// specializations. // specializations.
#define GTEST_INTERNAL_HAS_ANY 1 #define GTEST_INTERNAL_HAS_ANY 1
@ -2365,8 +2381,7 @@ using Any = ::std::any;
} // namespace testing } // namespace testing
// The case where absl is configured NOT to alias std::any is not // The case where absl is configured NOT to alias std::any is not
// supported. // supported.
#endif // __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L #endif // __cpp_lib_any
#endif // __has_include
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_ANY #ifndef GTEST_INTERNAL_HAS_ANY
@ -2386,8 +2401,8 @@ inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#else #else
#ifdef __has_include #if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \
#if __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<> // Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
// specializations. // specializations.
#define GTEST_INTERNAL_HAS_OPTIONAL 1 #define GTEST_INTERNAL_HAS_OPTIONAL 1
@ -2401,19 +2416,17 @@ inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
} // namespace testing } // namespace testing
// The case where absl is configured NOT to alias std::optional is not // The case where absl is configured NOT to alias std::optional is not
// supported. // supported.
#endif // __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L #endif // __cpp_lib_optional
#endif // __has_include
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_OPTIONAL #ifndef GTEST_INTERNAL_HAS_OPTIONAL
#define GTEST_INTERNAL_HAS_OPTIONAL 0 #define GTEST_INTERNAL_HAS_OPTIONAL 0
#endif #endif
#ifdef __has_include #if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
#if __has_include(<span>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)
#define GTEST_INTERNAL_HAS_STD_SPAN 1 #define GTEST_INTERNAL_HAS_STD_SPAN 1
#endif // __has_include(<span>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L #endif // __cpp_lib_span
#endif // __has_include
#ifndef GTEST_INTERNAL_HAS_STD_SPAN #ifndef GTEST_INTERNAL_HAS_STD_SPAN
#define GTEST_INTERNAL_HAS_STD_SPAN 0 #define GTEST_INTERNAL_HAS_STD_SPAN 0
@ -2430,8 +2443,9 @@ using StringView = ::absl::string_view;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#else #else
#ifdef __has_include #if defined(__cpp_lib_string_view) || \
#if __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L (GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::string_view for Matcher<> // Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations. // specializations.
#define GTEST_INTERNAL_HAS_STRING_VIEW 1 #define GTEST_INTERNAL_HAS_STRING_VIEW 1
@ -2443,9 +2457,7 @@ using StringView = ::std::string_view;
} // namespace testing } // namespace testing
// The case where absl is configured NOT to alias std::string_view is not // The case where absl is configured NOT to alias std::string_view is not
// supported. // supported.
#endif // __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= #endif // __cpp_lib_string_view
// 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW #ifndef GTEST_INTERNAL_HAS_STRING_VIEW
@ -2464,8 +2476,8 @@ using Variant = ::absl::variant<T...>;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#else #else
#ifdef __has_include #if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \
#if __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<> // Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
// specializations. // specializations.
#define GTEST_INTERNAL_HAS_VARIANT 1 #define GTEST_INTERNAL_HAS_VARIANT 1
@ -2477,16 +2489,16 @@ using Variant = ::std::variant<T...>;
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
// The case where absl is configured NOT to alias std::variant is not supported. // The case where absl is configured NOT to alias std::variant is not supported.
#endif // __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L #endif // __cpp_lib_variant
#endif // __has_include
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_VARIANT #ifndef GTEST_INTERNAL_HAS_VARIANT
#define GTEST_INTERNAL_HAS_VARIANT 0 #define GTEST_INTERNAL_HAS_VARIANT 0
#endif #endif
#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \ #if (defined(__cpp_constexpr) && !defined(__cpp_inline_variables)) || \
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L (defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L)
#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1 #define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1
#endif #endif