#ifndef RFL_PARSING_STRUCTREADER_HPP_ #define RFL_PARSING_STRUCTREADER_HPP_ #include #include #include #include #include "../Result.hpp" #include "../to_view.hpp" #include "AreReaderAndWriter.hpp" namespace rfl::parsing { template requires AreReaderAndWriter struct StructReader { public: using InputVarType = typename R::InputVarType; /// The way this works is that we allocate space on the stack in this size of /// the struct in which we then write the individual fields using /// views and placement new. This is how we deal with the fact that some /// fields might not be default-constructible. static Result read(const R& _r, const InputVarType& _var) { alignas(StructType) unsigned char buf[sizeof(StructType)]; auto ptr = reinterpret_cast(buf); auto view = ProcessorsType::template process(to_view(*ptr)); using ViewType = std::remove_cvref_t; const auto err = Parser::read_view(_r, _var, &view); if (err) { return *err; } return std::move(*ptr); } }; } // namespace rfl::parsing #endif