#pragma once #include "packbits.hpp" #include #include #include #include "compat/assert.hpp" namespace floormat::detail_Pack { template struct input { static_assert(CAPACITY <= sizeof(T)*8); static constexpr size_t Capacity = CAPACITY; T value; template constexpr T get() const { static_assert(N > 0); static_assert(N <= sizeof(T)*8); static_assert(N <= Capacity); return T(value & (T(1) << N) - T(1)); } template constexpr T advance() const { static_assert(N <= sizeof(T)*8); static_assert(N <= Capacity); return T(value >> N); } constexpr bool operator==(const input&) const noexcept = default; [[nodiscard]] constexpr inline bool check_zero() const { return value == T(0); } template struct next_ { static_assert(N <= Capacity); using type = input; }; template using next = typename next_::type; }; template struct input { using Type = T; static constexpr size_t Capacity = 0; T value; template [[maybe_unused]] constexpr T get() const = delete; template [[maybe_unused]] constexpr T advance() const = delete; constexpr bool operator==(const input&) const noexcept = default; [[nodiscard]] constexpr inline bool check_zero() const { return true; } template struct next { static_assert(N == 0, "reading past the end"); static_assert(N != 0, "reading past the end"); }; }; template constexpr void read(Place& p, input st, std::index_sequence, empty_pack_tuple, Sizes...>) { static_assert(sizeof...(Is) == sizeof...(Sizes)); static_assert(Size <= Left, "too many bits requested"); static_assert(I < std::tuple_size_v, "too few tuple members"); using S = input; using next_type = typename S::template next; get(p) = st.template get(); T next_value = st.template advance(); read(p, next_type{ next_value }, std::index_sequence{}, empty_pack_tuple{}); } template constexpr void read(Place&, input st, std::index_sequence<>, empty_pack_tuple<>) { fm_assert(st.check_zero()); } template requires(sizeof...(Is) != sizeof...(Sizes)) constexpr void read(Place&, input, std::index_sequence, empty_pack_tuple) = delete; template using make_pack = empty_pack_tuple...>; } // namespace floormat::detail_Pack namespace floormat::pack { } // namespace floormat::pack