Serileştirmeyi uygulamak için aşağıdaki şablonu kullanıyorum:
template <class T, class Mode = void> struct Serializer
{
template <class OutputCharIterator>
static void serializeImpl(const T &object, OutputCharIterator &&it)
{
object.template serializeThis<Mode>(it);
}
template <class InputCharIterator>
static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
{
return T::template deserializeFrom<Mode>(it, end);
}
};
template <class Mode = void, class T, class OutputCharIterator>
void serialize(const T &object, OutputCharIterator &&it)
{
Serializer<T, Mode>::serializeImpl(object, it);
}
template <class T, class Mode = void, class InputCharIterator>
T deserialize(InputCharIterator &&it, InputCharIterator &&end)
{
return Serializer<T, Mode>::deserializeImpl(it, end);
}
template <class Mode = void, class T, class InputCharIterator>
void deserialize(T &result, InputCharIterator &&it, InputCharIterator &&end)
{
result = Serializer<T, Mode>::deserializeImpl(it, end);
}
İşte Tsize serialize istediğiniz tip olduğu Modegibi serileştirme farklı türde birbirinden ayırt edebilmek için kukla türüdür. aynı tamsayı küçük endian, büyük endian, varint vb.
Varsayılan olarak Serializer, görevi serileştirilen nesneye delege eder. Yerleşik türler için bir şablon uzmanlığı yapmalısınız Serializer.
Kolaylık fonksiyonu şablonları da sunulmaktadır.
Örneğin, işaretsiz tam sayıların küçük endian serileştirmesi:
struct LittleEndianMode
{
};
template <class T>
struct Serializer<
T, std::enable_if_t<std::is_unsigned<T>::value, LittleEndianMode>>
{
template <class InputCharIterator>
static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
{
T res = 0;
for (size_t i = 0; i < sizeof(T); i++)
{
if (it == end) break;
res |= static_cast<T>(*it) << (CHAR_BIT * i);
it++;
}
return res;
}
template <class OutputCharIterator>
static void serializeImpl(T number, OutputCharIterator &&it)
{
for (size_t i = 0; i < sizeof(T); i++)
{
*it = (number >> (CHAR_BIT * i)) & 0xFF;
it++;
}
}
};
Sonra serileştirmek için:
std::vector<char> serialized;
uint32_t val = 42;
serialize<LittleEndianMode>(val, std::back_inserter(serialized));
Serisini kaldırmak için:
uint32_t val;
deserialize(val, serialized.begin(), serialized.end());
Soyut yineleyici mantığı nedeniyle, herhangi bir yineleyici (örn. Akış yineleyicileri), işaretçi vb.