You can create a msgpack::object
from C++ types.
See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion
When you call msgpack::object
constructor with zone like msgpack::object(mc, z);
, object_with_zone<T>::operator()
is called internally.
If you don't want to create msgpack::object
from C++ types, you don't need to define object_with_zone
specialization. Packing, unpacking, and converting to C++ types from msgpack::object
don't require it.
Here is an example:
#include <iostream>
#include <msgpack.hpp>
class my_class {
public:
my_class(std::string const& name, int age):name_(name), age_(age) {}
std::string const& get_name() const { return name_; }
int get_age() const { return age_; }
private:
std::string name_;
int age_;
};
// User defined class template specialization
namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {
template <>
struct object_with_zone<my_class> {
void operator()(msgpack::object::with_zone& o, my_class const& v) const {
std::cout << "object_with_zone<my_class> is called" << std::endl;
o.type = type::ARRAY;
o.via.array.size = 2;
o.via.array.ptr = static_cast<msgpack::object*>(
o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
o.via.array.ptr[0] = msgpack::object(v.get_name(), o.zone);
o.via.array.ptr[1] = msgpack::object(v.get_age(), o.zone);
}
};
} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack
int main() {
my_class mc("John", 42);
msgpack::zone z;
auto obj = msgpack::object(mc, z);
std::cout << obj << std::endl;
}
Output:
object_with_zone<my_class> is called
["John", 42]
Running demo: https://wandbox.org/permlink/dNmZX1FpUL3w8D5m
updated
Additional question. Why would i want to use the zone ?
Answer:
A zone is used internally when you unpack MessagePack formatted byte stream. You get msgpack::object_handle
. msgpack::object_handle
has a zone and a msgpack::object
. See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#what-is-msgpackobject.
The reason of using msgpack::zone
is for performance. If msgpack::object
is STR
, BIN
, or EXT
, the msgpack::object
need to allocate a memory dynamically. The msgpack::object
can have a handle of the memory by itself but it is inefficient. The destructor of msgpack::object
need to deallocate memory, if the msgpack::object
allocate memory. msgpack::object
is a composite data structure. That means the destructor cannot be inlined.
One of the goal of msgpack-c is efficient unpacking. So msgpack-c uses msgpack::zone
.
It is unpacking story. msgpack::zone
is also used when msgpack::object
is created from C++ types. I'm not sure when users want to do, is is up to users.