
At 9:14 AM -0800 2/12/06, Robert Ramey wrote:
David Abrahams wrote: A strong typedef should work, if all archives implement its serialization.
as a general rule, the included archives only implment serialization for primitives. This permits all serializations to work with all archives. Its been a constant battle to keep these things decoupled in order to preserve this feature.
serializations should be attributes of the type NOT any particular archive.
This is the objection I expected to hear from Robert much earlier in this discussion. A strong typedef for this purpose effectively widens the archive concept by adding a new thing that needs to be supported. That conceptual widening occurs even if the default archive behavior for a strong typedef is to just serialize the underlying type. It still needs to be documented as part of the archive concept, and anyone defining a new kind of archive ought to consider whether that default is the correct behavior for this new archive type, or whether something else is needed. And I think he would have a pretty good rationale for feeling that way. Keeping the archive interface narrow and minimizing the coupling between serialization and archives minimal is, I think, one of the strengths of the serialization library's design. I would be in full agreement with Robert here, except that all of the alternatives I can think of seem worse to me. 1. std::size_t This causes major problems for portable binary archives. I'm aware that portable binary archives are tricky (and perhaps not truly possible in the most general sense of "portable"). In particular, they require that users of such archives be very careful about the types that they include in such archives, avoiding all explicit use of primitive types with implementation-defined representations in favor of types with a fixed representation. So no int's or long's, only int32_t and the like. Floating point types add their own complexity. Some (potential) users of the serialization library (such as us) are already doing that, and have been working under such restrictions for a long time (long before we ever heard of boost.serialization), because cross-platform serialization is important to us. The problem for portable binary archives caused by using std::size_t as the container count is that it is buried inside the container serializer, where the library client has no control over it. All the archive gets out of the serializer is the underlying primitive type, with which it does whatever it does on the given platform. The semantic information that this is a container count is lost by the time the archive sees the value, so there's nothing a "portable" archive can do to address this loss of information. And this occurs no matter how careful clients are in their own adherence to use of fixed representation value types. This leaves a client needing a portable binary archive with several unappealing options (in no particular order) - Modify the library to use one of the other options. - Override all of the needed container serializers specifically for the portable archive. - Don't attempt to serialize any standard container types. 2. standard fixed-size type We already know that uint32_t is inadequate; there are users with very large containers. Maybe uint64_t is big enough, though of course predictions of that sort have a history of proving false, sometimes in a surprisingly short time. And uint64_t isn't truly portable anyway, since an implementation might not have that type at all. Also, some might object to always requiring 8 bytes of count information, even when the actual size will never be anything like that large. This was my preferred approach before I learned about the strong typedef approach, in spite of the stated problems. 3. some self-contained variable-size type This might be possible, but the additional complexity is questionable. Also, all of the ideas I've thought of along this line make the various text-based archives less human readable, which some might reasonably find objectionable. 4. something else I haven't thought of any. Anybody else? So it appears to me that all of the available options have downsides. While my initial reaction to the strong typedef approach was rather ambivalent because of the associated expansion of the archive concept, it seems to me to be the best of the available options.