#ifndef RFL_PARSING_PARSER_ARRAY_HPP_ #define RFL_PARSING_PARSER_ARRAY_HPP_ #include #include #include #include #include "../Ref.hpp" #include "../Result.hpp" #include "../always_false.hpp" #include "ArrayReader.hpp" #include "Parent.hpp" #include "Parser_base.hpp" #include "schema/Type.hpp" namespace rfl { namespace parsing { template requires AreReaderAndWriter> struct Parser, ProcessorsType> { public: using InputArrayType = typename R::InputArrayType; using InputVarType = typename R::InputVarType; using OutputArrayType = typename W::OutputArrayType; using OutputVarType = typename W::OutputVarType; using ParentType = Parent; static Result> read(const R& _r, const InputVarType& _var) noexcept { const auto parse = [&](const InputArrayType& _arr) -> Result> { alignas(std::array) unsigned char buf[sizeof(std::array)]; auto ptr = reinterpret_cast*>(buf); const auto array_reader = ArrayReader(&_r, ptr); auto err = _r.read_array(array_reader, _arr); if (err) { array_reader.call_destructors_where_necessary(); return *err; } err = array_reader.check_size(); if (err) { array_reader.call_destructors_where_necessary(); return *err; } return std::move(*ptr); }; return _r.to_array(_var).and_then(parse); } template static void write(const W& _w, const std::array& _arr, const P& _parent) noexcept { auto arr = ParentType::add_array(_w, _size, _parent); const auto new_parent = typename ParentType::Array { &arr }; for (const auto& e : _arr) { Parser, ProcessorsType>::write(_w, e, new_parent); } _w.end_array(&arr); } static schema::Type to_schema(std::map* _definitions) { using U = std::remove_cvref_t; return schema::Type { schema::Type::FixedSizeTypedArray { .size_ = _size, .type_ = Ref::make(Parser::to_schema(_definitions)) } }; } }; } // namespace parsing } // namespace rfl #endif