#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 <= sizeof(T)*8); 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_ <<= N; auto x_ = T(x & (T{1}< struct output_field { T value; static constexpr size_t Length = LENGTH; }; template struct count_bits; template struct count_bits, Ts...>> { static constexpr size_t length = N + count_bits>::length; static_assert(length <= sizeof(T)*8); }; template struct count_bits> { static constexpr size_t length = 0; }; #if 0 template constexpr T write_(output st, std::tuple> fields) { T value0 = fields.get< std::tuple_size_v>>-1 >(fields).value; T value = st.set(value0, output_bits{}); using next = typename output::template next; return write_(next{value}, ); } template constexpr T write_(output st) { return st.value; } #endif } // namespace floormat::detail_Pack_output