मैं क्रमांकन लागू करने के लिए निम्नलिखित टेम्पलेट का उपयोग कर रहा हूं:
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);
}
यहाँ T
प्रकार है जिसे आप क्रमबद्ध करना चाहते हैं Mode
, विभिन्न प्रकार के क्रमांकन के बीच अंतर करने के लिए एक डमी प्रकार है, जैसे। एक ही पूर्णांक को छोटे एंडियन, बड़े एंडियन, वेरिंट आदि के रूप में क्रमबद्ध किया जा सकता है।
डिफ़ॉल्ट रूप से Serializer
प्रतिनिधि को ऑब्जेक्ट को क्रमबद्ध किया जा रहा है। बिल्ट इन टाइप्स के लिए आपको एक खाका बनाना चाहिए Serializer
।
सुविधा फ़ंक्शन टेम्पलेट भी प्रदान किए जाते हैं।
उदाहरण के लिए अहस्ताक्षरित पूर्णांक के छोटे एंडियन क्रमांकन:
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++;
}
}
};
फिर क्रमबद्ध करने के लिए:
std::vector<char> serialized;
uint32_t val = 42;
serialize<LittleEndianMode>(val, std::back_inserter(serialized));
Deserialize करने के लिए:
uint32_t val;
deserialize(val, serialized.begin(), serialized.end());
अमूर्त पुनरावृत्ति तर्क के कारण, इसे किसी भी पुनरावृत्त (जैसे। स्ट्रीम पुनरावृत्तियों), सूचक आदि के साथ काम करना चाहिए।