Hi, Here are the benchmarks for this change:
* is_fundamental https://github.com/ken-matsui/gcc-benches/blob/main/is_fundamental.md#fri-jul-14-091146-pm-pdt-2023 Time: -37.1619% Peak Memory Usage: -29.4294% Total Memory Usage: -29.4783% * is_fundamental_v https://github.com/ken-matsui/gcc-benches/blob/main/is_fundamental_v.md#fri-jul-14-091757-pm-pdt-2023 Time: -35.5446% Peak Memory Usage: -30.0096% Total Memory Usage: -30.6021% * is_fundamental with bool_constant (on trunk [18dac101678b8c0aed4bd995351e47f26cd54dec]) https://github.com/ken-matsui/gcc-benches/blob/main/is_fundamental-bool_constant.md#fri-jul-14-094237-pm-pdt-2023 Time: -28.3908% Peak Memory Usage: -18.5403% Total Memory Usage: -19.9045% --- It appears using bool_constant is better than disjunction. If my understanding is correct, disjunction can avoid later instantiations when short-circuiting, but might the evaluation of disjunction be more expensive than evaluating is_void and is_null_pointer? Or my benchmark might be just incorrect. Sincerely, Ken Matsui On Fri, Jul 14, 2023 at 9:57 PM Ken Matsui <kmat...@gcc.gnu.org> wrote: > > This patch optimizes the performance of the is_fundamental trait by > dispatching to the new __is_arithmetic built-in trait. > > libstdc++-v3/ChangeLog: > > * include/std/type_traits (is_fundamental_v): Use __is_arithmetic > built-in trait. > (is_fundamental): Likewise. Optimize the original implementation. > > Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org> > --- > libstdc++-v3/include/std/type_traits | 21 +++++++++++++++++---- > 1 file changed, 17 insertions(+), 4 deletions(-) > > diff --git a/libstdc++-v3/include/std/type_traits > b/libstdc++-v3/include/std/type_traits > index 7ebbe04c77b..cf24de2fcac 100644 > --- a/libstdc++-v3/include/std/type_traits > +++ b/libstdc++-v3/include/std/type_traits > @@ -668,11 +668,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > #endif > > /// is_fundamental > +#if __has_builtin(__is_arithmetic) > + template<typename _Tp> > + struct is_fundamental > + : public __bool_constant<__is_arithmetic(_Tp) > + || is_void<_Tp>::value > + || is_null_pointer<_Tp>::value> > + { }; > +#else > template<typename _Tp> > struct is_fundamental > - : public __or_<is_arithmetic<_Tp>, is_void<_Tp>, > - is_null_pointer<_Tp>>::type > + : public __bool_constant<is_arithmetic<_Tp>::value > + || is_void<_Tp>::value > + || is_null_pointer<_Tp>::value> > { }; > +#endif > > /// is_object > template<typename _Tp> > @@ -3209,13 +3219,16 @@ template <typename _Tp> > #if __has_builtin(__is_arithmetic) > template <typename _Tp> > inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp); > +template <typename _Tp> > + inline constexpr bool is_fundamental_v > + = __is_arithmetic(_Tp) || is_void_v<_Tp> || is_null_pointer_v<_Tp>; > #else > template <typename _Tp> > inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; > -#endif > - > template <typename _Tp> > inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; > +#endif > + > template <typename _Tp> > inline constexpr bool is_object_v = is_object<_Tp>::value; > template <typename _Tp> > -- > 2.41.0 >