Dave Harris wrote:
You will not need any hooks; to fully bracket the data, you can use a type-conversion trick made concrete below.It's a neat trick, but I'd rather not rely on tricks. I might want:
For now, I'm of the same mind. Let's use tricks when a real need is seen. Explicit end marker is quite appropriate.
Yes; I had proposed in an earlier email a seperate serializor which included the name strings:
return o << "bar" << bar << "foo" << foo ...
This would provide the needed names to the system.
As I understood it, this also relied on a trick - on the XML oarchive assuming that alternate writes were names rather than values. If we sent the same output to a different oarchive, it presumably wouldn't make that assumption and they would be treated as values and repeated in the data of each object serialised. That is quite an overhead. The alternative, that non-XML archives also ignore alternate string writes, is bad too because one archive format should not have to work to indulge vagarities of another. A third alternative, for the object to somehow know when it is writing to an XML archive and serialise differently, is also bad.
I think such tricks are a bad way to go. I would much rather have something explicit like:
ar << tag("bar") << bar << tag("foo") << foo;
I wonder if this explicit enough. Not sure what is most common use case, but I might want to specify names for several variables and leave others unnamed, and is afraid of possible confusion. A better way, IMO, would be: ar(bar, "bar")(foo, "foo")(biz); Note that the third variable has no associated name. Yes, this completely different from how data is written now. Maybe, "tag" is OK, after all...
where the oarchive has a virtual function for writing tags. This also allows:
ar << tag("point") << x << y;
where there is no need for the tags to alternate with values.
It'd be possible to implement such stuff on top of the current submission, without adding virtual functions to the base classes, by using dynamic_cast. Eg:
struct tag {
tag( const char *str ) : str(str) {}
const char *str;
};
basic_oarchive &operator>>( basic_oarchive &ar, const tag &t ) {
if (basic_tagged_oarchive *p =
dynamic_cast<basic_tagged_oarchive *>( &ar ))
p->tag( t.str );
return ar;
}
I'd prefer virtual functin 'tag' to dynamic_cast.
Personally I'd rather add the virtual functions, because I prefer to avoid dynamic_cast<>. I'd rather have dynamic_cast<> than make assumptions about alternate writes, though.Hmm... do you prefer virtual function too? I don't see why we need assumptions
about alternate write, then. Just 'tag' method, if called, given a name for
the followng primitive or composite data item. Archives that do not care ignore the call.
Really we are just talking about 3 functions: start_group(), end_group() and tag(). People who don't need XML output wouldn't need to use them. In practice I think using them would help a lot in producing human readable output. We could probably get rid of the newline() function, for example.It's harder. I'll need separate markers for sequences, maps/sets and composites. This way it's possible to serialize to Python code or YAML,
read the data in Python, and do something sensible with it.
- Volodya
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost