
Robert Ramey wrote:
I've concluded that serializing shared pointer only depending on the std::tr1::shared_ptr interface isn't going to be possible within the current serialization library. This will have to be handled via some separate module.
I'll try to come up with something. No timelines, though. There are some places where the library can be of assistance, but this can be done later in a series of incremental improvements. I looked at the implementation of the serialization library. Quite complicated and remarkable in its own way. ;-) The root cause is, in my opinion, that you started off with something and then added features as requested. Had you started with the _requested features_ you might not have needed to add the rest. Anyway, to get back to shared_ptr. The key points are: 1. The ability to inject a data member (the pointer map) into an archive. I intend to handle this by creating custom archive types that hold the required pointer map. 2. The ability to upcast a shared_ptr<void>/type_info to another shared_ptr<void>/type_info. The library has void_cast, but it supports raw pointers, not shared_ptr<void>. A separate upcast registry will be required, unless the void_cast mechanism is expanded to also provide shared_ptr<void> to shared_ptr<void> conversions. 3. The ability to serialize a polymorphic object. I'll just serialize a raw pointer; the library takes care of the rest. 4. The ability to deserialize a polymorphic object. Initially I'll deserialize a raw pointer. The problem with this approach is that the deserialized shared_ptr<T> will contain a deleter that will attempt to destroy a T, whereas the original may have had a deleter destroying a Derived. This can affect users if ~T is inaccessible or non-virtual or if T is incomplete. It is not possible to solve this without help from the library; basically, the T* deserializer (which internally operates with void*/type_info pairs) will need to be duplicated to return shared_ptr<T> (internally shared_ptr<void>/type_info). 5. The ability to downcast the deserialized shared_ptr<T> to shared_ptr<void> pointing to the most derived object. This can be done with dynamic_pointer_cast<void>. The external representation of shared_ptr / weak_ptr is as demonstrated by the earlier example: - int pid; - (opt) T * px; where pid == 0 denotes an empty pointer, a newly seen pid denotes a new object and is followed by px, and an already seen pid denotes a reference to an existing object. shared_ptr probably needs to be marked as "never track, unversioned" to not clutter the archive, but I'm not sure what is the official serialization library policy regarding std:: types.