1 #pragma once
2 
3 #include <limits>
4 #include <type_traits>
5 #ifdef _MSC_VER
6 #include <intrin.h>
7 #endif
8 
9 namespace std20 {
10 
11 // A simple (and not very correct) implementation of C++20's std::log2p1
12 template <class T>
log2p1(T x)13 constexpr T log2p1(T x) noexcept {
14     static_assert(std::is_integral_v<T> && std::is_unsigned_v<T>);
15     if (x == 0)
16         return 0;
17 #ifdef _MSC_VER
18     unsigned long index = 0;
19     _BitScanReverse64(&index, x);
20     return static_cast<T>(index) + 1;
21 #else
22     return static_cast<T>(std::numeric_limits<unsigned long long>::digits - __builtin_clzll(x));
23 #endif
24 }
25 
26 } // namespace std20
27