aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfanquake <fanquake@gmail.com>2019-08-27 07:36:33 +0800
committerfanquake <fanquake@gmail.com>2019-08-27 07:57:50 +0800
commitefe1ee0d8d7f82150789f1f6840f139289628a2b (patch)
treec81b33db154860283af29779b700aa908868e191
parentadff8fe32101b2c007a85415c3ec565a7f137252 (diff)
parent92528c260e9bd5d36da4b017098a49fda5051154 (diff)
Merge #16730: Support serialization of std::vector<bool>
92528c260e9bd5d36da4b017098a49fda5051154 Support serialization of std::vector<bool> (Pieter Wuille) Pull request description: This adds support for serialization of `std::vector<bool>`, as a prerequisite of #16702. ACKs for top commit: MarcoFalke: ACK 92528c260e9bd5d36da4b017098a49fda5051154 (only looked at the diff on GitHub) practicalswift: ACK 92528c260e9bd5d36da4b017098a49fda5051154 -- diff looks correct jamesob: ACK https://github.com/bitcoin/bitcoin/pull/16730/commits/92528c260e9bd5d36da4b017098a49fda5051154 Tree-SHA512: 068246a55a889137098f817bf72d99fc3218a560d62a97c59cccc0392b110f6778843cee4e89d56f271ac64e03a0f64dc5e2cc22daa833fbbbe9234c5f42d7b9
-rw-r--r--src/serialize.h13
-rw-r--r--src/test/serialize_tests.cpp8
2 files changed, 21 insertions, 0 deletions
diff --git a/src/serialize.h b/src/serialize.h
index 1dc27d84eb..a38d76fc18 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -555,6 +555,7 @@ template<typename Stream, unsigned int N, typename T> inline void Unserialize(St
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
+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> inline void Serialize(Stream& os, const std::vector<T, A>& v);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
@@ -713,6 +714,18 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&
os.write((char*)v.data(), v.size() * sizeof(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&)
{
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index 8a8620938e..b90be15fba 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -258,6 +258,14 @@ 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)
{