#pragma once #include "compat/integer-types.hpp" #include "compat/defs.hpp" #include #include #include #include namespace Corrade::Containers { template class BasicStringView; using StringView = BasicStringView; } // namespace Corrade::Containers namespace floormat::Serialize { static_assert(std::endian::native == std::endian::big || std::endian::native == std::endian::little); enum class value_type : std::uint8_t { none, uc, u8, u16, u32, u64, f32, f64, COUNT }; template struct make_integer; template using make_integer_t = typename make_integer::type; #define FM_SERIALIZE_MAKE_INTEGER(T) template<> struct make_integer { using type = T; } FM_SERIALIZE_MAKE_INTEGER(std::uint8_t); FM_SERIALIZE_MAKE_INTEGER(std::uint16_t); FM_SERIALIZE_MAKE_INTEGER(std::uint32_t); FM_SERIALIZE_MAKE_INTEGER(std::uint64_t); #undef FN_SERIALIZE_MAKE_INTEGER template concept integer = requires(T x) { requires std::integral; requires sizeof(T) == sizeof(make_integer_t); }; union value_u { alignas(alignof(double)) 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 concept serializable = requires(T x) { requires std::floating_point || integer; }; template struct binary_reader final { template explicit constexpr binary_reader(const Seq& seq) noexcept; constexpr binary_reader(It begin, It end) noexcept; constexpr ~binary_reader() noexcept; template constexpr value_u read_u() noexcept; template constexpr value_u read_u() noexcept; template T read() noexcept; private: 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>; template It> struct binary_writer final { explicit constexpr binary_writer(It it) noexcept; template constexpr void write(T x) noexcept; template void write(T x) noexcept; constexpr void write_asciiz_string(StringView str) noexcept; constexpr std::size_t bytes_written() const noexcept { return _bytes_written; } private: It it; std::size_t _bytes_written; }; template It, serializable T> constexpr binary_writer& operator<<(binary_writer& writer, T x) noexcept; } // namespace floormat::Serialize