Creating collection of msgpack::object
I'm looking for a simple way for creating a collection of msgpack::object, for example: [1, 2, 3][4, 5, 6][7, 8, 9]
Recently I reached this by serializing several msgpack::object into buffer and deserializing it back into one object holding three arrays. I hope it can be done with much simpler approach.
How about this? https://wandbox.org/permlink/h9JPuQeMNFfS9nkC https://wandbox.org/permlink/x4tOyPvlfIvnm0AQ
You can also do like this. https://wandbox.org/permlink/8C1s0e1N7G5xXSzm
In the approaches above, you need to care the lifetime of msgpack::zone.
You can make a pair of msgpack::object and msgpack::zone as follows:
#include <msgpack.hpp>
#include <iostream>
int main() {
auto z = std::make_unique<msgpack::zone>();
auto obj = msgpack::object(
std::make_tuple( std::make_tuple(1, 2.34, "ABC"), std::make_tuple(false, 5) ),
*z
);
std::cout << obj << std::endl;
msgpack::object_handle oh(obj, std::move(z));
std::cout << oh.get() << std::endl;
}
https://wandbox.org/permlink/tgNoHz16MFM3ajpc
You can treat the value oh like as the deserialized one ( msgpack::object_handle oh = msgpack::unpack(...);).
Thank you for quick answer. Please advice how to resolve next task:
We have some created objects:
msgpack::object Obj1;
msgpack::object Obj2;
msgpack::object Obj3;
How to put them into one msgpack::object as array in the most efficient way?
msgpack::object is basically designed as a kind of view type.
msgpack::object can be created from any C++ types that support adaptor.
In addition msgpack::object can be created from MessagePack formatted byte stream. It is called unpacking.
However, you cannot add elements dynamically to the msgpack::object that is previously created.
So, you need to do something like as follows:
#include <msgpack.hpp>
#include <iostream>
int main() {
auto z = std::make_unique<msgpack::zone>();
msgpack::object o1(1);
msgpack::object o2(2);
msgpack::object o3(3);
// create a vector of msgpack::object
std::vector<msgpack::object> vmo;
// add msgpack::object to the vector
vmo.push_back(o1);
vmo.push_back(o2);
vmo.push_back(o3);
// create the new msgpack::object from the vector
auto obj = msgpack::object(
vmo,
*z
);
std::cout << obj << std::endl;
msgpack::object_handle oh(obj, std::move(z));
std::cout << oh.get() << std::endl;
}
https://wandbox.org/permlink/snQMompWOHD4YwrP
Thank you. It seems that this solution fits all described tasks ^) But there is some inconvenience caused by need to keep zone alive when passing msgpack::object between functions.
But there is some inconvenience caused by need to keep zone alive when passing msgpack::object between functions.
See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object
msgpack::object_handle can treat zone and msgpack::object (including recursive sub objects) well.
NOTE:
You might think why msgpack::zone is needed, msgpack::object can manage their sub object by itself. It is for performance.
I used to try to eliminate msgpack::zone from the msgpack-c library. During that process, I noticed that I need to implement msgpack::object destructor recursively. If a msgpack::object has sub objects, the parent destructor need to call the sub-objects' destructor recursively. That means the destructor cannot be inlined. Inline or not inline is decided at compile time. That means most of leaf objects destructor that do nothing is actually called. It wasteful. I measured the performance. Using zone version is better.