#pragma once #include "binary-reader.hpp" #include "compat/exception.hpp" namespace floormat::Serialize { template template constexpr binary_reader::binary_reader(const Seq& seq) noexcept : it{std::cbegin(seq)}, end{std::cend(seq)} {} template constexpr binary_reader::binary_reader(It begin, It end) noexcept : it{std::move(begin)}, end{std::move(end)} {} template template constexpr T binary_reader::read() noexcept(false) { constexpr std::size_t N = sizeof(T); fm_soft_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(false) { std::array array; if (std::is_constant_evaluated()) array = {}; fm_soft_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(false) { fm_soft_assert(it == end); } template binary_reader& operator>>(binary_reader& reader, T& x) noexcept(false) { x = reader.template read(); return reader; } template void operator<<(T& x, binary_reader& reader) noexcept(false) { x = reader.template read(); } template template constexpr auto binary_reader::read_asciiz_string() noexcept(false) { static_assert(MAX > 0); struct fixed_string final { char buf[MAX]; std::size_t len; operator StringView() const noexcept { return { buf, len, StringViewFlag::NullTerminated }; } }; 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_throw("can't find string terminator"_cf); } } // namespace floormat::Serialize