summaryrefslogtreecommitdiffhomepage
path: root/serialize/packbits.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'serialize/packbits.hpp')
-rw-r--r--serialize/packbits.hpp38
1 files changed, 32 insertions, 6 deletions
diff --git a/serialize/packbits.hpp b/serialize/packbits.hpp
index cb91602f..12c1dd31 100644
--- a/serialize/packbits.hpp
+++ b/serialize/packbits.hpp
@@ -1,6 +1,8 @@
#pragma once
#include <type_traits>
#include <concepts>
+#include <tuple>
+#include "compat/assert.hpp"
namespace floormat::Pack {
template<std::unsigned_integral T, uint8_t N> struct Bits_;
@@ -55,7 +57,7 @@ struct Storage
}
constexpr bool operator==(const Storage&) const noexcept = default;
- constexpr bool check_zero() const = delete;
+ [[nodiscard]] constexpr inline bool check_zero() const { return value == T(0); }
template<size_t N> using next = Storage<T, Capacity - N>;
};
@@ -70,11 +72,7 @@ struct Storage<T, 0>
template<size_t N> [[maybe_unused]] constexpr T get() const = delete;
template<size_t N> [[maybe_unused]] constexpr T advance() const = delete;
constexpr bool operator==(const Storage&) const noexcept = default;
-
- [[nodiscard]] constexpr inline bool check_zero() const
- {
- return value == T(0);
- }
+ [[nodiscard]] constexpr inline bool check_zero() const { return true; }
template<size_t N> struct next
{
@@ -83,6 +81,34 @@ struct Storage<T, 0>
};
};
+template<std::unsigned_integral T, size_t N>
+struct make_tuple_type_
+{
+ template<size_t> using index_to_type = T;
+ template<typename> struct aux;
+ template<size_t... Is> struct aux<std::index_sequence<Is...>>
+ {
+ static_assert(sizeof...(Is) > 0);
+ using type = std::tuple<index_to_type<Is>...>;
+ };
+ using Seq = typename aux<std::make_index_sequence<N>>::type;
+};
+template<std::unsigned_integral T, size_t N> using make_tuple_type = typename make_tuple_type_<T, N>::Seq;
+
+template<typename T, typename Place, size_t Left>
+static void assign_to_tuple(Place&, Storage<T, Left> st, std::index_sequence<>)
+{
+ fm_assert(st.check_zero());
+}
+
+template<typename T, typename Place, size_t Left, size_t Size, size_t... Sizes>
+static void assign_to_tuple(Place& p, Storage<T, Left> st, std::index_sequence<Size, Sizes...>)
+{
+ using std::get;
+ get<Size>(p) = st.template get<Size>(st);
+ assign_to_tuple(p, st.template advance<Size>(), std::index_sequence<Sizes...>{});
+}
+
} // namespace floormat::detail_Pack
namespace floormat::Pack {