Search code examples
c++serializationenumsrtticereal

Cereal: Shared serialization function across enums


Lets suppose I have something like:

enum t_color { BLUE=0,RED,GREEN};
vector<string> TAG_color={"BLUE", "RED", "GREEN"};

enum t_colores { AZUL=0,ROJO,VERDE};
vector<string> TAG_colores={"AZUL", "ROJO", "VERDE"};

I want to use (in cereal) a common save_minimal, such as:

  template <class Archive,typename T > inline
  std::string save_minimal( Archive const &, typename std::enable_if< std::is_enum<T>::value, T >::type const & t )
  {
    std::string ret="Unknown";
    if ( std::is_same<T,t_color>::value)
    {
      ret=TAG_color[t];
    }
    else if (  std::is_same<T,t_colores>::value)
    {
      ret=TAG_colores[t];
    }
    return ret;
 }

It compiles but seems like cereal is ignoring the template. It just use the "integer" value of the enum.


Solution

  • Yep... it is doable (but not directly through cereal):

    #define SERIALIZE_ENUM(enumname)                                               \
    template <class Archive> inline                                                \
    std::string save_minimal( Archive const &, t_##enumname const & t )            \
    {                                                                              \
      return std::string(TAG_##enumname[t]);                                       \
    }                                                                              \
    template <class Archive> inline                                                \
    void load_minimal(Archive const&, t_##enumname & t,std::string  const& value ) \
    {                                                                              \
      int a=0;                                                                     \
      for (auto const &tag:TAG_##enumname)                                         \
      {                                                                            \
        if ( tag == value )                                                        \
        {                                                                          \
          t = static_cast<t_##enumname>(a);                                        \
          return;                                                                  \
        }                                                                          \
        a++;                                                                       \
      }                                                                            \
    
    namespace cereal { 
      SERIALIZE_ENUM(color)
      SERIALIZE_ENUM(colores)
    }