#pragma once #include "binary-reader.hpp" #include "compat/assert.hpp" namespace floormat::Serialize { template template constexpr binary_reader::binary_reader(const Seq& seq) noexcept : it{std::begin(seq)}, end{std::end(seq)} {} template constexpr binary_reader::binary_reader(It begin, It end) noexcept : it{begin}, end{end} {} template template constexpr T binary_reader::read() noexcept { constexpr std::size_t N = sizeof(T); fm_assert((std::ptrdiff_t)N <= std::distance(it, end)); num_bytes_read += N; char buf[N]; for (std::size_t i = 0; i < N; i++) buf[i] = *it++; return maybe_byteswap(std::bit_cast(buf)); } template template constexpr std::array binary_reader::read() noexcept { std::array array; if (std::is_constant_evaluated()) array = {}; fm_assert(N <= (std::size_t)std::distance(it, end)); num_bytes_read += N; for (std::size_t i = 0; i < N; i++) array[i] = *it++; return array; } template constexpr void binary_reader::assert_end() noexcept { fm_assert(it == end); } template binary_reader& operator>>(binary_reader& reader, T& x) noexcept { x = reader.template read(); return reader; } template template constexpr auto binary_reader::read_asciiz_string() noexcept { static_assert(MAX > 0); struct fixed_string final { char buf[MAX]; std::size_t len; }; fixed_string ret; for (std::size_t i = 0; i < MAX && it != end; i++) { const char c = *it++; ret.buf[i] = c; if (c == '\0') { ret.len = i; return ret; } } fm_abort("can't find string terminator"); } } // namespace floormat::Serialize