msgpack-c
msgpack-c copied to clipboard
Variant of MSGPACK_DEFINE that is intrusive
Is it possible to have a variant of MSGPACK_DEFINE that is non-intrusive. For example, instead of :
struct A
{
int a;
int b;
MSGPACK_DEFINE(a,b);
};
we have:
struct A
{
int a;
int b;
};
MSGPACK_DEFINE_EXTERNAL(A, a,b);
This would be useful to extend the functionality of messagepack.
For example, how do i support std::complex
?
Mainly, right now i need to support std::complex
. I can look at the adaptor for std::pair to write my own. But a macro would make things a lot easier.
#ifndef MSGPACK_COMPLEX_H
#define MSGPACK_COMPLEX_H
#include <complex>
#include "msgpack/versioning.hpp"
#include "msgpack/adaptor/adaptor_base.hpp"
#include "msgpack/meta.hpp"
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v1) {
/// @endcond
namespace adaptor {
#if !defined(MSGPACK_USE_CPP03)
template <typename T>
struct as<std::complex<T>, typename std::enable_if<msgpack::has_as<T>::value>::type>
{
std::complex<T> operator()(msgpack::object const& o) const
{
if (o.type != msgpack::type::ARRAY)
throw msgpack::type_error();
if (o.via.array.size != 2)
throw msgpack::type_error();
return std::complex<T>(o.via.array.ptr[0].as<T>(), o.via.array.ptr[1].as<T>());
}
};
#endif // !defined(MSGPACK_USE_CPP03)
template <typename T>
struct convert<std::complex<T> >
{
msgpack::object const& operator()(msgpack::object const& o, std::complex<T>& v) const
{
if(o.type != msgpack::type::ARRAY)
throw msgpack::type_error();
if(o.via.array.size != 2)
throw msgpack::type_error();
T real = v.real();
T imag = v.imag();
o.via.array.ptr[0].convert(real);
o.via.array.ptr[1].convert(imag);
v.real(real);
v.imag(imag);
return o;
}
};
template <typename T>
struct pack<std::complex<T> >
{
template <typename Stream>
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::complex<T>& v) const
{
o.pack_array(2);
o.pack(v.real());
o.pack(v.imag());
return o;
}
};
template <typename T>
struct object_with_zone<std::complex<T> >
{
void operator()(msgpack::object::with_zone& o, const std::complex<T>& v) const
{
o.type = msgpack::type::ARRAY;
msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*2, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
o.via.array.ptr = p;
o.via.array.size = 2;
p[0] = msgpack::object(v.real(), o.zone);
p[1] = msgpack::object(v.imag(), o.zone);
}
};
} // namespace adaptor
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v1)
/// @endcond
} // namespace msgpack
#endif /* MSGPACK_COMPLEX_H */
Is this ok?
https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor#non-intrusive-approach
This is a document how to write non-intrusive adaptor. You can use that way.
I've added a pull request for complex type. I think the CI config is broken because the build is failing when trying to apt install stuff from an azure ppa. @redboltz could you have a look at this. I think other people's pull requests are failing due to the same issue.
Yes, it seems that CI script needs to update. Unfortunately, I don't have much time. @ygj6 , if you have time, could you investigate CI error?
the build is failing when trying to apt install stuff from an azure ppa.
Indeed, I will fix it as soon as possible.