diff --git a/CHANGELOG.md b/CHANGELOG.md index 88f8cb3d..4b165af7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ See PR links for more information. ## 1.7.6 - NEW: modified template project to include `-ffunction-sections`, `-fdata-sections`, `--gc-sections` flags and changed assembly files to use unique sections so linker can better strip unused code/data +- NEW: updated `type_traits` include ## 1.7.5 - FIX: fixed missing `obj` and `out` directories in template project diff --git a/bin/darwin/opt/m68k-amiga-elf/include/c++config b/bin/darwin/opt/m68k-amiga-elf/include/c++config index 6caaf7ad..a75e2cb3 100644 --- a/bin/darwin/opt/m68k-amiga-elf/include/c++config +++ b/bin/darwin/opt/m68k-amiga-elf/include/c++config @@ -1,6 +1,6 @@ // Predefined symbols and macros -*- C++ -*- -// Copyright (C) 1997-2020 Free Software Foundation, Inc. +// Copyright (C) 1997-2023 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -30,6 +30,8 @@ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 +#pragma GCC system_header + // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE @@ -64,9 +66,9 @@ // Macros for visibility attributes. // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY // _GLIBCXX_VISIBILITY -#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 +#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY -#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +#ifdef _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) #else // If this is not supplied by the OS-specific or CPU-specific @@ -77,28 +79,68 @@ // Macros for deprecated attributes. // _GLIBCXX_USE_DEPRECATED // _GLIBCXX_DEPRECATED +// _GLIBCXX_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX11_DEPRECATED +// _GLIBCXX11_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX14_DEPRECATED +// _GLIBCXX14_DEPRECATED_SUGGEST( string-literal ) // _GLIBCXX17_DEPRECATED -// _GLIBCXX20_DEPRECATED( string-literal ) +// _GLIBCXX17_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX20_DEPRECATED +// _GLIBCXX20_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX23_DEPRECATED +// _GLIBCXX23_DEPRECATED_SUGGEST( string-literal ) #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif -#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +#if defined(__DEPRECATED) # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) +# define _GLIBCXX_DEPRECATED_SUGGEST(ALT) \ + __attribute__ ((__deprecated__ ("use '" ALT "' instead"))) #else # define _GLIBCXX_DEPRECATED +# define _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +# define _GLIBCXX11_DEPRECATED _GLIBCXX_DEPRECATED +# define _GLIBCXX11_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX11_DEPRECATED +# define _GLIBCXX11_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201402L) +# define _GLIBCXX14_DEPRECATED _GLIBCXX_DEPRECATED +# define _GLIBCXX14_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX14_DEPRECATED +# define _GLIBCXX14_DEPRECATED_SUGGEST(ALT) #endif #if defined(__DEPRECATED) && (__cplusplus >= 201703L) # define _GLIBCXX17_DEPRECATED [[__deprecated__]] +# define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) #else # define _GLIBCXX17_DEPRECATED +# define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 202002L) +# define _GLIBCXX20_DEPRECATED [[__deprecated__]] +# define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX20_DEPRECATED +# define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) #endif -#if defined(__DEPRECATED) && (__cplusplus > 201703L) -# define _GLIBCXX20_DEPRECATED(MSG) [[deprecated(MSG)]] +#if defined(__DEPRECATED) && (__cplusplus >= 202100L) +# define _GLIBCXX23_DEPRECATED [[__deprecated__]] +# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) #else -# define _GLIBCXX20_DEPRECATED(MSG) +# define _GLIBCXX23_DEPRECATED +# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) #endif // Macros for ABI tag attributes. @@ -145,13 +187,21 @@ #endif #ifndef _GLIBCXX20_CONSTEXPR -# if __cplusplus > 201703L +# if __cplusplus >= 202002L # define _GLIBCXX20_CONSTEXPR constexpr # else # define _GLIBCXX20_CONSTEXPR # endif #endif +#ifndef _GLIBCXX23_CONSTEXPR +# if __cplusplus >= 202100L +# define _GLIBCXX23_CONSTEXPR constexpr +# else +# define _GLIBCXX23_CONSTEXPR +# endif +#endif + #ifndef _GLIBCXX17_INLINE # if __cplusplus >= 201703L # define _GLIBCXX17_INLINE inline @@ -263,20 +313,31 @@ namespace std #if __cplusplus >= 201103L typedef decltype(nullptr) nullptr_t; #endif + +#pragma GCC visibility push(default) + // This allows the library to terminate without including all of + // and without making the declaration of std::terminate visible to users. + extern "C++" __attribute__ ((__noreturn__, __always_inline__)) + inline void __terminate() _GLIBCXX_USE_NOEXCEPT + { + void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__,__cold__)); + terminate(); + } +#pragma GCC visibility pop } -#define _GLIBCXX_USE_DUAL_ABI 0 +#define _GLIBCXX_USE_DUAL_ABI -#if ! _GLIBCXX_USE_DUAL_ABI +#ifndef _GLIBCXX_USE_DUAL_ABI // Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI # undef _GLIBCXX_USE_CXX11_ABI #endif #ifndef _GLIBCXX_USE_CXX11_ABI -#define _GLIBCXX_USE_CXX11_ABI 1 +#define _GLIBCXX_USE_CXX11_ABI #endif -#if _GLIBCXX_USE_CXX11_ABI +#ifdef _GLIBCXX_USE_CXX11_ABI namespace std { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } @@ -296,13 +357,16 @@ namespace __gnu_cxx # define _GLIBCXX_DEFAULT_ABI_TAG #endif -// Defined if inline namespaces are used for versioning. -#define _GLIBCXX_INLINE_VERSION 1 +// Non-zero if inline namespaces are used for versioning the entire library. +#define _GLIBCXX_INLINE_VERSION -// Inline namespace for symbol versioning. -#if _GLIBCXX_INLINE_VERSION +#ifdef _GLIBCXX_INLINE_VERSION +// Inline namespace for symbol versioning of (nearly) everything in std. # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 { # define _GLIBCXX_END_NAMESPACE_VERSION } +// Unused when everything in std is versioned anyway. +# define _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X) +# define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) namespace std { @@ -327,8 +391,19 @@ _GLIBCXX_END_NAMESPACE_VERSION } #else +// Unused. # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION +// Used to version individual components, e.g. std::_V2::error_category. +# define _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X) inline namespace X { +# define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) } // inline namespace X +#endif + +// In the case that we don't have a hosted environment, we can't provide the +// debugging mode. Instead, we do our best and downgrade to assertions. +#if defined(_GLIBCXX_DEBUG) && !__STDC_HOSTED__ +#undef _GLIBCXX_DEBUG +#define _GLIBCXX_ASSERTIONS 1 #endif // Inline namespaces for special modes: debug, parallel. @@ -406,7 +481,30 @@ _GLIBCXX_END_NAMESPACE_VERSION // Define if compatibility should be provided for -mlong-double-64. #undef _GLIBCXX_LONG_DOUBLE_COMPAT -// Inline namespace for long double 128 mode. +// Define if compatibility should be provided for alternative 128-bit long +// double formats. Not possible for Clang until __ibm128 is supported. +#ifndef __clang__ +#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT +#endif + +// Inline namespaces for long double 128 modes. +#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ + && defined __LONG_DOUBLE_IEEE128__ +namespace std +{ + // Namespaces for 128-bit IEEE long double format on 64-bit POWER LE. + inline namespace __gnu_cxx_ieee128 { } + inline namespace __gnu_cxx11_ieee128 { } +} +# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ieee128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ieee128 { +# define _GLIBCXX_END_NAMESPACE_LDBL } +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 __gnu_cxx11_ieee128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 namespace __gnu_cxx11_ieee128 { +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 } + +#else // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128 + #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ namespace std { @@ -420,7 +518,8 @@ namespace std # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif -#if _GLIBCXX_USE_CXX11_ABI + +#ifdef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 @@ -430,6 +529,31 @@ namespace std # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL #endif +#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128 + +namespace std +{ +#pragma GCC visibility push(default) + // Internal version of std::is_constant_evaluated(). + // This can be used without checking if the compiler supports the feature. + // The macro _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED can be used to check if + // the compiler support is present to make this function work as expected. + _GLIBCXX_CONSTEXPR inline bool + __is_constant_evaluated() _GLIBCXX_NOEXCEPT + { +#if __cpp_if_consteval >= 202106L +# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1 + if consteval { return true; } else { return false; } +#elif __cplusplus >= 201103L && __has_builtin(__builtin_is_constant_evaluated) +# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1 + return __builtin_is_constant_evaluated(); +#else + return false; +#endif + } +#pragma GCC visibility pop +} + // Debug Mode implies checking assertions. #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS) # define _GLIBCXX_ASSERTIONS 1 @@ -441,35 +565,65 @@ namespace std # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif + +#if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED +# define __glibcxx_constexpr_assert(cond) \ + if (std::__is_constant_evaluated() && !bool(cond)) \ + __builtin_unreachable() /* precondition violation detected! */ +#else +# define __glibcxx_constexpr_assert(unevaluated) +#endif + +#undef _GLIBCXX_VERBOSE_ASSERT + // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) +# ifdef _GLIBCXX_VERBOSE_ASSERT namespace std { +#pragma GCC visibility push(default) // Avoid the use of assert, because we're trying to keep the // include out of the mix. - extern "C++" inline void - __replacement_assert(const char* __file, int __line, - const char* __function, const char* __condition) - { - __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, - __function, __condition); - __builtin_abort(); - } + extern "C++" _GLIBCXX_NORETURN + void + __glibcxx_assert_fail(const char* __file, int __line, + const char* __function, const char* __condition) + _GLIBCXX_NOEXCEPT; +#pragma GCC visibility pop } -#define __glibcxx_assert_impl(_Condition) \ - do \ - { \ - if (! (_Condition)) \ - std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ - #_Condition); \ - } while (false) +#define __glibcxx_assert_impl(_Condition) \ + if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(false); \ + std::__glibcxx_assert_fail(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } +# else // ! VERBOSE_ASSERT +# define __glibcxx_assert_impl(_Condition) \ + if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(false); \ + __builtin_abort(); \ + } +# endif #endif #if defined(_GLIBCXX_ASSERTIONS) -# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_assert_impl(cond); } while (false) #else -# define __glibcxx_assert(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_constexpr_assert(cond); } while (false) +#endif + +// Macro indicating that TSAN is in use. +#if __SANITIZE_THREAD__ +# define _GLIBCXX_TSAN 1 +#elif defined __has_feature +# if __has_feature(thread_sanitizer) +# define _GLIBCXX_TSAN 1 +# endif #endif // Macros for race detectors. @@ -504,7 +658,16 @@ namespace std # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { # define _GLIBCXX_END_EXTERN_C } -#define _GLIBCXX_USE_ALLOCATOR_NEW 1 +#define _GLIBCXX_USE_ALLOCATOR_NEW + +#ifdef __SIZEOF_INT128__ +#if ! defined __GLIBCXX_TYPE_INT_N_0 && ! defined __STRICT_ANSI__ +// If __int128 is supported, we expect __GLIBCXX_TYPE_INT_N_0 to be defined +// unless the compiler is in strict mode. If it's not defined and the strict +// macro is not defined, something is wrong. +#warning "__STRICT_ANSI__ seems to have been undefined; this is not supported" +#endif +#endif #else // !__cplusplus # define _GLIBCXX_BEGIN_EXTERN_C @@ -544,10 +707,10 @@ namespace std // Conditionally enable annotations for the Transactional Memory TS on C++11. // Most of the following conditions are due to limitations in the current // implementation. -#if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI \ - && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201500L \ +#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_CXX11_ABI) \ + && defined(_GLIBCXX_USE_DUAL_ABI) && __cpp_transactional_memory >= 201500L \ && !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF \ - && _GLIBCXX_USE_ALLOCATOR_NEW + && defined(_GLIBCXX_USE_ALLOCATOR_NEW) #define _GLIBCXX_TXN_SAFE transaction_safe #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic #else @@ -630,38 +793,79 @@ namespace std # define __cpp_lib_char8_t 201907L #endif -/* Define if __float128 is supported on this host. */ +/* Define if __float128 is supported on this host. */ #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) -#define _GLIBCXX_USE_FLOAT128 +/* For powerpc64 don't use __float128 when it's the same type as long double. */ +# if !(defined(_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) && defined(__LONG_DOUBLE_IEEE128__)) +# define _GLIBCXX_USE_FLOAT128 +# endif +#endif + +// Define if float has the IEEE binary32 format. +#if __FLT_MANT_DIG__ == 24 \ + && __FLT_MIN_EXP__ == -125 \ + && __FLT_MAX_EXP__ == 128 +# define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1 +#endif + +// Define if double has the IEEE binary64 format. +#if __DBL_MANT_DIG__ == 53 \ + && __DBL_MIN_EXP__ == -1021 \ + && __DBL_MAX_EXP__ == 1024 +# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1 +#endif + +// Define if long double has the IEEE binary128 format. +#if __LDBL_MANT_DIG__ == 113 \ + && __LDBL_MIN_EXP__ == -16381 \ + && __LDBL_MAX_EXP__ == 16384 +# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1 +#endif + +#if defined __cplusplus && defined __BFLT16_DIG__ +namespace __gnu_cxx +{ + typedef __decltype(0.0bf16) __bfloat16_t; +} #endif -#if __GNUC__ >= 7 -// Assume these are available if the compiler claims to be a recent GCC: +#ifdef __has_builtin +# ifdef __is_identifier +// Intel and older Clang require !__is_identifier for some built-ins: +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) || ! __is_identifier(B) +# else +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) +# endif +#endif + +#if _GLIBCXX_HAS_BUILTIN(__has_unique_object_representations) # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__is_aggregate) # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__is_same) +# define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__builtin_launder) # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -# define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same_as(T, U) -# if __GNUC__ >= 9 -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -# endif -#elif defined(__is_identifier) && defined(__has_builtin) -// For non-GNU compilers: -# if ! __is_identifier(__has_unique_object_representations) -# define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 -# endif -# if ! __is_identifier(__is_aggregate) -# define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 -# endif -# if __has_builtin(__builtin_launder) -# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -# endif -# if __has_builtin(__builtin_is_constant_evaluated) -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -# endif -# if ! __is_identifier(__is_same) -# define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U) -# endif -#endif // GCC +#endif + +// Returns 1 if _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS is not defined and the +// compiler has a corresponding built-in type trait, 0 otherwise. +// _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS can be defined to disable the use of +// built-in traits. +#ifndef _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS +# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) _GLIBCXX_HAS_BUILTIN(BT) +#else +# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) 0 +#endif + +// Mark code that should be ignored by the compiler, but seen by Doxygen. +#define _GLIBCXX_DOXYGEN_ONLY(X) // PSTL configuration @@ -689,5 +893,5 @@ namespace std #endif // __has_include #endif // C++17 -#endif // End of prewritten config; the settings discovered at configure time follow. +#endif \ No newline at end of file diff --git a/bin/darwin/opt/m68k-amiga-elf/include/type_traits b/bin/darwin/opt/m68k-amiga-elf/include/type_traits index cea999f4..13c0cbb7 100644 --- a/bin/darwin/opt/m68k-amiga-elf/include/type_traits +++ b/bin/darwin/opt/m68k-amiga-elf/include/type_traits @@ -1,6 +1,6 @@ // C++11 -*- C++ -*- -// Copyright (C) 2007-2020 Free Software Foundation, Inc. +// Copyright (C) 2007-2024 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -37,8 +37,37 @@ #include "c++config" -namespace std +#define __glibcxx_want_bool_constant +#define __glibcxx_want_bounded_array_traits +#define __glibcxx_want_has_unique_object_representations +#define __glibcxx_want_integral_constant_callable +#define __glibcxx_want_is_aggregate +#define __glibcxx_want_is_constant_evaluated +#define __glibcxx_want_is_final +#define __glibcxx_want_is_invocable +#define __glibcxx_want_is_layout_compatible +#define __glibcxx_want_is_nothrow_convertible +#define __glibcxx_want_is_null_pointer +#define __glibcxx_want_is_pointer_interconvertible +#define __glibcxx_want_is_scoped_enum +#define __glibcxx_want_is_swappable +#define __glibcxx_want_logical_traits +#define __glibcxx_want_reference_from_temporary +#define __glibcxx_want_remove_cvref +#define __glibcxx_want_result_of_sfinae +#define __glibcxx_want_transformation_trait_aliases +#define __glibcxx_want_type_identity +#define __glibcxx_want_type_trait_variable_templates +#define __glibcxx_want_unwrap_ref +#define __glibcxx_want_void_t +//#include + +namespace std _GLIBCXX_VISIBILITY(default) { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + class reference_wrapper; /** * @defgroup metaprogramming Metaprogramming @@ -48,6 +77,8 @@ namespace std * including type classification traits, type property inspection traits * and type transformation traits. * + * @since C++11 + * * @{ */ @@ -55,41 +86,77 @@ namespace std template struct integral_constant { - static constexpr _Tp value = __v; - typedef _Tp value_type; - typedef integral_constant<_Tp, __v> type; + static constexpr _Tp value = __v; + using value_type = _Tp; + using type = integral_constant<_Tp, __v>; constexpr operator value_type() const noexcept { return value; } -#if __cplusplus > 201103L - -#define __cpp_lib_integral_constant_callable 201304 +#ifdef __cpp_lib_integral_constant_callable // C++ >= 14 constexpr value_type operator()() const noexcept { return value; } #endif }; +#if ! __cpp_inline_variables template constexpr _Tp integral_constant<_Tp, __v>::value; +#endif + + /// @cond undocumented + /// bool_constant for C++11 + template + using __bool_constant = integral_constant; + /// @endcond /// The type used as a compile-time boolean with true value. - typedef integral_constant true_type; + using true_type = __bool_constant; /// The type used as a compile-time boolean with false value. - typedef integral_constant false_type; + using false_type = __bool_constant; +#ifdef __cpp_lib_bool_constant // C++ >= 17 + /// Alias template for compile-time boolean constant types. + /// @since C++17 template - using __bool_constant = integral_constant; - -#if __cplusplus > 201402L -# define __cpp_lib_bool_constant 201505 - template - using bool_constant = integral_constant; + using bool_constant = __bool_constant<__v>; #endif - // Meta programming helper types. + // Metaprogramming helper types. + + // Primary template. + /// Define a member typedef `type` only if a boolean constant is true. + template + struct enable_if + { }; + + // Partial specialization for true. + template + struct enable_if + { using type = _Tp; }; + + // __enable_if_t (std::enable_if_t for C++11) + template + using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + + template + struct __conditional + { + template + using type = _Tp; + }; - template - struct conditional; + template<> + struct __conditional + { + template + using type = _Up; + }; + + // More efficient version of std::conditional_t for internal use (and C++11) + template + using __conditional_t + = typename __conditional<_Cond>::template type<_If, _Else>; + /// @cond undocumented template struct __type_identity { using type = _Type; }; @@ -97,81 +164,103 @@ namespace std template using __type_identity_t = typename __type_identity<_Tp>::type; - template - struct __or_; - - template<> - struct __or_<> - : public false_type - { }; - - template - struct __or_<_B1> - : public _B1 - { }; - - template - struct __or_<_B1, _B2> - : public conditional<_B1::value, _B1, _B2>::type - { }; + namespace __detail + { + // A variadic alias template that resolves to its first argument. + template + using __first_t = _Tp; - template - struct __or_<_B1, _B2, _B3, _Bn...> - : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type - { }; + // These are deliberately not defined. + template + auto __or_fn(int) -> __first_t...>; - template - struct __and_; + template + auto __or_fn(...) -> true_type; - template<> - struct __and_<> - : public true_type - { }; + template + auto __and_fn(int) -> __first_t...>; - template - struct __and_<_B1> - : public _B1 - { }; + template + auto __and_fn(...) -> false_type; + } // namespace detail - template - struct __and_<_B1, _B2> - : public conditional<_B1::value, _B2, _B1>::type + // Like C++17 std::dis/conjunction, but usable in C++11 and resolves + // to either true_type or false_type which allows for a more efficient + // implementation that avoids recursive class template instantiation. + template + struct __or_ + : decltype(__detail::__or_fn<_Bn...>(0)) { }; - template - struct __and_<_B1, _B2, _B3, _Bn...> - : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type + template + struct __and_ + : decltype(__detail::__and_fn<_Bn...>(0)) { }; template struct __not_ - : public __bool_constant + : __bool_constant { }; + /// @endcond -#if __cplusplus >= 201703L +#ifdef __cpp_lib_logical_traits // C++ >= 17 + /// @cond undocumented template inline constexpr bool __or_v = __or_<_Bn...>::value; template inline constexpr bool __and_v = __and_<_Bn...>::value; -#define __cpp_lib_logical_traits 201510 + namespace __detail + { + template + struct __disjunction_impl + { using type = _B1; }; + + template + struct __disjunction_impl<__enable_if_t, _B1, _B2, _Bn...> + { using type = typename __disjunction_impl::type; }; + + template + struct __conjunction_impl + { using type = _B1; }; + + template + struct __conjunction_impl<__enable_if_t, _B1, _B2, _Bn...> + { using type = typename __conjunction_impl::type; }; + } // namespace __detail + /// @endcond template struct conjunction - : __and_<_Bn...> + : __detail::__conjunction_impl::type + { }; + + template<> + struct conjunction<> + : true_type { }; template struct disjunction - : __or_<_Bn...> + : __detail::__disjunction_impl::type + { }; + + template<> + struct disjunction<> + : false_type { }; template struct negation - : __not_<_Pp> + : __not_<_Pp>::type { }; + /** @ingroup variable_templates + * @{ + */ template inline constexpr bool conjunction_v = conjunction<_Bn...>::value; @@ -180,8 +269,9 @@ namespace std template inline constexpr bool negation_v = negation<_Pp>::value; + /// @} -#endif // C++17 +#endif // __cpp_lib_logical_traits // Forward declarations template @@ -190,6 +280,12 @@ namespace std struct is_function; template struct is_void; + template + struct remove_cv; + template + struct is_const; + + /// @cond undocumented template struct __is_array_unknown_bounds; @@ -210,44 +306,35 @@ namespace std >::type __is_complete_or_unbounded(_TypeIdentity) { return {}; } - // For several sfinae-friendly trait implementations we transport both the - // result information (as the member type) and the failure information (no - // member type). This is very similar to std::enable_if, but we cannot use - // them, because we need to derive from them as an implementation detail. - - template - struct __success_type - { typedef _Tp type; }; - - struct __failure_type - { }; - - template - struct remove_cv; - // __remove_cv_t (std::remove_cv_t for C++11). template using __remove_cv_t = typename remove_cv<_Tp>::type; - - template - struct is_const; + /// @endcond // Primary type categories. - template - struct __is_void_helper + /// is_void + template + struct is_void : public false_type { }; template<> - struct __is_void_helper + struct is_void : public true_type { }; - /// is_void - template - struct is_void - : public __is_void_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_void + : public true_type { }; + template<> + struct is_void + : public true_type { }; + + template<> + struct is_void + : public true_type { }; + + /// @cond undocumented template struct __is_integral_helper : public false_type { }; @@ -268,11 +355,12 @@ namespace std struct __is_integral_helper : public true_type { }; -#ifdef _GLIBCXX_USE_WCHAR_T + // We want is_integral to be true (and make_signed/unsigned to work) + // even when libc doesn't provide working and related functions, + // so don't check _GLIBCXX_USE_WCHAR_T here. template<> struct __is_integral_helper : public true_type { }; -#endif #ifdef _GLIBCXX_USE_CHAR8_T template<> @@ -323,41 +411,50 @@ namespace std // Conditionalizing on __STRICT_ANSI__ here will break any port that // uses one of these types for size_t. #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif + /// @endcond /// is_integral template @@ -365,6 +462,7 @@ namespace std : public __is_integral_helper<__remove_cv_t<_Tp>>::type { }; + /// @cond undocumented template struct __is_floating_point_helper : public false_type { }; @@ -381,11 +479,42 @@ namespace std struct __is_floating_point_helper : public true_type { }; +#ifdef __STDCPP_FLOAT16_T__ + template<> + struct __is_floating_point_helper<_Float16> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT32_T__ + template<> + struct __is_floating_point_helper<_Float32> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT64_T__ + template<> + struct __is_floating_point_helper<_Float64> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT128_T__ + template<> + struct __is_floating_point_helper<_Float128> + : public true_type { }; +#endif + +#ifdef __STDCPP_BFLOAT16_T__ + template<> + struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t> + : public true_type { }; +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) template<> struct __is_floating_point_helper<__float128> : public true_type { }; #endif + /// @endcond /// is_floating_point template @@ -394,6 +523,12 @@ namespace std { }; /// is_array +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) + template + struct is_array + : public __bool_constant<__is_array(_Tp)> + { }; +#else template struct is_array : public false_type { }; @@ -405,6 +540,7 @@ namespace std template struct is_array<_Tp[]> : public true_type { }; +#endif template struct __is_pointer_helper @@ -438,6 +574,13 @@ namespace std struct is_rvalue_reference<_Tp&&> : public true_type { }; + /// is_member_object_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) + template + struct is_member_object_pointer + : public __bool_constant<__is_member_object_pointer(_Tp)> + { }; +#else template struct __is_member_object_pointer_helper : public false_type { }; @@ -446,12 +589,20 @@ namespace std struct __is_member_object_pointer_helper<_Tp _Cp::*> : public __not_>::type { }; - /// is_member_object_pointer + template struct is_member_object_pointer : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) + /// is_member_function_pointer + template + struct is_member_function_pointer + : public __bool_constant<__is_member_function_pointer(_Tp)> + { }; +#else template struct __is_member_function_pointer_helper : public false_type { }; @@ -465,26 +616,33 @@ namespace std struct is_member_function_pointer : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif /// is_enum template struct is_enum - : public integral_constant + : public __bool_constant<__is_enum(_Tp)> { }; /// is_union template struct is_union - : public integral_constant + : public __bool_constant<__is_union(_Tp)> { }; /// is_class template struct is_class - : public integral_constant + : public __bool_constant<__is_class(_Tp)> { }; /// is_function +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) + template + struct is_function + : public __bool_constant<__is_function(_Tp)> + { }; +#else template struct is_function : public __bool_constant::value> { }; @@ -496,38 +654,63 @@ namespace std template struct is_function<_Tp&&> : public false_type { }; +#endif -#define __cpp_lib_is_null_pointer 201309 - - template - struct __is_null_pointer_helper +#ifdef __glibcxx_want_is_null_pointer // C++ >= 11 + /// is_null_pointer (LWG 2247). + template + struct is_null_pointer : public false_type { }; template<> - struct __is_null_pointer_helper + struct is_null_pointer : public true_type { }; - /// is_null_pointer (LWG 2247). - template - struct is_null_pointer - : public __is_null_pointer_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_null_pointer + : public true_type { }; + + template<> + struct is_null_pointer + : public true_type { }; + + template<> + struct is_null_pointer + : public true_type { }; /// __is_nullptr_t (deprecated extension). + /// @deprecated Non-standard. Use `is_null_pointer` instead. template struct __is_nullptr_t : public is_null_pointer<_Tp> - { } _GLIBCXX_DEPRECATED; + { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer"); +#endif // __cpp_lib_is_null_pointer // Composite type categories. /// is_reference +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) + template + struct is_reference + : public __bool_constant<__is_reference(_Tp)> + { }; +#else template struct is_reference - : public __or_, - is_rvalue_reference<_Tp>>::type + : public false_type + { }; + + template + struct is_reference<_Tp&> + : public true_type { }; + template + struct is_reference<_Tp&&> + : public true_type + { }; +#endif + /// is_arithmetic template struct is_arithmetic @@ -542,11 +725,18 @@ namespace std { }; /// is_object +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) + template + struct is_object + : public __bool_constant<__is_object(_Tp)> + { }; +#else template struct is_object : public __not_<__or_, is_reference<_Tp>, is_void<_Tp>>>::type { }; +#endif template struct is_member_pointer; @@ -561,8 +751,16 @@ namespace std /// is_compound template struct is_compound - : public __not_>::type { }; + : public __bool_constant::value> { }; + /// is_member_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) + template + struct is_member_pointer + : public __bool_constant<__is_member_pointer(_Tp)> + { }; +#else + /// @cond undocumented template struct __is_member_pointer_helper : public false_type { }; @@ -570,20 +768,23 @@ namespace std template struct __is_member_pointer_helper<_Tp _Cp::*> : public true_type { }; + /// @endcond - /// is_member_pointer template struct is_member_pointer : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif template struct is_same; + /// @cond undocumented template using __is_one_of = __or_...>; // Check if a type is one of the signed integer types. + __extension__ template using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>, signed char, signed short, signed int, signed long, @@ -603,6 +804,7 @@ namespace std >; // Check if a type is one of the unsigned integer types. + __extension__ template using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>, unsigned char, unsigned short, unsigned int, unsigned long, @@ -628,18 +830,7 @@ namespace std // __void_t (std::void_t for C++11) template using __void_t = void; - - // Utility to detect referenceable types ([defns.referenceable]). - - template - struct __is_referenceable - : public false_type - { }; - - template - struct __is_referenceable<_Tp, __void_t<_Tp&>> - : public true_type - { }; + /// @endcond // Type properties. @@ -664,16 +855,16 @@ namespace std /// is_trivial template struct is_trivial - : public integral_constant + : public __bool_constant<__is_trivial(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - // is_trivially_copyable + /// is_trivially_copyable template struct is_trivially_copyable - : public integral_constant + : public __bool_constant<__is_trivially_copyable(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -682,28 +873,36 @@ namespace std /// is_standard_layout template struct is_standard_layout - : public integral_constant + : public __bool_constant<__is_standard_layout(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - /// is_pod (deprecated in C++20) + /** is_pod + * @deprecated Deprecated in C++20. + * Use `is_standard_layout && is_trivial` instead. + */ // Could use is_standard_layout && is_trivial instead of the builtin. template struct - _GLIBCXX20_DEPRECATED("use is_standard_layout && is_trivial instead") + _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial") is_pod - : public integral_constant + : public __bool_constant<__is_pod(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - /// is_literal_type + /** is_literal_type + * @deprecated Deprecated in C++17, removed in C++20. + * The idea of a literal type isn't useful. + */ template - struct is_literal_type - : public integral_constant + struct + _GLIBCXX17_DEPRECATED + is_literal_type + : public __bool_constant<__is_literal_type(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -712,30 +911,31 @@ namespace std /// is_empty template struct is_empty - : public integral_constant + : public __bool_constant<__is_empty(_Tp)> { }; /// is_polymorphic template struct is_polymorphic - : public integral_constant + : public __bool_constant<__is_polymorphic(_Tp)> { }; -#if __cplusplus >= 201402L -#define __cpp_lib_is_final 201402L +#ifdef __cpp_lib_is_final // C++ >= 14 /// is_final + /// @since C++14 template struct is_final - : public integral_constant + : public __bool_constant<__is_final(_Tp)> { }; #endif /// is_abstract template struct is_abstract - : public integral_constant + : public __bool_constant<__is_abstract(_Tp)> { }; + /// @cond undocumented template::value> struct __is_signed_helper @@ -743,8 +943,9 @@ namespace std template struct __is_signed_helper<_Tp, true> - : public integral_constant + : public __bool_constant<_Tp(-1) < _Tp(0)> { }; + /// @endcond /// is_signed template @@ -755,17 +956,10 @@ namespace std /// is_unsigned template struct is_unsigned - : public __and_, __not_>> + : public __and_, __not_>>::type { }; - - // Destructible and constructible type properties. - - /** - * @brief Utility to simplify expressions used in unevaluated operands - * @ingroup utilities - */ - + /// @cond undocumented template _Up __declval(int); @@ -773,26 +967,37 @@ namespace std template _Tp __declval(long); + /// @endcond template auto declval() noexcept -> decltype(__declval<_Tp>(0)); - template - struct extent; - template struct remove_all_extents; + /// @cond undocumented template struct __is_array_known_bounds - : public integral_constant::value > 0)> + : public false_type + { }; + + template + struct __is_array_known_bounds<_Tp[_Size]> + : public true_type { }; template struct __is_array_unknown_bounds - : public __and_, __not_>> + : public false_type + { }; + + template + struct __is_array_unknown_bounds<_Tp[]> + : public true_type { }; + // Destructible and constructible type properties. + // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete @@ -811,7 +1016,7 @@ namespace std struct __is_destructible_impl : public __do_is_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_destructible_safe<_Tp, false, true> : public true_type { }; + /// @endcond /// is_destructible template @@ -844,6 +1050,8 @@ namespace std "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + // is_nothrow_destructible requires that is_destructible is // satisfied as well. We realize that by mimicing the // implementation of is_destructible but refer to noexcept(expr) @@ -862,7 +1070,7 @@ namespace std struct __is_nt_destructible_impl : public __do_is_nt_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_nt_destructible_safe<_Tp, false, true> : public true_type { }; + /// @endcond /// is_nothrow_destructible template @@ -895,10 +1104,11 @@ namespace std "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented template - struct __is_constructible_impl - : public __bool_constant<__is_constructible(_Tp, _Args...)> - { }; + using __is_constructible_impl + = __bool_constant<__is_constructible(_Tp, _Args...)>; + /// @endcond /// is_constructible template @@ -912,100 +1122,66 @@ namespace std /// is_default_constructible template struct is_default_constructible - : public __is_constructible_impl<_Tp>::type + : public __is_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_copy_constructible_impl; + /// @cond undocumented + template + struct __add_lvalue_reference_helper + { using type = _Tp; }; template - struct __is_copy_constructible_impl<_Tp, false> - : public false_type { }; + struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>> + { using type = _Tp&; }; template - struct __is_copy_constructible_impl<_Tp, true> - : public __is_constructible_impl<_Tp, const _Tp&> - { }; + using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type; + /// @endcond /// is_copy_constructible template struct is_copy_constructible - : public __is_copy_constructible_impl<_Tp> + : public __is_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_move_constructible_impl; + /// @cond undocumented + template + struct __add_rvalue_reference_helper + { using type = _Tp; }; template - struct __is_move_constructible_impl<_Tp, false> - : public false_type { }; + struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>> + { using type = _Tp&&; }; template - struct __is_move_constructible_impl<_Tp, true> - : public __is_constructible_impl<_Tp, _Tp&&> - { }; + using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type; + /// @endcond /// is_move_constructible template struct is_move_constructible - : public __is_move_constructible_impl<_Tp> + : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template - struct __is_nt_constructible_impl - : public false_type - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant()...))> - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant(std::declval<_Arg>()))> - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant::type())> - { }; - -#if __cpp_aggregate_paren_init - template - struct __is_nt_constructible_impl - : public __is_nt_constructible_impl - { }; - - template - struct __is_nt_constructible_impl - : public __and_<__is_nt_constructible_impl...> - { }; -#endif - + /// @cond undocumented template using __is_nothrow_constructible_impl - = __is_nt_constructible_impl<__is_constructible(_Tp, _Args...), - _Tp, _Args...>; + = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>; + /// @endcond /// is_nothrow_constructible template struct is_nothrow_constructible - : public __is_nothrow_constructible_impl<_Tp, _Args...>::type + : public __is_nothrow_constructible_impl<_Tp, _Args...> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1014,116 +1190,68 @@ namespace std /// is_nothrow_default_constructible template struct is_nothrow_default_constructible - : public __is_nothrow_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - - template::value> - struct __is_nothrow_copy_constructible_impl; - - template - struct __is_nothrow_copy_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nothrow_copy_constructible_impl<_Tp, true> - : public __is_nothrow_constructible_impl<_Tp, const _Tp&> - { }; - /// is_nothrow_copy_constructible template struct is_nothrow_copy_constructible - : public __is_nothrow_copy_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nothrow_move_constructible_impl; - - template - struct __is_nothrow_move_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nothrow_move_constructible_impl<_Tp, true> - : public __is_nothrow_constructible_impl<_Tp, _Tp&&> - { }; - /// is_nothrow_move_constructible template struct is_nothrow_move_constructible - : public __is_nothrow_move_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>; + /// @endcond + /// is_assignable template struct is_assignable - : public __bool_constant<__is_assignable(_Tp, _Up)> + : public __is_assignable_impl<_Tp, _Up> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_copy_assignable_impl; - - template - struct __is_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_copy_assignable_impl<_Tp, true> - : public __bool_constant<__is_assignable(_Tp&, const _Tp&)> - { }; - /// is_copy_assignable template struct is_copy_assignable - : public __is_copy_assignable_impl<_Tp>::type + : public __is_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_move_assignable_impl; - - template - struct __is_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_move_assignable_impl<_Tp, true> - : public __bool_constant<__is_assignable(_Tp&, _Tp&&)> - { }; - /// is_move_assignable template struct is_move_assignable - : public __is_move_assignable_impl<_Tp>::type + : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented template - struct __is_nt_assignable_impl - : public integral_constant() = declval<_Up>())> - { }; - - template - struct __is_nothrow_assignable_impl - : public __and_<__bool_constant<__is_assignable(_Tp, _Up)>, - __is_nt_assignable_impl<_Tp, _Up>> - { }; + using __is_nothrow_assignable_impl + = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>; + /// @endcond /// is_nothrow_assignable template @@ -1134,52 +1262,36 @@ namespace std "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nt_copy_assignable_impl; - - template - struct __is_nt_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nt_copy_assignable_impl<_Tp, true> - : public __is_nothrow_assignable_impl<_Tp&, const _Tp&> - { }; - /// is_nothrow_copy_assignable template struct is_nothrow_copy_assignable - : public __is_nt_copy_assignable_impl<_Tp> + : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nt_move_assignable_impl; - - template - struct __is_nt_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nt_move_assignable_impl<_Tp, true> - : public __is_nothrow_assignable_impl<_Tp&, _Tp&&> - { }; - /// is_nothrow_move_assignable template struct is_nothrow_move_assignable - : public __is_nt_move_assignable_impl<_Tp> + : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_trivially_constructible_impl + = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>; + /// @endcond + /// is_trivially_constructible template struct is_trivially_constructible - : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)> + : public __is_trivially_constructible_impl<_Tp, _Args...> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1188,12 +1300,22 @@ namespace std /// is_trivially_default_constructible template struct is_trivially_default_constructible - : public __bool_constant<__is_trivially_constructible(_Tp)> + : public __is_trivially_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; +#if __cpp_variable_templates && __cpp_concepts + template + constexpr bool __is_implicitly_default_constructible_v + = requires (void(&__f)(_Tp)) { __f({}); }; + + template + struct __is_implicitly_default_constructible + : __bool_constant<__is_implicitly_default_constructible_v<_Tp>> + { }; +#else struct __do_is_implicitly_default_constructible_impl { template @@ -1210,7 +1332,7 @@ namespace std struct __is_implicitly_default_constructible_impl : public __do_is_implicitly_default_constructible_impl { - typedef decltype(__test(declval<_Tp>())) type; + using type = decltype(__test(declval<_Tp>())); }; template @@ -1221,101 +1343,58 @@ namespace std template struct __is_implicitly_default_constructible : public __and_<__is_constructible_impl<_Tp>, - __is_implicitly_default_constructible_safe<_Tp>> - { }; - - template::value> - struct __is_trivially_copy_constructible_impl; - - template - struct __is_trivially_copy_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_copy_constructible_impl<_Tp, true> - : public __and_<__is_copy_constructible_impl<_Tp>, - integral_constant> + __is_implicitly_default_constructible_safe<_Tp>>::type { }; +#endif /// is_trivially_copy_constructible template struct is_trivially_copy_constructible - : public __is_trivially_copy_constructible_impl<_Tp> + : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_move_constructible_impl; - - template - struct __is_trivially_move_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_move_constructible_impl<_Tp, true> - : public __and_<__is_move_constructible_impl<_Tp>, - integral_constant> - { }; - /// is_trivially_move_constructible template struct is_trivially_move_constructible - : public __is_trivially_move_constructible_impl<_Tp> + : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_trivially_assignable_impl + = __bool_constant<__is_trivially_assignable(_Tp, _Up)>; + /// @endcond + /// is_trivially_assignable template struct is_trivially_assignable - : public __bool_constant<__is_trivially_assignable(_Tp, _Up)> + : public __is_trivially_assignable_impl<_Tp, _Up> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_copy_assignable_impl; - - template - struct __is_trivially_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_copy_assignable_impl<_Tp, true> - : public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)> - { }; - /// is_trivially_copy_assignable template struct is_trivially_copy_assignable - : public __is_trivially_copy_assignable_impl<_Tp> + : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_move_assignable_impl; - - template - struct __is_trivially_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_move_assignable_impl<_Tp, true> - : public __bool_constant<__is_trivially_assignable(_Tp&, _Tp&&)> - { }; - /// is_trivially_move_assignable template struct is_trivially_move_assignable - : public __is_trivially_move_assignable_impl<_Tp> + : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1325,7 +1404,7 @@ namespace std template struct is_trivially_destructible : public __and_<__is_destructible_safe<_Tp>, - __bool_constant<__has_trivial_destructor(_Tp)>> + __bool_constant<__has_trivial_destructor(_Tp)>>::type { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1335,7 +1414,7 @@ namespace std /// has_virtual_destructor template struct has_virtual_destructor - : public integral_constant + : public __bool_constant<__has_virtual_destructor(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1367,23 +1446,25 @@ namespace std : public integral_constant::value> { }; /// extent - template + template struct extent - : public integral_constant { }; + : public integral_constant { }; + + template + struct extent<_Tp[_Size], 0> + : public integral_constant { }; - template + template struct extent<_Tp[_Size], _Uint> - : public integral_constant::value> - { }; + : public extent<_Tp, _Uint - 1>::type { }; + + template + struct extent<_Tp[], 0> + : public integral_constant { }; template struct extent<_Tp[], _Uint> - : public integral_constant::value> - { }; + : public extent<_Tp, _Uint - 1>::type { }; // Type relations. @@ -1391,14 +1472,14 @@ namespace std /// is_same template struct is_same -#ifdef _GLIBCXX_BUILTIN_IS_SAME_AS - : public integral_constant +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME + : public __bool_constant<__is_same(_Tp, _Up)> #else : public false_type #endif { }; -#ifndef _GLIBCXX_BUILTIN_IS_SAME_AS +#ifndef _GLIBCXX_HAVE_BUILTIN_IS_SAME template struct is_same<_Tp, _Tp> : public true_type @@ -1408,15 +1489,21 @@ namespace std /// is_base_of template struct is_base_of - : public integral_constant + : public __bool_constant<__is_base_of(_Base, _Derived)> { }; +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) + template + struct is_convertible + : public __bool_constant<__is_convertible(_From, _To)> + { }; +#else template, is_function<_To>, is_array<_To>>::value> struct __is_convertible_helper { - typedef typename is_void<_To>::type type; + using type = typename is_void<_To>::type; }; #pragma GCC diagnostic push @@ -1437,7 +1524,7 @@ namespace std __test(...); public: - typedef decltype(__test<_From, _To>(0)) type; + using type = decltype(__test<_From, _To>(0)); }; #pragma GCC diagnostic pop @@ -1446,12 +1533,27 @@ namespace std struct is_convertible : public __is_convertible_helper<_From, _To>::type { }; +#endif // helper trait for unique_ptr, shared_ptr, and span template using __is_array_convertible = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>; +#ifdef __cpp_lib_is_nothrow_convertible // C++ >= 20 + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_convertible) + /// is_nothrow_convertible_v + template + inline constexpr bool is_nothrow_convertible_v + = __is_nothrow_convertible(_From, _To); + + /// is_nothrow_convertible + template + struct is_nothrow_convertible + : public bool_constant> + { }; +#else template, is_function<_To>, is_array<_To>>::value> @@ -1481,14 +1583,6 @@ namespace std }; #pragma GCC diagnostic pop - // is_nothrow_convertible for C++11 - template - struct __is_nothrow_convertible - : public __is_nt_convertible_helper<_From, _To>::type - { }; - -#if __cplusplus > 201703L -#define __cpp_lib_is_nothrow_convertible 201806L /// is_nothrow_convertible template struct is_nothrow_convertible @@ -1499,29 +1593,35 @@ namespace std template inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_From, _To>::value; -#endif // C++2a +#endif +#endif // __cpp_lib_is_nothrow_convertible // Const-volatile modifications. /// remove_const template struct remove_const - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_const<_Tp const> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_volatile template struct remove_volatile - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_volatile<_Tp volatile> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_cv +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cv) + template + struct remove_cv + { using type = __remove_cv(_Tp); }; +#else template struct remove_cv { using type = _Tp; }; @@ -1537,29 +1637,24 @@ namespace std template struct remove_cv { using type = _Tp; }; +#endif /// add_const template struct add_const - { typedef _Tp const type; }; + { using type = _Tp const; }; /// add_volatile template struct add_volatile - { typedef _Tp volatile type; }; + { using type = _Tp volatile; }; /// add_cv template struct add_cv - { - typedef typename - add_const::type>::type type; - }; - -#if __cplusplus > 201103L - -#define __cpp_lib_transformation_trait_aliases 201304 + { using type = _Tp const volatile; }; +#ifdef __cpp_lib_transformation_trait_aliases // C++ >= 14 /// Alias template for remove_const template using remove_const_t = typename remove_const<_Tp>::type; @@ -1588,45 +1683,33 @@ namespace std // Reference transformations. /// remove_reference +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference) + template + struct remove_reference + { using type = __remove_reference(_Tp); }; +#else template struct remove_reference - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_reference<_Tp&> - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_reference<_Tp&&> - { typedef _Tp type; }; - - template::value> - struct __add_lvalue_reference_helper - { typedef _Tp type; }; - - template - struct __add_lvalue_reference_helper<_Tp, true> - { typedef _Tp& type; }; + { using type = _Tp; }; +#endif /// add_lvalue_reference template struct add_lvalue_reference - : public __add_lvalue_reference_helper<_Tp> - { }; - - template::value> - struct __add_rvalue_reference_helper - { typedef _Tp type; }; - - template - struct __add_rvalue_reference_helper<_Tp, true> - { typedef _Tp&& type; }; + { using type = __add_lval_ref_t<_Tp>; }; /// add_rvalue_reference template struct add_rvalue_reference - : public __add_rvalue_reference_helper<_Tp> - { }; + { using type = __add_rval_ref_t<_Tp>; }; #if __cplusplus > 201103L /// Alias template for remove_reference @@ -1644,91 +1727,97 @@ namespace std // Sign modifications. + /// @cond undocumented + // Utility for constructing identically cv-qualified types. template struct __cv_selector; template struct __cv_selector<_Unqualified, false, false> - { typedef _Unqualified __type; }; + { using __type = _Unqualified; }; template struct __cv_selector<_Unqualified, false, true> - { typedef volatile _Unqualified __type; }; + { using __type = volatile _Unqualified; }; template struct __cv_selector<_Unqualified, true, false> - { typedef const _Unqualified __type; }; + { using __type = const _Unqualified; }; template struct __cv_selector<_Unqualified, true, true> - { typedef const volatile _Unqualified __type; }; + { using __type = const volatile _Unqualified; }; template::value, bool _IsVol = is_volatile<_Qualified>::value> class __match_cv_qualifiers { - typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; + using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>; public: - typedef typename __match::__type __type; + using __type = typename __match::__type; }; // Utility for finding the unsigned versions of signed integral types. template struct __make_unsigned - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_unsigned - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned - { typedef unsigned short __type; }; + { using __type = unsigned short; }; template<> struct __make_unsigned - { typedef unsigned int __type; }; + { using __type = unsigned int; }; template<> struct __make_unsigned - { typedef unsigned long __type; }; + { using __type = unsigned long; }; template<> struct __make_unsigned - { typedef unsigned long long __type; }; + { using __type = unsigned long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> - { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> - { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> - { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> - { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. template::value, - bool _IsEnum = is_enum<_Tp>::value> + bool _IsEnum = __is_enum(_Tp)> class __make_unsigned_selector; template @@ -1784,14 +1873,12 @@ namespace std // neither signed integer types nor unsigned integer types, so must be // transformed to the unsigned integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. -#if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; -#endif #ifdef _GLIBCXX_USE_CHAR8_T template<> @@ -1815,6 +1902,7 @@ namespace std using __type = typename __make_unsigned_selector::__type; }; + /// @endcond // Given an integral/enum type, return the corresponding unsigned // integer type. @@ -1822,67 +1910,74 @@ namespace std /// make_unsigned template struct make_unsigned - { typedef typename __make_unsigned_selector<_Tp>::__type type; }; + { using type = typename __make_unsigned_selector<_Tp>::__type; }; // Integral, but don't define. - template<> - struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + /// @cond undocumented // Utility for finding the signed versions of unsigned integral types. template struct __make_signed - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_signed - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed - { typedef signed short __type; }; + { using __type = signed short; }; template<> struct __make_signed - { typedef signed int __type; }; + { using __type = signed int; }; template<> struct __make_signed - { typedef signed long __type; }; + { using __type = signed long; }; template<> struct __make_signed - { typedef signed long long __type; }; + { using __type = signed long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. template::value, - bool _IsEnum = is_enum<_Tp>::value> + bool _IsEnum = __is_enum(_Tp)> class __make_signed_selector; template @@ -1900,24 +1995,22 @@ namespace std template class __make_signed_selector<_Tp, false, true> { - typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; + using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type; public: - typedef typename __make_signed_selector<__unsigned_type>::__type __type; + using __type = typename __make_signed_selector<__unsigned_type>::__type; }; // wchar_t, char16_t and char32_t are integral types but are neither // signed integer types nor unsigned integer types, so must be // transformed to the signed integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. -#if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; -#endif #if defined(_GLIBCXX_USE_CHAR8_T) template<> @@ -1941,6 +2034,7 @@ namespace std using __type = typename __make_signed_selector::__type; }; + /// @endcond // Given an integral/enum type, return the corresponding signed // integer type. @@ -1948,11 +2042,13 @@ namespace std /// make_signed template struct make_signed - { typedef typename __make_signed_selector<_Tp>::__type type; }; + { using type = typename __make_signed_selector<_Tp>::__type; }; // Integral, but don't define. - template<> - struct make_signed; + template<> struct make_signed; + template<> struct make_signed; + template<> struct make_signed; + template<> struct make_signed; #if __cplusplus > 201103L /// Alias template for make_signed @@ -1969,28 +2065,28 @@ namespace std /// remove_extent template struct remove_extent - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_extent<_Tp[_Size]> - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_extent<_Tp[]> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_all_extents template struct remove_all_extents - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_all_extents<_Tp[_Size]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; template struct remove_all_extents<_Tp[]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; #if __cplusplus > 201103L /// Alias template for remove_extent @@ -2004,35 +2100,48 @@ namespace std // Pointer modifications. + /// remove_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer) + template + struct remove_pointer + { using type = __remove_pointer(_Tp); }; +#else template struct __remove_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template struct __remove_pointer_helper<_Tp, _Up*> - { typedef _Up type; }; + { using type = _Up; }; - /// remove_pointer template struct remove_pointer : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>> { }; +#endif - /// add_pointer - template, - is_void<_Tp>>::value> + template struct __add_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template - struct __add_pointer_helper<_Tp, true> - { typedef typename remove_reference<_Tp>::type* type; }; + struct __add_pointer_helper<_Tp, __void_t<_Tp*>> + { using type = _Tp*; }; + /// add_pointer template struct add_pointer : public __add_pointer_helper<_Tp> { }; + template + struct add_pointer<_Tp&> + { using type = _Tp*; }; + + template + struct add_pointer<_Tp&&> + { using type = _Tp*; }; + #if __cplusplus > 201103L /// Alias template for remove_pointer template @@ -2062,10 +2171,15 @@ namespace std * type shall be a POD type suitable for use as uninitialized * storage for any object whose size is at most _Len and whose * alignment is a divisor of _Align. + * + * @deprecated Deprecated in C++23. Uses can be replaced by an + * array std::byte[_Len] declared with alignas(_Align). */ template::__type)> - struct aligned_storage + struct + _GLIBCXX23_DEPRECATED + aligned_storage { union type { @@ -2092,6 +2206,9 @@ namespace std ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + /** * @brief Provide aligned storage for types. * @@ -2101,9 +2218,13 @@ namespace std * least size _Len. * * @see aligned_storage + * + * @deprecated Deprecated in C++23. */ template - struct aligned_union + struct + _GLIBCXX23_DEPRECATED + aligned_union { private: static_assert(sizeof...(_Types) != 0, "At least one type is required"); @@ -2115,99 +2236,92 @@ namespace std /// The value of the strictest alignment of _Types. static const size_t alignment_value = __strictest::_S_alignment; /// The storage. - typedef typename aligned_storage<_S_len, alignment_value>::type type; + using type = typename aligned_storage<_S_len, alignment_value>::type; }; template const size_t aligned_union<_Len, _Types...>::alignment_value; +#pragma GCC diagnostic pop + + /// @cond undocumented // Decay trait for arrays and functions, used for perfect forwarding // in make_pair, make_tuple, etc. - template::value, - bool _IsFunction = is_function<_Up>::value> - struct __decay_selector; - - // NB: DR 705. template - struct __decay_selector<_Up, false, false> - { typedef __remove_cv_t<_Up> __type; }; + struct __decay_selector + : __conditional_t::value, // false for functions + remove_cv<_Up>, // N.B. DR 705. + add_pointer<_Up>> // function decays to pointer + { }; - template - struct __decay_selector<_Up, true, false> - { typedef typename remove_extent<_Up>::type* __type; }; + template + struct __decay_selector<_Up[_Nm]> + { using type = _Up*; }; template - struct __decay_selector<_Up, false, true> - { typedef typename add_pointer<_Up>::type __type; }; + struct __decay_selector<_Up[]> + { using type = _Up*; }; + + /// @endcond /// decay template - class decay - { - typedef typename remove_reference<_Tp>::type __remove_type; - - public: - typedef typename __decay_selector<__remove_type>::__type type; - }; + struct decay + { using type = typename __decay_selector<_Tp>::type; }; - // __decay_t (std::decay_t for C++11). template - using __decay_t = typename decay<_Tp>::type; + struct decay<_Tp&> + { using type = typename __decay_selector<_Tp>::type; }; template - class reference_wrapper; + struct decay<_Tp&&> + { using type = typename __decay_selector<_Tp>::type; }; + + /// @cond undocumented // Helper which adds a reference to a type when given a reference_wrapper template struct __strip_reference_wrapper { - typedef _Tp __type; + using __type = _Tp; }; template struct __strip_reference_wrapper > { - typedef _Tp& __type; + using __type = _Tp&; }; + // __decay_t (std::decay_t for C++11). template - using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; - - - // Primary template. - /// Define a member typedef @c type only if a boolean constant is true. - template - struct enable_if - { }; + using __decay_t = typename decay<_Tp>::type; - // Partial specialization for true. template - struct enable_if - { typedef _Tp type; }; + using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; + /// @endcond - // __enable_if_t (std::enable_if_t for C++11) - template - using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + /// @cond undocumented + // Helper for SFINAE constraints template using _Require = __enable_if_t<__and_<_Cond...>::value>; + // __remove_cvref_t (std::remove_cvref_t for C++11). + template + using __remove_cvref_t + = typename remove_cv::type>::type; + /// @endcond + // Primary template. /// Define a member typedef @c type to one of two argument types. template struct conditional - { typedef _Iftrue type; }; + { using type = _Iftrue; }; // Partial specialization for false. template struct conditional - { typedef _Iffalse type; }; - - // __remove_cvref_t (std::remove_cvref_t for C++11). - template - using __remove_cvref_t - = typename remove_cv::type>::type; + { using type = _Iffalse; }; /// common_type template @@ -2215,6 +2329,20 @@ namespace std // Sfinae-friendly common_type implementation: + /// @cond undocumented + + // For several sfinae-friendly trait implementations we transport both the + // result information (as the member type) and the failure information (no + // member type). This is very similar to std::enable_if, but we cannot use + // that, because we need to derive from them as an implementation detail. + + template + struct __success_type + { using type = _Tp; }; + + struct __failure_type + { }; + struct __do_common_type_impl { template @@ -2308,7 +2436,7 @@ namespace std struct __common_type_fold<_CTp, _Rp, void> { }; - template::value> + template struct __underlying_type_impl { using type = __underlying_type(_Tp); @@ -2317,6 +2445,7 @@ namespace std template struct __underlying_type_impl<_Tp, false> { }; + /// @endcond /// The underlying type of an enum. template @@ -2324,12 +2453,18 @@ namespace std : public __underlying_type_impl<_Tp> { }; + /// @cond undocumented template struct __declval_protector { static const bool __stop = false; }; + /// @endcond + /** Utility to simplify expressions used in unevaluated operands + * @since C++11 + * @ingroup utilities + */ template auto declval() noexcept -> decltype(__declval<_Tp>(0)) { @@ -2340,12 +2475,11 @@ namespace std /// result_of template - class result_of; + struct result_of; // Sfinae-friendly result_of implementation: -#define __cpp_lib_result_of_sfinae 201210 - + /// @cond undocumented struct __invoke_memfun_ref { }; struct __invoke_memfun_deref { }; struct __invoke_memobj_ref { }; @@ -2373,7 +2507,7 @@ namespace std struct __result_of_memfun_ref : private __result_of_memfun_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 2: @@ -2392,7 +2526,7 @@ namespace std struct __result_of_memfun_deref : private __result_of_memfun_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 3: @@ -2411,7 +2545,7 @@ namespace std struct __result_of_memobj_ref : private __result_of_memobj_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; // [func.require] paragraph 1 bullet 4: @@ -2430,7 +2564,7 @@ namespace std struct __result_of_memobj_deref : private __result_of_memobj_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; template @@ -2439,13 +2573,13 @@ namespace std template struct __result_of_memobj<_Res _Class::*, _Arg> { - typedef __remove_cvref_t<_Arg> _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename conditional<__or_, + using _Argval = __remove_cvref_t<_Arg>; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t<__or_, is_base_of<_Class, _Argval>>::value, __result_of_memobj_ref<_MemPtr, _Arg>, __result_of_memobj_deref<_MemPtr, _Arg> - >::type::type type; + >::type; }; template @@ -2454,12 +2588,12 @@ namespace std template struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> { - typedef typename remove_reference<_Arg>::type _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename conditional::value, + using _Argval = typename remove_reference<_Arg>::type; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t::value, __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, __result_of_memfun_deref<_MemPtr, _Arg, _Args...> - >::type::type type; + >::type; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -2482,7 +2616,7 @@ namespace std template struct __result_of_impl { - typedef __failure_type type; + using type = __failure_type; }; template @@ -2513,7 +2647,7 @@ namespace std struct __result_of_impl : private __result_of_other_impl { - typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type; + using type = decltype(_S_test<_Functor, _ArgTypes...>(0)); }; // __invoke_result (std::invoke_result for C++11) @@ -2529,20 +2663,24 @@ namespace std _Functor, _ArgTypes... >::type { }; + /// @endcond template struct result_of<_Functor(_ArgTypes...)> : public __invoke_result<_Functor, _ArgTypes...> - { }; + { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result"); #if __cplusplus >= 201402L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" /// Alias template for aligned_storage template::__type)> - using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; + using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type; template - using aligned_union_t = typename aligned_union<_Len, _Types...>::type; + using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type; +#pragma GCC diagnostic pop /// Alias template for decay template @@ -2569,19 +2707,41 @@ namespace std using result_of_t = typename result_of<_Tp>::type; #endif // C++14 -#if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11 -#define __cpp_lib_void_t 201411 +#ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11 /// A metafunction that always yields void, used for detecting valid types. template using void_t = void; #endif + /// @cond undocumented + + // Detection idiom. + // Detect whether _Op<_Args...> is a valid type, use default _Def if not. + +#if __cpp_concepts + // Implementation of the detection idiom (negative case). + template class _Op, typename... _Args> + struct __detected_or + { + using type = _Def; + using __is_detected = false_type; + }; + + // Implementation of the detection idiom (positive case). + template class _Op, typename... _Args> + requires requires { typename _Op<_Args...>; } + struct __detected_or<_Def, _Op, _Args...> + { + using type = _Op<_Args...>; + using __is_detected = true_type; + }; +#else /// Implementation of the detection idiom (negative case). template class _Op, typename... _Args> struct __detector { - using value_t = false_type; using type = _Default; + using __is_detected = false_type; }; /// Implementation of the detection idiom (positive case). @@ -2589,14 +2749,14 @@ namespace std typename... _Args> struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> { - using value_t = true_type; using type = _Op<_Args...>; + using __is_detected = true_type; }; - // Detect whether _Op<_Args...> is a valid type, use _Default if not. template class _Op, typename... _Args> using __detected_or = __detector<_Default, void, _Op, _Args...>; +#endif // __cpp_concepts // _Op<_Args...> if that is a valid type, otherwise _Default. template class _Op, @@ -2604,8 +2764,6 @@ namespace std using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; - /// @} group metaprogramming - /** * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. @@ -2626,22 +2784,16 @@ namespace std template struct __is_nothrow_swappable; - template - class tuple; - template struct __is_tuple_like_impl : false_type { }; - template - struct __is_tuple_like_impl> : true_type - { }; - // Internal type trait that allows us to sfinae-protect tuple_cat. template struct __is_tuple_like : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type { }; + /// @endcond template _GLIBCXX20_CONSTEXPR @@ -2660,6 +2812,7 @@ namespace std swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(__is_nothrow_swappable<_Tp>::value); + /// @cond undocumented namespace __swappable_details { using std::swap; @@ -2690,14 +2843,14 @@ namespace std struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template @@ -2709,9 +2862,9 @@ namespace std struct __is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; + /// @endcond -#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 -#define __cpp_lib_is_swappable 201603 +#ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11 /// Metafunctions used for detecting swappable types: p0185r1 /// is_swappable @@ -2744,6 +2897,7 @@ namespace std is_nothrow_swappable<_Tp>::value; #endif // __cplusplus >= 201402L + /// @cond undocumented namespace __swappable_with_details { using std::swap; @@ -2778,7 +2932,7 @@ namespace std struct __is_swappable_with_impl : public __swappable_with_details::__do_is_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2786,14 +2940,14 @@ namespace std struct __is_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; template struct __is_nothrow_swappable_with_impl : public __swappable_with_details::__do_is_nothrow_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2801,20 +2955,31 @@ namespace std struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; + /// @endcond /// is_swappable_with template struct is_swappable_with : public __is_swappable_with_impl<_Tp, _Up>::type - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), + "first template argument must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "second template argument must be a complete class or an unbounded array"); + }; /// is_nothrow_swappable_with template struct is_nothrow_swappable_with : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), + "first template argument must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "second template argument must be a complete class or an unbounded array"); + }; #if __cplusplus >= 201402L /// is_swappable_with_v @@ -2828,14 +2993,20 @@ namespace std is_nothrow_swappable_with<_Tp, _Up>::value; #endif // __cplusplus >= 201402L -#endif// c++1z or gnu++11 +#endif // __cpp_lib_is_swappable + + /// @cond undocumented // __is_invocable (std::is_invocable for C++11) // The primary template is used for invalid INVOKE expressions. template::value, typename = void> - struct __is_invocable_impl : false_type { }; + struct __is_invocable_impl + : false_type + { + using __nothrow_conv = false_type; // For is_nothrow_invocable_r + }; // Used for valid INVOKE and INVOKE expressions. template @@ -2843,7 +3014,9 @@ namespace std /* is_void<_Ret> = */ true, __void_t> : true_type - { }; + { + using __nothrow_conv = true_type; // For is_nothrow_invocable_r + }; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" @@ -2855,23 +3028,39 @@ namespace std { private: // The type of the INVOKE expression. - // Unlike declval, this doesn't add_rvalue_reference. - static typename _Result::type _S_get(); + using _Res_t = typename _Result::type; + + // Unlike declval, this doesn't add_rvalue_reference, so it respects + // guaranteed copy elision. + static _Res_t _S_get() noexcept; + // Used to check if _Res_t can implicitly convert to _Tp. template - static void _S_conv(_Tp); + static void _S_conv(__type_identity_t<_Tp>) noexcept; // This overload is viable if INVOKE(f, args...) can convert to _Tp. - template(_S_get()))> - static true_type + template(_S_get())), + typename = decltype(_S_conv<_Tp>(_S_get())), +#if __has_builtin(__reference_converts_from_temporary) + bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t) +#else + bool _Dangle = false +#endif + > + static __bool_constant<_Nothrow && !_Dangle> _S_test(int); - template + template static false_type _S_test(...); public: - using type = decltype(_S_test<_Ret>(1)); + // For is_invocable_r + using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1)); + + // For is_nothrow_invocable_r + using __nothrow_conv = decltype(_S_test<_Ret>(1)); }; #pragma GCC diagnostic pop @@ -2941,15 +3130,20 @@ namespace std void operator=(__nonesuch const&) = delete; }; #pragma GCC diagnostic pop + /// @endcond -#if __cplusplus >= 201703L -# define __cpp_lib_is_invocable 201703 - +#ifdef __cpp_lib_is_invocable // C++ >= 17 /// std::invoke_result template struct invoke_result : public __invoke_result<_Functor, _ArgTypes...> - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}), + "_Functor must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + }; /// std::invoke_result_t template @@ -2962,6 +3156,9 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); }; /// std::is_invocable_r @@ -2971,6 +3168,11 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), + "_Ret must be a complete class or an unbounded array"); }; /// std::is_nothrow_invocable @@ -2981,47 +3183,51 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); }; - template - struct __is_nt_invocable_impl : false_type { }; - + /// @cond undocumented + // This checks that the INVOKE expression is well-formed and that the + // conversion to R does not throw. It does *not* check whether the INVOKE + // expression itself can throw. That is done by __call_is_nothrow_ instead. template - struct __is_nt_invocable_impl<_Result, _Ret, - __void_t> - : __or_, - __is_nothrow_convertible> - { }; + using __is_nt_invocable_impl + = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv; + /// @endcond /// std::is_nothrow_invocable_r template struct is_nothrow_invocable_r : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type - { }; - - /// std::is_invocable_v - template - inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; - - /// std::is_nothrow_invocable_v - template - inline constexpr bool is_nothrow_invocable_v - = is_nothrow_invocable<_Fn, _Args...>::value; - - /// std::is_invocable_r_v - template - inline constexpr bool is_invocable_r_v - = is_invocable_r<_Ret, _Fn, _Args...>::value; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), + "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), + "_Ret must be a complete class or an unbounded array"); + }; +#endif // __cpp_lib_is_invocable - /// std::is_nothrow_invocable_r_v - template - inline constexpr bool is_nothrow_invocable_r_v - = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; -#endif // C++17 +#if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /** + * @defgroup variable_templates Variable templates for type traits + * @ingroup metaprogramming + * + * Each variable `is_xxx_v` is a boolean constant with the same value + * as the `value` member of the corresponding type trait `is_xxx`. + * + * @since C++17 unless noted otherwise. + */ -#if __cplusplus >= 201703L -# define __cpp_lib_type_trait_variable_templates 201510L + /** + * @{ + * @ingroup variable_templates + */ template inline constexpr bool is_void_v = is_void<_Tp>::value; template @@ -3030,167 +3236,301 @@ template inline constexpr bool is_integral_v = is_integral<_Tp>::value; template inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) +template + inline constexpr bool is_array_v = __is_array(_Tp); +#else +template + inline constexpr bool is_array_v = false; template - inline constexpr bool is_array_v = is_array<_Tp>::value; + inline constexpr bool is_array_v<_Tp[]> = true; +template + inline constexpr bool is_array_v<_Tp[_Num]> = true; +#endif + template inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; template - inline constexpr bool is_lvalue_reference_v = - is_lvalue_reference<_Tp>::value; + inline constexpr bool is_lvalue_reference_v = false; +template + inline constexpr bool is_lvalue_reference_v<_Tp&> = true; +template + inline constexpr bool is_rvalue_reference_v = false; template - inline constexpr bool is_rvalue_reference_v = - is_rvalue_reference<_Tp>::value; + inline constexpr bool is_rvalue_reference_v<_Tp&&> = true; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) +template + inline constexpr bool is_member_object_pointer_v = + __is_member_object_pointer(_Tp); +#else template inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value; +#endif + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) +template + inline constexpr bool is_member_function_pointer_v = + __is_member_function_pointer(_Tp); +#else template inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value; +#endif + +template + inline constexpr bool is_enum_v = __is_enum(_Tp); template - inline constexpr bool is_enum_v = is_enum<_Tp>::value; + inline constexpr bool is_union_v = __is_union(_Tp); template - inline constexpr bool is_union_v = is_union<_Tp>::value; + inline constexpr bool is_class_v = __is_class(_Tp); +// is_function_v is defined below, after is_const_v. + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) +template + inline constexpr bool is_reference_v = __is_reference(_Tp); +#else template - inline constexpr bool is_class_v = is_class<_Tp>::value; + inline constexpr bool is_reference_v = false; template - inline constexpr bool is_function_v = is_function<_Tp>::value; + inline constexpr bool is_reference_v<_Tp&> = true; template - inline constexpr bool is_reference_v = is_reference<_Tp>::value; + inline constexpr bool is_reference_v<_Tp&&> = true; +#endif + template inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; template inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) +template + inline constexpr bool is_object_v = __is_object(_Tp); +#else template inline constexpr bool is_object_v = is_object<_Tp>::value; +#endif + template inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; template - inline constexpr bool is_compound_v = is_compound<_Tp>::value; + inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) +template + inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); +#else template inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; +#endif + template - inline constexpr bool is_const_v = is_const<_Tp>::value; + inline constexpr bool is_const_v = false; template - inline constexpr bool is_volatile_v = is_volatile<_Tp>::value; + inline constexpr bool is_const_v = true; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) template - inline constexpr bool is_trivial_v = is_trivial<_Tp>::value; + inline constexpr bool is_function_v = __is_function(_Tp); +#else template - inline constexpr bool is_trivially_copyable_v = - is_trivially_copyable<_Tp>::value; + inline constexpr bool is_function_v = !is_const_v; template - inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + inline constexpr bool is_function_v<_Tp&> = false; template - _GLIBCXX20_DEPRECATED("use is_standard_layout_v && is_trivial_v instead") - inline constexpr bool is_pod_v = is_pod<_Tp>::value; -#pragma GCC diagnostic pop + inline constexpr bool is_function_v<_Tp&&> = false; +#endif + +template + inline constexpr bool is_volatile_v = false; +template + inline constexpr bool is_volatile_v = true; + +template + inline constexpr bool is_trivial_v = __is_trivial(_Tp); +template + inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp); +template + inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp); template - inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value; + _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v") + inline constexpr bool is_pod_v = __is_pod(_Tp); template - inline constexpr bool is_empty_v = is_empty<_Tp>::value; + _GLIBCXX17_DEPRECATED + inline constexpr bool is_literal_type_v = __is_literal_type(_Tp); template - inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value; + inline constexpr bool is_empty_v = __is_empty(_Tp); template - inline constexpr bool is_abstract_v = is_abstract<_Tp>::value; + inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp); template - inline constexpr bool is_final_v = is_final<_Tp>::value; + inline constexpr bool is_abstract_v = __is_abstract(_Tp); +template + inline constexpr bool is_final_v = __is_final(_Tp); + template inline constexpr bool is_signed_v = is_signed<_Tp>::value; template inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; + template - inline constexpr bool is_constructible_v = - is_constructible<_Tp, _Args...>::value; + inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); template - inline constexpr bool is_default_constructible_v = - is_default_constructible<_Tp>::value; + inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); template - inline constexpr bool is_copy_constructible_v = - is_copy_constructible<_Tp>::value; + inline constexpr bool is_copy_constructible_v + = __is_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_move_constructible_v = - is_move_constructible<_Tp>::value; + inline constexpr bool is_move_constructible_v + = __is_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value; + inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up); template - inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; + inline constexpr bool is_copy_assignable_v + = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t); template - inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; + inline constexpr bool is_move_assignable_v + = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); + template inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; + template - inline constexpr bool is_trivially_constructible_v = - is_trivially_constructible<_Tp, _Args...>::value; + inline constexpr bool is_trivially_constructible_v + = __is_trivially_constructible(_Tp, _Args...); template - inline constexpr bool is_trivially_default_constructible_v = - is_trivially_default_constructible<_Tp>::value; + inline constexpr bool is_trivially_default_constructible_v + = __is_trivially_constructible(_Tp); template - inline constexpr bool is_trivially_copy_constructible_v = - is_trivially_copy_constructible<_Tp>::value; + inline constexpr bool is_trivially_copy_constructible_v + = __is_trivially_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_trivially_move_constructible_v = - is_trivially_move_constructible<_Tp>::value; + inline constexpr bool is_trivially_move_constructible_v + = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_trivially_assignable_v = - is_trivially_assignable<_Tp, _Up>::value; + inline constexpr bool is_trivially_assignable_v + = __is_trivially_assignable(_Tp, _Up); +template + inline constexpr bool is_trivially_copy_assignable_v + = __is_trivially_assignable(__add_lval_ref_t<_Tp>, + __add_lval_ref_t); template - inline constexpr bool is_trivially_copy_assignable_v = - is_trivially_copy_assignable<_Tp>::value; + inline constexpr bool is_trivially_move_assignable_v + = __is_trivially_assignable(__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>); + +#if __cpp_concepts +template + inline constexpr bool is_trivially_destructible_v = false; + +template + requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); } + inline constexpr bool is_trivially_destructible_v<_Tp> + = __has_trivial_destructor(_Tp); template - inline constexpr bool is_trivially_move_assignable_v = - is_trivially_move_assignable<_Tp>::value; + inline constexpr bool is_trivially_destructible_v<_Tp&> = true; +template + inline constexpr bool is_trivially_destructible_v<_Tp&&> = true; +template + inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]> + = is_trivially_destructible_v<_Tp>; +#else template inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value; +#endif + template - inline constexpr bool is_nothrow_constructible_v = - is_nothrow_constructible<_Tp, _Args...>::value; + inline constexpr bool is_nothrow_constructible_v + = __is_nothrow_constructible(_Tp, _Args...); template - inline constexpr bool is_nothrow_default_constructible_v = - is_nothrow_default_constructible<_Tp>::value; + inline constexpr bool is_nothrow_default_constructible_v + = __is_nothrow_constructible(_Tp); template - inline constexpr bool is_nothrow_copy_constructible_v = - is_nothrow_copy_constructible<_Tp>::value; + inline constexpr bool is_nothrow_copy_constructible_v + = __is_nothrow_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_nothrow_move_constructible_v = - is_nothrow_move_constructible<_Tp>::value; + inline constexpr bool is_nothrow_move_constructible_v + = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_nothrow_assignable_v = - is_nothrow_assignable<_Tp, _Up>::value; + inline constexpr bool is_nothrow_assignable_v + = __is_nothrow_assignable(_Tp, _Up); template - inline constexpr bool is_nothrow_copy_assignable_v = - is_nothrow_copy_assignable<_Tp>::value; + inline constexpr bool is_nothrow_copy_assignable_v + = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, + __add_lval_ref_t); template - inline constexpr bool is_nothrow_move_assignable_v = - is_nothrow_move_assignable<_Tp>::value; + inline constexpr bool is_nothrow_move_assignable_v + = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); + template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; + template - inline constexpr bool has_virtual_destructor_v = - has_virtual_destructor<_Tp>::value; + inline constexpr bool has_virtual_destructor_v + = __has_virtual_destructor(_Tp); + template inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value; + +template + inline constexpr size_t rank_v = 0; +template + inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>; template - inline constexpr size_t rank_v = rank<_Tp>::value; + inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>; + template - inline constexpr size_t extent_v = extent<_Tp, _Idx>::value; -#ifdef _GLIBCXX_BUILTIN_IS_SAME_AS + inline constexpr size_t extent_v = 0; +template + inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size; +template + inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>; +template + inline constexpr size_t extent_v<_Tp[], 0> = 0; +template + inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>; + +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME template - inline constexpr bool is_same_v = _GLIBCXX_BUILTIN_IS_SAME_AS(_Tp, _Up); + inline constexpr bool is_same_v = __is_same(_Tp, _Up); #else template - inline constexpr bool is_same_v = std::is_same<_Tp, _Up>::value; + inline constexpr bool is_same_v = false; +template + inline constexpr bool is_same_v<_Tp, _Tp> = true; #endif template - inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value; + inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) +template + inline constexpr bool is_convertible_v = __is_convertible(_From, _To); +#else template inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; - -#ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP -# define __cpp_lib_has_unique_object_representations 201606 +#endif +template + inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; +template + inline constexpr bool is_nothrow_invocable_v + = is_nothrow_invocable<_Fn, _Args...>::value; +template + inline constexpr bool is_invocable_r_v + = is_invocable_r<_Ret, _Fn, _Args...>::value; +template + inline constexpr bool is_nothrow_invocable_r_v + = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; +/// @} +#endif // __cpp_lib_type_trait_variable_templates + +#ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP /// has_unique_object_representations + /// @since C++17 template struct has_unique_object_representations : bool_constant<__has_unique_object_representations( @@ -3201,49 +3541,78 @@ template "template argument must be a complete class or an unbounded array"); }; +# if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /// @ingroup variable_templates template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value; +# endif #endif -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE -# define __cpp_lib_is_aggregate 201703 - /// is_aggregate +#ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate + /// is_aggregate - true if the type is an aggregate. + /// @since C++17 template struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> { }; - /// is_aggregate_v +# if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /** is_aggregate_v - true if the type is an aggregate. + * @ingroup variable_templates + * @since C++17 + */ template - inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value; + inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>); +# endif #endif -#endif // C++17 - -#if __cplusplus > 201703L -#define __cpp_lib_remove_cvref 201711L - /// Remove references and cv-qualifiers. + /** * Remove references and cv-qualifiers. + * @since C++20 + * @{ + */ +#ifdef __cpp_lib_remove_cvref // C++ >= 20 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref) template struct remove_cvref - { - using type = __remove_cvref_t<_Tp>; - }; + { using type = __remove_cvref(_Tp); }; +# else + template + struct remove_cvref + { using type = typename remove_cv<_Tp>::type; }; + + template + struct remove_cvref<_Tp&> + { using type = typename remove_cv<_Tp>::type; }; + + template + struct remove_cvref<_Tp&&> + { using type = typename remove_cv<_Tp>::type; }; +# endif template - using remove_cvref_t = __remove_cvref_t<_Tp>; + using remove_cvref_t = typename remove_cvref<_Tp>::type; + /// @} +#endif // __cpp_lib_remove_cvref -#define __cpp_lib_type_identity 201806L - /// Identity metafunction. +#ifdef __cpp_lib_type_identity // C++ >= 20 + /** * Identity metafunction. + * @since C++20 + * @{ + */ template struct type_identity { using type = _Tp; }; template using type_identity_t = typename type_identity<_Tp>::type; + /// @} +#endif -#define __cpp_lib_unwrap_ref 201811L - - /// Unwrap a reference_wrapper +#ifdef __cpp_lib_unwrap_ref // C++ >= 20 + /** Unwrap a reference_wrapper + * @since C++20 + * @{ + */ template struct unwrap_reference { using type = _Tp; }; @@ -3252,45 +3621,206 @@ template template using unwrap_reference_t = typename unwrap_reference<_Tp>::type; + /// @} - /// Decay type and if it's a reference_wrapper, unwrap it + /** Decay type and if it's a reference_wrapper, unwrap it + * @since C++20 + * @{ + */ template struct unwrap_ref_decay { using type = unwrap_reference_t>; }; template using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; + /// @} +#endif // __cpp_lib_unwrap_ref + +#ifdef __cpp_lib_bounded_array_traits // C++ >= 20 + /// True for a type that is an array of known bound. + /// @ingroup variable_templates + /// @since C++20 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array) + template + inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); +# else + template + inline constexpr bool is_bounded_array_v = false; + + template + inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true; +# endif -#define __cpp_lib_bounded_array_traits 201902L + /// True for a type that is an array of unknown bound. + /// @ingroup variable_templates + /// @since C++20 + template + inline constexpr bool is_unbounded_array_v = false; + + template + inline constexpr bool is_unbounded_array_v<_Tp[]> = true; /// True for a type that is an array of known bound. + /// @since C++20 template struct is_bounded_array - : public __is_array_known_bounds<_Tp> + : public bool_constant> { }; /// True for a type that is an array of unknown bound. + /// @since C++20 template struct is_unbounded_array - : public __is_array_unknown_bounds<_Tp> + : public bool_constant> + { }; +#endif // __cpp_lib_bounded_array_traits + +#if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L + + /// @since C++20 + template + struct is_layout_compatible + : bool_constant<__is_layout_compatible(_Tp, _Up)> + { }; + + /// @ingroup variable_templates + /// @since C++20 + template + constexpr bool is_layout_compatible_v + = __is_layout_compatible(_Tp, _Up); + +#if __has_builtin(__builtin_is_corresponding_member) +# ifndef __cpp_lib_is_layout_compatible +# error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set" +# endif + + /// @since C++20 + template + constexpr bool + is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept + { return __builtin_is_corresponding_member(__m1, __m2); } +#endif +#endif + +#if __has_builtin(__is_pointer_interconvertible_base_of) \ + && __cplusplus >= 202002L + /// True if `_Derived` is standard-layout and has a base class of type `_Base` + /// @since C++20 + template + struct is_pointer_interconvertible_base_of + : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> + { }; + + /// @ingroup variable_templates + /// @since C++20 + template + constexpr bool is_pointer_interconvertible_base_of_v + = __is_pointer_interconvertible_base_of(_Base, _Derived); + +#if __has_builtin(__builtin_is_pointer_interconvertible_with_class) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set" +# endif + + /// True if `__mp` points to the first member of a standard-layout type + /// @returns true if `s.*__mp` is pointer-interconvertible with `s` + /// @since C++20 + template + constexpr bool + is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept + { return __builtin_is_pointer_interconvertible_with_class(__mp); } +#endif +#endif + +#ifdef __cpp_lib_is_scoped_enum // C++ >= 23 + /// True if the type is a scoped enumeration type. + /// @since C++23 + +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) + template + struct is_scoped_enum + : bool_constant<__is_scoped_enum(_Tp)> + { }; +# else + template + struct is_scoped_enum + : false_type { }; template - inline constexpr bool is_bounded_array_v - = is_bounded_array<_Tp>::value; + requires __is_enum(_Tp) + && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete + struct is_scoped_enum<_Tp> + : bool_constant + { }; +# endif + /// @ingroup variable_templates + /// @since C++23 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) template - inline constexpr bool is_unbounded_array_v - = is_unbounded_array<_Tp>::value; + inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp); +# else + template + inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value; +# endif +#endif + +#ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp + /// True if _Tp is a reference type, a _Up value can be bound to _Tp in + /// direct-initialization, and a temporary object would be bound to + /// the reference, false otherwise. + /// @since C++23 + template + struct reference_constructs_from_temporary + : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) + && std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "template argument must be a complete class or an unbounded array"); + }; + + /// True if _Tp is a reference type, a _Up value can be bound to _Tp in + /// copy-initialization, and a temporary object would be bound to + /// the reference, false otherwise. + /// @since C++23 + template + struct reference_converts_from_temporary + : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) + && std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "template argument must be a complete class or an unbounded array"); + }; -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED + /// @ingroup variable_templates + /// @since C++23 + template + inline constexpr bool reference_constructs_from_temporary_v + = reference_constructs_from_temporary<_Tp, _Up>::value; -#define __cpp_lib_is_constant_evaluated 201811L + /// @ingroup variable_templates + /// @since C++23 + template + inline constexpr bool reference_converts_from_temporary_v + = reference_converts_from_temporary<_Tp, _Up>::value; +#endif // __cpp_lib_reference_from_temporary +#ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL + /// Returns true only when called during constant evaluation. + /// @since C++20 constexpr inline bool is_constant_evaluated() noexcept - { return __builtin_is_constant_evaluated(); } + { +#if __cpp_if_consteval >= 202106L + if consteval { return true; } else { return false; } +#else + return __builtin_is_constant_evaluated(); +#endif + } #endif +#if __cplusplus >= 202002L + /// @cond undocumented template using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type; @@ -3306,11 +3836,17 @@ template template using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type; + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) + template + using __condres_cvref + = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; + // If A and B are both lvalue reference types, ... template - struct __common_ref_impl<_Xp&, _Yp&, - __void_t<__cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>>> - { using type = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; }; + struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>> + : enable_if>, + __condres_cvref<_Xp, _Yp>> + { }; // let C be remove_reference_t&& template @@ -3338,12 +3874,14 @@ template struct __common_ref_impl<_Xp&, _Yp&&> : __common_ref_impl<_Yp&&, _Xp&> { }; + /// @endcond template class _TQual, template class _UQual> struct basic_common_reference { }; + /// @cond undocumented template struct __xref { template using __type = __copy_cv<_Tp, _Up>; }; @@ -3362,6 +3900,7 @@ template remove_cvref_t<_Tp2>, __xref<_Tp1>::template __type, __xref<_Tp2>::template __type>::type; + /// @endcond template struct common_reference; @@ -3379,6 +3918,7 @@ template struct common_reference<_Tp0> { using type = _Tp0; }; + /// @cond undocumented template struct __common_reference_impl : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1> @@ -3448,9 +3988,13 @@ template void_t>> : public common_reference, _Rest...> { }; + /// @endcond #endif // C++2a + /// @} group metaprogramming + +_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 diff --git a/bin/linux/opt/m68k-amiga-elf/include/c++config b/bin/linux/opt/m68k-amiga-elf/include/c++config index 6caaf7ad..a75e2cb3 100644 --- a/bin/linux/opt/m68k-amiga-elf/include/c++config +++ b/bin/linux/opt/m68k-amiga-elf/include/c++config @@ -1,6 +1,6 @@ // Predefined symbols and macros -*- C++ -*- -// Copyright (C) 1997-2020 Free Software Foundation, Inc. +// Copyright (C) 1997-2023 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -30,6 +30,8 @@ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 +#pragma GCC system_header + // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE @@ -64,9 +66,9 @@ // Macros for visibility attributes. // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY // _GLIBCXX_VISIBILITY -#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 +#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY -#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +#ifdef _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) #else // If this is not supplied by the OS-specific or CPU-specific @@ -77,28 +79,68 @@ // Macros for deprecated attributes. // _GLIBCXX_USE_DEPRECATED // _GLIBCXX_DEPRECATED +// _GLIBCXX_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX11_DEPRECATED +// _GLIBCXX11_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX14_DEPRECATED +// _GLIBCXX14_DEPRECATED_SUGGEST( string-literal ) // _GLIBCXX17_DEPRECATED -// _GLIBCXX20_DEPRECATED( string-literal ) +// _GLIBCXX17_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX20_DEPRECATED +// _GLIBCXX20_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX23_DEPRECATED +// _GLIBCXX23_DEPRECATED_SUGGEST( string-literal ) #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif -#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +#if defined(__DEPRECATED) # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) +# define _GLIBCXX_DEPRECATED_SUGGEST(ALT) \ + __attribute__ ((__deprecated__ ("use '" ALT "' instead"))) #else # define _GLIBCXX_DEPRECATED +# define _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +# define _GLIBCXX11_DEPRECATED _GLIBCXX_DEPRECATED +# define _GLIBCXX11_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX11_DEPRECATED +# define _GLIBCXX11_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201402L) +# define _GLIBCXX14_DEPRECATED _GLIBCXX_DEPRECATED +# define _GLIBCXX14_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX14_DEPRECATED +# define _GLIBCXX14_DEPRECATED_SUGGEST(ALT) #endif #if defined(__DEPRECATED) && (__cplusplus >= 201703L) # define _GLIBCXX17_DEPRECATED [[__deprecated__]] +# define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) #else # define _GLIBCXX17_DEPRECATED +# define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 202002L) +# define _GLIBCXX20_DEPRECATED [[__deprecated__]] +# define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX20_DEPRECATED +# define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) #endif -#if defined(__DEPRECATED) && (__cplusplus > 201703L) -# define _GLIBCXX20_DEPRECATED(MSG) [[deprecated(MSG)]] +#if defined(__DEPRECATED) && (__cplusplus >= 202100L) +# define _GLIBCXX23_DEPRECATED [[__deprecated__]] +# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) #else -# define _GLIBCXX20_DEPRECATED(MSG) +# define _GLIBCXX23_DEPRECATED +# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) #endif // Macros for ABI tag attributes. @@ -145,13 +187,21 @@ #endif #ifndef _GLIBCXX20_CONSTEXPR -# if __cplusplus > 201703L +# if __cplusplus >= 202002L # define _GLIBCXX20_CONSTEXPR constexpr # else # define _GLIBCXX20_CONSTEXPR # endif #endif +#ifndef _GLIBCXX23_CONSTEXPR +# if __cplusplus >= 202100L +# define _GLIBCXX23_CONSTEXPR constexpr +# else +# define _GLIBCXX23_CONSTEXPR +# endif +#endif + #ifndef _GLIBCXX17_INLINE # if __cplusplus >= 201703L # define _GLIBCXX17_INLINE inline @@ -263,20 +313,31 @@ namespace std #if __cplusplus >= 201103L typedef decltype(nullptr) nullptr_t; #endif + +#pragma GCC visibility push(default) + // This allows the library to terminate without including all of + // and without making the declaration of std::terminate visible to users. + extern "C++" __attribute__ ((__noreturn__, __always_inline__)) + inline void __terminate() _GLIBCXX_USE_NOEXCEPT + { + void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__,__cold__)); + terminate(); + } +#pragma GCC visibility pop } -#define _GLIBCXX_USE_DUAL_ABI 0 +#define _GLIBCXX_USE_DUAL_ABI -#if ! _GLIBCXX_USE_DUAL_ABI +#ifndef _GLIBCXX_USE_DUAL_ABI // Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI # undef _GLIBCXX_USE_CXX11_ABI #endif #ifndef _GLIBCXX_USE_CXX11_ABI -#define _GLIBCXX_USE_CXX11_ABI 1 +#define _GLIBCXX_USE_CXX11_ABI #endif -#if _GLIBCXX_USE_CXX11_ABI +#ifdef _GLIBCXX_USE_CXX11_ABI namespace std { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } @@ -296,13 +357,16 @@ namespace __gnu_cxx # define _GLIBCXX_DEFAULT_ABI_TAG #endif -// Defined if inline namespaces are used for versioning. -#define _GLIBCXX_INLINE_VERSION 1 +// Non-zero if inline namespaces are used for versioning the entire library. +#define _GLIBCXX_INLINE_VERSION -// Inline namespace for symbol versioning. -#if _GLIBCXX_INLINE_VERSION +#ifdef _GLIBCXX_INLINE_VERSION +// Inline namespace for symbol versioning of (nearly) everything in std. # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 { # define _GLIBCXX_END_NAMESPACE_VERSION } +// Unused when everything in std is versioned anyway. +# define _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X) +# define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) namespace std { @@ -327,8 +391,19 @@ _GLIBCXX_END_NAMESPACE_VERSION } #else +// Unused. # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION +// Used to version individual components, e.g. std::_V2::error_category. +# define _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X) inline namespace X { +# define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) } // inline namespace X +#endif + +// In the case that we don't have a hosted environment, we can't provide the +// debugging mode. Instead, we do our best and downgrade to assertions. +#if defined(_GLIBCXX_DEBUG) && !__STDC_HOSTED__ +#undef _GLIBCXX_DEBUG +#define _GLIBCXX_ASSERTIONS 1 #endif // Inline namespaces for special modes: debug, parallel. @@ -406,7 +481,30 @@ _GLIBCXX_END_NAMESPACE_VERSION // Define if compatibility should be provided for -mlong-double-64. #undef _GLIBCXX_LONG_DOUBLE_COMPAT -// Inline namespace for long double 128 mode. +// Define if compatibility should be provided for alternative 128-bit long +// double formats. Not possible for Clang until __ibm128 is supported. +#ifndef __clang__ +#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT +#endif + +// Inline namespaces for long double 128 modes. +#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ + && defined __LONG_DOUBLE_IEEE128__ +namespace std +{ + // Namespaces for 128-bit IEEE long double format on 64-bit POWER LE. + inline namespace __gnu_cxx_ieee128 { } + inline namespace __gnu_cxx11_ieee128 { } +} +# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ieee128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ieee128 { +# define _GLIBCXX_END_NAMESPACE_LDBL } +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 __gnu_cxx11_ieee128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 namespace __gnu_cxx11_ieee128 { +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 } + +#else // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128 + #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ namespace std { @@ -420,7 +518,8 @@ namespace std # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif -#if _GLIBCXX_USE_CXX11_ABI + +#ifdef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 @@ -430,6 +529,31 @@ namespace std # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL #endif +#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128 + +namespace std +{ +#pragma GCC visibility push(default) + // Internal version of std::is_constant_evaluated(). + // This can be used without checking if the compiler supports the feature. + // The macro _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED can be used to check if + // the compiler support is present to make this function work as expected. + _GLIBCXX_CONSTEXPR inline bool + __is_constant_evaluated() _GLIBCXX_NOEXCEPT + { +#if __cpp_if_consteval >= 202106L +# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1 + if consteval { return true; } else { return false; } +#elif __cplusplus >= 201103L && __has_builtin(__builtin_is_constant_evaluated) +# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1 + return __builtin_is_constant_evaluated(); +#else + return false; +#endif + } +#pragma GCC visibility pop +} + // Debug Mode implies checking assertions. #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS) # define _GLIBCXX_ASSERTIONS 1 @@ -441,35 +565,65 @@ namespace std # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif + +#if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED +# define __glibcxx_constexpr_assert(cond) \ + if (std::__is_constant_evaluated() && !bool(cond)) \ + __builtin_unreachable() /* precondition violation detected! */ +#else +# define __glibcxx_constexpr_assert(unevaluated) +#endif + +#undef _GLIBCXX_VERBOSE_ASSERT + // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) +# ifdef _GLIBCXX_VERBOSE_ASSERT namespace std { +#pragma GCC visibility push(default) // Avoid the use of assert, because we're trying to keep the // include out of the mix. - extern "C++" inline void - __replacement_assert(const char* __file, int __line, - const char* __function, const char* __condition) - { - __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, - __function, __condition); - __builtin_abort(); - } + extern "C++" _GLIBCXX_NORETURN + void + __glibcxx_assert_fail(const char* __file, int __line, + const char* __function, const char* __condition) + _GLIBCXX_NOEXCEPT; +#pragma GCC visibility pop } -#define __glibcxx_assert_impl(_Condition) \ - do \ - { \ - if (! (_Condition)) \ - std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ - #_Condition); \ - } while (false) +#define __glibcxx_assert_impl(_Condition) \ + if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(false); \ + std::__glibcxx_assert_fail(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } +# else // ! VERBOSE_ASSERT +# define __glibcxx_assert_impl(_Condition) \ + if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(false); \ + __builtin_abort(); \ + } +# endif #endif #if defined(_GLIBCXX_ASSERTIONS) -# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_assert_impl(cond); } while (false) #else -# define __glibcxx_assert(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_constexpr_assert(cond); } while (false) +#endif + +// Macro indicating that TSAN is in use. +#if __SANITIZE_THREAD__ +# define _GLIBCXX_TSAN 1 +#elif defined __has_feature +# if __has_feature(thread_sanitizer) +# define _GLIBCXX_TSAN 1 +# endif #endif // Macros for race detectors. @@ -504,7 +658,16 @@ namespace std # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { # define _GLIBCXX_END_EXTERN_C } -#define _GLIBCXX_USE_ALLOCATOR_NEW 1 +#define _GLIBCXX_USE_ALLOCATOR_NEW + +#ifdef __SIZEOF_INT128__ +#if ! defined __GLIBCXX_TYPE_INT_N_0 && ! defined __STRICT_ANSI__ +// If __int128 is supported, we expect __GLIBCXX_TYPE_INT_N_0 to be defined +// unless the compiler is in strict mode. If it's not defined and the strict +// macro is not defined, something is wrong. +#warning "__STRICT_ANSI__ seems to have been undefined; this is not supported" +#endif +#endif #else // !__cplusplus # define _GLIBCXX_BEGIN_EXTERN_C @@ -544,10 +707,10 @@ namespace std // Conditionally enable annotations for the Transactional Memory TS on C++11. // Most of the following conditions are due to limitations in the current // implementation. -#if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI \ - && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201500L \ +#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_CXX11_ABI) \ + && defined(_GLIBCXX_USE_DUAL_ABI) && __cpp_transactional_memory >= 201500L \ && !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF \ - && _GLIBCXX_USE_ALLOCATOR_NEW + && defined(_GLIBCXX_USE_ALLOCATOR_NEW) #define _GLIBCXX_TXN_SAFE transaction_safe #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic #else @@ -630,38 +793,79 @@ namespace std # define __cpp_lib_char8_t 201907L #endif -/* Define if __float128 is supported on this host. */ +/* Define if __float128 is supported on this host. */ #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) -#define _GLIBCXX_USE_FLOAT128 +/* For powerpc64 don't use __float128 when it's the same type as long double. */ +# if !(defined(_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) && defined(__LONG_DOUBLE_IEEE128__)) +# define _GLIBCXX_USE_FLOAT128 +# endif +#endif + +// Define if float has the IEEE binary32 format. +#if __FLT_MANT_DIG__ == 24 \ + && __FLT_MIN_EXP__ == -125 \ + && __FLT_MAX_EXP__ == 128 +# define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1 +#endif + +// Define if double has the IEEE binary64 format. +#if __DBL_MANT_DIG__ == 53 \ + && __DBL_MIN_EXP__ == -1021 \ + && __DBL_MAX_EXP__ == 1024 +# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1 +#endif + +// Define if long double has the IEEE binary128 format. +#if __LDBL_MANT_DIG__ == 113 \ + && __LDBL_MIN_EXP__ == -16381 \ + && __LDBL_MAX_EXP__ == 16384 +# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1 +#endif + +#if defined __cplusplus && defined __BFLT16_DIG__ +namespace __gnu_cxx +{ + typedef __decltype(0.0bf16) __bfloat16_t; +} #endif -#if __GNUC__ >= 7 -// Assume these are available if the compiler claims to be a recent GCC: +#ifdef __has_builtin +# ifdef __is_identifier +// Intel and older Clang require !__is_identifier for some built-ins: +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) || ! __is_identifier(B) +# else +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) +# endif +#endif + +#if _GLIBCXX_HAS_BUILTIN(__has_unique_object_representations) # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__is_aggregate) # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__is_same) +# define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__builtin_launder) # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -# define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same_as(T, U) -# if __GNUC__ >= 9 -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -# endif -#elif defined(__is_identifier) && defined(__has_builtin) -// For non-GNU compilers: -# if ! __is_identifier(__has_unique_object_representations) -# define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 -# endif -# if ! __is_identifier(__is_aggregate) -# define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 -# endif -# if __has_builtin(__builtin_launder) -# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -# endif -# if __has_builtin(__builtin_is_constant_evaluated) -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -# endif -# if ! __is_identifier(__is_same) -# define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U) -# endif -#endif // GCC +#endif + +// Returns 1 if _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS is not defined and the +// compiler has a corresponding built-in type trait, 0 otherwise. +// _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS can be defined to disable the use of +// built-in traits. +#ifndef _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS +# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) _GLIBCXX_HAS_BUILTIN(BT) +#else +# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) 0 +#endif + +// Mark code that should be ignored by the compiler, but seen by Doxygen. +#define _GLIBCXX_DOXYGEN_ONLY(X) // PSTL configuration @@ -689,5 +893,5 @@ namespace std #endif // __has_include #endif // C++17 -#endif // End of prewritten config; the settings discovered at configure time follow. +#endif \ No newline at end of file diff --git a/bin/linux/opt/m68k-amiga-elf/include/type_traits b/bin/linux/opt/m68k-amiga-elf/include/type_traits index cea999f4..13c0cbb7 100644 --- a/bin/linux/opt/m68k-amiga-elf/include/type_traits +++ b/bin/linux/opt/m68k-amiga-elf/include/type_traits @@ -1,6 +1,6 @@ // C++11 -*- C++ -*- -// Copyright (C) 2007-2020 Free Software Foundation, Inc. +// Copyright (C) 2007-2024 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -37,8 +37,37 @@ #include "c++config" -namespace std +#define __glibcxx_want_bool_constant +#define __glibcxx_want_bounded_array_traits +#define __glibcxx_want_has_unique_object_representations +#define __glibcxx_want_integral_constant_callable +#define __glibcxx_want_is_aggregate +#define __glibcxx_want_is_constant_evaluated +#define __glibcxx_want_is_final +#define __glibcxx_want_is_invocable +#define __glibcxx_want_is_layout_compatible +#define __glibcxx_want_is_nothrow_convertible +#define __glibcxx_want_is_null_pointer +#define __glibcxx_want_is_pointer_interconvertible +#define __glibcxx_want_is_scoped_enum +#define __glibcxx_want_is_swappable +#define __glibcxx_want_logical_traits +#define __glibcxx_want_reference_from_temporary +#define __glibcxx_want_remove_cvref +#define __glibcxx_want_result_of_sfinae +#define __glibcxx_want_transformation_trait_aliases +#define __glibcxx_want_type_identity +#define __glibcxx_want_type_trait_variable_templates +#define __glibcxx_want_unwrap_ref +#define __glibcxx_want_void_t +//#include + +namespace std _GLIBCXX_VISIBILITY(default) { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + class reference_wrapper; /** * @defgroup metaprogramming Metaprogramming @@ -48,6 +77,8 @@ namespace std * including type classification traits, type property inspection traits * and type transformation traits. * + * @since C++11 + * * @{ */ @@ -55,41 +86,77 @@ namespace std template struct integral_constant { - static constexpr _Tp value = __v; - typedef _Tp value_type; - typedef integral_constant<_Tp, __v> type; + static constexpr _Tp value = __v; + using value_type = _Tp; + using type = integral_constant<_Tp, __v>; constexpr operator value_type() const noexcept { return value; } -#if __cplusplus > 201103L - -#define __cpp_lib_integral_constant_callable 201304 +#ifdef __cpp_lib_integral_constant_callable // C++ >= 14 constexpr value_type operator()() const noexcept { return value; } #endif }; +#if ! __cpp_inline_variables template constexpr _Tp integral_constant<_Tp, __v>::value; +#endif + + /// @cond undocumented + /// bool_constant for C++11 + template + using __bool_constant = integral_constant; + /// @endcond /// The type used as a compile-time boolean with true value. - typedef integral_constant true_type; + using true_type = __bool_constant; /// The type used as a compile-time boolean with false value. - typedef integral_constant false_type; + using false_type = __bool_constant; +#ifdef __cpp_lib_bool_constant // C++ >= 17 + /// Alias template for compile-time boolean constant types. + /// @since C++17 template - using __bool_constant = integral_constant; - -#if __cplusplus > 201402L -# define __cpp_lib_bool_constant 201505 - template - using bool_constant = integral_constant; + using bool_constant = __bool_constant<__v>; #endif - // Meta programming helper types. + // Metaprogramming helper types. + + // Primary template. + /// Define a member typedef `type` only if a boolean constant is true. + template + struct enable_if + { }; + + // Partial specialization for true. + template + struct enable_if + { using type = _Tp; }; + + // __enable_if_t (std::enable_if_t for C++11) + template + using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + + template + struct __conditional + { + template + using type = _Tp; + }; - template - struct conditional; + template<> + struct __conditional + { + template + using type = _Up; + }; + + // More efficient version of std::conditional_t for internal use (and C++11) + template + using __conditional_t + = typename __conditional<_Cond>::template type<_If, _Else>; + /// @cond undocumented template struct __type_identity { using type = _Type; }; @@ -97,81 +164,103 @@ namespace std template using __type_identity_t = typename __type_identity<_Tp>::type; - template - struct __or_; - - template<> - struct __or_<> - : public false_type - { }; - - template - struct __or_<_B1> - : public _B1 - { }; - - template - struct __or_<_B1, _B2> - : public conditional<_B1::value, _B1, _B2>::type - { }; + namespace __detail + { + // A variadic alias template that resolves to its first argument. + template + using __first_t = _Tp; - template - struct __or_<_B1, _B2, _B3, _Bn...> - : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type - { }; + // These are deliberately not defined. + template + auto __or_fn(int) -> __first_t...>; - template - struct __and_; + template + auto __or_fn(...) -> true_type; - template<> - struct __and_<> - : public true_type - { }; + template + auto __and_fn(int) -> __first_t...>; - template - struct __and_<_B1> - : public _B1 - { }; + template + auto __and_fn(...) -> false_type; + } // namespace detail - template - struct __and_<_B1, _B2> - : public conditional<_B1::value, _B2, _B1>::type + // Like C++17 std::dis/conjunction, but usable in C++11 and resolves + // to either true_type or false_type which allows for a more efficient + // implementation that avoids recursive class template instantiation. + template + struct __or_ + : decltype(__detail::__or_fn<_Bn...>(0)) { }; - template - struct __and_<_B1, _B2, _B3, _Bn...> - : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type + template + struct __and_ + : decltype(__detail::__and_fn<_Bn...>(0)) { }; template struct __not_ - : public __bool_constant + : __bool_constant { }; + /// @endcond -#if __cplusplus >= 201703L +#ifdef __cpp_lib_logical_traits // C++ >= 17 + /// @cond undocumented template inline constexpr bool __or_v = __or_<_Bn...>::value; template inline constexpr bool __and_v = __and_<_Bn...>::value; -#define __cpp_lib_logical_traits 201510 + namespace __detail + { + template + struct __disjunction_impl + { using type = _B1; }; + + template + struct __disjunction_impl<__enable_if_t, _B1, _B2, _Bn...> + { using type = typename __disjunction_impl::type; }; + + template + struct __conjunction_impl + { using type = _B1; }; + + template + struct __conjunction_impl<__enable_if_t, _B1, _B2, _Bn...> + { using type = typename __conjunction_impl::type; }; + } // namespace __detail + /// @endcond template struct conjunction - : __and_<_Bn...> + : __detail::__conjunction_impl::type + { }; + + template<> + struct conjunction<> + : true_type { }; template struct disjunction - : __or_<_Bn...> + : __detail::__disjunction_impl::type + { }; + + template<> + struct disjunction<> + : false_type { }; template struct negation - : __not_<_Pp> + : __not_<_Pp>::type { }; + /** @ingroup variable_templates + * @{ + */ template inline constexpr bool conjunction_v = conjunction<_Bn...>::value; @@ -180,8 +269,9 @@ namespace std template inline constexpr bool negation_v = negation<_Pp>::value; + /// @} -#endif // C++17 +#endif // __cpp_lib_logical_traits // Forward declarations template @@ -190,6 +280,12 @@ namespace std struct is_function; template struct is_void; + template + struct remove_cv; + template + struct is_const; + + /// @cond undocumented template struct __is_array_unknown_bounds; @@ -210,44 +306,35 @@ namespace std >::type __is_complete_or_unbounded(_TypeIdentity) { return {}; } - // For several sfinae-friendly trait implementations we transport both the - // result information (as the member type) and the failure information (no - // member type). This is very similar to std::enable_if, but we cannot use - // them, because we need to derive from them as an implementation detail. - - template - struct __success_type - { typedef _Tp type; }; - - struct __failure_type - { }; - - template - struct remove_cv; - // __remove_cv_t (std::remove_cv_t for C++11). template using __remove_cv_t = typename remove_cv<_Tp>::type; - - template - struct is_const; + /// @endcond // Primary type categories. - template - struct __is_void_helper + /// is_void + template + struct is_void : public false_type { }; template<> - struct __is_void_helper + struct is_void : public true_type { }; - /// is_void - template - struct is_void - : public __is_void_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_void + : public true_type { }; + template<> + struct is_void + : public true_type { }; + + template<> + struct is_void + : public true_type { }; + + /// @cond undocumented template struct __is_integral_helper : public false_type { }; @@ -268,11 +355,12 @@ namespace std struct __is_integral_helper : public true_type { }; -#ifdef _GLIBCXX_USE_WCHAR_T + // We want is_integral to be true (and make_signed/unsigned to work) + // even when libc doesn't provide working and related functions, + // so don't check _GLIBCXX_USE_WCHAR_T here. template<> struct __is_integral_helper : public true_type { }; -#endif #ifdef _GLIBCXX_USE_CHAR8_T template<> @@ -323,41 +411,50 @@ namespace std // Conditionalizing on __STRICT_ANSI__ here will break any port that // uses one of these types for size_t. #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif + /// @endcond /// is_integral template @@ -365,6 +462,7 @@ namespace std : public __is_integral_helper<__remove_cv_t<_Tp>>::type { }; + /// @cond undocumented template struct __is_floating_point_helper : public false_type { }; @@ -381,11 +479,42 @@ namespace std struct __is_floating_point_helper : public true_type { }; +#ifdef __STDCPP_FLOAT16_T__ + template<> + struct __is_floating_point_helper<_Float16> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT32_T__ + template<> + struct __is_floating_point_helper<_Float32> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT64_T__ + template<> + struct __is_floating_point_helper<_Float64> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT128_T__ + template<> + struct __is_floating_point_helper<_Float128> + : public true_type { }; +#endif + +#ifdef __STDCPP_BFLOAT16_T__ + template<> + struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t> + : public true_type { }; +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) template<> struct __is_floating_point_helper<__float128> : public true_type { }; #endif + /// @endcond /// is_floating_point template @@ -394,6 +523,12 @@ namespace std { }; /// is_array +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) + template + struct is_array + : public __bool_constant<__is_array(_Tp)> + { }; +#else template struct is_array : public false_type { }; @@ -405,6 +540,7 @@ namespace std template struct is_array<_Tp[]> : public true_type { }; +#endif template struct __is_pointer_helper @@ -438,6 +574,13 @@ namespace std struct is_rvalue_reference<_Tp&&> : public true_type { }; + /// is_member_object_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) + template + struct is_member_object_pointer + : public __bool_constant<__is_member_object_pointer(_Tp)> + { }; +#else template struct __is_member_object_pointer_helper : public false_type { }; @@ -446,12 +589,20 @@ namespace std struct __is_member_object_pointer_helper<_Tp _Cp::*> : public __not_>::type { }; - /// is_member_object_pointer + template struct is_member_object_pointer : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) + /// is_member_function_pointer + template + struct is_member_function_pointer + : public __bool_constant<__is_member_function_pointer(_Tp)> + { }; +#else template struct __is_member_function_pointer_helper : public false_type { }; @@ -465,26 +616,33 @@ namespace std struct is_member_function_pointer : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif /// is_enum template struct is_enum - : public integral_constant + : public __bool_constant<__is_enum(_Tp)> { }; /// is_union template struct is_union - : public integral_constant + : public __bool_constant<__is_union(_Tp)> { }; /// is_class template struct is_class - : public integral_constant + : public __bool_constant<__is_class(_Tp)> { }; /// is_function +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) + template + struct is_function + : public __bool_constant<__is_function(_Tp)> + { }; +#else template struct is_function : public __bool_constant::value> { }; @@ -496,38 +654,63 @@ namespace std template struct is_function<_Tp&&> : public false_type { }; +#endif -#define __cpp_lib_is_null_pointer 201309 - - template - struct __is_null_pointer_helper +#ifdef __glibcxx_want_is_null_pointer // C++ >= 11 + /// is_null_pointer (LWG 2247). + template + struct is_null_pointer : public false_type { }; template<> - struct __is_null_pointer_helper + struct is_null_pointer : public true_type { }; - /// is_null_pointer (LWG 2247). - template - struct is_null_pointer - : public __is_null_pointer_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_null_pointer + : public true_type { }; + + template<> + struct is_null_pointer + : public true_type { }; + + template<> + struct is_null_pointer + : public true_type { }; /// __is_nullptr_t (deprecated extension). + /// @deprecated Non-standard. Use `is_null_pointer` instead. template struct __is_nullptr_t : public is_null_pointer<_Tp> - { } _GLIBCXX_DEPRECATED; + { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer"); +#endif // __cpp_lib_is_null_pointer // Composite type categories. /// is_reference +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) + template + struct is_reference + : public __bool_constant<__is_reference(_Tp)> + { }; +#else template struct is_reference - : public __or_, - is_rvalue_reference<_Tp>>::type + : public false_type + { }; + + template + struct is_reference<_Tp&> + : public true_type { }; + template + struct is_reference<_Tp&&> + : public true_type + { }; +#endif + /// is_arithmetic template struct is_arithmetic @@ -542,11 +725,18 @@ namespace std { }; /// is_object +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) + template + struct is_object + : public __bool_constant<__is_object(_Tp)> + { }; +#else template struct is_object : public __not_<__or_, is_reference<_Tp>, is_void<_Tp>>>::type { }; +#endif template struct is_member_pointer; @@ -561,8 +751,16 @@ namespace std /// is_compound template struct is_compound - : public __not_>::type { }; + : public __bool_constant::value> { }; + /// is_member_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) + template + struct is_member_pointer + : public __bool_constant<__is_member_pointer(_Tp)> + { }; +#else + /// @cond undocumented template struct __is_member_pointer_helper : public false_type { }; @@ -570,20 +768,23 @@ namespace std template struct __is_member_pointer_helper<_Tp _Cp::*> : public true_type { }; + /// @endcond - /// is_member_pointer template struct is_member_pointer : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif template struct is_same; + /// @cond undocumented template using __is_one_of = __or_...>; // Check if a type is one of the signed integer types. + __extension__ template using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>, signed char, signed short, signed int, signed long, @@ -603,6 +804,7 @@ namespace std >; // Check if a type is one of the unsigned integer types. + __extension__ template using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>, unsigned char, unsigned short, unsigned int, unsigned long, @@ -628,18 +830,7 @@ namespace std // __void_t (std::void_t for C++11) template using __void_t = void; - - // Utility to detect referenceable types ([defns.referenceable]). - - template - struct __is_referenceable - : public false_type - { }; - - template - struct __is_referenceable<_Tp, __void_t<_Tp&>> - : public true_type - { }; + /// @endcond // Type properties. @@ -664,16 +855,16 @@ namespace std /// is_trivial template struct is_trivial - : public integral_constant + : public __bool_constant<__is_trivial(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - // is_trivially_copyable + /// is_trivially_copyable template struct is_trivially_copyable - : public integral_constant + : public __bool_constant<__is_trivially_copyable(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -682,28 +873,36 @@ namespace std /// is_standard_layout template struct is_standard_layout - : public integral_constant + : public __bool_constant<__is_standard_layout(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - /// is_pod (deprecated in C++20) + /** is_pod + * @deprecated Deprecated in C++20. + * Use `is_standard_layout && is_trivial` instead. + */ // Could use is_standard_layout && is_trivial instead of the builtin. template struct - _GLIBCXX20_DEPRECATED("use is_standard_layout && is_trivial instead") + _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial") is_pod - : public integral_constant + : public __bool_constant<__is_pod(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - /// is_literal_type + /** is_literal_type + * @deprecated Deprecated in C++17, removed in C++20. + * The idea of a literal type isn't useful. + */ template - struct is_literal_type - : public integral_constant + struct + _GLIBCXX17_DEPRECATED + is_literal_type + : public __bool_constant<__is_literal_type(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -712,30 +911,31 @@ namespace std /// is_empty template struct is_empty - : public integral_constant + : public __bool_constant<__is_empty(_Tp)> { }; /// is_polymorphic template struct is_polymorphic - : public integral_constant + : public __bool_constant<__is_polymorphic(_Tp)> { }; -#if __cplusplus >= 201402L -#define __cpp_lib_is_final 201402L +#ifdef __cpp_lib_is_final // C++ >= 14 /// is_final + /// @since C++14 template struct is_final - : public integral_constant + : public __bool_constant<__is_final(_Tp)> { }; #endif /// is_abstract template struct is_abstract - : public integral_constant + : public __bool_constant<__is_abstract(_Tp)> { }; + /// @cond undocumented template::value> struct __is_signed_helper @@ -743,8 +943,9 @@ namespace std template struct __is_signed_helper<_Tp, true> - : public integral_constant + : public __bool_constant<_Tp(-1) < _Tp(0)> { }; + /// @endcond /// is_signed template @@ -755,17 +956,10 @@ namespace std /// is_unsigned template struct is_unsigned - : public __and_, __not_>> + : public __and_, __not_>>::type { }; - - // Destructible and constructible type properties. - - /** - * @brief Utility to simplify expressions used in unevaluated operands - * @ingroup utilities - */ - + /// @cond undocumented template _Up __declval(int); @@ -773,26 +967,37 @@ namespace std template _Tp __declval(long); + /// @endcond template auto declval() noexcept -> decltype(__declval<_Tp>(0)); - template - struct extent; - template struct remove_all_extents; + /// @cond undocumented template struct __is_array_known_bounds - : public integral_constant::value > 0)> + : public false_type + { }; + + template + struct __is_array_known_bounds<_Tp[_Size]> + : public true_type { }; template struct __is_array_unknown_bounds - : public __and_, __not_>> + : public false_type + { }; + + template + struct __is_array_unknown_bounds<_Tp[]> + : public true_type { }; + // Destructible and constructible type properties. + // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete @@ -811,7 +1016,7 @@ namespace std struct __is_destructible_impl : public __do_is_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_destructible_safe<_Tp, false, true> : public true_type { }; + /// @endcond /// is_destructible template @@ -844,6 +1050,8 @@ namespace std "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + // is_nothrow_destructible requires that is_destructible is // satisfied as well. We realize that by mimicing the // implementation of is_destructible but refer to noexcept(expr) @@ -862,7 +1070,7 @@ namespace std struct __is_nt_destructible_impl : public __do_is_nt_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_nt_destructible_safe<_Tp, false, true> : public true_type { }; + /// @endcond /// is_nothrow_destructible template @@ -895,10 +1104,11 @@ namespace std "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented template - struct __is_constructible_impl - : public __bool_constant<__is_constructible(_Tp, _Args...)> - { }; + using __is_constructible_impl + = __bool_constant<__is_constructible(_Tp, _Args...)>; + /// @endcond /// is_constructible template @@ -912,100 +1122,66 @@ namespace std /// is_default_constructible template struct is_default_constructible - : public __is_constructible_impl<_Tp>::type + : public __is_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_copy_constructible_impl; + /// @cond undocumented + template + struct __add_lvalue_reference_helper + { using type = _Tp; }; template - struct __is_copy_constructible_impl<_Tp, false> - : public false_type { }; + struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>> + { using type = _Tp&; }; template - struct __is_copy_constructible_impl<_Tp, true> - : public __is_constructible_impl<_Tp, const _Tp&> - { }; + using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type; + /// @endcond /// is_copy_constructible template struct is_copy_constructible - : public __is_copy_constructible_impl<_Tp> + : public __is_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_move_constructible_impl; + /// @cond undocumented + template + struct __add_rvalue_reference_helper + { using type = _Tp; }; template - struct __is_move_constructible_impl<_Tp, false> - : public false_type { }; + struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>> + { using type = _Tp&&; }; template - struct __is_move_constructible_impl<_Tp, true> - : public __is_constructible_impl<_Tp, _Tp&&> - { }; + using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type; + /// @endcond /// is_move_constructible template struct is_move_constructible - : public __is_move_constructible_impl<_Tp> + : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template - struct __is_nt_constructible_impl - : public false_type - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant()...))> - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant(std::declval<_Arg>()))> - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant::type())> - { }; - -#if __cpp_aggregate_paren_init - template - struct __is_nt_constructible_impl - : public __is_nt_constructible_impl - { }; - - template - struct __is_nt_constructible_impl - : public __and_<__is_nt_constructible_impl...> - { }; -#endif - + /// @cond undocumented template using __is_nothrow_constructible_impl - = __is_nt_constructible_impl<__is_constructible(_Tp, _Args...), - _Tp, _Args...>; + = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>; + /// @endcond /// is_nothrow_constructible template struct is_nothrow_constructible - : public __is_nothrow_constructible_impl<_Tp, _Args...>::type + : public __is_nothrow_constructible_impl<_Tp, _Args...> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1014,116 +1190,68 @@ namespace std /// is_nothrow_default_constructible template struct is_nothrow_default_constructible - : public __is_nothrow_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - - template::value> - struct __is_nothrow_copy_constructible_impl; - - template - struct __is_nothrow_copy_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nothrow_copy_constructible_impl<_Tp, true> - : public __is_nothrow_constructible_impl<_Tp, const _Tp&> - { }; - /// is_nothrow_copy_constructible template struct is_nothrow_copy_constructible - : public __is_nothrow_copy_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nothrow_move_constructible_impl; - - template - struct __is_nothrow_move_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nothrow_move_constructible_impl<_Tp, true> - : public __is_nothrow_constructible_impl<_Tp, _Tp&&> - { }; - /// is_nothrow_move_constructible template struct is_nothrow_move_constructible - : public __is_nothrow_move_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>; + /// @endcond + /// is_assignable template struct is_assignable - : public __bool_constant<__is_assignable(_Tp, _Up)> + : public __is_assignable_impl<_Tp, _Up> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_copy_assignable_impl; - - template - struct __is_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_copy_assignable_impl<_Tp, true> - : public __bool_constant<__is_assignable(_Tp&, const _Tp&)> - { }; - /// is_copy_assignable template struct is_copy_assignable - : public __is_copy_assignable_impl<_Tp>::type + : public __is_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_move_assignable_impl; - - template - struct __is_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_move_assignable_impl<_Tp, true> - : public __bool_constant<__is_assignable(_Tp&, _Tp&&)> - { }; - /// is_move_assignable template struct is_move_assignable - : public __is_move_assignable_impl<_Tp>::type + : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented template - struct __is_nt_assignable_impl - : public integral_constant() = declval<_Up>())> - { }; - - template - struct __is_nothrow_assignable_impl - : public __and_<__bool_constant<__is_assignable(_Tp, _Up)>, - __is_nt_assignable_impl<_Tp, _Up>> - { }; + using __is_nothrow_assignable_impl + = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>; + /// @endcond /// is_nothrow_assignable template @@ -1134,52 +1262,36 @@ namespace std "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nt_copy_assignable_impl; - - template - struct __is_nt_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nt_copy_assignable_impl<_Tp, true> - : public __is_nothrow_assignable_impl<_Tp&, const _Tp&> - { }; - /// is_nothrow_copy_assignable template struct is_nothrow_copy_assignable - : public __is_nt_copy_assignable_impl<_Tp> + : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nt_move_assignable_impl; - - template - struct __is_nt_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nt_move_assignable_impl<_Tp, true> - : public __is_nothrow_assignable_impl<_Tp&, _Tp&&> - { }; - /// is_nothrow_move_assignable template struct is_nothrow_move_assignable - : public __is_nt_move_assignable_impl<_Tp> + : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_trivially_constructible_impl + = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>; + /// @endcond + /// is_trivially_constructible template struct is_trivially_constructible - : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)> + : public __is_trivially_constructible_impl<_Tp, _Args...> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1188,12 +1300,22 @@ namespace std /// is_trivially_default_constructible template struct is_trivially_default_constructible - : public __bool_constant<__is_trivially_constructible(_Tp)> + : public __is_trivially_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; +#if __cpp_variable_templates && __cpp_concepts + template + constexpr bool __is_implicitly_default_constructible_v + = requires (void(&__f)(_Tp)) { __f({}); }; + + template + struct __is_implicitly_default_constructible + : __bool_constant<__is_implicitly_default_constructible_v<_Tp>> + { }; +#else struct __do_is_implicitly_default_constructible_impl { template @@ -1210,7 +1332,7 @@ namespace std struct __is_implicitly_default_constructible_impl : public __do_is_implicitly_default_constructible_impl { - typedef decltype(__test(declval<_Tp>())) type; + using type = decltype(__test(declval<_Tp>())); }; template @@ -1221,101 +1343,58 @@ namespace std template struct __is_implicitly_default_constructible : public __and_<__is_constructible_impl<_Tp>, - __is_implicitly_default_constructible_safe<_Tp>> - { }; - - template::value> - struct __is_trivially_copy_constructible_impl; - - template - struct __is_trivially_copy_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_copy_constructible_impl<_Tp, true> - : public __and_<__is_copy_constructible_impl<_Tp>, - integral_constant> + __is_implicitly_default_constructible_safe<_Tp>>::type { }; +#endif /// is_trivially_copy_constructible template struct is_trivially_copy_constructible - : public __is_trivially_copy_constructible_impl<_Tp> + : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_move_constructible_impl; - - template - struct __is_trivially_move_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_move_constructible_impl<_Tp, true> - : public __and_<__is_move_constructible_impl<_Tp>, - integral_constant> - { }; - /// is_trivially_move_constructible template struct is_trivially_move_constructible - : public __is_trivially_move_constructible_impl<_Tp> + : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_trivially_assignable_impl + = __bool_constant<__is_trivially_assignable(_Tp, _Up)>; + /// @endcond + /// is_trivially_assignable template struct is_trivially_assignable - : public __bool_constant<__is_trivially_assignable(_Tp, _Up)> + : public __is_trivially_assignable_impl<_Tp, _Up> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_copy_assignable_impl; - - template - struct __is_trivially_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_copy_assignable_impl<_Tp, true> - : public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)> - { }; - /// is_trivially_copy_assignable template struct is_trivially_copy_assignable - : public __is_trivially_copy_assignable_impl<_Tp> + : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_move_assignable_impl; - - template - struct __is_trivially_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_move_assignable_impl<_Tp, true> - : public __bool_constant<__is_trivially_assignable(_Tp&, _Tp&&)> - { }; - /// is_trivially_move_assignable template struct is_trivially_move_assignable - : public __is_trivially_move_assignable_impl<_Tp> + : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1325,7 +1404,7 @@ namespace std template struct is_trivially_destructible : public __and_<__is_destructible_safe<_Tp>, - __bool_constant<__has_trivial_destructor(_Tp)>> + __bool_constant<__has_trivial_destructor(_Tp)>>::type { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1335,7 +1414,7 @@ namespace std /// has_virtual_destructor template struct has_virtual_destructor - : public integral_constant + : public __bool_constant<__has_virtual_destructor(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1367,23 +1446,25 @@ namespace std : public integral_constant::value> { }; /// extent - template + template struct extent - : public integral_constant { }; + : public integral_constant { }; + + template + struct extent<_Tp[_Size], 0> + : public integral_constant { }; - template + template struct extent<_Tp[_Size], _Uint> - : public integral_constant::value> - { }; + : public extent<_Tp, _Uint - 1>::type { }; + + template + struct extent<_Tp[], 0> + : public integral_constant { }; template struct extent<_Tp[], _Uint> - : public integral_constant::value> - { }; + : public extent<_Tp, _Uint - 1>::type { }; // Type relations. @@ -1391,14 +1472,14 @@ namespace std /// is_same template struct is_same -#ifdef _GLIBCXX_BUILTIN_IS_SAME_AS - : public integral_constant +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME + : public __bool_constant<__is_same(_Tp, _Up)> #else : public false_type #endif { }; -#ifndef _GLIBCXX_BUILTIN_IS_SAME_AS +#ifndef _GLIBCXX_HAVE_BUILTIN_IS_SAME template struct is_same<_Tp, _Tp> : public true_type @@ -1408,15 +1489,21 @@ namespace std /// is_base_of template struct is_base_of - : public integral_constant + : public __bool_constant<__is_base_of(_Base, _Derived)> { }; +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) + template + struct is_convertible + : public __bool_constant<__is_convertible(_From, _To)> + { }; +#else template, is_function<_To>, is_array<_To>>::value> struct __is_convertible_helper { - typedef typename is_void<_To>::type type; + using type = typename is_void<_To>::type; }; #pragma GCC diagnostic push @@ -1437,7 +1524,7 @@ namespace std __test(...); public: - typedef decltype(__test<_From, _To>(0)) type; + using type = decltype(__test<_From, _To>(0)); }; #pragma GCC diagnostic pop @@ -1446,12 +1533,27 @@ namespace std struct is_convertible : public __is_convertible_helper<_From, _To>::type { }; +#endif // helper trait for unique_ptr, shared_ptr, and span template using __is_array_convertible = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>; +#ifdef __cpp_lib_is_nothrow_convertible // C++ >= 20 + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_convertible) + /// is_nothrow_convertible_v + template + inline constexpr bool is_nothrow_convertible_v + = __is_nothrow_convertible(_From, _To); + + /// is_nothrow_convertible + template + struct is_nothrow_convertible + : public bool_constant> + { }; +#else template, is_function<_To>, is_array<_To>>::value> @@ -1481,14 +1583,6 @@ namespace std }; #pragma GCC diagnostic pop - // is_nothrow_convertible for C++11 - template - struct __is_nothrow_convertible - : public __is_nt_convertible_helper<_From, _To>::type - { }; - -#if __cplusplus > 201703L -#define __cpp_lib_is_nothrow_convertible 201806L /// is_nothrow_convertible template struct is_nothrow_convertible @@ -1499,29 +1593,35 @@ namespace std template inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_From, _To>::value; -#endif // C++2a +#endif +#endif // __cpp_lib_is_nothrow_convertible // Const-volatile modifications. /// remove_const template struct remove_const - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_const<_Tp const> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_volatile template struct remove_volatile - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_volatile<_Tp volatile> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_cv +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cv) + template + struct remove_cv + { using type = __remove_cv(_Tp); }; +#else template struct remove_cv { using type = _Tp; }; @@ -1537,29 +1637,24 @@ namespace std template struct remove_cv { using type = _Tp; }; +#endif /// add_const template struct add_const - { typedef _Tp const type; }; + { using type = _Tp const; }; /// add_volatile template struct add_volatile - { typedef _Tp volatile type; }; + { using type = _Tp volatile; }; /// add_cv template struct add_cv - { - typedef typename - add_const::type>::type type; - }; - -#if __cplusplus > 201103L - -#define __cpp_lib_transformation_trait_aliases 201304 + { using type = _Tp const volatile; }; +#ifdef __cpp_lib_transformation_trait_aliases // C++ >= 14 /// Alias template for remove_const template using remove_const_t = typename remove_const<_Tp>::type; @@ -1588,45 +1683,33 @@ namespace std // Reference transformations. /// remove_reference +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference) + template + struct remove_reference + { using type = __remove_reference(_Tp); }; +#else template struct remove_reference - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_reference<_Tp&> - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_reference<_Tp&&> - { typedef _Tp type; }; - - template::value> - struct __add_lvalue_reference_helper - { typedef _Tp type; }; - - template - struct __add_lvalue_reference_helper<_Tp, true> - { typedef _Tp& type; }; + { using type = _Tp; }; +#endif /// add_lvalue_reference template struct add_lvalue_reference - : public __add_lvalue_reference_helper<_Tp> - { }; - - template::value> - struct __add_rvalue_reference_helper - { typedef _Tp type; }; - - template - struct __add_rvalue_reference_helper<_Tp, true> - { typedef _Tp&& type; }; + { using type = __add_lval_ref_t<_Tp>; }; /// add_rvalue_reference template struct add_rvalue_reference - : public __add_rvalue_reference_helper<_Tp> - { }; + { using type = __add_rval_ref_t<_Tp>; }; #if __cplusplus > 201103L /// Alias template for remove_reference @@ -1644,91 +1727,97 @@ namespace std // Sign modifications. + /// @cond undocumented + // Utility for constructing identically cv-qualified types. template struct __cv_selector; template struct __cv_selector<_Unqualified, false, false> - { typedef _Unqualified __type; }; + { using __type = _Unqualified; }; template struct __cv_selector<_Unqualified, false, true> - { typedef volatile _Unqualified __type; }; + { using __type = volatile _Unqualified; }; template struct __cv_selector<_Unqualified, true, false> - { typedef const _Unqualified __type; }; + { using __type = const _Unqualified; }; template struct __cv_selector<_Unqualified, true, true> - { typedef const volatile _Unqualified __type; }; + { using __type = const volatile _Unqualified; }; template::value, bool _IsVol = is_volatile<_Qualified>::value> class __match_cv_qualifiers { - typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; + using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>; public: - typedef typename __match::__type __type; + using __type = typename __match::__type; }; // Utility for finding the unsigned versions of signed integral types. template struct __make_unsigned - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_unsigned - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned - { typedef unsigned short __type; }; + { using __type = unsigned short; }; template<> struct __make_unsigned - { typedef unsigned int __type; }; + { using __type = unsigned int; }; template<> struct __make_unsigned - { typedef unsigned long __type; }; + { using __type = unsigned long; }; template<> struct __make_unsigned - { typedef unsigned long long __type; }; + { using __type = unsigned long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> - { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> - { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> - { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> - { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. template::value, - bool _IsEnum = is_enum<_Tp>::value> + bool _IsEnum = __is_enum(_Tp)> class __make_unsigned_selector; template @@ -1784,14 +1873,12 @@ namespace std // neither signed integer types nor unsigned integer types, so must be // transformed to the unsigned integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. -#if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; -#endif #ifdef _GLIBCXX_USE_CHAR8_T template<> @@ -1815,6 +1902,7 @@ namespace std using __type = typename __make_unsigned_selector::__type; }; + /// @endcond // Given an integral/enum type, return the corresponding unsigned // integer type. @@ -1822,67 +1910,74 @@ namespace std /// make_unsigned template struct make_unsigned - { typedef typename __make_unsigned_selector<_Tp>::__type type; }; + { using type = typename __make_unsigned_selector<_Tp>::__type; }; // Integral, but don't define. - template<> - struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + /// @cond undocumented // Utility for finding the signed versions of unsigned integral types. template struct __make_signed - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_signed - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed - { typedef signed short __type; }; + { using __type = signed short; }; template<> struct __make_signed - { typedef signed int __type; }; + { using __type = signed int; }; template<> struct __make_signed - { typedef signed long __type; }; + { using __type = signed long; }; template<> struct __make_signed - { typedef signed long long __type; }; + { using __type = signed long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. template::value, - bool _IsEnum = is_enum<_Tp>::value> + bool _IsEnum = __is_enum(_Tp)> class __make_signed_selector; template @@ -1900,24 +1995,22 @@ namespace std template class __make_signed_selector<_Tp, false, true> { - typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; + using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type; public: - typedef typename __make_signed_selector<__unsigned_type>::__type __type; + using __type = typename __make_signed_selector<__unsigned_type>::__type; }; // wchar_t, char16_t and char32_t are integral types but are neither // signed integer types nor unsigned integer types, so must be // transformed to the signed integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. -#if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; -#endif #if defined(_GLIBCXX_USE_CHAR8_T) template<> @@ -1941,6 +2034,7 @@ namespace std using __type = typename __make_signed_selector::__type; }; + /// @endcond // Given an integral/enum type, return the corresponding signed // integer type. @@ -1948,11 +2042,13 @@ namespace std /// make_signed template struct make_signed - { typedef typename __make_signed_selector<_Tp>::__type type; }; + { using type = typename __make_signed_selector<_Tp>::__type; }; // Integral, but don't define. - template<> - struct make_signed; + template<> struct make_signed; + template<> struct make_signed; + template<> struct make_signed; + template<> struct make_signed; #if __cplusplus > 201103L /// Alias template for make_signed @@ -1969,28 +2065,28 @@ namespace std /// remove_extent template struct remove_extent - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_extent<_Tp[_Size]> - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_extent<_Tp[]> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_all_extents template struct remove_all_extents - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_all_extents<_Tp[_Size]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; template struct remove_all_extents<_Tp[]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; #if __cplusplus > 201103L /// Alias template for remove_extent @@ -2004,35 +2100,48 @@ namespace std // Pointer modifications. + /// remove_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer) + template + struct remove_pointer + { using type = __remove_pointer(_Tp); }; +#else template struct __remove_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template struct __remove_pointer_helper<_Tp, _Up*> - { typedef _Up type; }; + { using type = _Up; }; - /// remove_pointer template struct remove_pointer : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>> { }; +#endif - /// add_pointer - template, - is_void<_Tp>>::value> + template struct __add_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template - struct __add_pointer_helper<_Tp, true> - { typedef typename remove_reference<_Tp>::type* type; }; + struct __add_pointer_helper<_Tp, __void_t<_Tp*>> + { using type = _Tp*; }; + /// add_pointer template struct add_pointer : public __add_pointer_helper<_Tp> { }; + template + struct add_pointer<_Tp&> + { using type = _Tp*; }; + + template + struct add_pointer<_Tp&&> + { using type = _Tp*; }; + #if __cplusplus > 201103L /// Alias template for remove_pointer template @@ -2062,10 +2171,15 @@ namespace std * type shall be a POD type suitable for use as uninitialized * storage for any object whose size is at most _Len and whose * alignment is a divisor of _Align. + * + * @deprecated Deprecated in C++23. Uses can be replaced by an + * array std::byte[_Len] declared with alignas(_Align). */ template::__type)> - struct aligned_storage + struct + _GLIBCXX23_DEPRECATED + aligned_storage { union type { @@ -2092,6 +2206,9 @@ namespace std ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + /** * @brief Provide aligned storage for types. * @@ -2101,9 +2218,13 @@ namespace std * least size _Len. * * @see aligned_storage + * + * @deprecated Deprecated in C++23. */ template - struct aligned_union + struct + _GLIBCXX23_DEPRECATED + aligned_union { private: static_assert(sizeof...(_Types) != 0, "At least one type is required"); @@ -2115,99 +2236,92 @@ namespace std /// The value of the strictest alignment of _Types. static const size_t alignment_value = __strictest::_S_alignment; /// The storage. - typedef typename aligned_storage<_S_len, alignment_value>::type type; + using type = typename aligned_storage<_S_len, alignment_value>::type; }; template const size_t aligned_union<_Len, _Types...>::alignment_value; +#pragma GCC diagnostic pop + + /// @cond undocumented // Decay trait for arrays and functions, used for perfect forwarding // in make_pair, make_tuple, etc. - template::value, - bool _IsFunction = is_function<_Up>::value> - struct __decay_selector; - - // NB: DR 705. template - struct __decay_selector<_Up, false, false> - { typedef __remove_cv_t<_Up> __type; }; + struct __decay_selector + : __conditional_t::value, // false for functions + remove_cv<_Up>, // N.B. DR 705. + add_pointer<_Up>> // function decays to pointer + { }; - template - struct __decay_selector<_Up, true, false> - { typedef typename remove_extent<_Up>::type* __type; }; + template + struct __decay_selector<_Up[_Nm]> + { using type = _Up*; }; template - struct __decay_selector<_Up, false, true> - { typedef typename add_pointer<_Up>::type __type; }; + struct __decay_selector<_Up[]> + { using type = _Up*; }; + + /// @endcond /// decay template - class decay - { - typedef typename remove_reference<_Tp>::type __remove_type; - - public: - typedef typename __decay_selector<__remove_type>::__type type; - }; + struct decay + { using type = typename __decay_selector<_Tp>::type; }; - // __decay_t (std::decay_t for C++11). template - using __decay_t = typename decay<_Tp>::type; + struct decay<_Tp&> + { using type = typename __decay_selector<_Tp>::type; }; template - class reference_wrapper; + struct decay<_Tp&&> + { using type = typename __decay_selector<_Tp>::type; }; + + /// @cond undocumented // Helper which adds a reference to a type when given a reference_wrapper template struct __strip_reference_wrapper { - typedef _Tp __type; + using __type = _Tp; }; template struct __strip_reference_wrapper > { - typedef _Tp& __type; + using __type = _Tp&; }; + // __decay_t (std::decay_t for C++11). template - using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; - - - // Primary template. - /// Define a member typedef @c type only if a boolean constant is true. - template - struct enable_if - { }; + using __decay_t = typename decay<_Tp>::type; - // Partial specialization for true. template - struct enable_if - { typedef _Tp type; }; + using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; + /// @endcond - // __enable_if_t (std::enable_if_t for C++11) - template - using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + /// @cond undocumented + // Helper for SFINAE constraints template using _Require = __enable_if_t<__and_<_Cond...>::value>; + // __remove_cvref_t (std::remove_cvref_t for C++11). + template + using __remove_cvref_t + = typename remove_cv::type>::type; + /// @endcond + // Primary template. /// Define a member typedef @c type to one of two argument types. template struct conditional - { typedef _Iftrue type; }; + { using type = _Iftrue; }; // Partial specialization for false. template struct conditional - { typedef _Iffalse type; }; - - // __remove_cvref_t (std::remove_cvref_t for C++11). - template - using __remove_cvref_t - = typename remove_cv::type>::type; + { using type = _Iffalse; }; /// common_type template @@ -2215,6 +2329,20 @@ namespace std // Sfinae-friendly common_type implementation: + /// @cond undocumented + + // For several sfinae-friendly trait implementations we transport both the + // result information (as the member type) and the failure information (no + // member type). This is very similar to std::enable_if, but we cannot use + // that, because we need to derive from them as an implementation detail. + + template + struct __success_type + { using type = _Tp; }; + + struct __failure_type + { }; + struct __do_common_type_impl { template @@ -2308,7 +2436,7 @@ namespace std struct __common_type_fold<_CTp, _Rp, void> { }; - template::value> + template struct __underlying_type_impl { using type = __underlying_type(_Tp); @@ -2317,6 +2445,7 @@ namespace std template struct __underlying_type_impl<_Tp, false> { }; + /// @endcond /// The underlying type of an enum. template @@ -2324,12 +2453,18 @@ namespace std : public __underlying_type_impl<_Tp> { }; + /// @cond undocumented template struct __declval_protector { static const bool __stop = false; }; + /// @endcond + /** Utility to simplify expressions used in unevaluated operands + * @since C++11 + * @ingroup utilities + */ template auto declval() noexcept -> decltype(__declval<_Tp>(0)) { @@ -2340,12 +2475,11 @@ namespace std /// result_of template - class result_of; + struct result_of; // Sfinae-friendly result_of implementation: -#define __cpp_lib_result_of_sfinae 201210 - + /// @cond undocumented struct __invoke_memfun_ref { }; struct __invoke_memfun_deref { }; struct __invoke_memobj_ref { }; @@ -2373,7 +2507,7 @@ namespace std struct __result_of_memfun_ref : private __result_of_memfun_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 2: @@ -2392,7 +2526,7 @@ namespace std struct __result_of_memfun_deref : private __result_of_memfun_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 3: @@ -2411,7 +2545,7 @@ namespace std struct __result_of_memobj_ref : private __result_of_memobj_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; // [func.require] paragraph 1 bullet 4: @@ -2430,7 +2564,7 @@ namespace std struct __result_of_memobj_deref : private __result_of_memobj_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; template @@ -2439,13 +2573,13 @@ namespace std template struct __result_of_memobj<_Res _Class::*, _Arg> { - typedef __remove_cvref_t<_Arg> _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename conditional<__or_, + using _Argval = __remove_cvref_t<_Arg>; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t<__or_, is_base_of<_Class, _Argval>>::value, __result_of_memobj_ref<_MemPtr, _Arg>, __result_of_memobj_deref<_MemPtr, _Arg> - >::type::type type; + >::type; }; template @@ -2454,12 +2588,12 @@ namespace std template struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> { - typedef typename remove_reference<_Arg>::type _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename conditional::value, + using _Argval = typename remove_reference<_Arg>::type; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t::value, __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, __result_of_memfun_deref<_MemPtr, _Arg, _Args...> - >::type::type type; + >::type; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -2482,7 +2616,7 @@ namespace std template struct __result_of_impl { - typedef __failure_type type; + using type = __failure_type; }; template @@ -2513,7 +2647,7 @@ namespace std struct __result_of_impl : private __result_of_other_impl { - typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type; + using type = decltype(_S_test<_Functor, _ArgTypes...>(0)); }; // __invoke_result (std::invoke_result for C++11) @@ -2529,20 +2663,24 @@ namespace std _Functor, _ArgTypes... >::type { }; + /// @endcond template struct result_of<_Functor(_ArgTypes...)> : public __invoke_result<_Functor, _ArgTypes...> - { }; + { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result"); #if __cplusplus >= 201402L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" /// Alias template for aligned_storage template::__type)> - using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; + using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type; template - using aligned_union_t = typename aligned_union<_Len, _Types...>::type; + using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type; +#pragma GCC diagnostic pop /// Alias template for decay template @@ -2569,19 +2707,41 @@ namespace std using result_of_t = typename result_of<_Tp>::type; #endif // C++14 -#if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11 -#define __cpp_lib_void_t 201411 +#ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11 /// A metafunction that always yields void, used for detecting valid types. template using void_t = void; #endif + /// @cond undocumented + + // Detection idiom. + // Detect whether _Op<_Args...> is a valid type, use default _Def if not. + +#if __cpp_concepts + // Implementation of the detection idiom (negative case). + template class _Op, typename... _Args> + struct __detected_or + { + using type = _Def; + using __is_detected = false_type; + }; + + // Implementation of the detection idiom (positive case). + template class _Op, typename... _Args> + requires requires { typename _Op<_Args...>; } + struct __detected_or<_Def, _Op, _Args...> + { + using type = _Op<_Args...>; + using __is_detected = true_type; + }; +#else /// Implementation of the detection idiom (negative case). template class _Op, typename... _Args> struct __detector { - using value_t = false_type; using type = _Default; + using __is_detected = false_type; }; /// Implementation of the detection idiom (positive case). @@ -2589,14 +2749,14 @@ namespace std typename... _Args> struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> { - using value_t = true_type; using type = _Op<_Args...>; + using __is_detected = true_type; }; - // Detect whether _Op<_Args...> is a valid type, use _Default if not. template class _Op, typename... _Args> using __detected_or = __detector<_Default, void, _Op, _Args...>; +#endif // __cpp_concepts // _Op<_Args...> if that is a valid type, otherwise _Default. template class _Op, @@ -2604,8 +2764,6 @@ namespace std using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; - /// @} group metaprogramming - /** * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. @@ -2626,22 +2784,16 @@ namespace std template struct __is_nothrow_swappable; - template - class tuple; - template struct __is_tuple_like_impl : false_type { }; - template - struct __is_tuple_like_impl> : true_type - { }; - // Internal type trait that allows us to sfinae-protect tuple_cat. template struct __is_tuple_like : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type { }; + /// @endcond template _GLIBCXX20_CONSTEXPR @@ -2660,6 +2812,7 @@ namespace std swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(__is_nothrow_swappable<_Tp>::value); + /// @cond undocumented namespace __swappable_details { using std::swap; @@ -2690,14 +2843,14 @@ namespace std struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template @@ -2709,9 +2862,9 @@ namespace std struct __is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; + /// @endcond -#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 -#define __cpp_lib_is_swappable 201603 +#ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11 /// Metafunctions used for detecting swappable types: p0185r1 /// is_swappable @@ -2744,6 +2897,7 @@ namespace std is_nothrow_swappable<_Tp>::value; #endif // __cplusplus >= 201402L + /// @cond undocumented namespace __swappable_with_details { using std::swap; @@ -2778,7 +2932,7 @@ namespace std struct __is_swappable_with_impl : public __swappable_with_details::__do_is_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2786,14 +2940,14 @@ namespace std struct __is_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; template struct __is_nothrow_swappable_with_impl : public __swappable_with_details::__do_is_nothrow_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2801,20 +2955,31 @@ namespace std struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; + /// @endcond /// is_swappable_with template struct is_swappable_with : public __is_swappable_with_impl<_Tp, _Up>::type - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), + "first template argument must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "second template argument must be a complete class or an unbounded array"); + }; /// is_nothrow_swappable_with template struct is_nothrow_swappable_with : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), + "first template argument must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "second template argument must be a complete class or an unbounded array"); + }; #if __cplusplus >= 201402L /// is_swappable_with_v @@ -2828,14 +2993,20 @@ namespace std is_nothrow_swappable_with<_Tp, _Up>::value; #endif // __cplusplus >= 201402L -#endif// c++1z or gnu++11 +#endif // __cpp_lib_is_swappable + + /// @cond undocumented // __is_invocable (std::is_invocable for C++11) // The primary template is used for invalid INVOKE expressions. template::value, typename = void> - struct __is_invocable_impl : false_type { }; + struct __is_invocable_impl + : false_type + { + using __nothrow_conv = false_type; // For is_nothrow_invocable_r + }; // Used for valid INVOKE and INVOKE expressions. template @@ -2843,7 +3014,9 @@ namespace std /* is_void<_Ret> = */ true, __void_t> : true_type - { }; + { + using __nothrow_conv = true_type; // For is_nothrow_invocable_r + }; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" @@ -2855,23 +3028,39 @@ namespace std { private: // The type of the INVOKE expression. - // Unlike declval, this doesn't add_rvalue_reference. - static typename _Result::type _S_get(); + using _Res_t = typename _Result::type; + + // Unlike declval, this doesn't add_rvalue_reference, so it respects + // guaranteed copy elision. + static _Res_t _S_get() noexcept; + // Used to check if _Res_t can implicitly convert to _Tp. template - static void _S_conv(_Tp); + static void _S_conv(__type_identity_t<_Tp>) noexcept; // This overload is viable if INVOKE(f, args...) can convert to _Tp. - template(_S_get()))> - static true_type + template(_S_get())), + typename = decltype(_S_conv<_Tp>(_S_get())), +#if __has_builtin(__reference_converts_from_temporary) + bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t) +#else + bool _Dangle = false +#endif + > + static __bool_constant<_Nothrow && !_Dangle> _S_test(int); - template + template static false_type _S_test(...); public: - using type = decltype(_S_test<_Ret>(1)); + // For is_invocable_r + using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1)); + + // For is_nothrow_invocable_r + using __nothrow_conv = decltype(_S_test<_Ret>(1)); }; #pragma GCC diagnostic pop @@ -2941,15 +3130,20 @@ namespace std void operator=(__nonesuch const&) = delete; }; #pragma GCC diagnostic pop + /// @endcond -#if __cplusplus >= 201703L -# define __cpp_lib_is_invocable 201703 - +#ifdef __cpp_lib_is_invocable // C++ >= 17 /// std::invoke_result template struct invoke_result : public __invoke_result<_Functor, _ArgTypes...> - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}), + "_Functor must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + }; /// std::invoke_result_t template @@ -2962,6 +3156,9 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); }; /// std::is_invocable_r @@ -2971,6 +3168,11 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), + "_Ret must be a complete class or an unbounded array"); }; /// std::is_nothrow_invocable @@ -2981,47 +3183,51 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); }; - template - struct __is_nt_invocable_impl : false_type { }; - + /// @cond undocumented + // This checks that the INVOKE expression is well-formed and that the + // conversion to R does not throw. It does *not* check whether the INVOKE + // expression itself can throw. That is done by __call_is_nothrow_ instead. template - struct __is_nt_invocable_impl<_Result, _Ret, - __void_t> - : __or_, - __is_nothrow_convertible> - { }; + using __is_nt_invocable_impl + = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv; + /// @endcond /// std::is_nothrow_invocable_r template struct is_nothrow_invocable_r : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type - { }; - - /// std::is_invocable_v - template - inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; - - /// std::is_nothrow_invocable_v - template - inline constexpr bool is_nothrow_invocable_v - = is_nothrow_invocable<_Fn, _Args...>::value; - - /// std::is_invocable_r_v - template - inline constexpr bool is_invocable_r_v - = is_invocable_r<_Ret, _Fn, _Args...>::value; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), + "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), + "_Ret must be a complete class or an unbounded array"); + }; +#endif // __cpp_lib_is_invocable - /// std::is_nothrow_invocable_r_v - template - inline constexpr bool is_nothrow_invocable_r_v - = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; -#endif // C++17 +#if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /** + * @defgroup variable_templates Variable templates for type traits + * @ingroup metaprogramming + * + * Each variable `is_xxx_v` is a boolean constant with the same value + * as the `value` member of the corresponding type trait `is_xxx`. + * + * @since C++17 unless noted otherwise. + */ -#if __cplusplus >= 201703L -# define __cpp_lib_type_trait_variable_templates 201510L + /** + * @{ + * @ingroup variable_templates + */ template inline constexpr bool is_void_v = is_void<_Tp>::value; template @@ -3030,167 +3236,301 @@ template inline constexpr bool is_integral_v = is_integral<_Tp>::value; template inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) +template + inline constexpr bool is_array_v = __is_array(_Tp); +#else +template + inline constexpr bool is_array_v = false; template - inline constexpr bool is_array_v = is_array<_Tp>::value; + inline constexpr bool is_array_v<_Tp[]> = true; +template + inline constexpr bool is_array_v<_Tp[_Num]> = true; +#endif + template inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; template - inline constexpr bool is_lvalue_reference_v = - is_lvalue_reference<_Tp>::value; + inline constexpr bool is_lvalue_reference_v = false; +template + inline constexpr bool is_lvalue_reference_v<_Tp&> = true; +template + inline constexpr bool is_rvalue_reference_v = false; template - inline constexpr bool is_rvalue_reference_v = - is_rvalue_reference<_Tp>::value; + inline constexpr bool is_rvalue_reference_v<_Tp&&> = true; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) +template + inline constexpr bool is_member_object_pointer_v = + __is_member_object_pointer(_Tp); +#else template inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value; +#endif + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) +template + inline constexpr bool is_member_function_pointer_v = + __is_member_function_pointer(_Tp); +#else template inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value; +#endif + +template + inline constexpr bool is_enum_v = __is_enum(_Tp); template - inline constexpr bool is_enum_v = is_enum<_Tp>::value; + inline constexpr bool is_union_v = __is_union(_Tp); template - inline constexpr bool is_union_v = is_union<_Tp>::value; + inline constexpr bool is_class_v = __is_class(_Tp); +// is_function_v is defined below, after is_const_v. + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) +template + inline constexpr bool is_reference_v = __is_reference(_Tp); +#else template - inline constexpr bool is_class_v = is_class<_Tp>::value; + inline constexpr bool is_reference_v = false; template - inline constexpr bool is_function_v = is_function<_Tp>::value; + inline constexpr bool is_reference_v<_Tp&> = true; template - inline constexpr bool is_reference_v = is_reference<_Tp>::value; + inline constexpr bool is_reference_v<_Tp&&> = true; +#endif + template inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; template inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) +template + inline constexpr bool is_object_v = __is_object(_Tp); +#else template inline constexpr bool is_object_v = is_object<_Tp>::value; +#endif + template inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; template - inline constexpr bool is_compound_v = is_compound<_Tp>::value; + inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) +template + inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); +#else template inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; +#endif + template - inline constexpr bool is_const_v = is_const<_Tp>::value; + inline constexpr bool is_const_v = false; template - inline constexpr bool is_volatile_v = is_volatile<_Tp>::value; + inline constexpr bool is_const_v = true; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) template - inline constexpr bool is_trivial_v = is_trivial<_Tp>::value; + inline constexpr bool is_function_v = __is_function(_Tp); +#else template - inline constexpr bool is_trivially_copyable_v = - is_trivially_copyable<_Tp>::value; + inline constexpr bool is_function_v = !is_const_v; template - inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + inline constexpr bool is_function_v<_Tp&> = false; template - _GLIBCXX20_DEPRECATED("use is_standard_layout_v && is_trivial_v instead") - inline constexpr bool is_pod_v = is_pod<_Tp>::value; -#pragma GCC diagnostic pop + inline constexpr bool is_function_v<_Tp&&> = false; +#endif + +template + inline constexpr bool is_volatile_v = false; +template + inline constexpr bool is_volatile_v = true; + +template + inline constexpr bool is_trivial_v = __is_trivial(_Tp); +template + inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp); +template + inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp); template - inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value; + _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v") + inline constexpr bool is_pod_v = __is_pod(_Tp); template - inline constexpr bool is_empty_v = is_empty<_Tp>::value; + _GLIBCXX17_DEPRECATED + inline constexpr bool is_literal_type_v = __is_literal_type(_Tp); template - inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value; + inline constexpr bool is_empty_v = __is_empty(_Tp); template - inline constexpr bool is_abstract_v = is_abstract<_Tp>::value; + inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp); template - inline constexpr bool is_final_v = is_final<_Tp>::value; + inline constexpr bool is_abstract_v = __is_abstract(_Tp); +template + inline constexpr bool is_final_v = __is_final(_Tp); + template inline constexpr bool is_signed_v = is_signed<_Tp>::value; template inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; + template - inline constexpr bool is_constructible_v = - is_constructible<_Tp, _Args...>::value; + inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); template - inline constexpr bool is_default_constructible_v = - is_default_constructible<_Tp>::value; + inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); template - inline constexpr bool is_copy_constructible_v = - is_copy_constructible<_Tp>::value; + inline constexpr bool is_copy_constructible_v + = __is_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_move_constructible_v = - is_move_constructible<_Tp>::value; + inline constexpr bool is_move_constructible_v + = __is_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value; + inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up); template - inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; + inline constexpr bool is_copy_assignable_v + = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t); template - inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; + inline constexpr bool is_move_assignable_v + = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); + template inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; + template - inline constexpr bool is_trivially_constructible_v = - is_trivially_constructible<_Tp, _Args...>::value; + inline constexpr bool is_trivially_constructible_v + = __is_trivially_constructible(_Tp, _Args...); template - inline constexpr bool is_trivially_default_constructible_v = - is_trivially_default_constructible<_Tp>::value; + inline constexpr bool is_trivially_default_constructible_v + = __is_trivially_constructible(_Tp); template - inline constexpr bool is_trivially_copy_constructible_v = - is_trivially_copy_constructible<_Tp>::value; + inline constexpr bool is_trivially_copy_constructible_v + = __is_trivially_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_trivially_move_constructible_v = - is_trivially_move_constructible<_Tp>::value; + inline constexpr bool is_trivially_move_constructible_v + = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_trivially_assignable_v = - is_trivially_assignable<_Tp, _Up>::value; + inline constexpr bool is_trivially_assignable_v + = __is_trivially_assignable(_Tp, _Up); +template + inline constexpr bool is_trivially_copy_assignable_v + = __is_trivially_assignable(__add_lval_ref_t<_Tp>, + __add_lval_ref_t); template - inline constexpr bool is_trivially_copy_assignable_v = - is_trivially_copy_assignable<_Tp>::value; + inline constexpr bool is_trivially_move_assignable_v + = __is_trivially_assignable(__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>); + +#if __cpp_concepts +template + inline constexpr bool is_trivially_destructible_v = false; + +template + requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); } + inline constexpr bool is_trivially_destructible_v<_Tp> + = __has_trivial_destructor(_Tp); template - inline constexpr bool is_trivially_move_assignable_v = - is_trivially_move_assignable<_Tp>::value; + inline constexpr bool is_trivially_destructible_v<_Tp&> = true; +template + inline constexpr bool is_trivially_destructible_v<_Tp&&> = true; +template + inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]> + = is_trivially_destructible_v<_Tp>; +#else template inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value; +#endif + template - inline constexpr bool is_nothrow_constructible_v = - is_nothrow_constructible<_Tp, _Args...>::value; + inline constexpr bool is_nothrow_constructible_v + = __is_nothrow_constructible(_Tp, _Args...); template - inline constexpr bool is_nothrow_default_constructible_v = - is_nothrow_default_constructible<_Tp>::value; + inline constexpr bool is_nothrow_default_constructible_v + = __is_nothrow_constructible(_Tp); template - inline constexpr bool is_nothrow_copy_constructible_v = - is_nothrow_copy_constructible<_Tp>::value; + inline constexpr bool is_nothrow_copy_constructible_v + = __is_nothrow_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_nothrow_move_constructible_v = - is_nothrow_move_constructible<_Tp>::value; + inline constexpr bool is_nothrow_move_constructible_v + = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_nothrow_assignable_v = - is_nothrow_assignable<_Tp, _Up>::value; + inline constexpr bool is_nothrow_assignable_v + = __is_nothrow_assignable(_Tp, _Up); template - inline constexpr bool is_nothrow_copy_assignable_v = - is_nothrow_copy_assignable<_Tp>::value; + inline constexpr bool is_nothrow_copy_assignable_v + = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, + __add_lval_ref_t); template - inline constexpr bool is_nothrow_move_assignable_v = - is_nothrow_move_assignable<_Tp>::value; + inline constexpr bool is_nothrow_move_assignable_v + = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); + template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; + template - inline constexpr bool has_virtual_destructor_v = - has_virtual_destructor<_Tp>::value; + inline constexpr bool has_virtual_destructor_v + = __has_virtual_destructor(_Tp); + template inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value; + +template + inline constexpr size_t rank_v = 0; +template + inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>; template - inline constexpr size_t rank_v = rank<_Tp>::value; + inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>; + template - inline constexpr size_t extent_v = extent<_Tp, _Idx>::value; -#ifdef _GLIBCXX_BUILTIN_IS_SAME_AS + inline constexpr size_t extent_v = 0; +template + inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size; +template + inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>; +template + inline constexpr size_t extent_v<_Tp[], 0> = 0; +template + inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>; + +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME template - inline constexpr bool is_same_v = _GLIBCXX_BUILTIN_IS_SAME_AS(_Tp, _Up); + inline constexpr bool is_same_v = __is_same(_Tp, _Up); #else template - inline constexpr bool is_same_v = std::is_same<_Tp, _Up>::value; + inline constexpr bool is_same_v = false; +template + inline constexpr bool is_same_v<_Tp, _Tp> = true; #endif template - inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value; + inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) +template + inline constexpr bool is_convertible_v = __is_convertible(_From, _To); +#else template inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; - -#ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP -# define __cpp_lib_has_unique_object_representations 201606 +#endif +template + inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; +template + inline constexpr bool is_nothrow_invocable_v + = is_nothrow_invocable<_Fn, _Args...>::value; +template + inline constexpr bool is_invocable_r_v + = is_invocable_r<_Ret, _Fn, _Args...>::value; +template + inline constexpr bool is_nothrow_invocable_r_v + = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; +/// @} +#endif // __cpp_lib_type_trait_variable_templates + +#ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP /// has_unique_object_representations + /// @since C++17 template struct has_unique_object_representations : bool_constant<__has_unique_object_representations( @@ -3201,49 +3541,78 @@ template "template argument must be a complete class or an unbounded array"); }; +# if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /// @ingroup variable_templates template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value; +# endif #endif -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE -# define __cpp_lib_is_aggregate 201703 - /// is_aggregate +#ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate + /// is_aggregate - true if the type is an aggregate. + /// @since C++17 template struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> { }; - /// is_aggregate_v +# if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /** is_aggregate_v - true if the type is an aggregate. + * @ingroup variable_templates + * @since C++17 + */ template - inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value; + inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>); +# endif #endif -#endif // C++17 - -#if __cplusplus > 201703L -#define __cpp_lib_remove_cvref 201711L - /// Remove references and cv-qualifiers. + /** * Remove references and cv-qualifiers. + * @since C++20 + * @{ + */ +#ifdef __cpp_lib_remove_cvref // C++ >= 20 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref) template struct remove_cvref - { - using type = __remove_cvref_t<_Tp>; - }; + { using type = __remove_cvref(_Tp); }; +# else + template + struct remove_cvref + { using type = typename remove_cv<_Tp>::type; }; + + template + struct remove_cvref<_Tp&> + { using type = typename remove_cv<_Tp>::type; }; + + template + struct remove_cvref<_Tp&&> + { using type = typename remove_cv<_Tp>::type; }; +# endif template - using remove_cvref_t = __remove_cvref_t<_Tp>; + using remove_cvref_t = typename remove_cvref<_Tp>::type; + /// @} +#endif // __cpp_lib_remove_cvref -#define __cpp_lib_type_identity 201806L - /// Identity metafunction. +#ifdef __cpp_lib_type_identity // C++ >= 20 + /** * Identity metafunction. + * @since C++20 + * @{ + */ template struct type_identity { using type = _Tp; }; template using type_identity_t = typename type_identity<_Tp>::type; + /// @} +#endif -#define __cpp_lib_unwrap_ref 201811L - - /// Unwrap a reference_wrapper +#ifdef __cpp_lib_unwrap_ref // C++ >= 20 + /** Unwrap a reference_wrapper + * @since C++20 + * @{ + */ template struct unwrap_reference { using type = _Tp; }; @@ -3252,45 +3621,206 @@ template template using unwrap_reference_t = typename unwrap_reference<_Tp>::type; + /// @} - /// Decay type and if it's a reference_wrapper, unwrap it + /** Decay type and if it's a reference_wrapper, unwrap it + * @since C++20 + * @{ + */ template struct unwrap_ref_decay { using type = unwrap_reference_t>; }; template using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; + /// @} +#endif // __cpp_lib_unwrap_ref + +#ifdef __cpp_lib_bounded_array_traits // C++ >= 20 + /// True for a type that is an array of known bound. + /// @ingroup variable_templates + /// @since C++20 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array) + template + inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); +# else + template + inline constexpr bool is_bounded_array_v = false; + + template + inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true; +# endif -#define __cpp_lib_bounded_array_traits 201902L + /// True for a type that is an array of unknown bound. + /// @ingroup variable_templates + /// @since C++20 + template + inline constexpr bool is_unbounded_array_v = false; + + template + inline constexpr bool is_unbounded_array_v<_Tp[]> = true; /// True for a type that is an array of known bound. + /// @since C++20 template struct is_bounded_array - : public __is_array_known_bounds<_Tp> + : public bool_constant> { }; /// True for a type that is an array of unknown bound. + /// @since C++20 template struct is_unbounded_array - : public __is_array_unknown_bounds<_Tp> + : public bool_constant> + { }; +#endif // __cpp_lib_bounded_array_traits + +#if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L + + /// @since C++20 + template + struct is_layout_compatible + : bool_constant<__is_layout_compatible(_Tp, _Up)> + { }; + + /// @ingroup variable_templates + /// @since C++20 + template + constexpr bool is_layout_compatible_v + = __is_layout_compatible(_Tp, _Up); + +#if __has_builtin(__builtin_is_corresponding_member) +# ifndef __cpp_lib_is_layout_compatible +# error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set" +# endif + + /// @since C++20 + template + constexpr bool + is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept + { return __builtin_is_corresponding_member(__m1, __m2); } +#endif +#endif + +#if __has_builtin(__is_pointer_interconvertible_base_of) \ + && __cplusplus >= 202002L + /// True if `_Derived` is standard-layout and has a base class of type `_Base` + /// @since C++20 + template + struct is_pointer_interconvertible_base_of + : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> + { }; + + /// @ingroup variable_templates + /// @since C++20 + template + constexpr bool is_pointer_interconvertible_base_of_v + = __is_pointer_interconvertible_base_of(_Base, _Derived); + +#if __has_builtin(__builtin_is_pointer_interconvertible_with_class) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set" +# endif + + /// True if `__mp` points to the first member of a standard-layout type + /// @returns true if `s.*__mp` is pointer-interconvertible with `s` + /// @since C++20 + template + constexpr bool + is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept + { return __builtin_is_pointer_interconvertible_with_class(__mp); } +#endif +#endif + +#ifdef __cpp_lib_is_scoped_enum // C++ >= 23 + /// True if the type is a scoped enumeration type. + /// @since C++23 + +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) + template + struct is_scoped_enum + : bool_constant<__is_scoped_enum(_Tp)> + { }; +# else + template + struct is_scoped_enum + : false_type { }; template - inline constexpr bool is_bounded_array_v - = is_bounded_array<_Tp>::value; + requires __is_enum(_Tp) + && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete + struct is_scoped_enum<_Tp> + : bool_constant + { }; +# endif + /// @ingroup variable_templates + /// @since C++23 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) template - inline constexpr bool is_unbounded_array_v - = is_unbounded_array<_Tp>::value; + inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp); +# else + template + inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value; +# endif +#endif + +#ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp + /// True if _Tp is a reference type, a _Up value can be bound to _Tp in + /// direct-initialization, and a temporary object would be bound to + /// the reference, false otherwise. + /// @since C++23 + template + struct reference_constructs_from_temporary + : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) + && std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "template argument must be a complete class or an unbounded array"); + }; + + /// True if _Tp is a reference type, a _Up value can be bound to _Tp in + /// copy-initialization, and a temporary object would be bound to + /// the reference, false otherwise. + /// @since C++23 + template + struct reference_converts_from_temporary + : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) + && std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "template argument must be a complete class or an unbounded array"); + }; -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED + /// @ingroup variable_templates + /// @since C++23 + template + inline constexpr bool reference_constructs_from_temporary_v + = reference_constructs_from_temporary<_Tp, _Up>::value; -#define __cpp_lib_is_constant_evaluated 201811L + /// @ingroup variable_templates + /// @since C++23 + template + inline constexpr bool reference_converts_from_temporary_v + = reference_converts_from_temporary<_Tp, _Up>::value; +#endif // __cpp_lib_reference_from_temporary +#ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL + /// Returns true only when called during constant evaluation. + /// @since C++20 constexpr inline bool is_constant_evaluated() noexcept - { return __builtin_is_constant_evaluated(); } + { +#if __cpp_if_consteval >= 202106L + if consteval { return true; } else { return false; } +#else + return __builtin_is_constant_evaluated(); +#endif + } #endif +#if __cplusplus >= 202002L + /// @cond undocumented template using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type; @@ -3306,11 +3836,17 @@ template template using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type; + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) + template + using __condres_cvref + = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; + // If A and B are both lvalue reference types, ... template - struct __common_ref_impl<_Xp&, _Yp&, - __void_t<__cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>>> - { using type = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; }; + struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>> + : enable_if>, + __condres_cvref<_Xp, _Yp>> + { }; // let C be remove_reference_t&& template @@ -3338,12 +3874,14 @@ template struct __common_ref_impl<_Xp&, _Yp&&> : __common_ref_impl<_Yp&&, _Xp&> { }; + /// @endcond template class _TQual, template class _UQual> struct basic_common_reference { }; + /// @cond undocumented template struct __xref { template using __type = __copy_cv<_Tp, _Up>; }; @@ -3362,6 +3900,7 @@ template remove_cvref_t<_Tp2>, __xref<_Tp1>::template __type, __xref<_Tp2>::template __type>::type; + /// @endcond template struct common_reference; @@ -3379,6 +3918,7 @@ template struct common_reference<_Tp0> { using type = _Tp0; }; + /// @cond undocumented template struct __common_reference_impl : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1> @@ -3448,9 +3988,13 @@ template void_t>> : public common_reference, _Rest...> { }; + /// @endcond #endif // C++2a + /// @} group metaprogramming + +_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 diff --git a/bin/win32/opt/m68k-amiga-elf/include/c++config b/bin/win32/opt/m68k-amiga-elf/include/c++config index 6caaf7ad..a75e2cb3 100644 --- a/bin/win32/opt/m68k-amiga-elf/include/c++config +++ b/bin/win32/opt/m68k-amiga-elf/include/c++config @@ -1,6 +1,6 @@ // Predefined symbols and macros -*- C++ -*- -// Copyright (C) 1997-2020 Free Software Foundation, Inc. +// Copyright (C) 1997-2023 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -30,6 +30,8 @@ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 +#pragma GCC system_header + // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE @@ -64,9 +66,9 @@ // Macros for visibility attributes. // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY // _GLIBCXX_VISIBILITY -#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 +#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY -#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +#ifdef _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) #else // If this is not supplied by the OS-specific or CPU-specific @@ -77,28 +79,68 @@ // Macros for deprecated attributes. // _GLIBCXX_USE_DEPRECATED // _GLIBCXX_DEPRECATED +// _GLIBCXX_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX11_DEPRECATED +// _GLIBCXX11_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX14_DEPRECATED +// _GLIBCXX14_DEPRECATED_SUGGEST( string-literal ) // _GLIBCXX17_DEPRECATED -// _GLIBCXX20_DEPRECATED( string-literal ) +// _GLIBCXX17_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX20_DEPRECATED +// _GLIBCXX20_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX23_DEPRECATED +// _GLIBCXX23_DEPRECATED_SUGGEST( string-literal ) #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif -#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +#if defined(__DEPRECATED) # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) +# define _GLIBCXX_DEPRECATED_SUGGEST(ALT) \ + __attribute__ ((__deprecated__ ("use '" ALT "' instead"))) #else # define _GLIBCXX_DEPRECATED +# define _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +# define _GLIBCXX11_DEPRECATED _GLIBCXX_DEPRECATED +# define _GLIBCXX11_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX11_DEPRECATED +# define _GLIBCXX11_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201402L) +# define _GLIBCXX14_DEPRECATED _GLIBCXX_DEPRECATED +# define _GLIBCXX14_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX14_DEPRECATED +# define _GLIBCXX14_DEPRECATED_SUGGEST(ALT) #endif #if defined(__DEPRECATED) && (__cplusplus >= 201703L) # define _GLIBCXX17_DEPRECATED [[__deprecated__]] +# define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) #else # define _GLIBCXX17_DEPRECATED +# define _GLIBCXX17_DEPRECATED_SUGGEST(ALT) +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 202002L) +# define _GLIBCXX20_DEPRECATED [[__deprecated__]] +# define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX20_DEPRECATED +# define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) #endif -#if defined(__DEPRECATED) && (__cplusplus > 201703L) -# define _GLIBCXX20_DEPRECATED(MSG) [[deprecated(MSG)]] +#if defined(__DEPRECATED) && (__cplusplus >= 202100L) +# define _GLIBCXX23_DEPRECATED [[__deprecated__]] +# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) #else -# define _GLIBCXX20_DEPRECATED(MSG) +# define _GLIBCXX23_DEPRECATED +# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) #endif // Macros for ABI tag attributes. @@ -145,13 +187,21 @@ #endif #ifndef _GLIBCXX20_CONSTEXPR -# if __cplusplus > 201703L +# if __cplusplus >= 202002L # define _GLIBCXX20_CONSTEXPR constexpr # else # define _GLIBCXX20_CONSTEXPR # endif #endif +#ifndef _GLIBCXX23_CONSTEXPR +# if __cplusplus >= 202100L +# define _GLIBCXX23_CONSTEXPR constexpr +# else +# define _GLIBCXX23_CONSTEXPR +# endif +#endif + #ifndef _GLIBCXX17_INLINE # if __cplusplus >= 201703L # define _GLIBCXX17_INLINE inline @@ -263,20 +313,31 @@ namespace std #if __cplusplus >= 201103L typedef decltype(nullptr) nullptr_t; #endif + +#pragma GCC visibility push(default) + // This allows the library to terminate without including all of + // and without making the declaration of std::terminate visible to users. + extern "C++" __attribute__ ((__noreturn__, __always_inline__)) + inline void __terminate() _GLIBCXX_USE_NOEXCEPT + { + void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__,__cold__)); + terminate(); + } +#pragma GCC visibility pop } -#define _GLIBCXX_USE_DUAL_ABI 0 +#define _GLIBCXX_USE_DUAL_ABI -#if ! _GLIBCXX_USE_DUAL_ABI +#ifndef _GLIBCXX_USE_DUAL_ABI // Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI # undef _GLIBCXX_USE_CXX11_ABI #endif #ifndef _GLIBCXX_USE_CXX11_ABI -#define _GLIBCXX_USE_CXX11_ABI 1 +#define _GLIBCXX_USE_CXX11_ABI #endif -#if _GLIBCXX_USE_CXX11_ABI +#ifdef _GLIBCXX_USE_CXX11_ABI namespace std { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } @@ -296,13 +357,16 @@ namespace __gnu_cxx # define _GLIBCXX_DEFAULT_ABI_TAG #endif -// Defined if inline namespaces are used for versioning. -#define _GLIBCXX_INLINE_VERSION 1 +// Non-zero if inline namespaces are used for versioning the entire library. +#define _GLIBCXX_INLINE_VERSION -// Inline namespace for symbol versioning. -#if _GLIBCXX_INLINE_VERSION +#ifdef _GLIBCXX_INLINE_VERSION +// Inline namespace for symbol versioning of (nearly) everything in std. # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 { # define _GLIBCXX_END_NAMESPACE_VERSION } +// Unused when everything in std is versioned anyway. +# define _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X) +# define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) namespace std { @@ -327,8 +391,19 @@ _GLIBCXX_END_NAMESPACE_VERSION } #else +// Unused. # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION +// Used to version individual components, e.g. std::_V2::error_category. +# define _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X) inline namespace X { +# define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) } // inline namespace X +#endif + +// In the case that we don't have a hosted environment, we can't provide the +// debugging mode. Instead, we do our best and downgrade to assertions. +#if defined(_GLIBCXX_DEBUG) && !__STDC_HOSTED__ +#undef _GLIBCXX_DEBUG +#define _GLIBCXX_ASSERTIONS 1 #endif // Inline namespaces for special modes: debug, parallel. @@ -406,7 +481,30 @@ _GLIBCXX_END_NAMESPACE_VERSION // Define if compatibility should be provided for -mlong-double-64. #undef _GLIBCXX_LONG_DOUBLE_COMPAT -// Inline namespace for long double 128 mode. +// Define if compatibility should be provided for alternative 128-bit long +// double formats. Not possible for Clang until __ibm128 is supported. +#ifndef __clang__ +#undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT +#endif + +// Inline namespaces for long double 128 modes. +#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ + && defined __LONG_DOUBLE_IEEE128__ +namespace std +{ + // Namespaces for 128-bit IEEE long double format on 64-bit POWER LE. + inline namespace __gnu_cxx_ieee128 { } + inline namespace __gnu_cxx11_ieee128 { } +} +# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ieee128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ieee128 { +# define _GLIBCXX_END_NAMESPACE_LDBL } +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 __gnu_cxx11_ieee128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 namespace __gnu_cxx11_ieee128 { +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 } + +#else // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128 + #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ namespace std { @@ -420,7 +518,8 @@ namespace std # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif -#if _GLIBCXX_USE_CXX11_ABI + +#ifdef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 @@ -430,6 +529,31 @@ namespace std # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL #endif +#endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128 + +namespace std +{ +#pragma GCC visibility push(default) + // Internal version of std::is_constant_evaluated(). + // This can be used without checking if the compiler supports the feature. + // The macro _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED can be used to check if + // the compiler support is present to make this function work as expected. + _GLIBCXX_CONSTEXPR inline bool + __is_constant_evaluated() _GLIBCXX_NOEXCEPT + { +#if __cpp_if_consteval >= 202106L +# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1 + if consteval { return true; } else { return false; } +#elif __cplusplus >= 201103L && __has_builtin(__builtin_is_constant_evaluated) +# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1 + return __builtin_is_constant_evaluated(); +#else + return false; +#endif + } +#pragma GCC visibility pop +} + // Debug Mode implies checking assertions. #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS) # define _GLIBCXX_ASSERTIONS 1 @@ -441,35 +565,65 @@ namespace std # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif + +#if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED +# define __glibcxx_constexpr_assert(cond) \ + if (std::__is_constant_evaluated() && !bool(cond)) \ + __builtin_unreachable() /* precondition violation detected! */ +#else +# define __glibcxx_constexpr_assert(unevaluated) +#endif + +#undef _GLIBCXX_VERBOSE_ASSERT + // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) +# ifdef _GLIBCXX_VERBOSE_ASSERT namespace std { +#pragma GCC visibility push(default) // Avoid the use of assert, because we're trying to keep the // include out of the mix. - extern "C++" inline void - __replacement_assert(const char* __file, int __line, - const char* __function, const char* __condition) - { - __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, - __function, __condition); - __builtin_abort(); - } + extern "C++" _GLIBCXX_NORETURN + void + __glibcxx_assert_fail(const char* __file, int __line, + const char* __function, const char* __condition) + _GLIBCXX_NOEXCEPT; +#pragma GCC visibility pop } -#define __glibcxx_assert_impl(_Condition) \ - do \ - { \ - if (! (_Condition)) \ - std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ - #_Condition); \ - } while (false) +#define __glibcxx_assert_impl(_Condition) \ + if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(false); \ + std::__glibcxx_assert_fail(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } +# else // ! VERBOSE_ASSERT +# define __glibcxx_assert_impl(_Condition) \ + if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(false); \ + __builtin_abort(); \ + } +# endif #endif #if defined(_GLIBCXX_ASSERTIONS) -# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_assert_impl(cond); } while (false) #else -# define __glibcxx_assert(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_constexpr_assert(cond); } while (false) +#endif + +// Macro indicating that TSAN is in use. +#if __SANITIZE_THREAD__ +# define _GLIBCXX_TSAN 1 +#elif defined __has_feature +# if __has_feature(thread_sanitizer) +# define _GLIBCXX_TSAN 1 +# endif #endif // Macros for race detectors. @@ -504,7 +658,16 @@ namespace std # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { # define _GLIBCXX_END_EXTERN_C } -#define _GLIBCXX_USE_ALLOCATOR_NEW 1 +#define _GLIBCXX_USE_ALLOCATOR_NEW + +#ifdef __SIZEOF_INT128__ +#if ! defined __GLIBCXX_TYPE_INT_N_0 && ! defined __STRICT_ANSI__ +// If __int128 is supported, we expect __GLIBCXX_TYPE_INT_N_0 to be defined +// unless the compiler is in strict mode. If it's not defined and the strict +// macro is not defined, something is wrong. +#warning "__STRICT_ANSI__ seems to have been undefined; this is not supported" +#endif +#endif #else // !__cplusplus # define _GLIBCXX_BEGIN_EXTERN_C @@ -544,10 +707,10 @@ namespace std // Conditionally enable annotations for the Transactional Memory TS on C++11. // Most of the following conditions are due to limitations in the current // implementation. -#if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI \ - && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201500L \ +#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_CXX11_ABI) \ + && defined(_GLIBCXX_USE_DUAL_ABI) && __cpp_transactional_memory >= 201500L \ && !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF \ - && _GLIBCXX_USE_ALLOCATOR_NEW + && defined(_GLIBCXX_USE_ALLOCATOR_NEW) #define _GLIBCXX_TXN_SAFE transaction_safe #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic #else @@ -630,38 +793,79 @@ namespace std # define __cpp_lib_char8_t 201907L #endif -/* Define if __float128 is supported on this host. */ +/* Define if __float128 is supported on this host. */ #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) -#define _GLIBCXX_USE_FLOAT128 +/* For powerpc64 don't use __float128 when it's the same type as long double. */ +# if !(defined(_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) && defined(__LONG_DOUBLE_IEEE128__)) +# define _GLIBCXX_USE_FLOAT128 +# endif +#endif + +// Define if float has the IEEE binary32 format. +#if __FLT_MANT_DIG__ == 24 \ + && __FLT_MIN_EXP__ == -125 \ + && __FLT_MAX_EXP__ == 128 +# define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1 +#endif + +// Define if double has the IEEE binary64 format. +#if __DBL_MANT_DIG__ == 53 \ + && __DBL_MIN_EXP__ == -1021 \ + && __DBL_MAX_EXP__ == 1024 +# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1 +#endif + +// Define if long double has the IEEE binary128 format. +#if __LDBL_MANT_DIG__ == 113 \ + && __LDBL_MIN_EXP__ == -16381 \ + && __LDBL_MAX_EXP__ == 16384 +# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1 +#endif + +#if defined __cplusplus && defined __BFLT16_DIG__ +namespace __gnu_cxx +{ + typedef __decltype(0.0bf16) __bfloat16_t; +} #endif -#if __GNUC__ >= 7 -// Assume these are available if the compiler claims to be a recent GCC: +#ifdef __has_builtin +# ifdef __is_identifier +// Intel and older Clang require !__is_identifier for some built-ins: +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) || ! __is_identifier(B) +# else +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) +# endif +#endif + +#if _GLIBCXX_HAS_BUILTIN(__has_unique_object_representations) # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__is_aggregate) # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__is_same) +# define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1 +#endif + +#if _GLIBCXX_HAS_BUILTIN(__builtin_launder) # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -# define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same_as(T, U) -# if __GNUC__ >= 9 -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -# endif -#elif defined(__is_identifier) && defined(__has_builtin) -// For non-GNU compilers: -# if ! __is_identifier(__has_unique_object_representations) -# define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 -# endif -# if ! __is_identifier(__is_aggregate) -# define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 -# endif -# if __has_builtin(__builtin_launder) -# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -# endif -# if __has_builtin(__builtin_is_constant_evaluated) -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -# endif -# if ! __is_identifier(__is_same) -# define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U) -# endif -#endif // GCC +#endif + +// Returns 1 if _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS is not defined and the +// compiler has a corresponding built-in type trait, 0 otherwise. +// _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS can be defined to disable the use of +// built-in traits. +#ifndef _GLIBCXX_DO_NOT_USE_BUILTIN_TRAITS +# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) _GLIBCXX_HAS_BUILTIN(BT) +#else +# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) 0 +#endif + +// Mark code that should be ignored by the compiler, but seen by Doxygen. +#define _GLIBCXX_DOXYGEN_ONLY(X) // PSTL configuration @@ -689,5 +893,5 @@ namespace std #endif // __has_include #endif // C++17 -#endif // End of prewritten config; the settings discovered at configure time follow. +#endif \ No newline at end of file diff --git a/bin/win32/opt/m68k-amiga-elf/include/type_traits b/bin/win32/opt/m68k-amiga-elf/include/type_traits index cea999f4..13c0cbb7 100644 --- a/bin/win32/opt/m68k-amiga-elf/include/type_traits +++ b/bin/win32/opt/m68k-amiga-elf/include/type_traits @@ -1,6 +1,6 @@ // C++11 -*- C++ -*- -// Copyright (C) 2007-2020 Free Software Foundation, Inc. +// Copyright (C) 2007-2024 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -37,8 +37,37 @@ #include "c++config" -namespace std +#define __glibcxx_want_bool_constant +#define __glibcxx_want_bounded_array_traits +#define __glibcxx_want_has_unique_object_representations +#define __glibcxx_want_integral_constant_callable +#define __glibcxx_want_is_aggregate +#define __glibcxx_want_is_constant_evaluated +#define __glibcxx_want_is_final +#define __glibcxx_want_is_invocable +#define __glibcxx_want_is_layout_compatible +#define __glibcxx_want_is_nothrow_convertible +#define __glibcxx_want_is_null_pointer +#define __glibcxx_want_is_pointer_interconvertible +#define __glibcxx_want_is_scoped_enum +#define __glibcxx_want_is_swappable +#define __glibcxx_want_logical_traits +#define __glibcxx_want_reference_from_temporary +#define __glibcxx_want_remove_cvref +#define __glibcxx_want_result_of_sfinae +#define __glibcxx_want_transformation_trait_aliases +#define __glibcxx_want_type_identity +#define __glibcxx_want_type_trait_variable_templates +#define __glibcxx_want_unwrap_ref +#define __glibcxx_want_void_t +//#include + +namespace std _GLIBCXX_VISIBILITY(default) { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + class reference_wrapper; /** * @defgroup metaprogramming Metaprogramming @@ -48,6 +77,8 @@ namespace std * including type classification traits, type property inspection traits * and type transformation traits. * + * @since C++11 + * * @{ */ @@ -55,41 +86,77 @@ namespace std template struct integral_constant { - static constexpr _Tp value = __v; - typedef _Tp value_type; - typedef integral_constant<_Tp, __v> type; + static constexpr _Tp value = __v; + using value_type = _Tp; + using type = integral_constant<_Tp, __v>; constexpr operator value_type() const noexcept { return value; } -#if __cplusplus > 201103L - -#define __cpp_lib_integral_constant_callable 201304 +#ifdef __cpp_lib_integral_constant_callable // C++ >= 14 constexpr value_type operator()() const noexcept { return value; } #endif }; +#if ! __cpp_inline_variables template constexpr _Tp integral_constant<_Tp, __v>::value; +#endif + + /// @cond undocumented + /// bool_constant for C++11 + template + using __bool_constant = integral_constant; + /// @endcond /// The type used as a compile-time boolean with true value. - typedef integral_constant true_type; + using true_type = __bool_constant; /// The type used as a compile-time boolean with false value. - typedef integral_constant false_type; + using false_type = __bool_constant; +#ifdef __cpp_lib_bool_constant // C++ >= 17 + /// Alias template for compile-time boolean constant types. + /// @since C++17 template - using __bool_constant = integral_constant; - -#if __cplusplus > 201402L -# define __cpp_lib_bool_constant 201505 - template - using bool_constant = integral_constant; + using bool_constant = __bool_constant<__v>; #endif - // Meta programming helper types. + // Metaprogramming helper types. + + // Primary template. + /// Define a member typedef `type` only if a boolean constant is true. + template + struct enable_if + { }; + + // Partial specialization for true. + template + struct enable_if + { using type = _Tp; }; + + // __enable_if_t (std::enable_if_t for C++11) + template + using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + + template + struct __conditional + { + template + using type = _Tp; + }; - template - struct conditional; + template<> + struct __conditional + { + template + using type = _Up; + }; + + // More efficient version of std::conditional_t for internal use (and C++11) + template + using __conditional_t + = typename __conditional<_Cond>::template type<_If, _Else>; + /// @cond undocumented template struct __type_identity { using type = _Type; }; @@ -97,81 +164,103 @@ namespace std template using __type_identity_t = typename __type_identity<_Tp>::type; - template - struct __or_; - - template<> - struct __or_<> - : public false_type - { }; - - template - struct __or_<_B1> - : public _B1 - { }; - - template - struct __or_<_B1, _B2> - : public conditional<_B1::value, _B1, _B2>::type - { }; + namespace __detail + { + // A variadic alias template that resolves to its first argument. + template + using __first_t = _Tp; - template - struct __or_<_B1, _B2, _B3, _Bn...> - : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type - { }; + // These are deliberately not defined. + template + auto __or_fn(int) -> __first_t...>; - template - struct __and_; + template + auto __or_fn(...) -> true_type; - template<> - struct __and_<> - : public true_type - { }; + template + auto __and_fn(int) -> __first_t...>; - template - struct __and_<_B1> - : public _B1 - { }; + template + auto __and_fn(...) -> false_type; + } // namespace detail - template - struct __and_<_B1, _B2> - : public conditional<_B1::value, _B2, _B1>::type + // Like C++17 std::dis/conjunction, but usable in C++11 and resolves + // to either true_type or false_type which allows for a more efficient + // implementation that avoids recursive class template instantiation. + template + struct __or_ + : decltype(__detail::__or_fn<_Bn...>(0)) { }; - template - struct __and_<_B1, _B2, _B3, _Bn...> - : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type + template + struct __and_ + : decltype(__detail::__and_fn<_Bn...>(0)) { }; template struct __not_ - : public __bool_constant + : __bool_constant { }; + /// @endcond -#if __cplusplus >= 201703L +#ifdef __cpp_lib_logical_traits // C++ >= 17 + /// @cond undocumented template inline constexpr bool __or_v = __or_<_Bn...>::value; template inline constexpr bool __and_v = __and_<_Bn...>::value; -#define __cpp_lib_logical_traits 201510 + namespace __detail + { + template + struct __disjunction_impl + { using type = _B1; }; + + template + struct __disjunction_impl<__enable_if_t, _B1, _B2, _Bn...> + { using type = typename __disjunction_impl::type; }; + + template + struct __conjunction_impl + { using type = _B1; }; + + template + struct __conjunction_impl<__enable_if_t, _B1, _B2, _Bn...> + { using type = typename __conjunction_impl::type; }; + } // namespace __detail + /// @endcond template struct conjunction - : __and_<_Bn...> + : __detail::__conjunction_impl::type + { }; + + template<> + struct conjunction<> + : true_type { }; template struct disjunction - : __or_<_Bn...> + : __detail::__disjunction_impl::type + { }; + + template<> + struct disjunction<> + : false_type { }; template struct negation - : __not_<_Pp> + : __not_<_Pp>::type { }; + /** @ingroup variable_templates + * @{ + */ template inline constexpr bool conjunction_v = conjunction<_Bn...>::value; @@ -180,8 +269,9 @@ namespace std template inline constexpr bool negation_v = negation<_Pp>::value; + /// @} -#endif // C++17 +#endif // __cpp_lib_logical_traits // Forward declarations template @@ -190,6 +280,12 @@ namespace std struct is_function; template struct is_void; + template + struct remove_cv; + template + struct is_const; + + /// @cond undocumented template struct __is_array_unknown_bounds; @@ -210,44 +306,35 @@ namespace std >::type __is_complete_or_unbounded(_TypeIdentity) { return {}; } - // For several sfinae-friendly trait implementations we transport both the - // result information (as the member type) and the failure information (no - // member type). This is very similar to std::enable_if, but we cannot use - // them, because we need to derive from them as an implementation detail. - - template - struct __success_type - { typedef _Tp type; }; - - struct __failure_type - { }; - - template - struct remove_cv; - // __remove_cv_t (std::remove_cv_t for C++11). template using __remove_cv_t = typename remove_cv<_Tp>::type; - - template - struct is_const; + /// @endcond // Primary type categories. - template - struct __is_void_helper + /// is_void + template + struct is_void : public false_type { }; template<> - struct __is_void_helper + struct is_void : public true_type { }; - /// is_void - template - struct is_void - : public __is_void_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_void + : public true_type { }; + template<> + struct is_void + : public true_type { }; + + template<> + struct is_void + : public true_type { }; + + /// @cond undocumented template struct __is_integral_helper : public false_type { }; @@ -268,11 +355,12 @@ namespace std struct __is_integral_helper : public true_type { }; -#ifdef _GLIBCXX_USE_WCHAR_T + // We want is_integral to be true (and make_signed/unsigned to work) + // even when libc doesn't provide working and related functions, + // so don't check _GLIBCXX_USE_WCHAR_T here. template<> struct __is_integral_helper : public true_type { }; -#endif #ifdef _GLIBCXX_USE_CHAR8_T template<> @@ -323,41 +411,50 @@ namespace std // Conditionalizing on __STRICT_ANSI__ here will break any port that // uses one of these types for size_t. #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> : public true_type { }; + __extension__ template<> struct __is_integral_helper : public true_type { }; #endif + /// @endcond /// is_integral template @@ -365,6 +462,7 @@ namespace std : public __is_integral_helper<__remove_cv_t<_Tp>>::type { }; + /// @cond undocumented template struct __is_floating_point_helper : public false_type { }; @@ -381,11 +479,42 @@ namespace std struct __is_floating_point_helper : public true_type { }; +#ifdef __STDCPP_FLOAT16_T__ + template<> + struct __is_floating_point_helper<_Float16> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT32_T__ + template<> + struct __is_floating_point_helper<_Float32> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT64_T__ + template<> + struct __is_floating_point_helper<_Float64> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT128_T__ + template<> + struct __is_floating_point_helper<_Float128> + : public true_type { }; +#endif + +#ifdef __STDCPP_BFLOAT16_T__ + template<> + struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t> + : public true_type { }; +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) template<> struct __is_floating_point_helper<__float128> : public true_type { }; #endif + /// @endcond /// is_floating_point template @@ -394,6 +523,12 @@ namespace std { }; /// is_array +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) + template + struct is_array + : public __bool_constant<__is_array(_Tp)> + { }; +#else template struct is_array : public false_type { }; @@ -405,6 +540,7 @@ namespace std template struct is_array<_Tp[]> : public true_type { }; +#endif template struct __is_pointer_helper @@ -438,6 +574,13 @@ namespace std struct is_rvalue_reference<_Tp&&> : public true_type { }; + /// is_member_object_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) + template + struct is_member_object_pointer + : public __bool_constant<__is_member_object_pointer(_Tp)> + { }; +#else template struct __is_member_object_pointer_helper : public false_type { }; @@ -446,12 +589,20 @@ namespace std struct __is_member_object_pointer_helper<_Tp _Cp::*> : public __not_>::type { }; - /// is_member_object_pointer + template struct is_member_object_pointer : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) + /// is_member_function_pointer + template + struct is_member_function_pointer + : public __bool_constant<__is_member_function_pointer(_Tp)> + { }; +#else template struct __is_member_function_pointer_helper : public false_type { }; @@ -465,26 +616,33 @@ namespace std struct is_member_function_pointer : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif /// is_enum template struct is_enum - : public integral_constant + : public __bool_constant<__is_enum(_Tp)> { }; /// is_union template struct is_union - : public integral_constant + : public __bool_constant<__is_union(_Tp)> { }; /// is_class template struct is_class - : public integral_constant + : public __bool_constant<__is_class(_Tp)> { }; /// is_function +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) + template + struct is_function + : public __bool_constant<__is_function(_Tp)> + { }; +#else template struct is_function : public __bool_constant::value> { }; @@ -496,38 +654,63 @@ namespace std template struct is_function<_Tp&&> : public false_type { }; +#endif -#define __cpp_lib_is_null_pointer 201309 - - template - struct __is_null_pointer_helper +#ifdef __glibcxx_want_is_null_pointer // C++ >= 11 + /// is_null_pointer (LWG 2247). + template + struct is_null_pointer : public false_type { }; template<> - struct __is_null_pointer_helper + struct is_null_pointer : public true_type { }; - /// is_null_pointer (LWG 2247). - template - struct is_null_pointer - : public __is_null_pointer_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_null_pointer + : public true_type { }; + + template<> + struct is_null_pointer + : public true_type { }; + + template<> + struct is_null_pointer + : public true_type { }; /// __is_nullptr_t (deprecated extension). + /// @deprecated Non-standard. Use `is_null_pointer` instead. template struct __is_nullptr_t : public is_null_pointer<_Tp> - { } _GLIBCXX_DEPRECATED; + { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer"); +#endif // __cpp_lib_is_null_pointer // Composite type categories. /// is_reference +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) + template + struct is_reference + : public __bool_constant<__is_reference(_Tp)> + { }; +#else template struct is_reference - : public __or_, - is_rvalue_reference<_Tp>>::type + : public false_type + { }; + + template + struct is_reference<_Tp&> + : public true_type { }; + template + struct is_reference<_Tp&&> + : public true_type + { }; +#endif + /// is_arithmetic template struct is_arithmetic @@ -542,11 +725,18 @@ namespace std { }; /// is_object +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) + template + struct is_object + : public __bool_constant<__is_object(_Tp)> + { }; +#else template struct is_object : public __not_<__or_, is_reference<_Tp>, is_void<_Tp>>>::type { }; +#endif template struct is_member_pointer; @@ -561,8 +751,16 @@ namespace std /// is_compound template struct is_compound - : public __not_>::type { }; + : public __bool_constant::value> { }; + /// is_member_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) + template + struct is_member_pointer + : public __bool_constant<__is_member_pointer(_Tp)> + { }; +#else + /// @cond undocumented template struct __is_member_pointer_helper : public false_type { }; @@ -570,20 +768,23 @@ namespace std template struct __is_member_pointer_helper<_Tp _Cp::*> : public true_type { }; + /// @endcond - /// is_member_pointer template struct is_member_pointer : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type { }; +#endif template struct is_same; + /// @cond undocumented template using __is_one_of = __or_...>; // Check if a type is one of the signed integer types. + __extension__ template using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>, signed char, signed short, signed int, signed long, @@ -603,6 +804,7 @@ namespace std >; // Check if a type is one of the unsigned integer types. + __extension__ template using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>, unsigned char, unsigned short, unsigned int, unsigned long, @@ -628,18 +830,7 @@ namespace std // __void_t (std::void_t for C++11) template using __void_t = void; - - // Utility to detect referenceable types ([defns.referenceable]). - - template - struct __is_referenceable - : public false_type - { }; - - template - struct __is_referenceable<_Tp, __void_t<_Tp&>> - : public true_type - { }; + /// @endcond // Type properties. @@ -664,16 +855,16 @@ namespace std /// is_trivial template struct is_trivial - : public integral_constant + : public __bool_constant<__is_trivial(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - // is_trivially_copyable + /// is_trivially_copyable template struct is_trivially_copyable - : public integral_constant + : public __bool_constant<__is_trivially_copyable(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -682,28 +873,36 @@ namespace std /// is_standard_layout template struct is_standard_layout - : public integral_constant + : public __bool_constant<__is_standard_layout(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - /// is_pod (deprecated in C++20) + /** is_pod + * @deprecated Deprecated in C++20. + * Use `is_standard_layout && is_trivial` instead. + */ // Could use is_standard_layout && is_trivial instead of the builtin. template struct - _GLIBCXX20_DEPRECATED("use is_standard_layout && is_trivial instead") + _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial") is_pod - : public integral_constant + : public __bool_constant<__is_pod(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - /// is_literal_type + /** is_literal_type + * @deprecated Deprecated in C++17, removed in C++20. + * The idea of a literal type isn't useful. + */ template - struct is_literal_type - : public integral_constant + struct + _GLIBCXX17_DEPRECATED + is_literal_type + : public __bool_constant<__is_literal_type(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -712,30 +911,31 @@ namespace std /// is_empty template struct is_empty - : public integral_constant + : public __bool_constant<__is_empty(_Tp)> { }; /// is_polymorphic template struct is_polymorphic - : public integral_constant + : public __bool_constant<__is_polymorphic(_Tp)> { }; -#if __cplusplus >= 201402L -#define __cpp_lib_is_final 201402L +#ifdef __cpp_lib_is_final // C++ >= 14 /// is_final + /// @since C++14 template struct is_final - : public integral_constant + : public __bool_constant<__is_final(_Tp)> { }; #endif /// is_abstract template struct is_abstract - : public integral_constant + : public __bool_constant<__is_abstract(_Tp)> { }; + /// @cond undocumented template::value> struct __is_signed_helper @@ -743,8 +943,9 @@ namespace std template struct __is_signed_helper<_Tp, true> - : public integral_constant + : public __bool_constant<_Tp(-1) < _Tp(0)> { }; + /// @endcond /// is_signed template @@ -755,17 +956,10 @@ namespace std /// is_unsigned template struct is_unsigned - : public __and_, __not_>> + : public __and_, __not_>>::type { }; - - // Destructible and constructible type properties. - - /** - * @brief Utility to simplify expressions used in unevaluated operands - * @ingroup utilities - */ - + /// @cond undocumented template _Up __declval(int); @@ -773,26 +967,37 @@ namespace std template _Tp __declval(long); + /// @endcond template auto declval() noexcept -> decltype(__declval<_Tp>(0)); - template - struct extent; - template struct remove_all_extents; + /// @cond undocumented template struct __is_array_known_bounds - : public integral_constant::value > 0)> + : public false_type + { }; + + template + struct __is_array_known_bounds<_Tp[_Size]> + : public true_type { }; template struct __is_array_unknown_bounds - : public __and_, __not_>> + : public false_type + { }; + + template + struct __is_array_unknown_bounds<_Tp[]> + : public true_type { }; + // Destructible and constructible type properties. + // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete @@ -811,7 +1016,7 @@ namespace std struct __is_destructible_impl : public __do_is_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_destructible_safe<_Tp, false, true> : public true_type { }; + /// @endcond /// is_destructible template @@ -844,6 +1050,8 @@ namespace std "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + // is_nothrow_destructible requires that is_destructible is // satisfied as well. We realize that by mimicing the // implementation of is_destructible but refer to noexcept(expr) @@ -862,7 +1070,7 @@ namespace std struct __is_nt_destructible_impl : public __do_is_nt_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_nt_destructible_safe<_Tp, false, true> : public true_type { }; + /// @endcond /// is_nothrow_destructible template @@ -895,10 +1104,11 @@ namespace std "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented template - struct __is_constructible_impl - : public __bool_constant<__is_constructible(_Tp, _Args...)> - { }; + using __is_constructible_impl + = __bool_constant<__is_constructible(_Tp, _Args...)>; + /// @endcond /// is_constructible template @@ -912,100 +1122,66 @@ namespace std /// is_default_constructible template struct is_default_constructible - : public __is_constructible_impl<_Tp>::type + : public __is_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_copy_constructible_impl; + /// @cond undocumented + template + struct __add_lvalue_reference_helper + { using type = _Tp; }; template - struct __is_copy_constructible_impl<_Tp, false> - : public false_type { }; + struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>> + { using type = _Tp&; }; template - struct __is_copy_constructible_impl<_Tp, true> - : public __is_constructible_impl<_Tp, const _Tp&> - { }; + using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type; + /// @endcond /// is_copy_constructible template struct is_copy_constructible - : public __is_copy_constructible_impl<_Tp> + : public __is_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_move_constructible_impl; + /// @cond undocumented + template + struct __add_rvalue_reference_helper + { using type = _Tp; }; template - struct __is_move_constructible_impl<_Tp, false> - : public false_type { }; + struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>> + { using type = _Tp&&; }; template - struct __is_move_constructible_impl<_Tp, true> - : public __is_constructible_impl<_Tp, _Tp&&> - { }; + using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type; + /// @endcond /// is_move_constructible template struct is_move_constructible - : public __is_move_constructible_impl<_Tp> + : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template - struct __is_nt_constructible_impl - : public false_type - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant()...))> - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant(std::declval<_Arg>()))> - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant - { }; - - template - struct __is_nt_constructible_impl - : public __bool_constant::type())> - { }; - -#if __cpp_aggregate_paren_init - template - struct __is_nt_constructible_impl - : public __is_nt_constructible_impl - { }; - - template - struct __is_nt_constructible_impl - : public __and_<__is_nt_constructible_impl...> - { }; -#endif - + /// @cond undocumented template using __is_nothrow_constructible_impl - = __is_nt_constructible_impl<__is_constructible(_Tp, _Args...), - _Tp, _Args...>; + = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>; + /// @endcond /// is_nothrow_constructible template struct is_nothrow_constructible - : public __is_nothrow_constructible_impl<_Tp, _Args...>::type + : public __is_nothrow_constructible_impl<_Tp, _Args...> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1014,116 +1190,68 @@ namespace std /// is_nothrow_default_constructible template struct is_nothrow_default_constructible - : public __is_nothrow_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - - template::value> - struct __is_nothrow_copy_constructible_impl; - - template - struct __is_nothrow_copy_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nothrow_copy_constructible_impl<_Tp, true> - : public __is_nothrow_constructible_impl<_Tp, const _Tp&> - { }; - /// is_nothrow_copy_constructible template struct is_nothrow_copy_constructible - : public __is_nothrow_copy_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nothrow_move_constructible_impl; - - template - struct __is_nothrow_move_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nothrow_move_constructible_impl<_Tp, true> - : public __is_nothrow_constructible_impl<_Tp, _Tp&&> - { }; - /// is_nothrow_move_constructible template struct is_nothrow_move_constructible - : public __is_nothrow_move_constructible_impl<_Tp>::type + : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>; + /// @endcond + /// is_assignable template struct is_assignable - : public __bool_constant<__is_assignable(_Tp, _Up)> + : public __is_assignable_impl<_Tp, _Up> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_copy_assignable_impl; - - template - struct __is_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_copy_assignable_impl<_Tp, true> - : public __bool_constant<__is_assignable(_Tp&, const _Tp&)> - { }; - /// is_copy_assignable template struct is_copy_assignable - : public __is_copy_assignable_impl<_Tp>::type + : public __is_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_move_assignable_impl; - - template - struct __is_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_move_assignable_impl<_Tp, true> - : public __bool_constant<__is_assignable(_Tp&, _Tp&&)> - { }; - /// is_move_assignable template struct is_move_assignable - : public __is_move_assignable_impl<_Tp>::type + : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented template - struct __is_nt_assignable_impl - : public integral_constant() = declval<_Up>())> - { }; - - template - struct __is_nothrow_assignable_impl - : public __and_<__bool_constant<__is_assignable(_Tp, _Up)>, - __is_nt_assignable_impl<_Tp, _Up>> - { }; + using __is_nothrow_assignable_impl + = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>; + /// @endcond /// is_nothrow_assignable template @@ -1134,52 +1262,36 @@ namespace std "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nt_copy_assignable_impl; - - template - struct __is_nt_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nt_copy_assignable_impl<_Tp, true> - : public __is_nothrow_assignable_impl<_Tp&, const _Tp&> - { }; - /// is_nothrow_copy_assignable template struct is_nothrow_copy_assignable - : public __is_nt_copy_assignable_impl<_Tp> + : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_nt_move_assignable_impl; - - template - struct __is_nt_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_nt_move_assignable_impl<_Tp, true> - : public __is_nothrow_assignable_impl<_Tp&, _Tp&&> - { }; - /// is_nothrow_move_assignable template struct is_nothrow_move_assignable - : public __is_nt_move_assignable_impl<_Tp> + : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_trivially_constructible_impl + = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>; + /// @endcond + /// is_trivially_constructible template struct is_trivially_constructible - : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)> + : public __is_trivially_constructible_impl<_Tp, _Args...> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1188,12 +1300,22 @@ namespace std /// is_trivially_default_constructible template struct is_trivially_default_constructible - : public __bool_constant<__is_trivially_constructible(_Tp)> + : public __is_trivially_constructible_impl<_Tp> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; +#if __cpp_variable_templates && __cpp_concepts + template + constexpr bool __is_implicitly_default_constructible_v + = requires (void(&__f)(_Tp)) { __f({}); }; + + template + struct __is_implicitly_default_constructible + : __bool_constant<__is_implicitly_default_constructible_v<_Tp>> + { }; +#else struct __do_is_implicitly_default_constructible_impl { template @@ -1210,7 +1332,7 @@ namespace std struct __is_implicitly_default_constructible_impl : public __do_is_implicitly_default_constructible_impl { - typedef decltype(__test(declval<_Tp>())) type; + using type = decltype(__test(declval<_Tp>())); }; template @@ -1221,101 +1343,58 @@ namespace std template struct __is_implicitly_default_constructible : public __and_<__is_constructible_impl<_Tp>, - __is_implicitly_default_constructible_safe<_Tp>> - { }; - - template::value> - struct __is_trivially_copy_constructible_impl; - - template - struct __is_trivially_copy_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_copy_constructible_impl<_Tp, true> - : public __and_<__is_copy_constructible_impl<_Tp>, - integral_constant> + __is_implicitly_default_constructible_safe<_Tp>>::type { }; +#endif /// is_trivially_copy_constructible template struct is_trivially_copy_constructible - : public __is_trivially_copy_constructible_impl<_Tp> + : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_move_constructible_impl; - - template - struct __is_trivially_move_constructible_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_move_constructible_impl<_Tp, true> - : public __and_<__is_move_constructible_impl<_Tp>, - integral_constant> - { }; - /// is_trivially_move_constructible template struct is_trivially_move_constructible - : public __is_trivially_move_constructible_impl<_Tp> + : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; + /// @cond undocumented + template + using __is_trivially_assignable_impl + = __bool_constant<__is_trivially_assignable(_Tp, _Up)>; + /// @endcond + /// is_trivially_assignable template struct is_trivially_assignable - : public __bool_constant<__is_trivially_assignable(_Tp, _Up)> + : public __is_trivially_assignable_impl<_Tp, _Up> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_copy_assignable_impl; - - template - struct __is_trivially_copy_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_copy_assignable_impl<_Tp, true> - : public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)> - { }; - /// is_trivially_copy_assignable template struct is_trivially_copy_assignable - : public __is_trivially_copy_assignable_impl<_Tp> + : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, + __add_lval_ref_t> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); }; - template::value> - struct __is_trivially_move_assignable_impl; - - template - struct __is_trivially_move_assignable_impl<_Tp, false> - : public false_type { }; - - template - struct __is_trivially_move_assignable_impl<_Tp, true> - : public __bool_constant<__is_trivially_assignable(_Tp&, _Tp&&)> - { }; - /// is_trivially_move_assignable template struct is_trivially_move_assignable - : public __is_trivially_move_assignable_impl<_Tp> + : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1325,7 +1404,7 @@ namespace std template struct is_trivially_destructible : public __and_<__is_destructible_safe<_Tp>, - __bool_constant<__has_trivial_destructor(_Tp)>> + __bool_constant<__has_trivial_destructor(_Tp)>>::type { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1335,7 +1414,7 @@ namespace std /// has_virtual_destructor template struct has_virtual_destructor - : public integral_constant + : public __bool_constant<__has_virtual_destructor(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1367,23 +1446,25 @@ namespace std : public integral_constant::value> { }; /// extent - template + template struct extent - : public integral_constant { }; + : public integral_constant { }; + + template + struct extent<_Tp[_Size], 0> + : public integral_constant { }; - template + template struct extent<_Tp[_Size], _Uint> - : public integral_constant::value> - { }; + : public extent<_Tp, _Uint - 1>::type { }; + + template + struct extent<_Tp[], 0> + : public integral_constant { }; template struct extent<_Tp[], _Uint> - : public integral_constant::value> - { }; + : public extent<_Tp, _Uint - 1>::type { }; // Type relations. @@ -1391,14 +1472,14 @@ namespace std /// is_same template struct is_same -#ifdef _GLIBCXX_BUILTIN_IS_SAME_AS - : public integral_constant +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME + : public __bool_constant<__is_same(_Tp, _Up)> #else : public false_type #endif { }; -#ifndef _GLIBCXX_BUILTIN_IS_SAME_AS +#ifndef _GLIBCXX_HAVE_BUILTIN_IS_SAME template struct is_same<_Tp, _Tp> : public true_type @@ -1408,15 +1489,21 @@ namespace std /// is_base_of template struct is_base_of - : public integral_constant + : public __bool_constant<__is_base_of(_Base, _Derived)> { }; +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) + template + struct is_convertible + : public __bool_constant<__is_convertible(_From, _To)> + { }; +#else template, is_function<_To>, is_array<_To>>::value> struct __is_convertible_helper { - typedef typename is_void<_To>::type type; + using type = typename is_void<_To>::type; }; #pragma GCC diagnostic push @@ -1437,7 +1524,7 @@ namespace std __test(...); public: - typedef decltype(__test<_From, _To>(0)) type; + using type = decltype(__test<_From, _To>(0)); }; #pragma GCC diagnostic pop @@ -1446,12 +1533,27 @@ namespace std struct is_convertible : public __is_convertible_helper<_From, _To>::type { }; +#endif // helper trait for unique_ptr, shared_ptr, and span template using __is_array_convertible = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>; +#ifdef __cpp_lib_is_nothrow_convertible // C++ >= 20 + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_convertible) + /// is_nothrow_convertible_v + template + inline constexpr bool is_nothrow_convertible_v + = __is_nothrow_convertible(_From, _To); + + /// is_nothrow_convertible + template + struct is_nothrow_convertible + : public bool_constant> + { }; +#else template, is_function<_To>, is_array<_To>>::value> @@ -1481,14 +1583,6 @@ namespace std }; #pragma GCC diagnostic pop - // is_nothrow_convertible for C++11 - template - struct __is_nothrow_convertible - : public __is_nt_convertible_helper<_From, _To>::type - { }; - -#if __cplusplus > 201703L -#define __cpp_lib_is_nothrow_convertible 201806L /// is_nothrow_convertible template struct is_nothrow_convertible @@ -1499,29 +1593,35 @@ namespace std template inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_From, _To>::value; -#endif // C++2a +#endif +#endif // __cpp_lib_is_nothrow_convertible // Const-volatile modifications. /// remove_const template struct remove_const - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_const<_Tp const> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_volatile template struct remove_volatile - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_volatile<_Tp volatile> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_cv +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cv) + template + struct remove_cv + { using type = __remove_cv(_Tp); }; +#else template struct remove_cv { using type = _Tp; }; @@ -1537,29 +1637,24 @@ namespace std template struct remove_cv { using type = _Tp; }; +#endif /// add_const template struct add_const - { typedef _Tp const type; }; + { using type = _Tp const; }; /// add_volatile template struct add_volatile - { typedef _Tp volatile type; }; + { using type = _Tp volatile; }; /// add_cv template struct add_cv - { - typedef typename - add_const::type>::type type; - }; - -#if __cplusplus > 201103L - -#define __cpp_lib_transformation_trait_aliases 201304 + { using type = _Tp const volatile; }; +#ifdef __cpp_lib_transformation_trait_aliases // C++ >= 14 /// Alias template for remove_const template using remove_const_t = typename remove_const<_Tp>::type; @@ -1588,45 +1683,33 @@ namespace std // Reference transformations. /// remove_reference +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference) + template + struct remove_reference + { using type = __remove_reference(_Tp); }; +#else template struct remove_reference - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_reference<_Tp&> - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_reference<_Tp&&> - { typedef _Tp type; }; - - template::value> - struct __add_lvalue_reference_helper - { typedef _Tp type; }; - - template - struct __add_lvalue_reference_helper<_Tp, true> - { typedef _Tp& type; }; + { using type = _Tp; }; +#endif /// add_lvalue_reference template struct add_lvalue_reference - : public __add_lvalue_reference_helper<_Tp> - { }; - - template::value> - struct __add_rvalue_reference_helper - { typedef _Tp type; }; - - template - struct __add_rvalue_reference_helper<_Tp, true> - { typedef _Tp&& type; }; + { using type = __add_lval_ref_t<_Tp>; }; /// add_rvalue_reference template struct add_rvalue_reference - : public __add_rvalue_reference_helper<_Tp> - { }; + { using type = __add_rval_ref_t<_Tp>; }; #if __cplusplus > 201103L /// Alias template for remove_reference @@ -1644,91 +1727,97 @@ namespace std // Sign modifications. + /// @cond undocumented + // Utility for constructing identically cv-qualified types. template struct __cv_selector; template struct __cv_selector<_Unqualified, false, false> - { typedef _Unqualified __type; }; + { using __type = _Unqualified; }; template struct __cv_selector<_Unqualified, false, true> - { typedef volatile _Unqualified __type; }; + { using __type = volatile _Unqualified; }; template struct __cv_selector<_Unqualified, true, false> - { typedef const _Unqualified __type; }; + { using __type = const _Unqualified; }; template struct __cv_selector<_Unqualified, true, true> - { typedef const volatile _Unqualified __type; }; + { using __type = const volatile _Unqualified; }; template::value, bool _IsVol = is_volatile<_Qualified>::value> class __match_cv_qualifiers { - typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; + using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>; public: - typedef typename __match::__type __type; + using __type = typename __match::__type; }; // Utility for finding the unsigned versions of signed integral types. template struct __make_unsigned - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_unsigned - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned - { typedef unsigned short __type; }; + { using __type = unsigned short; }; template<> struct __make_unsigned - { typedef unsigned int __type; }; + { using __type = unsigned int; }; template<> struct __make_unsigned - { typedef unsigned long __type; }; + { using __type = unsigned long; }; template<> struct __make_unsigned - { typedef unsigned long long __type; }; + { using __type = unsigned long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> - { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> - { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> - { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> - { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. template::value, - bool _IsEnum = is_enum<_Tp>::value> + bool _IsEnum = __is_enum(_Tp)> class __make_unsigned_selector; template @@ -1784,14 +1873,12 @@ namespace std // neither signed integer types nor unsigned integer types, so must be // transformed to the unsigned integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. -#if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; -#endif #ifdef _GLIBCXX_USE_CHAR8_T template<> @@ -1815,6 +1902,7 @@ namespace std using __type = typename __make_unsigned_selector::__type; }; + /// @endcond // Given an integral/enum type, return the corresponding unsigned // integer type. @@ -1822,67 +1910,74 @@ namespace std /// make_unsigned template struct make_unsigned - { typedef typename __make_unsigned_selector<_Tp>::__type type; }; + { using type = typename __make_unsigned_selector<_Tp>::__type; }; // Integral, but don't define. - template<> - struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + template<> struct make_unsigned; + /// @cond undocumented // Utility for finding the signed versions of unsigned integral types. template struct __make_signed - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_signed - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed - { typedef signed short __type; }; + { using __type = signed short; }; template<> struct __make_signed - { typedef signed int __type; }; + { using __type = signed int; }; template<> struct __make_signed - { typedef signed long __type; }; + { using __type = signed long; }; template<> struct __make_signed - { typedef signed long long __type; }; + { using __type = signed long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) + __extension__ template<> struct __make_signed - { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. template::value, - bool _IsEnum = is_enum<_Tp>::value> + bool _IsEnum = __is_enum(_Tp)> class __make_signed_selector; template @@ -1900,24 +1995,22 @@ namespace std template class __make_signed_selector<_Tp, false, true> { - typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; + using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type; public: - typedef typename __make_signed_selector<__unsigned_type>::__type __type; + using __type = typename __make_signed_selector<__unsigned_type>::__type; }; // wchar_t, char16_t and char32_t are integral types but are neither // signed integer types nor unsigned integer types, so must be // transformed to the signed integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. -#if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; -#endif #if defined(_GLIBCXX_USE_CHAR8_T) template<> @@ -1941,6 +2034,7 @@ namespace std using __type = typename __make_signed_selector::__type; }; + /// @endcond // Given an integral/enum type, return the corresponding signed // integer type. @@ -1948,11 +2042,13 @@ namespace std /// make_signed template struct make_signed - { typedef typename __make_signed_selector<_Tp>::__type type; }; + { using type = typename __make_signed_selector<_Tp>::__type; }; // Integral, but don't define. - template<> - struct make_signed; + template<> struct make_signed; + template<> struct make_signed; + template<> struct make_signed; + template<> struct make_signed; #if __cplusplus > 201103L /// Alias template for make_signed @@ -1969,28 +2065,28 @@ namespace std /// remove_extent template struct remove_extent - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_extent<_Tp[_Size]> - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_extent<_Tp[]> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_all_extents template struct remove_all_extents - { typedef _Tp type; }; + { using type = _Tp; }; template struct remove_all_extents<_Tp[_Size]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; template struct remove_all_extents<_Tp[]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; #if __cplusplus > 201103L /// Alias template for remove_extent @@ -2004,35 +2100,48 @@ namespace std // Pointer modifications. + /// remove_pointer +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer) + template + struct remove_pointer + { using type = __remove_pointer(_Tp); }; +#else template struct __remove_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template struct __remove_pointer_helper<_Tp, _Up*> - { typedef _Up type; }; + { using type = _Up; }; - /// remove_pointer template struct remove_pointer : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>> { }; +#endif - /// add_pointer - template, - is_void<_Tp>>::value> + template struct __add_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template - struct __add_pointer_helper<_Tp, true> - { typedef typename remove_reference<_Tp>::type* type; }; + struct __add_pointer_helper<_Tp, __void_t<_Tp*>> + { using type = _Tp*; }; + /// add_pointer template struct add_pointer : public __add_pointer_helper<_Tp> { }; + template + struct add_pointer<_Tp&> + { using type = _Tp*; }; + + template + struct add_pointer<_Tp&&> + { using type = _Tp*; }; + #if __cplusplus > 201103L /// Alias template for remove_pointer template @@ -2062,10 +2171,15 @@ namespace std * type shall be a POD type suitable for use as uninitialized * storage for any object whose size is at most _Len and whose * alignment is a divisor of _Align. + * + * @deprecated Deprecated in C++23. Uses can be replaced by an + * array std::byte[_Len] declared with alignas(_Align). */ template::__type)> - struct aligned_storage + struct + _GLIBCXX23_DEPRECATED + aligned_storage { union type { @@ -2092,6 +2206,9 @@ namespace std ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + /** * @brief Provide aligned storage for types. * @@ -2101,9 +2218,13 @@ namespace std * least size _Len. * * @see aligned_storage + * + * @deprecated Deprecated in C++23. */ template - struct aligned_union + struct + _GLIBCXX23_DEPRECATED + aligned_union { private: static_assert(sizeof...(_Types) != 0, "At least one type is required"); @@ -2115,99 +2236,92 @@ namespace std /// The value of the strictest alignment of _Types. static const size_t alignment_value = __strictest::_S_alignment; /// The storage. - typedef typename aligned_storage<_S_len, alignment_value>::type type; + using type = typename aligned_storage<_S_len, alignment_value>::type; }; template const size_t aligned_union<_Len, _Types...>::alignment_value; +#pragma GCC diagnostic pop + + /// @cond undocumented // Decay trait for arrays and functions, used for perfect forwarding // in make_pair, make_tuple, etc. - template::value, - bool _IsFunction = is_function<_Up>::value> - struct __decay_selector; - - // NB: DR 705. template - struct __decay_selector<_Up, false, false> - { typedef __remove_cv_t<_Up> __type; }; + struct __decay_selector + : __conditional_t::value, // false for functions + remove_cv<_Up>, // N.B. DR 705. + add_pointer<_Up>> // function decays to pointer + { }; - template - struct __decay_selector<_Up, true, false> - { typedef typename remove_extent<_Up>::type* __type; }; + template + struct __decay_selector<_Up[_Nm]> + { using type = _Up*; }; template - struct __decay_selector<_Up, false, true> - { typedef typename add_pointer<_Up>::type __type; }; + struct __decay_selector<_Up[]> + { using type = _Up*; }; + + /// @endcond /// decay template - class decay - { - typedef typename remove_reference<_Tp>::type __remove_type; - - public: - typedef typename __decay_selector<__remove_type>::__type type; - }; + struct decay + { using type = typename __decay_selector<_Tp>::type; }; - // __decay_t (std::decay_t for C++11). template - using __decay_t = typename decay<_Tp>::type; + struct decay<_Tp&> + { using type = typename __decay_selector<_Tp>::type; }; template - class reference_wrapper; + struct decay<_Tp&&> + { using type = typename __decay_selector<_Tp>::type; }; + + /// @cond undocumented // Helper which adds a reference to a type when given a reference_wrapper template struct __strip_reference_wrapper { - typedef _Tp __type; + using __type = _Tp; }; template struct __strip_reference_wrapper > { - typedef _Tp& __type; + using __type = _Tp&; }; + // __decay_t (std::decay_t for C++11). template - using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; - - - // Primary template. - /// Define a member typedef @c type only if a boolean constant is true. - template - struct enable_if - { }; + using __decay_t = typename decay<_Tp>::type; - // Partial specialization for true. template - struct enable_if - { typedef _Tp type; }; + using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; + /// @endcond - // __enable_if_t (std::enable_if_t for C++11) - template - using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + /// @cond undocumented + // Helper for SFINAE constraints template using _Require = __enable_if_t<__and_<_Cond...>::value>; + // __remove_cvref_t (std::remove_cvref_t for C++11). + template + using __remove_cvref_t + = typename remove_cv::type>::type; + /// @endcond + // Primary template. /// Define a member typedef @c type to one of two argument types. template struct conditional - { typedef _Iftrue type; }; + { using type = _Iftrue; }; // Partial specialization for false. template struct conditional - { typedef _Iffalse type; }; - - // __remove_cvref_t (std::remove_cvref_t for C++11). - template - using __remove_cvref_t - = typename remove_cv::type>::type; + { using type = _Iffalse; }; /// common_type template @@ -2215,6 +2329,20 @@ namespace std // Sfinae-friendly common_type implementation: + /// @cond undocumented + + // For several sfinae-friendly trait implementations we transport both the + // result information (as the member type) and the failure information (no + // member type). This is very similar to std::enable_if, but we cannot use + // that, because we need to derive from them as an implementation detail. + + template + struct __success_type + { using type = _Tp; }; + + struct __failure_type + { }; + struct __do_common_type_impl { template @@ -2308,7 +2436,7 @@ namespace std struct __common_type_fold<_CTp, _Rp, void> { }; - template::value> + template struct __underlying_type_impl { using type = __underlying_type(_Tp); @@ -2317,6 +2445,7 @@ namespace std template struct __underlying_type_impl<_Tp, false> { }; + /// @endcond /// The underlying type of an enum. template @@ -2324,12 +2453,18 @@ namespace std : public __underlying_type_impl<_Tp> { }; + /// @cond undocumented template struct __declval_protector { static const bool __stop = false; }; + /// @endcond + /** Utility to simplify expressions used in unevaluated operands + * @since C++11 + * @ingroup utilities + */ template auto declval() noexcept -> decltype(__declval<_Tp>(0)) { @@ -2340,12 +2475,11 @@ namespace std /// result_of template - class result_of; + struct result_of; // Sfinae-friendly result_of implementation: -#define __cpp_lib_result_of_sfinae 201210 - + /// @cond undocumented struct __invoke_memfun_ref { }; struct __invoke_memfun_deref { }; struct __invoke_memobj_ref { }; @@ -2373,7 +2507,7 @@ namespace std struct __result_of_memfun_ref : private __result_of_memfun_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 2: @@ -2392,7 +2526,7 @@ namespace std struct __result_of_memfun_deref : private __result_of_memfun_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 3: @@ -2411,7 +2545,7 @@ namespace std struct __result_of_memobj_ref : private __result_of_memobj_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; // [func.require] paragraph 1 bullet 4: @@ -2430,7 +2564,7 @@ namespace std struct __result_of_memobj_deref : private __result_of_memobj_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; template @@ -2439,13 +2573,13 @@ namespace std template struct __result_of_memobj<_Res _Class::*, _Arg> { - typedef __remove_cvref_t<_Arg> _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename conditional<__or_, + using _Argval = __remove_cvref_t<_Arg>; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t<__or_, is_base_of<_Class, _Argval>>::value, __result_of_memobj_ref<_MemPtr, _Arg>, __result_of_memobj_deref<_MemPtr, _Arg> - >::type::type type; + >::type; }; template @@ -2454,12 +2588,12 @@ namespace std template struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> { - typedef typename remove_reference<_Arg>::type _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename conditional::value, + using _Argval = typename remove_reference<_Arg>::type; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t::value, __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, __result_of_memfun_deref<_MemPtr, _Arg, _Args...> - >::type::type type; + >::type; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -2482,7 +2616,7 @@ namespace std template struct __result_of_impl { - typedef __failure_type type; + using type = __failure_type; }; template @@ -2513,7 +2647,7 @@ namespace std struct __result_of_impl : private __result_of_other_impl { - typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type; + using type = decltype(_S_test<_Functor, _ArgTypes...>(0)); }; // __invoke_result (std::invoke_result for C++11) @@ -2529,20 +2663,24 @@ namespace std _Functor, _ArgTypes... >::type { }; + /// @endcond template struct result_of<_Functor(_ArgTypes...)> : public __invoke_result<_Functor, _ArgTypes...> - { }; + { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result"); #if __cplusplus >= 201402L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" /// Alias template for aligned_storage template::__type)> - using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; + using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type; template - using aligned_union_t = typename aligned_union<_Len, _Types...>::type; + using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type; +#pragma GCC diagnostic pop /// Alias template for decay template @@ -2569,19 +2707,41 @@ namespace std using result_of_t = typename result_of<_Tp>::type; #endif // C++14 -#if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11 -#define __cpp_lib_void_t 201411 +#ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11 /// A metafunction that always yields void, used for detecting valid types. template using void_t = void; #endif + /// @cond undocumented + + // Detection idiom. + // Detect whether _Op<_Args...> is a valid type, use default _Def if not. + +#if __cpp_concepts + // Implementation of the detection idiom (negative case). + template class _Op, typename... _Args> + struct __detected_or + { + using type = _Def; + using __is_detected = false_type; + }; + + // Implementation of the detection idiom (positive case). + template class _Op, typename... _Args> + requires requires { typename _Op<_Args...>; } + struct __detected_or<_Def, _Op, _Args...> + { + using type = _Op<_Args...>; + using __is_detected = true_type; + }; +#else /// Implementation of the detection idiom (negative case). template class _Op, typename... _Args> struct __detector { - using value_t = false_type; using type = _Default; + using __is_detected = false_type; }; /// Implementation of the detection idiom (positive case). @@ -2589,14 +2749,14 @@ namespace std typename... _Args> struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> { - using value_t = true_type; using type = _Op<_Args...>; + using __is_detected = true_type; }; - // Detect whether _Op<_Args...> is a valid type, use _Default if not. template class _Op, typename... _Args> using __detected_or = __detector<_Default, void, _Op, _Args...>; +#endif // __cpp_concepts // _Op<_Args...> if that is a valid type, otherwise _Default. template class _Op, @@ -2604,8 +2764,6 @@ namespace std using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; - /// @} group metaprogramming - /** * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. @@ -2626,22 +2784,16 @@ namespace std template struct __is_nothrow_swappable; - template - class tuple; - template struct __is_tuple_like_impl : false_type { }; - template - struct __is_tuple_like_impl> : true_type - { }; - // Internal type trait that allows us to sfinae-protect tuple_cat. template struct __is_tuple_like : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type { }; + /// @endcond template _GLIBCXX20_CONSTEXPR @@ -2660,6 +2812,7 @@ namespace std swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(__is_nothrow_swappable<_Tp>::value); + /// @cond undocumented namespace __swappable_details { using std::swap; @@ -2690,14 +2843,14 @@ namespace std struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template @@ -2709,9 +2862,9 @@ namespace std struct __is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; + /// @endcond -#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 -#define __cpp_lib_is_swappable 201603 +#ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11 /// Metafunctions used for detecting swappable types: p0185r1 /// is_swappable @@ -2744,6 +2897,7 @@ namespace std is_nothrow_swappable<_Tp>::value; #endif // __cplusplus >= 201402L + /// @cond undocumented namespace __swappable_with_details { using std::swap; @@ -2778,7 +2932,7 @@ namespace std struct __is_swappable_with_impl : public __swappable_with_details::__do_is_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2786,14 +2940,14 @@ namespace std struct __is_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; template struct __is_nothrow_swappable_with_impl : public __swappable_with_details::__do_is_nothrow_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2801,20 +2955,31 @@ namespace std struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; + /// @endcond /// is_swappable_with template struct is_swappable_with : public __is_swappable_with_impl<_Tp, _Up>::type - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), + "first template argument must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "second template argument must be a complete class or an unbounded array"); + }; /// is_nothrow_swappable_with template struct is_nothrow_swappable_with : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), + "first template argument must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "second template argument must be a complete class or an unbounded array"); + }; #if __cplusplus >= 201402L /// is_swappable_with_v @@ -2828,14 +2993,20 @@ namespace std is_nothrow_swappable_with<_Tp, _Up>::value; #endif // __cplusplus >= 201402L -#endif// c++1z or gnu++11 +#endif // __cpp_lib_is_swappable + + /// @cond undocumented // __is_invocable (std::is_invocable for C++11) // The primary template is used for invalid INVOKE expressions. template::value, typename = void> - struct __is_invocable_impl : false_type { }; + struct __is_invocable_impl + : false_type + { + using __nothrow_conv = false_type; // For is_nothrow_invocable_r + }; // Used for valid INVOKE and INVOKE expressions. template @@ -2843,7 +3014,9 @@ namespace std /* is_void<_Ret> = */ true, __void_t> : true_type - { }; + { + using __nothrow_conv = true_type; // For is_nothrow_invocable_r + }; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" @@ -2855,23 +3028,39 @@ namespace std { private: // The type of the INVOKE expression. - // Unlike declval, this doesn't add_rvalue_reference. - static typename _Result::type _S_get(); + using _Res_t = typename _Result::type; + + // Unlike declval, this doesn't add_rvalue_reference, so it respects + // guaranteed copy elision. + static _Res_t _S_get() noexcept; + // Used to check if _Res_t can implicitly convert to _Tp. template - static void _S_conv(_Tp); + static void _S_conv(__type_identity_t<_Tp>) noexcept; // This overload is viable if INVOKE(f, args...) can convert to _Tp. - template(_S_get()))> - static true_type + template(_S_get())), + typename = decltype(_S_conv<_Tp>(_S_get())), +#if __has_builtin(__reference_converts_from_temporary) + bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t) +#else + bool _Dangle = false +#endif + > + static __bool_constant<_Nothrow && !_Dangle> _S_test(int); - template + template static false_type _S_test(...); public: - using type = decltype(_S_test<_Ret>(1)); + // For is_invocable_r + using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1)); + + // For is_nothrow_invocable_r + using __nothrow_conv = decltype(_S_test<_Ret>(1)); }; #pragma GCC diagnostic pop @@ -2941,15 +3130,20 @@ namespace std void operator=(__nonesuch const&) = delete; }; #pragma GCC diagnostic pop + /// @endcond -#if __cplusplus >= 201703L -# define __cpp_lib_is_invocable 201703 - +#ifdef __cpp_lib_is_invocable // C++ >= 17 /// std::invoke_result template struct invoke_result : public __invoke_result<_Functor, _ArgTypes...> - { }; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}), + "_Functor must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + }; /// std::invoke_result_t template @@ -2962,6 +3156,9 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); }; /// std::is_invocable_r @@ -2971,6 +3168,11 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), + "_Ret must be a complete class or an unbounded array"); }; /// std::is_nothrow_invocable @@ -2981,47 +3183,51 @@ namespace std { static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); }; - template - struct __is_nt_invocable_impl : false_type { }; - + /// @cond undocumented + // This checks that the INVOKE expression is well-formed and that the + // conversion to R does not throw. It does *not* check whether the INVOKE + // expression itself can throw. That is done by __call_is_nothrow_ instead. template - struct __is_nt_invocable_impl<_Result, _Ret, - __void_t> - : __or_, - __is_nothrow_convertible> - { }; + using __is_nt_invocable_impl + = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv; + /// @endcond /// std::is_nothrow_invocable_r template struct is_nothrow_invocable_r : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type - { }; - - /// std::is_invocable_v - template - inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; - - /// std::is_nothrow_invocable_v - template - inline constexpr bool is_nothrow_invocable_v - = is_nothrow_invocable<_Fn, _Args...>::value; - - /// std::is_invocable_r_v - template - inline constexpr bool is_invocable_r_v - = is_invocable_r<_Ret, _Fn, _Args...>::value; + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), + "_Fn must be a complete class or an unbounded array"); + static_assert((std::__is_complete_or_unbounded( + __type_identity<_ArgTypes>{}) && ...), + "each argument type must be a complete class or an unbounded array"); + static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), + "_Ret must be a complete class or an unbounded array"); + }; +#endif // __cpp_lib_is_invocable - /// std::is_nothrow_invocable_r_v - template - inline constexpr bool is_nothrow_invocable_r_v - = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; -#endif // C++17 +#if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /** + * @defgroup variable_templates Variable templates for type traits + * @ingroup metaprogramming + * + * Each variable `is_xxx_v` is a boolean constant with the same value + * as the `value` member of the corresponding type trait `is_xxx`. + * + * @since C++17 unless noted otherwise. + */ -#if __cplusplus >= 201703L -# define __cpp_lib_type_trait_variable_templates 201510L + /** + * @{ + * @ingroup variable_templates + */ template inline constexpr bool is_void_v = is_void<_Tp>::value; template @@ -3030,167 +3236,301 @@ template inline constexpr bool is_integral_v = is_integral<_Tp>::value; template inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) +template + inline constexpr bool is_array_v = __is_array(_Tp); +#else +template + inline constexpr bool is_array_v = false; template - inline constexpr bool is_array_v = is_array<_Tp>::value; + inline constexpr bool is_array_v<_Tp[]> = true; +template + inline constexpr bool is_array_v<_Tp[_Num]> = true; +#endif + template inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; template - inline constexpr bool is_lvalue_reference_v = - is_lvalue_reference<_Tp>::value; + inline constexpr bool is_lvalue_reference_v = false; +template + inline constexpr bool is_lvalue_reference_v<_Tp&> = true; +template + inline constexpr bool is_rvalue_reference_v = false; template - inline constexpr bool is_rvalue_reference_v = - is_rvalue_reference<_Tp>::value; + inline constexpr bool is_rvalue_reference_v<_Tp&&> = true; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) +template + inline constexpr bool is_member_object_pointer_v = + __is_member_object_pointer(_Tp); +#else template inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value; +#endif + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) +template + inline constexpr bool is_member_function_pointer_v = + __is_member_function_pointer(_Tp); +#else template inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value; +#endif + +template + inline constexpr bool is_enum_v = __is_enum(_Tp); template - inline constexpr bool is_enum_v = is_enum<_Tp>::value; + inline constexpr bool is_union_v = __is_union(_Tp); template - inline constexpr bool is_union_v = is_union<_Tp>::value; + inline constexpr bool is_class_v = __is_class(_Tp); +// is_function_v is defined below, after is_const_v. + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) +template + inline constexpr bool is_reference_v = __is_reference(_Tp); +#else template - inline constexpr bool is_class_v = is_class<_Tp>::value; + inline constexpr bool is_reference_v = false; template - inline constexpr bool is_function_v = is_function<_Tp>::value; + inline constexpr bool is_reference_v<_Tp&> = true; template - inline constexpr bool is_reference_v = is_reference<_Tp>::value; + inline constexpr bool is_reference_v<_Tp&&> = true; +#endif + template inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; template inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) +template + inline constexpr bool is_object_v = __is_object(_Tp); +#else template inline constexpr bool is_object_v = is_object<_Tp>::value; +#endif + template inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; template - inline constexpr bool is_compound_v = is_compound<_Tp>::value; + inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) +template + inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); +#else template inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; +#endif + template - inline constexpr bool is_const_v = is_const<_Tp>::value; + inline constexpr bool is_const_v = false; template - inline constexpr bool is_volatile_v = is_volatile<_Tp>::value; + inline constexpr bool is_const_v = true; + +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) template - inline constexpr bool is_trivial_v = is_trivial<_Tp>::value; + inline constexpr bool is_function_v = __is_function(_Tp); +#else template - inline constexpr bool is_trivially_copyable_v = - is_trivially_copyable<_Tp>::value; + inline constexpr bool is_function_v = !is_const_v; template - inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + inline constexpr bool is_function_v<_Tp&> = false; template - _GLIBCXX20_DEPRECATED("use is_standard_layout_v && is_trivial_v instead") - inline constexpr bool is_pod_v = is_pod<_Tp>::value; -#pragma GCC diagnostic pop + inline constexpr bool is_function_v<_Tp&&> = false; +#endif + +template + inline constexpr bool is_volatile_v = false; +template + inline constexpr bool is_volatile_v = true; + +template + inline constexpr bool is_trivial_v = __is_trivial(_Tp); +template + inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp); +template + inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp); template - inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value; + _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v") + inline constexpr bool is_pod_v = __is_pod(_Tp); template - inline constexpr bool is_empty_v = is_empty<_Tp>::value; + _GLIBCXX17_DEPRECATED + inline constexpr bool is_literal_type_v = __is_literal_type(_Tp); template - inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value; + inline constexpr bool is_empty_v = __is_empty(_Tp); template - inline constexpr bool is_abstract_v = is_abstract<_Tp>::value; + inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp); template - inline constexpr bool is_final_v = is_final<_Tp>::value; + inline constexpr bool is_abstract_v = __is_abstract(_Tp); +template + inline constexpr bool is_final_v = __is_final(_Tp); + template inline constexpr bool is_signed_v = is_signed<_Tp>::value; template inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; + template - inline constexpr bool is_constructible_v = - is_constructible<_Tp, _Args...>::value; + inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); template - inline constexpr bool is_default_constructible_v = - is_default_constructible<_Tp>::value; + inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); template - inline constexpr bool is_copy_constructible_v = - is_copy_constructible<_Tp>::value; + inline constexpr bool is_copy_constructible_v + = __is_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_move_constructible_v = - is_move_constructible<_Tp>::value; + inline constexpr bool is_move_constructible_v + = __is_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value; + inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up); template - inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; + inline constexpr bool is_copy_assignable_v + = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t); template - inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; + inline constexpr bool is_move_assignable_v + = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); + template inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; + template - inline constexpr bool is_trivially_constructible_v = - is_trivially_constructible<_Tp, _Args...>::value; + inline constexpr bool is_trivially_constructible_v + = __is_trivially_constructible(_Tp, _Args...); template - inline constexpr bool is_trivially_default_constructible_v = - is_trivially_default_constructible<_Tp>::value; + inline constexpr bool is_trivially_default_constructible_v + = __is_trivially_constructible(_Tp); template - inline constexpr bool is_trivially_copy_constructible_v = - is_trivially_copy_constructible<_Tp>::value; + inline constexpr bool is_trivially_copy_constructible_v + = __is_trivially_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_trivially_move_constructible_v = - is_trivially_move_constructible<_Tp>::value; + inline constexpr bool is_trivially_move_constructible_v + = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_trivially_assignable_v = - is_trivially_assignable<_Tp, _Up>::value; + inline constexpr bool is_trivially_assignable_v + = __is_trivially_assignable(_Tp, _Up); +template + inline constexpr bool is_trivially_copy_assignable_v + = __is_trivially_assignable(__add_lval_ref_t<_Tp>, + __add_lval_ref_t); template - inline constexpr bool is_trivially_copy_assignable_v = - is_trivially_copy_assignable<_Tp>::value; + inline constexpr bool is_trivially_move_assignable_v + = __is_trivially_assignable(__add_lval_ref_t<_Tp>, + __add_rval_ref_t<_Tp>); + +#if __cpp_concepts +template + inline constexpr bool is_trivially_destructible_v = false; + +template + requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); } + inline constexpr bool is_trivially_destructible_v<_Tp> + = __has_trivial_destructor(_Tp); template - inline constexpr bool is_trivially_move_assignable_v = - is_trivially_move_assignable<_Tp>::value; + inline constexpr bool is_trivially_destructible_v<_Tp&> = true; +template + inline constexpr bool is_trivially_destructible_v<_Tp&&> = true; +template + inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]> + = is_trivially_destructible_v<_Tp>; +#else template inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value; +#endif + template - inline constexpr bool is_nothrow_constructible_v = - is_nothrow_constructible<_Tp, _Args...>::value; + inline constexpr bool is_nothrow_constructible_v + = __is_nothrow_constructible(_Tp, _Args...); template - inline constexpr bool is_nothrow_default_constructible_v = - is_nothrow_default_constructible<_Tp>::value; + inline constexpr bool is_nothrow_default_constructible_v + = __is_nothrow_constructible(_Tp); template - inline constexpr bool is_nothrow_copy_constructible_v = - is_nothrow_copy_constructible<_Tp>::value; + inline constexpr bool is_nothrow_copy_constructible_v + = __is_nothrow_constructible(_Tp, __add_lval_ref_t); template - inline constexpr bool is_nothrow_move_constructible_v = - is_nothrow_move_constructible<_Tp>::value; + inline constexpr bool is_nothrow_move_constructible_v + = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>); + template - inline constexpr bool is_nothrow_assignable_v = - is_nothrow_assignable<_Tp, _Up>::value; + inline constexpr bool is_nothrow_assignable_v + = __is_nothrow_assignable(_Tp, _Up); template - inline constexpr bool is_nothrow_copy_assignable_v = - is_nothrow_copy_assignable<_Tp>::value; + inline constexpr bool is_nothrow_copy_assignable_v + = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, + __add_lval_ref_t); template - inline constexpr bool is_nothrow_move_assignable_v = - is_nothrow_move_assignable<_Tp>::value; + inline constexpr bool is_nothrow_move_assignable_v + = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); + template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; + template - inline constexpr bool has_virtual_destructor_v = - has_virtual_destructor<_Tp>::value; + inline constexpr bool has_virtual_destructor_v + = __has_virtual_destructor(_Tp); + template inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value; + +template + inline constexpr size_t rank_v = 0; +template + inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>; template - inline constexpr size_t rank_v = rank<_Tp>::value; + inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>; + template - inline constexpr size_t extent_v = extent<_Tp, _Idx>::value; -#ifdef _GLIBCXX_BUILTIN_IS_SAME_AS + inline constexpr size_t extent_v = 0; +template + inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size; +template + inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>; +template + inline constexpr size_t extent_v<_Tp[], 0> = 0; +template + inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>; + +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME template - inline constexpr bool is_same_v = _GLIBCXX_BUILTIN_IS_SAME_AS(_Tp, _Up); + inline constexpr bool is_same_v = __is_same(_Tp, _Up); #else template - inline constexpr bool is_same_v = std::is_same<_Tp, _Up>::value; + inline constexpr bool is_same_v = false; +template + inline constexpr bool is_same_v<_Tp, _Tp> = true; #endif template - inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value; + inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) +template + inline constexpr bool is_convertible_v = __is_convertible(_From, _To); +#else template inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; - -#ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP -# define __cpp_lib_has_unique_object_representations 201606 +#endif +template + inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; +template + inline constexpr bool is_nothrow_invocable_v + = is_nothrow_invocable<_Fn, _Args...>::value; +template + inline constexpr bool is_invocable_r_v + = is_invocable_r<_Ret, _Fn, _Args...>::value; +template + inline constexpr bool is_nothrow_invocable_r_v + = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; +/// @} +#endif // __cpp_lib_type_trait_variable_templates + +#ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP /// has_unique_object_representations + /// @since C++17 template struct has_unique_object_representations : bool_constant<__has_unique_object_representations( @@ -3201,49 +3541,78 @@ template "template argument must be a complete class or an unbounded array"); }; +# if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /// @ingroup variable_templates template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value; +# endif #endif -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE -# define __cpp_lib_is_aggregate 201703 - /// is_aggregate +#ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate + /// is_aggregate - true if the type is an aggregate. + /// @since C++17 template struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> { }; - /// is_aggregate_v +# if __cpp_lib_type_trait_variable_templates // C++ >= 17 + /** is_aggregate_v - true if the type is an aggregate. + * @ingroup variable_templates + * @since C++17 + */ template - inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value; + inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>); +# endif #endif -#endif // C++17 - -#if __cplusplus > 201703L -#define __cpp_lib_remove_cvref 201711L - /// Remove references and cv-qualifiers. + /** * Remove references and cv-qualifiers. + * @since C++20 + * @{ + */ +#ifdef __cpp_lib_remove_cvref // C++ >= 20 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref) template struct remove_cvref - { - using type = __remove_cvref_t<_Tp>; - }; + { using type = __remove_cvref(_Tp); }; +# else + template + struct remove_cvref + { using type = typename remove_cv<_Tp>::type; }; + + template + struct remove_cvref<_Tp&> + { using type = typename remove_cv<_Tp>::type; }; + + template + struct remove_cvref<_Tp&&> + { using type = typename remove_cv<_Tp>::type; }; +# endif template - using remove_cvref_t = __remove_cvref_t<_Tp>; + using remove_cvref_t = typename remove_cvref<_Tp>::type; + /// @} +#endif // __cpp_lib_remove_cvref -#define __cpp_lib_type_identity 201806L - /// Identity metafunction. +#ifdef __cpp_lib_type_identity // C++ >= 20 + /** * Identity metafunction. + * @since C++20 + * @{ + */ template struct type_identity { using type = _Tp; }; template using type_identity_t = typename type_identity<_Tp>::type; + /// @} +#endif -#define __cpp_lib_unwrap_ref 201811L - - /// Unwrap a reference_wrapper +#ifdef __cpp_lib_unwrap_ref // C++ >= 20 + /** Unwrap a reference_wrapper + * @since C++20 + * @{ + */ template struct unwrap_reference { using type = _Tp; }; @@ -3252,45 +3621,206 @@ template template using unwrap_reference_t = typename unwrap_reference<_Tp>::type; + /// @} - /// Decay type and if it's a reference_wrapper, unwrap it + /** Decay type and if it's a reference_wrapper, unwrap it + * @since C++20 + * @{ + */ template struct unwrap_ref_decay { using type = unwrap_reference_t>; }; template using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; + /// @} +#endif // __cpp_lib_unwrap_ref + +#ifdef __cpp_lib_bounded_array_traits // C++ >= 20 + /// True for a type that is an array of known bound. + /// @ingroup variable_templates + /// @since C++20 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array) + template + inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); +# else + template + inline constexpr bool is_bounded_array_v = false; + + template + inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true; +# endif -#define __cpp_lib_bounded_array_traits 201902L + /// True for a type that is an array of unknown bound. + /// @ingroup variable_templates + /// @since C++20 + template + inline constexpr bool is_unbounded_array_v = false; + + template + inline constexpr bool is_unbounded_array_v<_Tp[]> = true; /// True for a type that is an array of known bound. + /// @since C++20 template struct is_bounded_array - : public __is_array_known_bounds<_Tp> + : public bool_constant> { }; /// True for a type that is an array of unknown bound. + /// @since C++20 template struct is_unbounded_array - : public __is_array_unknown_bounds<_Tp> + : public bool_constant> + { }; +#endif // __cpp_lib_bounded_array_traits + +#if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L + + /// @since C++20 + template + struct is_layout_compatible + : bool_constant<__is_layout_compatible(_Tp, _Up)> + { }; + + /// @ingroup variable_templates + /// @since C++20 + template + constexpr bool is_layout_compatible_v + = __is_layout_compatible(_Tp, _Up); + +#if __has_builtin(__builtin_is_corresponding_member) +# ifndef __cpp_lib_is_layout_compatible +# error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set" +# endif + + /// @since C++20 + template + constexpr bool + is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept + { return __builtin_is_corresponding_member(__m1, __m2); } +#endif +#endif + +#if __has_builtin(__is_pointer_interconvertible_base_of) \ + && __cplusplus >= 202002L + /// True if `_Derived` is standard-layout and has a base class of type `_Base` + /// @since C++20 + template + struct is_pointer_interconvertible_base_of + : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> + { }; + + /// @ingroup variable_templates + /// @since C++20 + template + constexpr bool is_pointer_interconvertible_base_of_v + = __is_pointer_interconvertible_base_of(_Base, _Derived); + +#if __has_builtin(__builtin_is_pointer_interconvertible_with_class) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set" +# endif + + /// True if `__mp` points to the first member of a standard-layout type + /// @returns true if `s.*__mp` is pointer-interconvertible with `s` + /// @since C++20 + template + constexpr bool + is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept + { return __builtin_is_pointer_interconvertible_with_class(__mp); } +#endif +#endif + +#ifdef __cpp_lib_is_scoped_enum // C++ >= 23 + /// True if the type is a scoped enumeration type. + /// @since C++23 + +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) + template + struct is_scoped_enum + : bool_constant<__is_scoped_enum(_Tp)> + { }; +# else + template + struct is_scoped_enum + : false_type { }; template - inline constexpr bool is_bounded_array_v - = is_bounded_array<_Tp>::value; + requires __is_enum(_Tp) + && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete + struct is_scoped_enum<_Tp> + : bool_constant + { }; +# endif + /// @ingroup variable_templates + /// @since C++23 +# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) template - inline constexpr bool is_unbounded_array_v - = is_unbounded_array<_Tp>::value; + inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp); +# else + template + inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value; +# endif +#endif + +#ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp + /// True if _Tp is a reference type, a _Up value can be bound to _Tp in + /// direct-initialization, and a temporary object would be bound to + /// the reference, false otherwise. + /// @since C++23 + template + struct reference_constructs_from_temporary + : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) + && std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "template argument must be a complete class or an unbounded array"); + }; + + /// True if _Tp is a reference type, a _Up value can be bound to _Tp in + /// copy-initialization, and a temporary object would be bound to + /// the reference, false otherwise. + /// @since C++23 + template + struct reference_converts_from_temporary + : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> + { + static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) + && std::__is_complete_or_unbounded(__type_identity<_Up>{}), + "template argument must be a complete class or an unbounded array"); + }; -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED + /// @ingroup variable_templates + /// @since C++23 + template + inline constexpr bool reference_constructs_from_temporary_v + = reference_constructs_from_temporary<_Tp, _Up>::value; -#define __cpp_lib_is_constant_evaluated 201811L + /// @ingroup variable_templates + /// @since C++23 + template + inline constexpr bool reference_converts_from_temporary_v + = reference_converts_from_temporary<_Tp, _Up>::value; +#endif // __cpp_lib_reference_from_temporary +#ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL + /// Returns true only when called during constant evaluation. + /// @since C++20 constexpr inline bool is_constant_evaluated() noexcept - { return __builtin_is_constant_evaluated(); } + { +#if __cpp_if_consteval >= 202106L + if consteval { return true; } else { return false; } +#else + return __builtin_is_constant_evaluated(); +#endif + } #endif +#if __cplusplus >= 202002L + /// @cond undocumented template using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type; @@ -3306,11 +3836,17 @@ template template using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type; + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) + template + using __condres_cvref + = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; + // If A and B are both lvalue reference types, ... template - struct __common_ref_impl<_Xp&, _Yp&, - __void_t<__cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>>> - { using type = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; }; + struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>> + : enable_if>, + __condres_cvref<_Xp, _Yp>> + { }; // let C be remove_reference_t&& template @@ -3338,12 +3874,14 @@ template struct __common_ref_impl<_Xp&, _Yp&&> : __common_ref_impl<_Yp&&, _Xp&> { }; + /// @endcond template class _TQual, template class _UQual> struct basic_common_reference { }; + /// @cond undocumented template struct __xref { template using __type = __copy_cv<_Tp, _Up>; }; @@ -3362,6 +3900,7 @@ template remove_cvref_t<_Tp2>, __xref<_Tp1>::template __type, __xref<_Tp2>::template __type>::type; + /// @endcond template struct common_reference; @@ -3379,6 +3918,7 @@ template struct common_reference<_Tp0> { using type = _Tp0; }; + /// @cond undocumented template struct __common_reference_impl : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1> @@ -3448,9 +3988,13 @@ template void_t>> : public common_reference, _Rest...> { }; + /// @endcond #endif // C++2a + /// @} group metaprogramming + +_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11