
"Peter Dimov" <pdimov@mmltd.net> wrote in message news:002d01c4cfe2$96d92bf0$6501a8c0@pdimov2...
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:
2. The ability to upcast a shared_ptr<void>/type_info to another shared_ptr<void>/type_info.
I don't see why this is necessary
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).
I don't see why this is necessary. During deserialization - the shared_ptr already exists - usually as a member variable of same data structure. Its already been created with the appropriate deleter. If the current deleter is different than the original - then its an issue to be addressed with class versioning. In general, the serialization library presumes that the s tructure being recovered is the same as that originally saved - any differences are addressed through versioning.
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>.
I don't see why this is necessary. The library does the appropriate downcasting of raw pointer. As far as I know there's no reason why a share_ptr<T> can't have a raw_ptr which, though it points to a T, actually corresponds to a derivation of T.
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.
I don't see why this is necessary. The library already correctly handles null raw pointers.
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.
For std collections, the policy I've used has been: a) unversioned - on the idea that std collections are "cast in stone". Given the complexity of serialization of shared_ptr, the possibility that its serialization may depend upon its implementation (at least for boost::shared_ptr, and that you've reserved the right to change the implementation) I think it would be prudent to leave it as the default - i.e versioned. This only adds 1 integer per template instantiation per archive. A small price to pay to maintain future readability. b) tracking - default. This means that instances are tracked if and only if anywhere in the program the the type is serialized through a pointer. I wouldn't expect that to happen so I expect the default would be just fine. The only real issue as I see it is that of pointer mapping. Making an archive derivation that includes the map would work fine - but I would hope we could find something that doesn't require a special archive type to serialize a specific data type. Perhaps we can permit one to register an exit routine with an archive. Then when a map is created a deletere is registered with the archive. I wouldn't be in love with this but I could probably live with it. The other thing I was thinking about was the possibility of adding access to the tracking map for matching up de-serialized shared_ptrs. So far, I haven't resolved this in my own mind - I'm still thinking about it. It's probably a dead end. Robert Ramey