From 36b02c6de553f95671dc08062e68ade1facc86eb Mon Sep 17 00:00:00 2001 From: Daniel Marshall Date: Wed, 2 Jun 2021 11:31:20 +0100 Subject: [PATCH 1/7] Implement is_scoped_enum --- stl/inc/type_traits | 16 ++++++++++++++-- stl/inc/yvals_core.h | 5 +++++ .../test.compile.pass.cpp | 3 +++ tests/std/tests/VSO_0000000_type_traits/test.cpp | 7 +++++++ .../test.compile.pass.cpp | 14 ++++++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 98c0eedca5..567b7576b3 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -366,6 +366,18 @@ 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 , negation>>> +inline constexpr bool is_scoped_enum_v = true; + +template +inline constexpr bool is_scoped_enum_v<_Ty, false> = false; + +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 @@ -1705,8 +1717,8 @@ struct _Invoke_traits_nonzero { }; template -using _Decltype_invoke_nonzero = decltype( - _Invoker1<_Callable, _Ty1>::_Call(_STD declval<_Callable>(), _STD declval<_Ty1>(), _STD declval<_Types2>()...)); +using _Decltype_invoke_nonzero = decltype(_Invoker1<_Callable, _Ty1>::_Call( + _STD declval<_Callable>(), _STD declval<_Ty1>(), _STD declval<_Types2>()...)); template struct _Invoke_traits_nonzero>, _Callable, _Ty1, diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 3b2c62061b..72ea3806f6 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1335,6 +1335,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 d24186ddee..657446e624 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 a623fb02c7..373de4d0af 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 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 59223c25fc..0da859a6bf 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 From 696c5360f09396f311e634f1a4d02115507db9ad Mon Sep 17 00:00:00 2001 From: Daniel Marshall Date: Wed, 2 Jun 2021 12:29:46 +0100 Subject: [PATCH 2/7] Small changes * Simplify is_scoped_enum_v thanks to miscco. * Add missing yvals_core.h macro comment. * Format with clang-format 11. --- stl/inc/type_traits | 9 +++------ stl/inc/yvals_core.h | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 567b7576b3..06d9b5b1e2 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -368,11 +368,8 @@ _INLINE_VAR constexpr bool is_enum_v = __is_enum(_Ty); #if _HAS_CXX23 // STRUCT TEMPLATE is_scoped_enum -template , negation>>> -inline constexpr bool is_scoped_enum_v = true; - template -inline constexpr bool is_scoped_enum_v<_Ty, false> = false; +inline constexpr bool is_scoped_enum_v = conjunction_v, negation>>; template struct is_scoped_enum : bool_constant> {}; @@ -1717,8 +1714,8 @@ struct _Invoke_traits_nonzero { }; template -using _Decltype_invoke_nonzero = decltype(_Invoker1<_Callable, _Ty1>::_Call( - _STD declval<_Callable>(), _STD declval<_Ty1>(), _STD declval<_Types2>()...)); +using _Decltype_invoke_nonzero = decltype( + _Invoker1<_Callable, _Ty1>::_Call(_STD declval<_Callable>(), _STD declval<_Ty1>(), _STD declval<_Types2>()...)); template struct _Invoke_traits_nonzero>, _Callable, _Ty1, diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 72ea3806f6..13779d9113 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. From 62c430ff41777a195edcfd84af69341c24d11ef7 Mon Sep 17 00:00:00 2001 From: Daniel Marshall Date: Wed, 2 Jun 2021 19:16:59 +0100 Subject: [PATCH 3/7] Add some test cases. --- tests/std/tests/VSO_0000000_type_traits/test.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/std/tests/VSO_0000000_type_traits/test.cpp b/tests/std/tests/VSO_0000000_type_traits/test.cpp index 373de4d0af..f36137fad4 100644 --- a/tests/std/tests/VSO_0000000_type_traits/test.cpp +++ b/tests/std/tests/VSO_0000000_type_traits/test.cpp @@ -858,6 +858,13 @@ 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); +#endif //_HAS_CXX23 + // P0258R2 has_unique_object_representations #if _HAS_CXX17 STATIC_ASSERT(!has_unique_object_representations_v); From a18b27ed292a0a317be2897c0f6dc675e058f283 Mon Sep 17 00:00:00 2001 From: Daniel Marshall Date: Thu, 3 Jun 2021 09:33:25 +0100 Subject: [PATCH 4/7] Add space in comment Co-authored-by: Stephan T. Lavavej --- stl/inc/yvals_core.h | 2 +- tests/std/tests/VSO_0000000_type_traits/test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 13779d9113..92330516f2 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1341,7 +1341,7 @@ // C++23 #if _HAS_CXX23 #define __cpp_lib_is_scoped_enum 202011L -#endif //_HAS_CXX23 +#endif // _HAS_CXX23 // EXPERIMENTAL #define __cpp_lib_experimental_erase_if 201411L diff --git a/tests/std/tests/VSO_0000000_type_traits/test.cpp b/tests/std/tests/VSO_0000000_type_traits/test.cpp index f36137fad4..c6407fff55 100644 --- a/tests/std/tests/VSO_0000000_type_traits/test.cpp +++ b/tests/std/tests/VSO_0000000_type_traits/test.cpp @@ -863,7 +863,7 @@ STATIC_ASSERT(!is_scoped_enum::value); STATIC_ASSERT(!is_scoped_enum_v); STATIC_ASSERT(is_scoped_enum_v); STATIC_ASSERT(is_scoped_enum_v); -#endif //_HAS_CXX23 +#endif // _HAS_CXX23 // P0258R2 has_unique_object_representations #if _HAS_CXX17 From 12f939a9a87a8c6ca4110179b29ae3fcdd5dc794 Mon Sep 17 00:00:00 2001 From: Daniel Marshall Date: Thu, 3 Jun 2021 09:38:05 +0100 Subject: [PATCH 5/7] One more test case. --- tests/std/tests/VSO_0000000_type_traits/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/VSO_0000000_type_traits/test.cpp b/tests/std/tests/VSO_0000000_type_traits/test.cpp index c6407fff55..c4b71fd774 100644 --- a/tests/std/tests/VSO_0000000_type_traits/test.cpp +++ b/tests/std/tests/VSO_0000000_type_traits/test.cpp @@ -861,6 +861,7 @@ 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); #endif // _HAS_CXX23 From 834c67738baffeab7c1dcc4bd5a5291676ed7c09 Mon Sep 17 00:00:00 2001 From: Daniel Marshall Date: Thu, 10 Jun 2021 08:40:20 +0100 Subject: [PATCH 6/7] Add a test for edge case. --- tests/std/tests/VSO_0000000_type_traits/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/VSO_0000000_type_traits/test.cpp b/tests/std/tests/VSO_0000000_type_traits/test.cpp index c4b71fd774..93be20f08d 100644 --- a/tests/std/tests/VSO_0000000_type_traits/test.cpp +++ b/tests/std/tests/VSO_0000000_type_traits/test.cpp @@ -864,6 +864,8 @@ 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 = std::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 From f95529a3e7460bcca03d4796384462e775673feb Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 10 Jun 2021 17:58:22 -0700 Subject: [PATCH 7/7] Remove unnecessary qualification. --- tests/std/tests/VSO_0000000_type_traits/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/VSO_0000000_type_traits/test.cpp b/tests/std/tests/VSO_0000000_type_traits/test.cpp index 93be20f08d..29365e4298 100644 --- a/tests/std/tests/VSO_0000000_type_traits/test.cpp +++ b/tests/std/tests/VSO_0000000_type_traits/test.cpp @@ -864,7 +864,7 @@ 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 = std::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