#pragma once #include "binary-serializer.hpp" #include #include namespace floormat::Serialize { union alignas(alignof(double)) value_u { char bytes[8]; unsigned char uc; std::uint8_t u8; std::uint16_t u16; std::uint32_t u32; std::uint64_t u64; float f32; double f64; }; static_assert(sizeof(value_u) == 8); template concept char_sequence = requires(T& x, const T& cx) { requires std::same_as; requires std::same_as; requires std::forward_iterator; requires std::forward_iterator; requires std::same_as>; requires std::same_as>; }; template concept string_input_iterator = requires(It it) { requires std::forward_iterator; requires std::is_same_v>; }; template struct binary_reader final { template explicit constexpr binary_reader(const Seq& seq) noexcept; constexpr binary_reader(It begin, It end) noexcept; constexpr void assert_end() noexcept; template constexpr value_u read_u() noexcept; template constexpr value_u read_u() noexcept; template T read() noexcept; template constexpr std::array read() noexcept; constexpr std::size_t bytes_read() const noexcept { return num_bytes_read; } template auto read_asciiz_string() noexcept; private: std::size_t num_bytes_read = 0; It it, end; }; template binary_reader& operator>>(binary_reader& reader, T& x) noexcept; template binary_reader(It&& begin, It&& end) -> binary_reader>; template binary_reader(Array&& array) -> binary_reader>; } // namespace floormat::Serialize