[xsd-users] Re: cxx-tree --variant-type= ?
Boris Kolpackov
boris at codesynthesis.com
Tue Dec 16 07:50:50 EST 2014
Hi Mario,
[CC'ed xsd-users].
Mario Lang <mlang at delysid.org> writes:
> For my MusicXML library, I now rewrote my two --ordered-type(s) with
> boost::variant as a --custom-type. I find this much more convenient to
> use on the client side, especially since container manipulation (insert,
> push_back, push_front, etc.) functions do not have to be manually implemented. As
> an added benefit, I get a compile-time checked visitor interface. The
> transformation was quite mechanical though:
>
> 1. Remove all direct sequence accessors.
> 2. Redefine content_oder_ and its accessors as variant_sequence, a
> std::vector<boost::variant<...>>.
> 3. Write a serialization_visitor to handle serialization from a
> container of variants. Something like this:
>
> class serialization_visitor : public boost::static_visitor<void> {
> ::xercesc::DOMElement &e;
>
> public:
> serialization_visitor(::xercesc::DOMElement &e) : e(e) {}
>
> void operator()(const ::musicxml::note &x) const {
> ::xsd::cxx::xml::dom::create_element("note", e) << x;
> }
> void operator()(const ::musicxml::backup &x) const {
> ::xsd::cxx::xml::dom::create_element("backup", e) << x;
> }
> void operator()(const ::musicxml::forward &x) const {
> ::xsd::cxx::xml::dom::create_element("forward", e) << x;
> }
> //...
> };
>
> 4. Rewrite the parsing code to *not* use element_traits::create,
> instead, push_back directly to variant_.
>
> This works WONDERFUL. I really love it. I wonder, have you ever
> considered to implement this as an alternative for --ordered-type?
> Maybe --variant-type= ? --variant-type=class[/accessor] maybe?
> So the user could override the name of the variant() accessor.
No, I haven't considered it. To do that would require quite a bit
more thinking because while you only needed to handle this particular
case, if we were to implement this in XSD, it would have to work with
all reasonable use-cases (wildcards, mixed content, polymorphic
types are the ones that came to mind; there are most likely others).
At the same time it should be very easy to implement a class
template (using variadic template arguments, if using C++11) that
would allow you to achieve pretty much what you want:
--custom-type=foo=ordered_as_variant<foo_base, bar, baz, fox>/foo_base
The only minor inconvenience is that you have to specify the
possible element types (bar, baz, and fox in this case) explicitly.
But I think this is a small price to pay.
Boris
More information about the xsd-users
mailing list