Skip to content

Commit

Permalink
Support serialization of std::vector<bool>
Browse files Browse the repository at this point in the history
Summary:
PR description:
> This adds support for serialization of std::vector<bool>, as a prerequisite of [[bitcoin/bitcoin#16702 | PR16702]].

Backport of Core [[bitcoin/bitcoin#16730 | PR16730]].

Test Plan: `ninja && ninja check`

Reviewers: O1 Bitcoin ABC, #bitcoin_abc, deadalnix

Reviewed By: O1 Bitcoin ABC, #bitcoin_abc, deadalnix

Subscribers: deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D7907
  • Loading branch information
sipa authored and PiRK committed Oct 14, 2020
1 parent ac424d9 commit 4b12d48
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,8 @@ inline void Unserialize(Stream &is, prevector<N, T> &v);
*/
template <typename Stream, typename T, typename A>
void Serialize_impl(Stream &os, const std::vector<T, A> &v, const uint8_t &);
template <typename Stream, typename T, typename A>
void Serialize_impl(Stream &os, const std::vector<T, A> &v, const bool &);
template <typename Stream, typename T, typename A, typename V>
void Serialize_impl(Stream &os, const std::vector<T, A> &v, const V &);
template <typename Stream, typename T, typename A>
Expand Down Expand Up @@ -810,6 +812,17 @@ void Serialize_impl(Stream &os, const std::vector<T, A> &v, const uint8_t &) {
}
}

template <typename Stream, typename T, typename A>
void Serialize_impl(Stream &os, const std::vector<T, A> &v, const bool &) {
// A special case for std::vector<bool>, as dereferencing
// std::vector<bool>::const_iterator does not result in a const bool&
// due to std::vector's special casing for bool arguments.
WriteCompactSize(os, v.size());
for (bool elem : v) {
::Serialize(os, elem);
}
}

template <typename Stream, typename T, typename A, typename V>
void Serialize_impl(Stream &os, const std::vector<T, A> &v, const V &) {
WriteCompactSize(os, v.size());
Expand Down
10 changes: 10 additions & 0 deletions src/test/serialize_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,16 @@ static bool isCanonicalException(const std::ios_base::failure &ex) {
return strcmp(expectedException.what(), ex.what()) == 0;
}

BOOST_AUTO_TEST_CASE(vector_bool) {
std::vector<uint8_t> vec1{1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1,
1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1};
std::vector<bool> vec2{1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1,
1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1};

BOOST_CHECK(vec1 == std::vector<uint8_t>(vec2.begin(), vec2.end()));
BOOST_CHECK(SerializeHash(vec1) == SerializeHash(vec2));
}

BOOST_AUTO_TEST_CASE(noncanonical) {
// Write some non-canonical CompactSize encodings, and make sure an
// exception is thrown when read back.
Expand Down

0 comments on commit 4b12d48

Please sign in to comment.