Hi François,
I would suggest that nothing should be changed in the core Boost/Serialization XML lib,
Sure. I am just seen what is the consensus on this. The suggestion was only based in the fact that the implementation of boost.serialization.XML was based on that XML is more human readable than text files. Now I will continue answering your questions.
even if what you propose is fancy and even if it is an option (who would choose the "name of the class" to be saved ?
In the same way "name of the class" is chosen arbitrarily for derived-from-base class during serialization. Furthermore it can be ignored on reading.
How to make sure that the convention for class naming is the same while reading and writing ? I guess it addresses some new problems...).
In the same way the convention for class naming is the same for derived-from-base classes. Again, it can be ignored on reading.
Rather than acking the BS lib, what you asked for could be probably easily implemented by some specific I/O manager dedicated for your specific need during I/O operations.
the "hacking" I suggested (i.e. the explicit code) does not hack Boost.Serialization but it hacks Boost.Units.serialization, and it is within the framework of Boost.Serialization. (the standalone serialization/load/save function can be anything the user wants... I guess, although I was not sure if it should throw or not)
When I serialize some heterogeneous sets of objects in any kind of archives (text/XML/eos::portable_binary), I first store/load a "serialization tag" (std::string) that identifies the type/class of the next object to be stored|loaded. It is thus my responsability to manage a set of known tags associated to the classes I need to serialize.
Do you mean something like this? void serialize(Archive & ar, Object obj, unsigned){ ar & typeof(obj.a).name(); // just one way to store type information, check enforce can be added in the same way I did in my quantity example ar & obj.a; ar & "type of b"; // just one way to store type information ar & obj.b; } It is actually a good idea, Thanks!. (It is indeed similar to what I did by storing the information but only inside the tag for boost.quantity.)
So it turns out that any serializable data is confined in some kind of virtual container, together with some kind of class ID: <archive> serial_tag #0 data_record #0 (snip) Of course, it implies some smarter management of the I/O operations and some hard-coded factory (in a basic implementation). But it is very convenient for debugging and compatible with all kind of archives.
I got lost with the "hard-coded factory" but I get the idea.
This mechanism is clearly a brute force approach and maybe some people consider this as inelegant. Anyway I have used this in production code for years and it is very robust.
Note that it is different from the BOOST_CLASS_EXPORT mechanism which implies all your objects must be serialized by a base pointer and inherited from a unique abstract class/interface.
Yes, I noticed the difference. In fact my suggestion was based in BOOST_CLASS_EXPORT but for cases where 1) the class name is not really necesary, e.g. there is not derived pointer 2) object serialized is not a pointer even. I liked the fact that the type information in the currently implemention appears in the xml tag, seemed elegant.
Could it be possible for you to use a wrapper class with the additional meta-info you need rather than to rely on some intrusive modification of the core functionality of the lib ?
I didn't investigate the use of wrappers but seems logical if the core library can not be changed. I found the description of wrapper http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/wrappers.html quite obfuscated
struct quantity_wrapper<...> { boost::units::quantity<...> q; std::string more_info; void serialize(...); };
I see, that is the wrapper, what next? do I replace quantity_wrapper
in all the classes where quantity is a member?
class Object{
quantity_wrapper< dim1 > a; // was quantity< dim1 >
quantity_wrapper< dim2 > b; // was quantity< di21 >
};
or do I serialize my class creating temporary quantity objects, don't
I need to use a wrapper of reference instead?
struct quantity_wrapper< Unit>{
boost::units::quantity< Unit >& q; <--- reference ???
std::string more_info;
quantity_wrapper< Unit >(quantity< Unit > q_) : q(q_),
more_info(to_string(Unit())){}
void serialize(...);
};
and then
serialize(Archive ar, Object o, unsigned){
ar & quantity_wrapper<dim1>(o.a); // a is quantity<dim1>
ar & quantity_wrapper<dim2 >(o.b); // b is quantity< dim2 >
}
do I need to specialize is_wrapper