aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/serialize.h187
1 files changed, 63 insertions, 124 deletions
diff --git a/src/serialize.h b/src/serialize.h
index 0cda0ac7d5..39f2c0f3ae 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -642,23 +642,14 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
* prevector
* prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
-template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
-template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
-template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
-template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
/**
* vector
* 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&);
-template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
/**
@@ -751,122 +742,82 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
/**
* prevector
*/
-template<typename Stream, unsigned int N, typename T>
-void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
-{
- WriteCompactSize(os, v.size());
- if (!v.empty())
- os.write(MakeByteSpan(v));
-}
-
-template<typename Stream, unsigned int N, typename T, typename V>
-void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
-{
- Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
-}
-
-template<typename Stream, unsigned int N, typename T>
-inline void Serialize(Stream& os, const prevector<N, T>& v)
-{
- Serialize_impl(os, v, T());
-}
-
-
-template<typename Stream, unsigned int N, typename T>
-void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
-{
- // Limit size per read so bogus size value won't cause out of memory
- v.clear();
- unsigned int nSize = ReadCompactSize(is);
- unsigned int i = 0;
- while (i < nSize)
- {
- unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
- v.resize_uninitialized(i + blk);
- is.read(AsWritableBytes(Span{&v[i], blk}));
- i += blk;
+template <typename Stream, unsigned int N, typename T>
+void Serialize(Stream& os, const prevector<N, T>& v)
+{
+ if constexpr (std::is_same_v<T, unsigned char>) {
+ WriteCompactSize(os, v.size());
+ if (!v.empty())
+ os.write(MakeByteSpan(v));
+ } else {
+ Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
-template<typename Stream, unsigned int N, typename T, typename V>
-void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
-{
- Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
-}
-template<typename Stream, unsigned int N, typename T>
-inline void Unserialize(Stream& is, prevector<N, T>& v)
+template <typename Stream, unsigned int N, typename T>
+void Unserialize(Stream& is, prevector<N, T>& v)
{
- Unserialize_impl(is, v, T());
+ if constexpr (std::is_same_v<T, unsigned char>) {
+ // Limit size per read so bogus size value won't cause out of memory
+ v.clear();
+ unsigned int nSize = ReadCompactSize(is);
+ unsigned int i = 0;
+ while (i < nSize) {
+ unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
+ v.resize_uninitialized(i + blk);
+ is.read(AsWritableBytes(Span{&v[i], blk}));
+ i += blk;
+ }
+ } else {
+ Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
+ }
}
-
/**
* vector
*/
-template<typename Stream, typename T, typename A>
-void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
-{
- WriteCompactSize(os, v.size());
- if (!v.empty())
- os.write(MakeByteSpan(v));
-}
-
-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>
+void Serialize(Stream& os, const std::vector<T, A>& v)
+{
+ if constexpr (std::is_same_v<T, unsigned char>) {
+ WriteCompactSize(os, v.size());
+ if (!v.empty())
+ os.write(MakeByteSpan(v));
+ } else if constexpr (std::is_same_v<T, 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);
+ }
+ } else {
+ Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
-template<typename Stream, typename T, typename A, typename V>
-void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
-{
- Serialize(os, Using<VectorFormatter<DefaultFormatter>>(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(Stream& is, std::vector<T, A>& v)
{
- Serialize_impl(os, v, T());
-}
-
-
-template<typename Stream, typename T, typename A>
-void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
-{
- // Limit size per read so bogus size value won't cause out of memory
- v.clear();
- unsigned int nSize = ReadCompactSize(is);
- unsigned int i = 0;
- while (i < nSize)
- {
- unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
- v.resize(i + blk);
- is.read(AsWritableBytes(Span{&v[i], blk}));
- i += blk;
+ if constexpr (std::is_same_v<T, unsigned char>) {
+ // Limit size per read so bogus size value won't cause out of memory
+ v.clear();
+ unsigned int nSize = ReadCompactSize(is);
+ unsigned int i = 0;
+ while (i < nSize) {
+ unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
+ v.resize(i + blk);
+ is.read(AsWritableBytes(Span{&v[i], blk}));
+ i += blk;
+ }
+ } else {
+ Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
-template<typename Stream, typename T, typename A, typename V>
-void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
-{
- Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
-}
-
-template<typename Stream, typename T, typename A>
-inline void Unserialize(Stream& is, std::vector<T, A>& v)
-{
- Unserialize_impl(is, v, T());
-}
-
-
/**
* pair
@@ -1039,28 +990,16 @@ public:
int GetVersion() const { return nVersion; }
};
-template<typename Stream>
-void SerializeMany(Stream& s)
-{
-}
-
-template<typename Stream, typename Arg, typename... Args>
-void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
-{
- ::Serialize(s, arg);
- ::SerializeMany(s, args...);
-}
-
-template<typename Stream>
-inline void UnserializeMany(Stream& s)
+template <typename Stream, typename... Args>
+void SerializeMany(Stream& s, const Args&... args)
{
+ (::Serialize(s, args), ...);
}
-template<typename Stream, typename Arg, typename... Args>
-inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
+template <typename Stream, typename... Args>
+inline void UnserializeMany(Stream& s, Args&&... args)
{
- ::Unserialize(s, arg);
- ::UnserializeMany(s, args...);
+ (::Unserialize(s, args), ...);
}
template<typename Stream, typename... Args>