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)13constexpr 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