Make VectorFormatter support stateful formatters

This commit is contained in:
Russell Yanofsky 2020-02-15 19:09:09 -08:00 committed by Pieter Wuille
parent 3ca574cef0
commit 56dd9f04c7
2 changed files with 13 additions and 7 deletions

View File

@ -424,15 +424,20 @@ public:
return first; return first;
} }
void push_back(const T& value) { template<typename... Args>
void emplace_back(Args&&... args) {
size_type new_size = size() + 1; size_type new_size = size() + 1;
if (capacity() < new_size) { if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1)); change_capacity(new_size + (new_size >> 1));
} }
new(item_ptr(size())) T(value); new(item_ptr(size())) T(std::forward<Args>(args)...);
_size++; _size++;
} }
void push_back(const T& value) {
emplace_back(value);
}
void pop_back() { void pop_back() {
erase(end() - 1, end()); erase(end() - 1, end());
} }

View File

@ -613,7 +613,7 @@ BigEndian<I> WrapBigEndian(I& n) { return BigEndian<I>(n); }
* as a vector of VarInt-encoded integers. * as a vector of VarInt-encoded integers.
* *
* V is not required to be an std::vector type. It works for any class that * 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<class Formatter> template<class Formatter>
struct VectorFormatter struct VectorFormatter
@ -621,15 +621,17 @@ struct VectorFormatter
template<typename Stream, typename V> template<typename Stream, typename V>
void Ser(Stream& s, const V& v) void Ser(Stream& s, const V& v)
{ {
Formatter formatter;
WriteCompactSize(s, v.size()); WriteCompactSize(s, v.size());
for (const typename V::value_type& elem : v) { for (const typename V::value_type& elem : v) {
s << Using<Formatter>(elem); formatter.Ser(s, elem);
} }
} }
template<typename Stream, typename V> template<typename Stream, typename V>
void Unser(Stream& s, V& v) void Unser(Stream& s, V& v)
{ {
Formatter formatter;
v.clear(); v.clear();
size_t size = ReadCompactSize(s); size_t size = ReadCompactSize(s);
size_t allocated = 0; size_t allocated = 0;
@ -641,9 +643,8 @@ struct VectorFormatter
allocated = std::min(size, allocated + MAX_VECTOR_ALLOCATE / sizeof(typename V::value_type)); allocated = std::min(size, allocated + MAX_VECTOR_ALLOCATE / sizeof(typename V::value_type));
v.reserve(allocated); v.reserve(allocated);
while (v.size() < allocated) { while (v.size() < allocated) {
typename V::value_type val; v.emplace_back();
s >> Using<Formatter>(val); formatter.Unser(s, v.back());
v.push_back(std::move(val));
} }
} }
}; };