diff options
Diffstat (limited to 'serialize/packbits.hpp')
-rw-r--r-- | serialize/packbits.hpp | 38 |
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 { |