7#include "utility/module.hpp"
13namespace hi::inline
v1 {
22template<
size_t BitsPerInteger,
size_t N>
34 static_assert(
sizeof(
unsigned long long) >= store_size);
43 std::conditional_t<
sizeof(
unsigned char) >=
store_size,
unsigned char,
44 std::conditional_t<
sizeof(
unsigned short) >=
store_size,
unsigned short,
45 std::conditional_t<
sizeof(
unsigned int) >=
store_size,
unsigned int,
46 std::conditional_t<
sizeof(
unsigned long) >=
store_size,
unsigned long,
47 unsigned long long>>>>;
55 template<std::integral... Args>
60 [[nodiscard]]
constexpr size_t size() const noexcept
79 hilet byte_offset = offset / CHAR_BIT;
80 hilet bit_offset = offset % CHAR_BIT;
100 constexpr size_t byte_offset = offset / CHAR_BIT;
101 constexpr size_t bit_offset = offset % CHAR_BIT;
103 return (
load<value_type>(rhs._v.data() + byte_offset) >> bit_offset) & mask;
107 constexpr static size_t total_num_bits = bits_per_integer * N;
108 constexpr static size_t total_num_bytes = (total_num_bits + CHAR_BIT - 1) / CHAR_BIT;
109 constexpr static size_t mask = (1_uz << bits_per_integer) - 1;
120 template<std::integral... Args>
121 [[nodiscard]]
constexpr static array_type make_v(Args... args)
noexcept
123 static_assert(
sizeof...(Args) == N);
125 auto r = array_type{};
128 for (
auto i = 0_uz; i != N; ++i) {
129 hilet offset = i * bits_per_integer;
130 hilet byte_offset = offset / CHAR_BIT;
131 hilet bit_offset = offset % CHAR_BIT;
133 hilet arg = args_[i];
135 store_or(arg << bit_offset, r.data() + byte_offset);
142template<
size_t BitsPerInteger, std::unsigned_integral... Args>
143packed_int_array(Args...) -> packed_int_array<BitsPerInteger,
sizeof...(Args)>;
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
constexpr T ceil(T value, T alignment) noexcept
The smallest multiple of alignment greater than or equal to value.
Definition math.hpp:127
constexpr T unaligned_load(B const *src) noexcept
Make an unaligned load of an unsigned integer.
Definition memory.hpp:267
constexpr T load(T const *src) noexcept
Load a numeric value from memory.
Definition endian.hpp:146
constexpr size_t size() const noexcept
The number of integers stored in the array.
Definition packed_int_array.hpp:60
constexpr value_type operator[](size_t i) const noexcept
Get the integer at an index.
Definition packed_int_array.hpp:74
std::conditional_t< sizeof(unsigned char) >=store_size, unsigned char, std::conditional_t< sizeof(unsigned short) >=store_size, unsigned short, std::conditional_t< sizeof(unsigned int) >=store_size, unsigned int, std::conditional_t< sizeof(unsigned long) >=store_size, unsigned long, unsigned long long > > > > value_type
The value type of the unsigned integers that are stored in the array.
Definition packed_int_array.hpp:42
static constexpr size_t bits_per_integer
Number of bits of the unsigned integer.
Definition packed_int_array.hpp:27
constexpr packed_int_array(Args... args) noexcept
Constructor of the array.
Definition packed_int_array.hpp:56
friend constexpr value_type get(packed_int_array const &rhs) noexcept
Get the integer at an index.
Definition packed_int_array.hpp:96
static constexpr size_t store_size
Number of bytes required to hold the number of bits.
Definition packed_int_array.hpp:33