Browse Source

boost: drop dependency on is_fundamental in serialization

There's only one case where a vector containing a fundamental type is
serialized all-at-once, unsigned char. Anything else would lead to
strange results.

Use a dummy argument to overload in that case.
0.10
Cory Fields 10 years ago
parent
commit
1d9b86d584
  1. 38
      src/serialize.h

38
src/serialize.h

@ -21,7 +21,6 @@
#include <vector> #include <vector>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_fundamental.hpp>
class CAutoFile; class CAutoFile;
class CDataStream; class CDataStream;
@ -432,14 +431,15 @@ template<typename Stream, typename C> void Serialize(Stream& os, const std::basi
template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0); template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
// vector // vector
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); // vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion); template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion); template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion); template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
// others derived from vector // others derived from vector
@ -536,13 +536,13 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
// vector // vector
// //
template<typename T, typename A> template<typename T, typename A>
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
{ {
return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
} }
template<typename T, typename A> template<typename T, typename A, typename V>
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
{ {
unsigned int nSize = GetSizeOfCompactSize(v.size()); unsigned int nSize = GetSizeOfCompactSize(v.size());
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
@ -553,20 +553,20 @@ unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nV
template<typename T, typename A> template<typename T, typename A>
inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion) inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
{ {
return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>()); return GetSerializeSize_impl(v, nType, nVersion, T());
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
{ {
WriteCompactSize(os, v.size()); WriteCompactSize(os, v.size());
if (!v.empty()) if (!v.empty())
os.write((char*)&v[0], v.size() * sizeof(T)); os.write((char*)&v[0], v.size() * sizeof(T));
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A, typename V>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
{ {
WriteCompactSize(os, v.size()); WriteCompactSize(os, v.size());
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
@ -576,12 +576,12 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVers
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion) inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
{ {
Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>()); Serialize_impl(os, v, nType, nVersion, T());
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
{ {
// Limit size per read so bogus size value won't cause out of memory // Limit size per read so bogus size value won't cause out of memory
v.clear(); v.clear();
@ -596,8 +596,8 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion,
} }
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A, typename V>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
{ {
v.clear(); v.clear();
unsigned int nSize = ReadCompactSize(is); unsigned int nSize = ReadCompactSize(is);
@ -617,7 +617,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion,
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion) inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
{ {
Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>()); Unserialize_impl(is, v, nType, nVersion, T());
} }

Loading…
Cancel
Save