From 186f7d2861637626eead85204cfe50ab31d0eafa Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 28 May 2019 15:15:37 +0200 Subject: [PATCH] Implement support for explicit enum serialization This allows to serialize enum values, but only if a specialized class of is_serializable_enum is found which is derived from std::true_type. --- src/serialize.h | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/serialize.h b/src/serialize.h index 99801f7e5..268c70396 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -720,20 +720,52 @@ template void Unserialize(Stream& os, std::unique_p /** - * If none of the specialized versions above matched, default to calling member function. + * If none of the specialized versions above matched and T is a class, default to calling member function. */ -template +template::value>::type* = nullptr> inline void Serialize(Stream& os, const T& a) { a.Serialize(os); } -template +template::value>::type* = nullptr> inline void Unserialize(Stream& is, T& a) { a.Unserialize(is); } +/** + * If none of the specialized versions above matched and T is an enum, default to calling + * Serialize/Unserialze with the underlying type. This is only allowed when a specialized struct of is_serializable_enum + * is found which derives from std::true_type. This is to ensure that enums are not serialized with the wrong type by + * accident. + */ + +template struct is_serializable_enum; +template struct is_serializable_enum : std::false_type {}; + +template::value>::type* = nullptr> +inline void Serialize(Stream& s, T a ) +{ + // If you ever get into this situation, it usaully means you forgot to declare is_serializable_enum for the desired enum type + static_assert(is_serializable_enum::value); + + typedef typename std::underlying_type::type T2; + T2 b = (T2)a; + Serialize(s, b); +} + +template::value>::type* = nullptr> +inline void Unserialize(Stream& s, T& a ) +{ + // If you ever get into this situation, it usaully means you forgot to declare is_serializable_enum for the desired enum type + static_assert(is_serializable_enum::value); + + typedef typename std::underlying_type::type T2; + T2 b; + Unserialize(s, b); + a = (T)b; +}