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/max.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,7 +53,28 @@ _Result operator()(_Source __t) const noexcept { return __t; } }; - +# if _LIBCPP_STD_VER >= 20 +template +_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN _Tp __gcd(_Tp __m, _Tp __n) { + static_assert((!is_signed<_Tp>::value), ""); + if (__m == 0) + return __n; + if (__n == 0) + return __m; + + int __az = countr_zero(__m); + int __bz = countr_zero(__n); + int __shift = min(__az, __bz); + __m >>= __az, __n >>= __bz; + while (__m != 0) { + int diff = __m - __n; + __n = min(__m, __n); + __m = abs(diff); + __m >>= countr_zero(__m); + } + return __n << __shift; +} +# else template _LIBCPP_CONSTEXPR _LIBCPP_HIDDEN _Tp __gcd(_Tp __m, _Tp __n) @@ -57,6 +82,7 @@ static_assert((!is_signed<_Tp>::value), ""); return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); } +# endif template _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY