Index: libcxx/include/__bit/countr.h =================================================================== --- libcxx/include/__bit/countr.h +++ libcxx/include/__bit/countr.h @@ -32,10 +32,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } -#if _LIBCPP_STD_VER >= 20 - -template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero(_Tp __t) noexcept { if (__t == 0) return numeric_limits<_Tp>::digits; @@ -56,6 +54,13 @@ } } +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { + return __countr_zero(__t); +} + template <__libcpp_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; Index: libcxx/include/__numeric/gcd_lcm.h =================================================================== --- libcxx/include/__numeric/gcd_lcm.h +++ libcxx/include/__numeric/gcd_lcm.h @@ -10,7 +10,9 @@ #ifndef _LIBCPP___NUMERIC_GCD_LCM_H #define _LIBCPP___NUMERIC_GCD_LCM_H +#include <__algorithm/min.h> #include <__assert> +#include <__bit/countr.h> #include <__config> #include <__type_traits/common_type.h> #include <__type_traits/is_integral.h> @@ -49,13 +51,26 @@ _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 __a, _Tp __b) { static_assert((!is_signed<_Tp>::value), ""); - return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); + if (__a == 0) + return __b; + if (__b == 0) + return __a; + + int __az = std::__countr_zero(__a); + int __bz = std::__countr_zero(__b); + int __shift = std::min(__az, __bz); + __b >>= __bz; + while (__a != 0) { + __a >>= __az; + _Tp __absdiff = __a > __b ? __a - __b : __b - __a; + __b = std::min(__a, __b); + __a = __absdiff; + __az = std::__countr_zero(__absdiff); + } + return __b << __shift; } template Index: libcxx/test/libcxx/transitive_includes/cxx23.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx23.csv +++ libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -399,6 +399,7 @@ numbers version numeric cmath numeric cstddef +numeric initializer_list numeric limits numeric version optional compare Index: libcxx/test/libcxx/transitive_includes/cxx26.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx26.csv +++ libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -188,6 +188,27 @@ experimental/utility utility experimental/vector experimental/memory_resource experimental/vector vector +ext/hash_map algorithm +ext/hash_map cmath +ext/hash_map cstddef +ext/hash_map cstdint +ext/hash_map cstring +ext/hash_map functional +ext/hash_map initializer_list +ext/hash_map limits +ext/hash_map new +ext/hash_map stdexcept +ext/hash_map string +ext/hash_set algorithm +ext/hash_set cmath +ext/hash_set cstddef +ext/hash_set cstdint +ext/hash_set cstring +ext/hash_set functional +ext/hash_set initializer_list +ext/hash_set limits +ext/hash_set new +ext/hash_set string filesystem compare filesystem cstddef filesystem cstdint @@ -399,6 +420,7 @@ numbers version numeric cmath numeric cstddef +numeric initializer_list numeric limits numeric version optional compare