| 55 | // Note that all returned indices are 1-based, not 0-based. |
| 56 | template<typename T> |
| 57 | [[nodiscard]] |
| 58 | constexpr int FindFirstSetBit(T value) noexcept { |
| 59 | static_assert(std::is_unsigned_v<T>, "Type must be unsigned."); |
| 60 | |
| 61 | if (value == 0) { |
| 62 | return 0; |
| 63 | } |
| 64 | |
| 65 | const int trailing_zeroes = std::countr_zero(value); |
| 66 | return trailing_zeroes + 1; |
| 67 | } |
| 68 | |
| 69 | // Stand-in for std::bit_cast until libc++ implements it. |
| 70 | template<typename To, typename From> |