diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index eeab1ca65fc..1f8b57b04a0 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -3287,9 +3287,20 @@ template : false_type { }; - template requires __is_enum(_Tp) + template + requires __is_enum(_Tp) + && requires(_Tp __t) { __t = __t; } // fails if incomplete struct is_scoped_enum<_Tp> - : __not_>::type + : bool_constant + { }; + + // FIXME remove this partial specialization and use remove_cv_t<_Tp> above + // when PR c++/99968 is fixed. + template + requires __is_enum(_Tp) + && requires(_Tp __t) { __t = __t; } // fails if incomplete + struct is_scoped_enum + : bool_constant { }; template diff --git a/libstdc++-v3/testsuite/20_util/is_scoped_enum/value.cc b/libstdc++-v3/testsuite/20_util/is_scoped_enum/value.cc index bab7263ae4a..2cef857a042 100644 --- a/libstdc++-v3/testsuite/20_util/is_scoped_enum/value.cc +++ b/libstdc++-v3/testsuite/20_util/is_scoped_enum/value.cc @@ -32,6 +32,8 @@ template concept Is_scoped_enum = __gnu_test::test_category(true); +struct Incomplete_struct; + void test01() { @@ -45,6 +47,9 @@ test01() static_assert( ! Is_scoped_enum ); enum F : int { f1, f2 }; static_assert( ! Is_scoped_enum ); + static_assert( ! Is_scoped_enum ); + struct S; + static_assert( ! Is_scoped_enum ); struct S { }; static_assert( ! Is_scoped_enum ); @@ -60,3 +65,36 @@ test01() static_assert( ! Is_scoped_enum ); static_assert( ! Is_scoped_enum ); } + +enum opaque_unscoped : short; +enum class opaque_scoped; +enum class opaque_scoped_with_base : long; + +static_assert( ! Is_scoped_enum ); +static_assert( Is_scoped_enum ); +static_assert( Is_scoped_enum ); + +void +test02() +{ + enum unscoped { + u_is_enum = std::is_enum_v, + u_is_scoped = std::is_scoped_enum_v, + }; + static_assert( unscoped::u_is_enum ); + static_assert( ! unscoped::u_is_scoped ); + + enum unscoped_fixed : char { + uf_is_enum = std::is_enum_v, + uf_is_scoped = std::is_scoped_enum_v, + }; + static_assert( unscoped_fixed::uf_is_enum); + static_assert( ! unscoped_fixed::uf_is_scoped ); + + enum class scoped { + is_enum = std::is_enum_v, + is_scoped = std::is_scoped_enum_v, + }; + static_assert( (bool) scoped::is_enum ); + static_assert( (bool) scoped::is_scoped ); +}