Index: libcxx/include/__numeric/gcd_lcm.h =================================================================== --- libcxx/include/__numeric/gcd_lcm.h +++ libcxx/include/__numeric/gcd_lcm.h @@ -12,6 +12,10 @@ #include <__assert> #include <__config> +#if _LIBCPP_STD_VER >= 20 +# include <__algorithm/min.h> +# include <__bit/countr.h> +#endif #include <__type_traits/common_type.h> #include <__type_traits/is_integral.h> #include <__type_traits/is_same.h> @@ -49,13 +53,30 @@ _Result operator()(_Source __t) const noexcept { return __t; } }; - -template -_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN -_Tp __gcd(_Tp __m, _Tp __n) -{ +template +_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN _Tp __gcd(_Tp __m, _Tp __n) { static_assert((!is_signed<_Tp>::value), ""); +# if _LIBCPP_STD_VER >= 20 + if (__m == 0) + return __n; + if (__n == 0) + return __m; + + int __az = _VSTD::countr_zero(__m); + int __bz = _VSTD::countr_zero(__n); + int __shift = _VSTD::min(__az, __bz); + __m >>= __az, __n >>= __bz; + while (__m != 0) { + int __diff = __m - __n; + __n = _VSTD::min(__m, __n); + __m = __diff >= 0 ? __diff : -__diff; + int __m_shift = _VSTD::min(_VSTD::countr_zero(__m), _VSTD::numeric_limits<_Tp>::digits - 1); + __m >>= __m_shift; + } + return __n << __shift; +# else return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); +# endif } template Index: libcxx/test/libcxx/transitive_includes/cxx2b.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx2b.csv +++ libcxx/test/libcxx/transitive_includes/cxx2b.csv @@ -432,6 +432,7 @@ numbers version numeric cmath numeric cstddef +numeric initializer_list numeric limits numeric version optional compare