#pragma once #include "compat/assert.hpp" #include #include #include namespace floormat::detail_Pack_output { template struct output_bits final { static_assert(N > 0); static_assert(N < sizeof(size_t)*8); static constexpr size_t length = N; }; template struct output { static_assert(std::is_fundamental_v); static_assert(CAPACITY <= sizeof(T)*8); static constexpr size_t Capacity = CAPACITY; T value{0}; template struct next_ { static_assert(N > 0); static_assert(N <= CAPACITY); using type = output; }; template using next = typename next_::type; template constexpr T set(T x, output_bits) const { static_assert(N <= CAPACITY, "data type too small"); static_assert(N > 0); T value_{value}; if constexpr(CAPACITY != sizeof(T)*8) value_ <<= CAPACITY; auto x_ = T(x & (T{1}< struct output_field { T value; static constexpr size_t Length = LENGTH; }; template constexpr T write_(output st, output_field field, Fields... fields) { T value = st.set(field.value, output_bits{}); using next = typename output::template next; return write_(next{value}, fields...); } template constexpr T write_(output st) { return st.value; } } // namespace floormat::detail_Pack_output