// // Created by Mindaugas Vinkelis on 17.1.3. // #ifndef TMP_SERIALIZER_H #define TMP_SERIALIZER_H #include "Common.h" #include template class Serializer { public: Serializer(Writter& w):_writter{w} {}; template Serializer& object(const T& obj) { return serialize(*this, obj); } /* * value overloads */ template::value>::type* = nullptr> Serializer& value(const T& v) { static_assert(std::numeric_limits::is_iec559, ""); static_assert(std::numeric_limits::is_iec559, ""); constexpr size_t ValueSize = VSIZE == 0 ? sizeof(T) : VSIZE; _writter.template writeBytes(reinterpret_cast&>(v)); return *this; } template::value>::type* = nullptr> Serializer& value(const T& v) { constexpr size_t ValueSize = VSIZE == 0 ? sizeof(T) : VSIZE; _writter.template writeBytes(reinterpret_cast&>(v)); return *this; } template::value>::type* = nullptr> Serializer& value(const T& v) { constexpr size_t ValueSize = VSIZE == 0 ? sizeof(T) : VSIZE; _writter.template writeBytes(v); return *this; } /* * range */ template Serializer& range(const T& v, const RangeSpec& r) { //assert(r.isValid(v)); //_writter.template writeBits(r.value(v), r.bitsRequired()); return *this; } /* * text overloads */ template Serializer& text(const std::basic_string& str) { procText(str.data(), str.size()); return *this; } template Serializer& text(const T (&str)[N]) { procText(str, std::min(std::char_traits::length(str), N-1)); return *this; } /* * container overloads */ template Serializer& container(const T& obj, Fnc&& fnc) { writeLength(obj.size()); for (auto& v: obj) fnc(v); return *this; } template Serializer& container(const T& obj) { writeLength(obj.size()); procContainer(obj); return *this; } template Serializer& container(const T& obj) { writeLength(obj.size()); procContainer>(obj); return *this; } /* * array overloads (fixed size array (std::array, and c-style array)) */ //std::array overloads template Serializer & array(const std::array &arr, Fnc&& fnc) { for (auto& v: arr) fnc(v); return *this; } template Serializer & array(const std::array &arr) { procContainer(arr); return *this; } template Serializer & array(const std::array &arr) { procContainer>(arr); return *this; } //c-style array overloads template Serializer& array(const T (&arr)[N], Fnc&& fnc) { const T* end = arr + N; for (const T* tmp = arr; tmp != end; ++tmp) fnc(*tmp); return *this; } template Serializer& array(const T (&arr)[N]) { procCArray(arr); return *this; } template Serializer& array(const T (&arr)[N]) { procCArray>(arr); return *this; } private: Writter& _writter; void writeLength(const size_t size) { _writter.writeBits(size, 32); } template void procContainer(T&& obj) { //todo could be improved for arithmetic types in contiguous containers (std::vector, std::array) (keep in mind std::vector specialization) for (auto& v: obj) ProcessAnyType::serialize(*this, v); }; template void procCArray(T (&arr)[N]) { //todo could be improved for arithmetic types const T* end = arr + N; for (const T* it = arr; it != end; ++it) ProcessAnyType::serialize(*this, *it); }; template void procText(const T* str, size_t size) { writeLength(size); if (size) _writter.template writeBuffer(str, size); } }; #endif //TMP_SERIALIZER_H