#ifndef OPENMW_COMPONENTS_SERIALIZATION_FORMAT_H #define OPENMW_COMPONENTS_SERIALIZATION_FORMAT_H #include #include #include #include #include #include #include #include namespace Serialization { enum class Mode { Read, Write, }; template struct IsContiguousContainer : std::false_type { }; template struct IsContiguousContainer> : std::true_type { }; template struct IsContiguousContainer> : std::true_type { }; template inline constexpr bool isContiguousContainer = IsContiguousContainer>::value; template struct Format { template void operator()(Visitor&& visitor, T* data, std::size_t size) const { if constexpr (std::is_arithmetic_v || std::is_enum_v) visitor(self(), data, size); else std::for_each(data, data + size, [&](auto& v) { visitor(self(), v); }); } template void operator()(Visitor&& visitor, T (&data)[size]) const { self()(std::forward(visitor), data, size); } template auto operator()(Visitor&& visitor, T&& value) const -> std::enable_if_t> { if constexpr (mode == Mode::Write) visitor(self(), static_cast(value.size())); else { static_assert(mode == Mode::Read); std::uint64_t size = 0; visitor(self(), size); value.resize(static_cast(size)); } self()(std::forward(visitor), value.data(), value.size()); } const Derived& self() const { return static_cast(*this); } }; } #endif