Megatech


ulog2

#include <cstddef>

#include <concepts>
#include <stdexcept>
#include <limits>

template <std::unsigned_integral Type>
constexpr Type ulog2(const Type x) {
  if (!x)
  {
    throw std::domain_error{ "ulog2(0) is undefined." };
  }
  auto right = static_cast<std::size_t>(std::numeric_limits<Type>::digits - 1);
  for (auto left = std::size_t{ 0 }, middle = (right + left) >> 1; left <= right; middle = (right + left) >> 1)
  {
    if (x >> middle != 0)
    {
      left = middle + 1;
    }
    else
    {
      right = middle - 1;
    }
  }
  return right;
}