diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 98c0eedca5a..06d9b5b1e2c 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -366,6 +366,15 @@ struct is_enum : bool_constant<__is_enum(_Ty)> {}; // determine whether _Ty is a template _INLINE_VAR constexpr bool is_enum_v = __is_enum(_Ty); +#if _HAS_CXX23 +// STRUCT TEMPLATE is_scoped_enum +template +inline constexpr bool is_scoped_enum_v = conjunction_v, negation>>; + +template +struct is_scoped_enum : bool_constant> {}; +#endif // _HAS_CXX23 + // STRUCT TEMPLATE is_compound template struct is_compound : bool_constant> {}; // determine whether _Ty is a compound type diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 3b2c62061be..92330516f20 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -255,6 +255,9 @@ // P1831R1 Deprecating volatile In The Standard Library // Other C++20 deprecation warnings +// _HAS_CXX23 directly controls: +// P1048R1 is_scoped_enum + // Parallel Algorithms Notes // C++ allows an implementation to implement parallel algorithms as calls to the serial algorithms. // This implementation parallelizes several common algorithm calls, but not all. @@ -1335,6 +1338,11 @@ #define __cpp_lib_coroutine 201902L #endif // __cpp_impl_coroutine +// C++23 +#if _HAS_CXX23 +#define __cpp_lib_is_scoped_enum 202011L +#endif // _HAS_CXX23 + // EXPERIMENTAL #define __cpp_lib_experimental_erase_if 201411L #define __cpp_lib_experimental_filesystem 201406L diff --git a/tests/std/tests/VSO_0000000_instantiate_type_traits/test.compile.pass.cpp b/tests/std/tests/VSO_0000000_instantiate_type_traits/test.compile.pass.cpp index d24186ddee6..657446e624a 100644 --- a/tests/std/tests/VSO_0000000_instantiate_type_traits/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0000000_instantiate_type_traits/test.compile.pass.cpp @@ -174,6 +174,9 @@ void type_traits_test_impl() { TRAIT_V(is_bounded_array, T); TRAIT_V(is_unbounded_array, T); #endif // _HAS_CXX20 +#if _HAS_CXX23 + TRAIT_V(is_scoped_enum, T); +#endif // _HAS_CXX23 TRAIT_V(rank, T); TRAIT_V(extent, T); TRAIT_V(is_same, T, U); // from xtr1common diff --git a/tests/std/tests/VSO_0000000_type_traits/test.cpp b/tests/std/tests/VSO_0000000_type_traits/test.cpp index a623fb02c73..29365e4298c 100644 --- a/tests/std/tests/VSO_0000000_type_traits/test.cpp +++ b/tests/std/tests/VSO_0000000_type_traits/test.cpp @@ -76,6 +76,9 @@ STATIC_ASSERT(!is_unsigned_v); STATIC_ASSERT(!is_bounded_array_v); STATIC_ASSERT(!is_unbounded_array_v); #endif // _HAS_CXX20 +#if _HAS_CXX23 +STATIC_ASSERT(!is_scoped_enum_v); +#endif // _HAS_CXX23 STATIC_ASSERT(!is_constructible_v); STATIC_ASSERT(!is_default_constructible_v); @@ -629,6 +632,10 @@ void test_function_type() { STATIC_ASSERT(!is_bounded_array_v); STATIC_ASSERT(!is_unbounded_array_v); #endif // _HAS_CXX20 + +#if _HAS_CXX23 + STATIC_ASSERT(!is_scoped_enum_v); +#endif } template @@ -851,6 +858,16 @@ enum LLEnum : long long { xLongExample, yLongExample }; enum class ExampleEnumClass { xExample, yExample }; enum class LLEnumClass : long long { xLongExample, yLongExample }; +#if _HAS_CXX23 +STATIC_ASSERT(!is_scoped_enum::value); +STATIC_ASSERT(!is_scoped_enum_v); +STATIC_ASSERT(!is_scoped_enum_v); +STATIC_ASSERT(is_scoped_enum_v); +STATIC_ASSERT(is_scoped_enum_v); +enum E { e = is_scoped_enum_v }; +static_assert(!e, "is_scoped_enum of an incomplete unscoped enum type is true"); +#endif // _HAS_CXX23 + // P0258R2 has_unique_object_representations #if _HAS_CXX17 STATIC_ASSERT(!has_unique_object_representations_v); diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 59223c25fc3..0da859a6bf9 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -955,6 +955,20 @@ STATIC_ASSERT(__cpp_lib_is_pointer_interconvertible == 201907L); #endif #endif +#if _HAS_CXX23 +#ifndef __cpp_lib_is_scoped_enum +#error __cpp_lib_is_scoped_enum is not defined +#elif __cpp_lib_is_scoped_enum != 202011L +#error __cpp_lib_is_scoped_enum is not 202011L +#else +STATIC_ASSERT(__cpp_lib_is_scoped_enum == 202011L); +#endif +#else +#ifdef __cpp_lib_is_scoped_enum +#error __cpp_lib_is_scoped_enum is defined +#endif +#endif + #if _HAS_CXX17 #ifndef __cpp_lib_is_swappable #error __cpp_lib_is_swappable is not defined