I have made a class that wraps boost::uuids::uuid
. Now I want to insert the the wrapped value into an XML using boost::archive::xml_oarchive
. The following minimal example does that:
#include <iostream>
#include <sstream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/wrapper.hpp>
#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_serialize.hpp>
class Wrapper {
public:
explicit Wrapper(boost::uuids::uuid value)
: m_value{value} {}
boost::uuids::uuid &operator*() { return m_value; }
private:
boost::uuids::uuid m_value;
};
BOOST_CLASS_IS_WRAPPER(Wrapper)
template <class Archive>
void serialize(Archive &archive, Wrapper &wrapper, [[maybe_unused]] const uint version) {
archive << boost::serialization::make_nvp("key", *wrapper);
}
int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) {
std::ostringstream oss;
boost::uuids::uuid value{};
Wrapper wrapper{value};
std::string string = to_string(*wrapper);
{
boost::archive::xml_oarchive archive(oss);
archive << boost::serialization::make_nvp("expected", string);
archive << boost::serialization::make_nvp("result", wrapper);
}
std::cout << oss.str() << std::endl;
return 0;
}
However, this outputs the following XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="18">
<expected>00000000-0000-0000-0000-000000000000</expected>
<result class_id="0" tracking_level="0" version="0">
<key>00000000-0000-0000-0000-000000000000</key>
</result>
</boost_serialization>
As you can see, the wrapped uuid is nested inside <result><key> ... </key></result>
, but want I want is it to be similar to the <expected> ... </expected>
part (the class_id
, etc metadata is fine, just not nesting).
I've tried various permutations of removing the BOOST_CLASS_IS_WRAPPER
, using it on boost::uuids::uuid
, using to_string
in serialize
and then serializing the std::string
, etc, but none of them achieves the desired result.
The nvp
wrapper adds a layer. Simplify:
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/wrapper.hpp>
#include <boost/uuid.hpp>
#include <iostream>
class Wrapper {
public:
explicit Wrapper(boost::uuids::uuid value) : m_value{value} {}
boost::uuids::uuid& operator*() { return m_value; }
private:
boost::uuids::uuid m_value;
};
BOOST_CLASS_IS_WRAPPER(Wrapper)
BOOST_CLASS_IMPLEMENTATION(Wrapper, boost::serialization::object_serializable)
BOOST_CLASS_TRACKING(Wrapper, boost::serialization::track_never)
void serialize(auto& archive, Wrapper& wrapper, unsigned) {
archive << boost::serialization::make_nvp("key", *wrapper);
}
int main() {
Wrapper w{{}};
boost::archive::xml_oarchive(std::cout) << w;
}
Prints
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="20">
<key>00000000-0000-0000-0000-000000000000</key>
</boost_serialization>