[libc++] Use __libcpp_clz for a tighter __log2i function · llvm/llvm-project@865ad6b (original) (raw)

File tree

1 file changed

lines changed

1 file changed

lines changed

Original file line number Diff line number Diff line change
@@ -14,8 +14,10 @@
14 14 #include <__algorithm/min_element.h>
15 15 #include <__algorithm/partial_sort.h>
16 16 #include <__algorithm/unwrap_iter.h>
17 +#include <__bits>
17 18 #include <__config>
18 19 #include <__utility/swap.h>
20 +#include <climits>
19 21 #include <memory>
20 22
21 23 #if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
@@ -498,6 +500,15 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
498 500
499 501 template <typename _Number>
500 502 inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
503 +if (__n == 0)
504 +return 0;
505 +if (sizeof(__n) <= sizeof(unsigned))
506 +return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned>(__n));
507 +if (sizeof(__n) <= sizeof(unsigned long))
508 +return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long>(__n));
509 +if (sizeof(__n) <= sizeof(unsigned long long))
510 +return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long long>(__n));
511 +
501 512 _Number __log2 = 0;
502 513 while (__n > 1) {
503 514 __log2++;