HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
packed_int_array.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "utility.hpp"
8#include "memory.hpp"
9#include "math.hpp"
10#include <cstddef>
11#include <climits>
12#include <concepts>
13#include <array>
14
15namespace hi::inline v1 {
16
24template<size_t BitsPerInteger, size_t N>
26public:
29 constexpr static size_t bits_per_integer = BitsPerInteger;
30
35 constexpr static size_t store_size = ceil(bits_per_integer + CHAR_BIT - 1, size_t{CHAR_BIT}) / size_t{CHAR_BIT};
36 static_assert(sizeof(unsigned long long) >= store_size);
37
38 // clang-format off
44 using value_type =
45 std::conditional_t<sizeof(unsigned char) >= store_size, unsigned char,
46 std::conditional_t<sizeof(unsigned short) >= store_size, unsigned short,
47 std::conditional_t<sizeof(unsigned int) >= store_size, unsigned int,
48 std::conditional_t<sizeof(unsigned long) >= store_size, unsigned long,
49 unsigned long long>>>>;
50 // clang-format on
51
52
57 template<std::integral... Args>
58 constexpr packed_int_array(Args... args) noexcept : _v(make_v(args...)) {}
59
62 [[nodiscard]] constexpr size_t size() const noexcept
63 {
64 return N;
65 }
66
76 [[nodiscard]] constexpr value_type operator[](size_t i) const noexcept
77 {
78 hi_axiom(i < N);
79
80 hilet offset = i * bits_per_integer;
81 hilet byte_offset = offset / CHAR_BIT;
82 hilet bit_offset = offset % CHAR_BIT;
83
84 return (load<value_type>(_v.data() + byte_offset) >> bit_offset) & mask;
85 }
86
97 template<size_t I>
98 [[nodiscard]] friend constexpr value_type get(packed_int_array const &rhs) noexcept
99 {
100 static_assert(I < N);
101 constexpr size_t offset = I * bits_per_integer;
102 constexpr size_t byte_offset = offset / CHAR_BIT;
103 constexpr size_t bit_offset = offset % CHAR_BIT;
104
105 return (load<value_type>(rhs._v.data() + byte_offset) >> bit_offset) & mask;
106 }
107
108private:
109 constexpr static size_t total_num_bits = bits_per_integer * N;
110 constexpr static size_t total_num_bytes = (total_num_bits + CHAR_BIT - 1) / CHAR_BIT;
111 constexpr static size_t mask = (1_uz << bits_per_integer) - 1;
112
113 using array_type = std::array<uint8_t, total_num_bytes>;
114
115 array_type _v;
116
122 template<std::integral... Args>
123 [[nodiscard]] constexpr static array_type make_v(Args... args) noexcept
124 {
125 static_assert(sizeof...(Args) == N);
126
127 auto r = array_type{};
128
129 hilet args_ = std::array<value_type, N>{narrow_cast<value_type>(args)...};
130 for (auto i = 0_uz; i != N; ++i) {
131 hilet offset = i * bits_per_integer;
132 hilet byte_offset = offset / CHAR_BIT;
133 hilet bit_offset = offset % CHAR_BIT;
134
135 hilet arg = args_[i];
136 hi_axiom(arg <= mask);
137 store_or(static_cast<value_type>(arg << bit_offset), r.data() + byte_offset);
138 }
139
140 return r;
141 }
142};
143
144template<size_t BitsPerInteger, std::unsigned_integral... Args>
145packed_int_array(Args...) -> packed_int_array<BitsPerInteger, sizeof...(Args)>;
146
147}
148
#define hi_axiom(expression)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
Miscellaneous math functions.
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
An array of integers.
Definition packed_int_array.hpp:25
constexpr size_t size() const noexcept
The number of integers stored in the array.
Definition packed_int_array.hpp:62
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:44
constexpr value_type operator[](size_t i) const noexcept
Get the integer at an index.
Definition packed_int_array.hpp:76
constexpr packed_int_array(Args... args) noexcept
Constructor of the array.
Definition packed_int_array.hpp:58
friend constexpr value_type get(packed_int_array const &rhs) noexcept
Get the integer at an index.
Definition packed_int_array.hpp:98