summaryrefslogtreecommitdiff
path: root/include/util
diff options
context:
space:
mode:
authorhovertank3d <[email protected]>2025-11-13 23:02:56 +0100
committerhovertank3d <[email protected]>2025-11-13 23:06:37 +0100
commita5b377745116de2b269cdfc5b90f08f46d0432d2 (patch)
tree7aea9482dadc4d66df17907282f2359c54c9df0d /include/util
downloadogurec-a5b377745116de2b269cdfc5b90f08f46d0432d2.tar.gz
ogurec-a5b377745116de2b269cdfc5b90f08f46d0432d2.zip
initial commit
Diffstat (limited to 'include/util')
-rw-r--r--include/util/bitset.hpp48
-rw-r--r--include/util/endian.hpp21
2 files changed, 69 insertions, 0 deletions
diff --git a/include/util/bitset.hpp b/include/util/bitset.hpp
new file mode 100644
index 0000000..8798a4a
--- /dev/null
+++ b/include/util/bitset.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <array>
+#include <cassert>
+#include <cstdint>
+
+constexpr int bits_ceil(int bits) {
+ return bits / 8 + (bits % 8 > 0 ? 1 : 0);
+}
+
+template <unsigned int flags, auto size = bits_ceil(flags)>
+struct bitset : std::array<std::uint8_t, size> {
+ using array_type = std::array<std::uint8_t, size>;
+
+private:
+ struct bit_ref {
+ bitset<flags> &a;
+ int referenced_byte;
+ uint8_t referenced_bit_mask;
+
+ bool operator=(bool b) {
+ if (b)
+ a.at(referenced_byte) |= referenced_bit_mask;
+ else
+ a.at(referenced_byte) &= ~referenced_bit_mask;
+ return b;
+ }
+
+ constexpr operator bool() const {
+ return (a.at(referenced_byte) & referenced_bit_mask) > 0;
+ }
+ };
+
+public:
+ template<class T>
+ constexpr bool operator [](T idx) const {
+ unsigned int i = (unsigned int)(idx);
+ assert(i < flags);
+ return (array_type::at(i/8) & (1 << (i%8))) > 0;
+ }
+
+ template<class T>
+ bit_ref operator[](T idx) {
+ unsigned int i = (unsigned int)(idx);
+ assert(i < flags);
+ return bit_ref(*this, i/8, (1 << (i%8)));
+ }
+}; \ No newline at end of file
diff --git a/include/util/endian.hpp b/include/util/endian.hpp
new file mode 100644
index 0000000..18e49f6
--- /dev/null
+++ b/include/util/endian.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <bit>
+#include <concepts>
+
+template <std::integral T>
+ requires(sizeof(T) <= 8)
+T to_little(T x)
+{
+ if constexpr (std::endian::native == std::endian::little || sizeof(T) == 1) {
+ return x;
+ }
+ switch (sizeof(T)) {
+ case 2:
+ return __builtin_bswap16(x);
+ case 4:
+ return __builtin_bswap32(x);
+ case 8:
+ return __builtin_bswap64(x);
+ }
+} \ No newline at end of file