diff --git a/src/prevector.h b/src/prevector.h --- a/src/prevector.h +++ b/src/prevector.h @@ -517,15 +517,17 @@ return first; } - void push_back(const T &value) { + template void emplace_back(Args &&... args) { size_type new_size = size() + 1; if (capacity() < new_size) { change_capacity(new_size + (new_size >> 1)); } - new (item_ptr(size())) T(value); + new (item_ptr(size())) T(std::forward(args)...); _size++; } + void push_back(const T &value) { emplace_back(value); } + void pop_back() { erase(end() - 1, end()); } T &front() { return *item_ptr(0); } diff --git a/src/serialize.h b/src/serialize.h --- a/src/serialize.h +++ b/src/serialize.h @@ -720,17 +720,19 @@ * as a vector of VarInt-encoded integers. * * V is not required to be an std::vector type. It works for any class that - * exposes a value_type, size, reserve, push_back, and const iterators. + * exposes a value_type, size, reserve, emplace_back, back, and const iterators. */ template struct VectorFormatter { template void Ser(Stream &s, const V &v) { + Formatter formatter; WriteCompactSize(s, v.size()); for (const typename V::value_type &elem : v) { - s << Using(elem); + formatter.Ser(s, elem); } } template void Unser(Stream &s, V &v) { + Formatter formatter; v.clear(); size_t size = ReadCompactSize(s); size_t allocated = 0; @@ -746,9 +748,8 @@ sizeof(typename V::value_type)); v.reserve(allocated); while (v.size() < allocated) { - typename V::value_type val; - s >> Using(val); - v.push_back(std::move(val)); + v.emplace_back(); + formatter.Unser(s, v.back()); } } };