msgpack / msgpack-c

MessagePack implementation for C and C++ / msgpack.org[C/C++]
Other
3.03k stars 883 forks source link

[Feature requestion] Integration with Boost::Describe #1143

Open pfeatherstone opened 1 month ago

pfeatherstone commented 1 month ago

I've been playing with a Boost::Describe integration.

Here is an example that packs a custom struct into a stream. It only supports packing for now.

#include <cstdio>
#include <msgpack.hpp>
#include <boost/describe/class.hpp>

template <
    bool as_map,
    class Stream,
    class T,
    class D1 = boost::describe::describe_members<T, boost::describe::mod_any_access>
>
void msgpack_pack(msgpack::packer<Stream>& packer, const T& obj, std::integral_constant<bool, as_map>)
{
    if constexpr (as_map)
    {
        packer.pack_map(boost::mp11::mp_size<D1>::value);

        boost::mp11::mp_for_each<D1>([&](auto D) {
            packer.pack(D.name);
            packer.pack(obj.*D.pointer);
        });
    }
    else
    {
        packer.pack_array(boost::mp11::mp_size<D1>::value);

        boost::mp11::mp_for_each<D1>([&](auto D) {
            packer.pack(obj.*D.pointer);
        });
    }
}

template <
    bool as_map,
    class Stream,
    class T,
    class D1 = boost::describe::describe_members<T, boost::describe::mod_any_access>
>
void msgpack_pack(Stream& stream, const T& obj, std::integral_constant<bool, as_map> option)
{
    msgpack::packer<Stream> packer(&stream);
    msgpack_pack(packer, obj, option);
}

struct example_struct
{
    std::string msg;
    std::vector<float> v; 
};

BOOST_DESCRIBE_STRUCT(example_struct, (), (msg, v))

int main()
{
    example_struct data;
    data.msg = "Hello there!";
    data.v.resize(10);

    msgpack::sbuffer buf1, buf2;
    msgpack_pack(buf1, data, std::true_type{}); // as map
    msgpack_pack(buf2, data, std::false_type{}); // as array

    printf("Serialized as map %zu - serialized as array %zu\n", buf1.size(), buf2.size());
    return 0;
}

Now i've implemented my own msgpack_pack function. What i would really like is to reuse the msgpack API. Can you think of ways to achieve this?