On Mon, 12 Jan 2026 at 15:12, Patrick Palka <[email protected]> wrote:
>
> (CCing libstdc++@)
>
> Could you resubmit this as a Git patch? See
> https://gcc.gnu.org/contribute.html#patches
Clang supports the built-in since 16.0.0 so I don't think we need to
care about the non-intrinsic case.
But this does seem simpler to read/maintain, so might be worth it for
that reason.
>
> On Fri, 2 Jan 2026, Bingzhi wrote:
>
> > Old code:
> > # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
> > template<typename _Tp>
> > struct is_scoped_enum
> > : bool_constant<__is_scoped_enum(_Tp)>
> > { };
> > # else
> > template<typename _Tp>
> > struct is_scoped_enum
> > : false_type
> > { };
> >
> > template<typename _Tp>
> > requires __is_enum(_Tp)
> > && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete
> > struct is_scoped_enum<_Tp>
> > : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
> > { };
> > # endif
> >
> > New code:
> > # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
> > template<typename _Tp>
> > struct is_scoped_enum
> > : bool_constant<__is_scoped_enum(_Tp)>
> > { };
> > # else
> > template<typename _Tp>
> > struct is_scoped_enum
> > : false_type
> > { };
> >
> > template<typename _Tp>
> > requires __is_enum(_Tp)
> > && requires { sizeof(_Tp); } // fails if incomplete
> > struct is_scoped_enum<_Tp>
> > : bool_constant<!requires(int __i) { __i = _Tp { }; }>
> > { };
> > # endif
> >
> > Easy to verify:
> > struct S { operator int() { return 4; } };
> > //enum E; // not legal.
> > enum E {};
> > enum Ei : int;
> > enum class CE;
> > enum U { Val = is_scoped_enum<U>::value };
> > static_assert(not is_scoped_enum<int*>::value);
> > static_assert(not is_scoped_enum<nullptr_t>::value);
> > static_assert(not is_scoped_enum<S>::value);
> > static_assert(not is_scoped_enum<E>::value);
> > static_assert(not is_scoped_enum<Ei>::value);
> > static_assert(is_scoped_enum<CE>::value);
> > static_assert(not is_scoped_enum<U>::value);
> >
> >