diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-14 19:48:43 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-14 19:48:43 +0100 |
commit | 6c747d58f85d29987011d9519109928c3438fcef (patch) | |
tree | 4713f84d7bc06d4ce8e9b71951546345ebdf5040 /serialize/packbits.hpp | |
parent | 9b957f519620a07597fa28f796c09bdbef2e8fab (diff) |
a
Diffstat (limited to 'serialize/packbits.hpp')
-rw-r--r-- | serialize/packbits.hpp | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/serialize/packbits.hpp b/serialize/packbits.hpp index 12c1dd31..527b7676 100644 --- a/serialize/packbits.hpp +++ b/serialize/packbits.hpp @@ -5,7 +5,7 @@ #include "compat/assert.hpp" namespace floormat::Pack { -template<std::unsigned_integral T, uint8_t N> struct Bits_; +template<std::unsigned_integral T, size_t N> struct Bits_; } // namespace floormat::Pack namespace floormat::detail_Pack { @@ -13,7 +13,7 @@ namespace floormat::detail_Pack { using namespace floormat::Pack; template<std::unsigned_integral T, size_t Sum, typename... Xs> struct check_size_overflow; -template<std::unsigned_integral T, std::unsigned_integral U, size_t Sum, uint8_t N, typename... Xs> +template<std::unsigned_integral T, std::unsigned_integral U, size_t Sum, size_t N, typename... Xs> struct check_size_overflow<T, Sum, Bits_<U, N>, Xs...> { static_assert(std::is_same_v<T, U>); @@ -95,25 +95,80 @@ struct make_tuple_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<>) +template<typename T, typename Place, size_t Left, size_t I, size_t... Is, size_t Size, typename... Sizes> +constexpr void assign_tuple2(Place& p, Storage<T, Left> st, std::index_sequence<I, Is...>, Bits_<T, Size>, Sizes... sizes) { - fm_assert(st.check_zero()); + using S = Storage<T, Left>; + using next_type = typename S::template next<Size>; + get<I>(p) = st.template get<Size>(); + T next_value = st.template advance<Size>(); + assign_tuple2(p, next_type{next_value}, std::index_sequence<Is...>{}, sizes...); } -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...>) +template<typename T, typename Place, size_t Left> +constexpr void assign_tuple2(Place&, Storage<T, Left>, std::index_sequence<>) { - using std::get; - get<Size>(p) = st.template get<Size>(st); - assign_to_tuple(p, st.template advance<Size>(), std::index_sequence<Sizes...>{}); } +#if 0 +template<typename T, typename Indexes, typename... Sizes> struct assign_tuple; + +template<typename T, size_t Index, size_t... Indexes, size_t Size, typename... Sizes> +struct assign_tuple<T, std::index_sequence<Index, Indexes...>, Bits_<T, Size>, Sizes...> +{ + static_assert(Size <= sizeof(T)*8, "bit count can't be larger than sizeof(T)*8"); + static_assert(Size > 0, "bit count can't be zero"); + + template<typename Place, size_t Left> + static constexpr inline void do_tuple(Place& p, Storage<T, Left> st) + { + static_assert(requires (Place& p) { std::get<0>(p) = T{0}; }); + static_assert(std::tuple_size_v<Place> >= sizeof...(Indexes) + 1); + static_assert(Size <= Left, "not enough bits for element"); + + get<Index>(p) = st.template get<Size>(st.value); + using Next = typename Storage<T, Left>::template next<Size>; + assign_tuple<T, std::index_sequence<Indexes...>, Sizes...>:: + template do_tuple<Place, Next>(p, Next{st.template advance<Size>()}); + } + + static constexpr bool is_empty = false; +}; + +template<typename T, size_t Index, size_t... Indexes> +struct assign_tuple<T, std::index_sequence<Index, Indexes...>> +{ + static_assert(sizeof(T) == (size_t)-1, "too few lhs elements"); + static_assert(sizeof(T) != (size_t)-1); +}; + +template<typename T, size_t Size, typename... Sizes> +struct assign_tuple<T, std::index_sequence<>, Bits_<T, Size>, Sizes...> +{ + static_assert(sizeof(T) == (size_t)-1, "too few rhs elements"); + static_assert(sizeof(T) != (size_t)-1); +}; + +template<typename T> +struct assign_tuple<T, std::index_sequence<>> +{ + template<typename Place, size_t Left> + static constexpr inline void do_tuple(Place&, Storage<T, Left> st) + { + fm_assert(st.check_zero()); + } + + static constexpr bool is_empty = true; + using type = T; +}; + +#endif + } // namespace floormat::detail_Pack namespace floormat::Pack { -template<std::unsigned_integral T, uint8_t N> +template<std::unsigned_integral T, size_t N> struct Bits_ final { static_assert(std::is_fundamental_v<T>); |