12#ifndef BOTAN_BIT_OPS_H_
13#define BOTAN_BIT_OPS_H_
15#include <botan/types.h>
17#include <botan/compiler.h>
18#include <botan/internal/bswap.h>
27 requires(std::is_integral<T>::value)
29 return static_cast<T>(0) - (a >> (
sizeof(
T) * 8 - 1));
37 requires(std::is_integral<T>::value)
49 requires(std::is_unsigned<T>::value)
51 return (arg != 0) && (arg != 1) && ((arg &
static_cast<T>(arg - 1)) == 0);
62 requires(std::is_unsigned<T>::value)
66 for(
size_t s = 8 *
sizeof(
T) / 2; s > 0; s /= 2) {
67 const size_t z = s * ((~ct_is_zero(n >> s)) & 1);
84 requires(std::is_integral<T>::value)
88 for(
size_t s = 8 *
sizeof(n) / 2; s >= 8; s /= 2) {
89 const size_t z = s * (~ct_is_zero(n >> s) & 1);
105inline constexpr size_t ctz(
T n)
106 requires(std::is_integral<T>::value)
114 for(
size_t s = 8 *
sizeof(
T) / 2; s > 0; s /= 2) {
115 const T mask = (
static_cast<T>(1) << s) - 1;
116 const size_t z = s * (
ct_is_zero(n & mask) & 1);
126 requires(std::is_unsigned<T>::value)
134 requires(std::is_integral<T>::value &&
sizeof(
T) < 32)
136 if(x >> (
sizeof(
T) * 8 - 1)) {
137 return sizeof(
T) * 8;
159template <std::
unsigned_
integral T>
161 return (a +
b - 1) /
b;
169 requires(std::is_integral<T>::value)
171 return (bits + 7) / 8;
176#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_ctz)
180 return __builtin_ctz(n);
192 const T swap = ((x >> shift) ^ x) & mask;
193 return (x ^ swap) ^ (swap << shift);
198 const T swap = ((x >> shift) ^ y) & mask;
206 return (
b ^ (mask & (a ^
b)));
226template <std::
unsigned_
integral T>
228 auto extend = [](uint8_t m) ->
T {
230 for(
size_t i = 0; i <
sizeof(
T); ++i) {
231 mask |=
T(m) << i * 8;
238 b = (
b & extend(0xF0)) >> 4 | (
b & extend(0x0F)) << 4;
239 b = (
b & extend(0xCC)) >> 2 | (
b & extend(0x33)) << 2;
240 b = (
b & extend(0xAA)) >> 1 | (
b & extend(0x55)) << 1;
260template <std::
unsigned_
integral T>
262 constexpr size_t s =
sizeof(
T);
263 static_assert(s <= 8,
"T is not a suitable unsigned integer value");
264 if constexpr(s == 8) {
265 x = x - ((x >> 1) & 0x5555555555555555);
266 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
267 x = (x + (x >> 4)) & 0xF0F0F0F0F0F0F0F;
268 return (x * 0x101010101010101) >> 56;
269 }
else if constexpr(s == 4) {
270 x = x - ((x >> 1) & 0x55555555);
271 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
272 x = (x + (x >> 4)) & 0x0F0F0F0F;
273 return (x * 0x01010101) >> 24;
#define BOTAN_ARG_CHECK(expr, msg)
constexpr bool is_power_of_2(T arg)
constexpr T ct_reverse_bits(T b)
constexpr size_t var_ctz32(uint32_t n)
constexpr T choose(T mask, T a, T b)
constexpr size_t high_bit(T n)
constexpr T floor_log2(T n)
constexpr void swap_bits(T &x, T &y, T mask, size_t shift)
constexpr T reverse_bytes(T x)
constexpr T ceil_division(T a, T b)
constexpr size_t ctz(T n)
constexpr T majority(T a, T b, T c)
constexpr T ceil_tobytes(T bits)
constexpr T ct_is_zero(T x)
constexpr size_t significant_bytes(T n)
constexpr uint8_t ceil_log2(T x)
constexpr T expand_top_bit(T a)
constexpr T bit_permute_step(T x, T mask, size_t shift)
constexpr uint8_t ct_popcount(T x)