#ifndef OPENMW_COMPONENTS_SERIALIZATION_BINARYREADER_H #define OPENMW_COMPONENTS_SERIALIZATION_BINARYREADER_H #include #include #include #include #include namespace Serialization { class BinaryReader { public: explicit BinaryReader(const std::byte* pos, const std::byte* end) : mPos(pos), mEnd(end) { assert(mPos <= mEnd); } BinaryReader(const BinaryReader&) = delete; template void operator()(Format&& format, T& value) { if constexpr (std::is_enum_v) (*this)(std::forward(format), static_cast&>(value)); else if constexpr (std::is_arithmetic_v) { if (mEnd - mPos < static_cast(sizeof(T))) throw std::runtime_error("Not enough data"); std::memcpy(&value, mPos, sizeof(T)); mPos += sizeof(T); } else { format(*this, value); } } template auto operator()(Format&& format, T* data, std::size_t count) { if constexpr (std::is_enum_v) (*this)(std::forward(format), reinterpret_cast*>(data), count); else if constexpr (std::is_arithmetic_v) { const std::size_t size = sizeof(T) * count; if (mEnd - mPos < static_cast(size)) throw std::runtime_error("Not enough data"); std::memcpy(data, mPos, size); mPos += size; } else { format(*this, data, count); } } private: const std::byte* mPos; const std::byte* const mEnd; }; } #endif