Как использовать библиотеку Cereal для сериализации массивов / векторов перечислений в виде XML? - PullRequest
0 голосов
/ 29 июня 2019

Я пытался сериализовать векторы перечислений не как целые числа, а как текстовые значения.Включив save-load и / или save_minimal-load_minimal, генерируются ошибки компиляции.Я заинтересован только в сериализации.Функции десериализации предназначены только для предотвращения возможных ошибок.

include <fstream>
#include <cereal/types/vector.hpp>
#include <cereal/archives/xml.hpp>

namespace Test
{
    enum Enum
    {
        alpha,
        beta,
        gamma
    };

    static const char* const text[]
    {
        "alpha",
        "beta",
        "gamma"
    };

    typedef std::vector<Enum> EnumVector;

    class Object
    {
    public:
        typedef std::vector<Object> Vector;

        EnumVector data;

        template <class Archive>
        void save(Archive& archive) const
        {
            archive(cereal::make_nvp("data", data));
        }

        template <class Archive>
        void load(Archive& archive)
        {
            archive(cereal::make_nvp("data", data));
        }
    };

#if 0
    template <class Archive>
    void save(Archive& archive, const Enum item)
    {
        const std::string t = text[item];
        archive(t);
    }

    template <class Archive>
    void load(Archive& archive, Enum& item)
    {
        std::string value;
        archive(value);

        int i = 0;
        for(; i != 3; ++i)
        {
            if (value == text[i])
            {
                break;
            }
        }

        item = Enum(i);
    }
#endif
}

#if 0
namespace cereal
{
    template <class Archive>
    std::string save_minimal(Archive&, const ::Test::Enum item)
    {
        return ::Test::text(item);
    }

    template <class Archive>
    void load_minimal(const Archive&, ::Test::Enum& item, const std::string& value)
    { 
        int i = 0;
        for(; i != 3; ++i)
        {
            if (value == ::Test::text[i])
            {
                break;
            }
        }

        item = ::Test::Enum(i);
    }
}
#endif

int main()
{
    using namespace Test;
    Object::Vector objects{ {{alpha, alpha, gamma}}, {{beta, gamma, gamma}}};

    std::ofstream ofs("out.xml");
    cereal::XMLOutputArchive out(ofs);
    out(cereal::make_nvp("objects", objects));
}

Ожидаемый результат должен быть

<?xml version="1.0" encoding="utf-8"?>
<cereal>
    <objects size="dynamic">
        <value0>
            <data size="dynamic">
                <value0>alpha</value0>
                <value1>alpha</value1>
                <value2>gamma</value2>
            </data>
        </value0>
        <value1>
            <data size="dynamic">
                <value0>beta</value0>
                <value1>beta</value1>
                <value2>gamma</value2>
            </data>
        </value1>
    </objects>
</cereal>

PS Имена элементов вектора / массива очень странны для XML, поскольку очень сложно определить схему XML (XSD) для такого представления.Можно ли подавить числа?

...