#pragma once #include class MessageVector { public: struct header_t { size_t len_{}; }; size_t get_buff_size() const { return buffer_.size(); } size_t get_buff_capacity() const { return buffer_.capacity(); } void clear() { buffer_.clear(); } void shrink(size_t size) { buffer_.reserve(size); } template static size_t get_len(T value, Types... args) { if constexpr (std::is_convertible_v) { return value ; } return 0; } template bool put(Types&&... args){ size_t total_len = (... + get_len(std::forward(args))) ; size_t buff_used = buffer_.size(); buffer_.resize(buff_used + total_len + sizeof(header_t)); header_t* p = (header_t*)(buffer_.data() + buff_used); p->len_ = total_len; char* pbuff = (char*)p + sizeof(header_t); auto func = [&pbuff](auto func, void* pdata, size_t len, auto&&... args) { memcpy(pbuff, pdata, len); pbuff += len; if constexpr (sizeof ... (args) > 0) { func(func, args...); } }; func(func, std::forward(args)...); return true; } bool peek(size_t& it, const void*& pdata, size_t& len) const { size_t pos = it + sizeof(header_t); if(pos > buffer_.size()) { return false; } header_t* p = (header_t*)(buffer_.data() + it); if(pos + p->len_ > buffer_.size()) { return false; } it = pos + p->len_; pdata = buffer_.data() + pos; len = p->len_; return true; } private: std::vector buffer_; };