From cfa322fa9a693d4ba652871fafc6dbb2039b55a2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 13 Apr 2025 09:45:18 +0800 Subject: [PATCH] [libc++][NFC] Reuse `__bit_log2` for `sort` (#135303) The `__log2i` function template in `` is basically equivalent to `__bit_log2` in `<__bit/bit_log2.h>`. It seems better to avoid duplication. --- libcxx/include/__algorithm/sort.h | 23 +++-------------------- libcxx/include/__bit/bit_log2.h | 6 +----- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h index 4332b62544b4..d7bc1381ba5e 100644 --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -17,6 +17,7 @@ #include <__algorithm/partial_sort.h> #include <__algorithm/unwrap_iter.h> #include <__assert> +#include <__bit/bit_log2.h> #include <__bit/blsr.h> #include <__bit/countl.h> #include <__bit/countr.h> @@ -34,6 +35,7 @@ #include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_same.h> #include <__type_traits/is_trivially_copyable.h> +#include <__type_traits/make_unsigned.h> #include <__utility/move.h> #include <__utility/pair.h> #include @@ -826,25 +828,6 @@ void __introsort(_RandomAccessIterator __first, } } -template -inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { - if (__n == 0) - return 0; - if (sizeof(__n) <= sizeof(unsigned)) - return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); - if (sizeof(__n) <= sizeof(unsigned long)) - return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); - if (sizeof(__n) <= sizeof(unsigned long long)) - return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); - - _Number __log2 = 0; - while (__n > 1) { - __log2++; - __n >>= 1; - } - return __log2; -} - template void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp); @@ -878,7 +861,7 @@ template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __depth_limit = 2 * std::__log2i(__last - __first); + difference_type __depth_limit = 2 * std::__bit_log2(std::__to_unsigned_like(__last - __first)); // Only use bitset partitioning for arithmetic types. We should also check // that the default comparator is in use so that we are sure that there are no diff --git a/libcxx/include/__bit/bit_log2.h b/libcxx/include/__bit/bit_log2.h index 94ee6c3b2bb1..b22e1ce1f84e 100644 --- a/libcxx/include/__bit/bit_log2.h +++ b/libcxx/include/__bit/bit_log2.h @@ -20,16 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if _LIBCPP_STD_VER >= 14 - template -_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT { static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__bit_log2 requires an unsigned integer type"); return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t); } -#endif // _LIBCPP_STD_VER >= 14 - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___BIT_BIT_LOG2_H