From 86e7ed369022841a860d415facc52465b5b78d56 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Sun, 1 Oct 2023 23:23:16 +0200 Subject: [PATCH] stream: add support for collection reading and writing Signed-off-by: Simon Rozman --- include/stdex/stream.hpp | 90 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/include/stdex/stream.hpp b/include/stdex/stream.hpp index b05bfc303..212124d27 100644 --- a/include/stdex/stream.hpp +++ b/include/stdex/stream.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -652,6 +653,95 @@ namespace stdex template inline basic& operator <<(_In_ const T* data) { return write_str(data); } + template > + basic& operator <<(_In_ const std::vector<_Ty, _Alloc>& data) + { + size_t num = data.size(); + if (num > UINT32_MAX) _Unlikely_ + throw std::invalid_argument("collection too big"); + *this << static_cast(num); + for (auto& el : data) + *this << el; + return *this; + } + + template > + basic& operator >>(_Out_ std::vector<_Ty, _Alloc>& data) + { + data.clear(); + uint32_t num; + *this >> num; + if (!ok()) _Unlikely_ + return *this; + data.reserve(num); + for (uint32_t i = 0; i < num; ++i) { + _Ty el; + *this >> el; + if (!ok()) _Unlikely_ + return *this; + data.push_back(std::move(el)); + } + } + + template , class _Alloc = std::allocator<_Kty>> + basic& operator <<(_In_ const std::set<_Kty, _Pr, _Alloc>& data) + { + size_t num = data.size(); + if (num > UINT32_MAX) _Unlikely_ + throw std::invalid_argument("collection too big"); + *this << static_cast(num); + for (auto& el : data) + *this << el; + return *this; + } + + template , class _Alloc = std::allocator<_Kty>> + basic& operator >>(_Out_ std::set<_Kty, _Pr, _Alloc>& data) + { + data.clear(); + uint32_t num; + *this >> num; + if (!ok()) _Unlikely_ + return *this; + for (uint32_t i = 0; i < num; ++i) { + _Kty el; + *this >> el; + if (!ok()) _Unlikely_ + return *this; + data.insert(std::move(el)); + } + } + + template , class _Alloc = std::allocator<_Kty>> + basic& operator <<(_In_ const std::multiset<_Kty, _Pr, _Alloc>& data) + { + size_t num = data.size(); + if (num > UINT32_MAX) _Unlikely_ + throw std::invalid_argument("collection too big"); + *this << static_cast(num); + for (auto& el : data) + *this << el; + return *this; + } + + template , class _Alloc = std::allocator<_Kty>> + basic& operator >>(_Out_ std::multiset<_Kty, _Pr, _Alloc>& data) + { + data.clear(); + uint32_t num; + *this >> num; + if (!ok()) _Unlikely_ + return *this; + for (uint32_t i = 0; i < num; ++i) { + _Kty el; + *this >> el; + if (!ok()) _Unlikely_ + return *this; + data.insert(std::move(el)); + } + return *this; + } + protected: state_t m_state; };