From c5e3c6ee3e291a5dfc6670160677f4962d526dc4 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 25 Nov 2010 14:54:24 +0200 Subject: Add the {parser,serializer}_maps functions to set polymorphic maps Use that in the generated aggregate classes in C++/Hybrid instead of the individual setters since their names are unknown for included and imported schemas. --- xsde/cxx/hybrid/parser-aggregate-source.cxx | 230 +++++++++++++---------- xsde/cxx/hybrid/serializer-aggregate-source.cxx | 240 +++++++++++++----------- xsde/cxx/parser/elements.hxx | 105 ++++++++++- xsde/cxx/parser/parser-header.cxx | 29 ++- xsde/cxx/parser/parser-inline.cxx | 79 +++++++- xsde/cxx/serializer/elements.hxx | 109 ++++++++++- xsde/cxx/serializer/serializer-header.cxx | 29 ++- xsde/cxx/serializer/serializer-inline.cxx | 82 +++++++- 8 files changed, 654 insertions(+), 249 deletions(-) (limited to 'xsde/cxx') diff --git a/xsde/cxx/hybrid/parser-aggregate-source.cxx b/xsde/cxx/hybrid/parser-aggregate-source.cxx index e4d3189..ddcd982 100644 --- a/xsde/cxx/hybrid/parser-aggregate-source.cxx +++ b/xsde/cxx/hybrid/parser-aggregate-source.cxx @@ -21,60 +21,110 @@ namespace CXX // struct ParticleArg: Traversal::Element, Context { - ParticleArg (Context& c, TypeInstanceMap& map, Boolean& first) - : Context (c), map_ (map), first_ (first) + ParticleArg (Context& c, + TypeInstanceMap& map, + Boolean& first, + Boolean poly, + String const& arg) + : Context (c), + poly_ (poly), + map_ (&map), + first_ (&first), + result_ (0), + arg_ (arg) + { + } + + ParticleArg (Context& c, Boolean& result, Boolean poly) + : Context (c), + poly_ (poly), + map_ (0), + first_ (0), + result_ (&result) { } virtual Void traverse (SemanticGraph::Element& e) { - if (!first_) + if (poly_ && anonymous (e.type ())) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + + if (!*first_) os << "," << endl; else - first_ = false; + *first_ = false; - os << "this->" << map_[&e.type ()]; + if (poly_) + os << "this->" << arg_; + else + os << "this->" << (*map_)[&e.type ()]; } private: - TypeInstanceMap& map_; - Boolean& first_; + Boolean poly_; + TypeInstanceMap* map_; + Boolean* first_; + Boolean* result_; + String arg_; }; struct AttributeArg: Traversal::Attribute, Context { AttributeArg (Context& c, TypeInstanceMap& map, Boolean& first) - : Context (c), map_ (map), first_ (first) + : Context (c), map_ (&map), first_ (&first), result_ (0) + { + } + + AttributeArg (Context& c, Boolean& result) + : Context (c), map_ (0), first_ (0), result_ (&result) { } virtual Void traverse (Type& a) { - if (!first_) + if (result_ != 0) + { + *result_ = true; + return; + } + + if (!*first_) os << "," << endl; else - first_ = false; + *first_ = false; - os << "this->" << map_[&a.type ()]; + os << "this->" << (*map_)[&a.type ()]; } private: - TypeInstanceMap& map_; - Boolean& first_; + TypeInstanceMap* map_; + Boolean* first_; + Boolean* result_; }; struct ArgList : Traversal::Complex, Traversal::List, Context { - ArgList (Context& c, TypeInstanceMap& map) + ArgList (Context& c, + TypeInstanceMap& map, + Boolean poly, + String const& arg) : Context (c), - map_ (map), - particle_ (c, map, first_), + poly_ (poly), + map_ (&map), + particle_ (c, map, first_, poly, arg), attribute_ (c, map, first_), - first_ (true) + first_ (true), + result_ (0) { inherits_ >> *this; @@ -83,7 +133,27 @@ namespace CXX contains_particle_ >> compositor_; contains_particle_ >> particle_; - names_ >> attribute_; + if (!poly_) + names_ >> attribute_; + } + + ArgList (Context& c, Boolean& result, Boolean poly) + : Context (c), + poly_ (poly), + map_ (0), + particle_ (c, result, poly), + attribute_ (c, result), + result_ (&result) + { + inherits_ >> *this; + + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> particle_; + + if (!poly_) + names_ >> attribute_; } virtual Void @@ -101,16 +171,26 @@ namespace CXX virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else first_ = false; - os << "this->" << map_[&l.argumented ().type ()]; + os << "this->" << (*map_)[&l.argumented ().type ()]; } private: - TypeInstanceMap& map_; + Boolean poly_; + TypeInstanceMap* map_; Traversal::Inherits inherits_; @@ -123,20 +203,27 @@ namespace CXX AttributeArg attribute_; Boolean first_; + Boolean* result_; }; struct ParserConnect: Traversal::List, Traversal::Complex, Context { - ParserConnect (Context& c, TypeInstanceMap& map) - : Context (c), map_ (map) + ParserConnect (Context& c, + TypeInstanceMap& map, + Boolean poly, + String const& map_inst = String ()) + : Context (c), poly_ (poly), map_ (map), map_inst_ (map_inst) { } virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + os << "this->" << map_[&l] << ".parsers (this->" << map_[&l.argumented ().type ()] << ");" << endl; @@ -147,9 +234,10 @@ namespace CXX { if (has_members (c)) { - os << "this->" << map_[&c] << ".parsers ("; + os << "this->" << map_[&c] << "." << + (poly_ ? "parser_maps" : "parsers") << " ("; - ArgList args (*this, map_); + ArgList args (*this, map_, poly_, map_inst_); args.dispatch (c); os << ");" @@ -161,79 +249,21 @@ namespace CXX Boolean has_members (SemanticGraph::Complex& c) { - using SemanticGraph::Complex; - - if (has (c)) - return true; - - if (c.inherits_p ()) - { - SemanticGraph::Type& b (c.inherits ().base ()); - - if (Complex* cb = dynamic_cast (&b)) - return has_members (*cb); - - return b.is_a (); - } - - return false; + Boolean r (false); + ArgList test (*this, r, poly_); + test.traverse (c); + return r; } private: + Boolean poly_; TypeInstanceMap& map_; + String map_inst_; }; + // // - struct ParserMapConnect: Traversal::Complex, - Traversal::Element, - Context - { - ParserMapConnect (Context& c, String const& inst, String const& map) - : Context (c), inst_ (inst), map_ (map) - { - *this >> inherits_ >> *this; - - *this >> contains_compositor_; - contains_compositor_ >> compositor_; - compositor_ >> contains_particle_; - contains_particle_ >> compositor_; - contains_particle_ >> *this; - } - - virtual Void - traverse (SemanticGraph::Complex& c) - { - inherits (c); - - if (!restriction_p (c)) - contains_compositor (c); - } - - virtual Void - traverse (SemanticGraph::Element& e) - { - SemanticGraph::Type& t (e.type ()); - - if (polymorphic (t)) - { - os << "this->" << inst_ << "." << - e.context ().get ("p:parser") << " (" << map_ << ");"; - } - } - - private: - String const& inst_; - String const& map_; - - Traversal::Inherits inherits_; - - Traversal::Compositor compositor_; - Traversal::Element particle_; - Traversal::ContainsCompositor contains_compositor_; - Traversal::ContainsParticle contains_particle_; - }; - struct GlobalType: Traversal::Type, Context { GlobalType (Context& c) @@ -298,7 +328,7 @@ namespace CXX // Connect parsers. // - ParserConnect connect (*this, map); + ParserConnect connect (*this, map, false); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) @@ -308,13 +338,12 @@ namespace CXX // if (tid_map) { + ParserConnect connect ( + *this, map, true, tc.get ("paggr-parser-map")); + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) - { - ParserMapConnect t ( - *this, i->second, tc.get ("paggr-parser-map")); - t.dispatch (*i->first); - } + connect.dispatch (*i->first); } os << "}"; @@ -385,7 +414,7 @@ namespace CXX // Connect parsers. // - ParserConnect connect (*this, map); + ParserConnect connect (*this, map, false); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) @@ -395,13 +424,12 @@ namespace CXX // if (tid_map) { + ParserConnect connect ( + *this, map, true, ec.get ("paggr-parser-map")); + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) - { - ParserMapConnect t ( - *this, i->second, ec.get ("paggr-parser-map")); - t.dispatch (*i->first); - } + connect.dispatch (*i->first); } os << "}"; diff --git a/xsde/cxx/hybrid/serializer-aggregate-source.cxx b/xsde/cxx/hybrid/serializer-aggregate-source.cxx index 35c9575..26a542d 100644 --- a/xsde/cxx/hybrid/serializer-aggregate-source.cxx +++ b/xsde/cxx/hybrid/serializer-aggregate-source.cxx @@ -17,64 +17,112 @@ namespace CXX { namespace { - // - // struct ParticleArg: Traversal::Element, Context { - ParticleArg (Context& c, TypeInstanceMap& map, Boolean& first) - : Context (c), map_ (map), first_ (first) + ParticleArg (Context& c, + TypeInstanceMap& map, + Boolean& first, + Boolean poly, + String const& arg) + : Context (c), + poly_ (poly), + map_ (&map), + first_ (&first), + result_ (0), + arg_ (arg) + { + } + + ParticleArg (Context& c, Boolean& result, Boolean poly) + : Context (c), + poly_ (poly), + map_ (0), + first_ (0), + result_ (&result) { } virtual Void traverse (SemanticGraph::Element& e) { - if (!first_) + if (poly_ && anonymous (e.type ())) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + + if (!*first_) os << "," << endl; else - first_ = false; + *first_ = false; - os << "this->" << map_[&e.type ()]; + if (poly_) + os << "this->" << arg_; + else + os << "this->" << (*map_)[&e.type ()]; } private: - TypeInstanceMap& map_; - Boolean& first_; + Boolean poly_; + TypeInstanceMap* map_; + Boolean* first_; + Boolean* result_; + String arg_; }; struct AttributeArg: Traversal::Attribute, Context { AttributeArg (Context& c, TypeInstanceMap& map, Boolean& first) - : Context (c), map_ (map), first_ (first) + : Context (c), map_ (&map), first_ (&first), result_ (0) + { + } + + AttributeArg (Context& c, Boolean& result) + : Context (c), map_ (0), first_ (0), result_ (&result) { } virtual Void traverse (Type& a) { - if (!first_) + if (result_ != 0) + { + *result_ = true; + return; + } + + if (!*first_) os << "," << endl; else - first_ = false; + *first_ = false; - os << "this->" << map_[&a.type ()]; + os << "this->" << (*map_)[&a.type ()]; } private: - TypeInstanceMap& map_; - Boolean& first_; + TypeInstanceMap* map_; + Boolean* first_; + Boolean* result_; }; struct ArgList : Traversal::Complex, Traversal::List, Context { - ArgList (Context& c, TypeInstanceMap& map) + ArgList (Context& c, + TypeInstanceMap& map, + Boolean poly, + String const& arg) : Context (c), - map_ (map), - particle_ (c, map, first_), + poly_ (poly), + map_ (&map), + particle_ (c, map, first_, poly, arg), attribute_ (c, map, first_), - first_ (true) + first_ (true), + result_ (0) { inherits_ >> *this; @@ -83,7 +131,27 @@ namespace CXX contains_particle_ >> compositor_; contains_particle_ >> particle_; - names_ >> attribute_; + if (!poly_) + names_ >> attribute_; + } + + ArgList (Context& c, Boolean& result, Boolean poly) + : Context (c), + poly_ (poly), + map_ (0), + particle_ (c, result, poly), + attribute_ (c, result), + result_ (&result) + { + inherits_ >> *this; + + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> particle_; + + if (!poly_) + names_ >> attribute_; } virtual Void @@ -101,16 +169,26 @@ namespace CXX virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else first_ = false; - os << "this->" << map_[&l.argumented ().type ()]; + os << "this->" << (*map_)[&l.argumented ().type ()]; } private: - TypeInstanceMap& map_; + Boolean poly_; + TypeInstanceMap* map_; Traversal::Inherits inherits_; @@ -123,20 +201,27 @@ namespace CXX AttributeArg attribute_; Boolean first_; + Boolean* result_; }; struct SerializerConnect: Traversal::List, - Traversal::Complex, - Context + Traversal::Complex, + Context { - SerializerConnect (Context& c, TypeInstanceMap& map) - : Context (c), map_ (map) + SerializerConnect (Context& c, + TypeInstanceMap& map, + Boolean poly, + String const& map_inst = String ()) + : Context (c), poly_ (poly), map_ (map), map_inst_ (map_inst) { } virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + os << "this->" << map_[&l] << ".serializers (this->" << map_[&l.argumented ().type ()] << ");" << endl; @@ -147,9 +232,10 @@ namespace CXX { if (has_members (c)) { - os << "this->" << map_[&c] << ".serializers ("; + os << "this->" << map_[&c] << "." << + (poly_ ? "serializer_maps" : "serializers") << " ("; - ArgList args (*this, map_); + ArgList args (*this, map_, poly_, map_inst_); args.dispatch (c); os << ");" @@ -161,80 +247,16 @@ namespace CXX Boolean has_members (SemanticGraph::Complex& c) { - using SemanticGraph::Complex; - - if (has (c)) - return true; - - if (c.inherits_p ()) - { - SemanticGraph::Type& b (c.inherits ().base ()); - - if (Complex* cb = dynamic_cast (&b)) - return has_members (*cb); - - return b.is_a (); - } - - return false; + Boolean r (false); + ArgList test (*this, r, poly_); + test.traverse (c); + return r; } private: + Boolean poly_; TypeInstanceMap& map_; - }; - - // - // - struct SerializerMapConnect: Traversal::Complex, - Traversal::Element, - Context - { - SerializerMapConnect (Context& c, - String const& inst, - String const& map) - : Context (c), inst_ (inst), map_ (map) - { - *this >> inherits_ >> *this; - - *this >> contains_compositor_; - contains_compositor_ >> compositor_; - compositor_ >> contains_particle_; - contains_particle_ >> compositor_; - contains_particle_ >> *this; - } - - virtual Void - traverse (SemanticGraph::Complex& c) - { - inherits (c); - - if (!restriction_p (c)) - contains_compositor (c); - } - - virtual Void - traverse (SemanticGraph::Element& e) - { - SemanticGraph::Type& t (e.type ()); - - if (polymorphic (t)) - { - os << "this->" << inst_ << "." << - e.context ().get ("s:serializer") << " (" << - map_ << ");"; - } - } - - private: - String const& inst_; - String const& map_; - - Traversal::Inherits inherits_; - - Traversal::Compositor compositor_; - Traversal::Element particle_; - Traversal::ContainsCompositor contains_compositor_; - Traversal::ContainsParticle contains_particle_; + String map_inst_; }; // @@ -304,7 +326,7 @@ namespace CXX // Connect parsers. // - SerializerConnect connect (*this, map); + SerializerConnect connect (*this, map, false); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) @@ -314,13 +336,12 @@ namespace CXX // if (tid_map) { + SerializerConnect connect ( + *this, map, true, tc.get ("saggr-serializer-map")); + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) - { - SerializerMapConnect t ( - *this, i->second, tc.get ("saggr-serializer-map")); - t.dispatch (*i->first); - } + connect.dispatch (*i->first); } os << "}"; @@ -392,7 +413,7 @@ namespace CXX // Connect parsers. // - SerializerConnect connect (*this, map); + SerializerConnect connect (*this, map, false); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) @@ -402,13 +423,12 @@ namespace CXX // if (tid_map) { + SerializerConnect connect ( + *this, map, true, ec.get ("saggr-serializer-map")); + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) - { - SerializerMapConnect t ( - *this, i->second, ec.get ("saggr-serializer-map")); - t.dispatch (*i->first); - } + connect.dispatch (*i->first); } os << "}"; diff --git a/xsde/cxx/parser/elements.hxx b/xsde/cxx/parser/elements.hxx index 497577f..9857989 100644 --- a/xsde/cxx/parser/elements.hxx +++ b/xsde/cxx/parser/elements.hxx @@ -323,20 +323,44 @@ namespace CXX // struct ParticleParamDecl: Traversal::Element, Context { - ParticleParamDecl (Context& c, Boolean& first, Boolean name_arg) - : Context (c), first_ (first), name_arg_ (name_arg) + ParticleParamDecl (Context& c, + Boolean& first, + Boolean name_arg, + Boolean poly) + : Context (c), + first_ (first), + name_arg_ (name_arg), + poly_ (poly), + result_ (0) + { + } + + ParticleParamDecl (Context& c, Boolean* result, Boolean poly) + : Context (c), first_ (name_arg_), poly_ (poly), result_ (result) { } virtual Void traverse (SemanticGraph::Element& e) { + if (poly_ && anonymous (e.type ())) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else first_ = false; - os << fq_name (e.type ()) << "&"; + if (poly_) + os << parser_map << "&"; + else + os << fq_name (e.type ()) << "&"; if (name_arg_) os << " " << ename (e); @@ -347,18 +371,34 @@ namespace CXX private: Boolean& first_; Boolean name_arg_; + Boolean poly_; + Boolean* result_; }; struct AttributeParamDecl: Traversal::Attribute, Context { AttributeParamDecl (Context& c, Boolean& first, Boolean name_arg) - : Context (c), first_ (first), name_arg_ (name_arg) + : Context (c), + first_ (first), + name_arg_ (name_arg), + result_ (0) + { + } + + AttributeParamDecl (Context& c, Boolean* result) + : Context (c), first_ (name_arg_), result_ (result) { } virtual Void traverse (Type& a) { + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else @@ -375,18 +415,38 @@ namespace CXX private: Boolean& first_; Boolean name_arg_; + Boolean* result_; }; struct ParserParamDecl : Traversal::Complex, Traversal::List, Context { - ParserParamDecl (Context& c, Boolean name_arg) + ParserParamDecl (Context& c, Boolean name_arg, Boolean poly) : Context (c), - particle_ (c, first_, name_arg), + particle_ (c, first_, name_arg, poly), attribute_ (c, first_, name_arg), first_ (true), - name_arg_ (name_arg) + name_arg_ (name_arg), + poly_ (poly), + result_ (0) + { + inherits_ >> *this; + + contains_compositor_ >> compositor_ >> contains_particle_; + contains_particle_ >> particle_; + contains_particle_ >> compositor_; + + if (!poly_) + names_ >> attribute_; + } + + ParserParamDecl (Context& c, Boolean* result, Boolean poly) + : Context (c), + particle_ (c, result, poly), + attribute_ (c, result), + poly_ (poly), + result_ (result) { inherits_ >> *this; @@ -394,7 +454,8 @@ namespace CXX contains_particle_ >> particle_; contains_particle_ >> compositor_; - names_ >> attribute_; + if (!poly_) + names_ >> attribute_; } virtual Void @@ -412,6 +473,15 @@ namespace CXX virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else @@ -438,6 +508,25 @@ namespace CXX Boolean first_; Boolean name_arg_; + Boolean poly_; + Boolean* result_; + }; + + struct ParserParamTest + { + ParserParamTest (Context& c, Boolean& result, Boolean poly) + : impl_ (c, &result, poly) + { + } + + Void + traverse (SemanticGraph::Complex& c) + { + impl_.traverse (c); + } + + private: + ParserParamDecl impl_; }; // diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx index 6e7dfe2..bec77fe 100644 --- a/xsde/cxx/parser/parser-header.cxx +++ b/xsde/cxx/parser/parser-header.cxx @@ -824,17 +824,44 @@ namespace CXX os << "// Parser construction API." << endl << "//" << endl; + // parsers () + // os << "void" << endl << "parsers ("; { - ParserParamDecl decl (*this, false); + ParserParamDecl decl (*this, false, false); decl.traverse (c); } os << ");" << endl; + // parser_maps () + // + if (poly_code && he) + { + Boolean r (false); + ParserParamTest test (*this, r, true); + test.traverse (c); + + // Have potentially polymorphic elements. + // + if (r) + { + os << "void" << endl + << "parser_maps ("; + + { + ParserParamDecl decl (*this, false, true); + decl.traverse (c); + } + + os << ");" + << endl; + } + } + if (ha) { os << "// Individual attribute parsers." << endl diff --git a/xsde/cxx/parser/parser-inline.cxx b/xsde/cxx/parser/parser-inline.cxx index f0d9e7b..2d02b3e 100644 --- a/xsde/cxx/parser/parser-inline.cxx +++ b/xsde/cxx/parser/parser-inline.cxx @@ -376,16 +376,22 @@ namespace CXX // struct ParticleMemberSet: Traversal::Element, Context { - ParticleMemberSet (Context& c) - : Context (c) + ParticleMemberSet (Context& c, Boolean poly) + : Context (c), poly_ (poly) { } virtual Void traverse (SemanticGraph::Element& e) { - os << "this->" << emember (e) << " = &" << ename (e) << ";"; + if (poly_) + os << "this->" << emember_map (e) << " = &" << ename (e) << ";"; + else + os << "this->" << emember (e) << " = &" << ename (e) << ";"; } + + private: + Boolean poly_; }; struct AttributeMemberSet: Traversal::Attribute, Context @@ -406,8 +412,8 @@ namespace CXX Traversal::List, Context { - BaseMemberSet (Context& c) - : Context (c) + BaseMemberSet (Context& c, Boolean poly) + : Context (c), poly_ (poly) { inherits_ >> *this; } @@ -427,6 +433,9 @@ namespace CXX virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + String const& name (ename (l)); String item (unclash (name, "item")); @@ -435,6 +444,7 @@ namespace CXX private: Traversal::Inherits inherits_; + Boolean poly_; }; // @@ -533,9 +543,11 @@ namespace CXX : Context (c), particle_accessor_ (c), attribute_accessor_ (c), - base_set_ (c), - particle_set_ (c), + base_set_ (c, false), + particle_set_ (c, false), attribute_set_ (c), + base_set_poly_ (c, true), + particle_set_poly_ (c, true), particle_ (c) { // Accessor. @@ -559,6 +571,16 @@ namespace CXX contains_particle_set_ >> particle_set_; names_attribute_set_ >> attribute_set_; + + // Member set polymorphic. + // + inherits_base_set_poly_ >> base_set_poly_; + base_set_poly_ >> contains_compositor_set_poly_; + + contains_compositor_set_poly_ >> compositor_set_poly_; + compositor_set_poly_ >> contains_particle_set_poly_; + contains_particle_set_poly_ >> compositor_set_poly_; + contains_particle_set_poly_ >> particle_set_poly_; } virtual Void @@ -611,7 +633,7 @@ namespace CXX << "parsers ("; { - ParserParamDecl decl (*this, true); + ParserParamDecl decl (*this, true, false); decl.traverse (c); } @@ -627,6 +649,37 @@ namespace CXX contains_compositor (c, contains_compositor_set_); os << "}"; + + // parser_maps () + // + if (poly_code && he) + { + Boolean r (false); + ParserParamTest test (*this, r, true); + test.traverse (c); + + // Have potentially polymorphic elements. + // + if (r) + { + os << inl + << "void " << name << "::" << endl + << "parser_maps ("; + + { + ParserParamDecl decl (*this, true, true); + decl.traverse (c); + } + + os << ")" + << "{"; + + inherits (c, inherits_base_set_poly_); + contains_compositor (c, contains_compositor_set_poly_); + + os << "}"; + } + } } String fq_base; @@ -832,6 +885,16 @@ namespace CXX // // + BaseMemberSet base_set_poly_; + Traversal::Inherits inherits_base_set_poly_; + + Traversal::Compositor compositor_set_poly_; + ParticleMemberSet particle_set_poly_; + Traversal::ContainsCompositor contains_compositor_set_poly_; + Traversal::ContainsParticle contains_particle_set_poly_; + + // + // Particle particle_; }; } diff --git a/xsde/cxx/serializer/elements.hxx b/xsde/cxx/serializer/elements.hxx index 7d2bf80..c429a64 100644 --- a/xsde/cxx/serializer/elements.hxx +++ b/xsde/cxx/serializer/elements.hxx @@ -336,20 +336,44 @@ namespace CXX // struct ParticleParamDecl: Traversal::Element, Context { - ParticleParamDecl (Context& c, Boolean& first, Boolean name_arg) - : Context (c), first_ (first), name_arg_ (name_arg) + ParticleParamDecl (Context& c, + Boolean& first, + Boolean name_arg, + Boolean poly) + : Context (c), + first_ (first), + name_arg_ (name_arg), + poly_ (poly), + result_ (0) + { + } + + ParticleParamDecl (Context& c, Boolean* result, Boolean poly) + : Context (c), first_ (name_arg_), poly_ (poly), result_ (result) { } virtual Void traverse (SemanticGraph::Element& e) { + if (poly_ && anonymous (e.type ())) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else first_ = false; - os << fq_name (e.type ()) << "&"; + if (poly_) + os << serializer_map << "&"; + else + os << fq_name (e.type ()) << "&"; if (name_arg_) os << " " << ename (e); @@ -360,18 +384,34 @@ namespace CXX private: Boolean& first_; Boolean name_arg_; + Boolean poly_; + Boolean* result_; }; struct AttributeParamDecl: Traversal::Attribute, Context { AttributeParamDecl (Context& c, Boolean& first, Boolean name_arg) - : Context (c), first_ (first), name_arg_ (name_arg) + : Context (c), + first_ (first), + name_arg_ (name_arg), + result_ (0) + { + } + + AttributeParamDecl (Context& c, Boolean* result) + : Context (c), first_ (name_arg_), result_ (result) { } virtual Void traverse (Type& a) { + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else @@ -388,18 +428,38 @@ namespace CXX private: Boolean& first_; Boolean name_arg_; + Boolean* result_; }; struct SerializerParamDecl : Traversal::Complex, - Traversal::List, - Context + Traversal::List, + Context { - SerializerParamDecl (Context& c, Boolean name_arg) + SerializerParamDecl (Context& c, Boolean name_arg, Boolean poly) : Context (c), - particle_ (c, first_, name_arg), + particle_ (c, first_, name_arg, poly), attribute_ (c, first_, name_arg), first_ (true), - name_arg_ (name_arg) + name_arg_ (name_arg), + poly_ (poly), + result_ (0) + { + inherits_ >> *this; + + contains_compositor_ >> compositor_ >> contains_particle_; + contains_particle_ >> particle_; + contains_particle_ >> compositor_; + + if (!poly_) + names_ >> attribute_; + } + + SerializerParamDecl (Context& c, Boolean* result, Boolean poly) + : Context (c), + particle_ (c, result, poly), + attribute_ (c, result), + poly_ (poly), + result_ (result) { inherits_ >> *this; @@ -407,7 +467,8 @@ namespace CXX contains_particle_ >> particle_; contains_particle_ >> compositor_; - names_ >> attribute_; + if (!poly_) + names_ >> attribute_; } virtual Void @@ -425,6 +486,15 @@ namespace CXX virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + + if (result_ != 0) + { + *result_ = true; + return; + } + if (!first_) os << "," << endl; else @@ -451,6 +521,25 @@ namespace CXX Boolean first_; Boolean name_arg_; + Boolean poly_; + Boolean* result_; + }; + + struct SerializerParamTest + { + SerializerParamTest (Context& c, Boolean& result, Boolean poly) + : impl_ (c, &result, poly) + { + } + + Void + traverse (SemanticGraph::Complex& c) + { + impl_.traverse (c); + } + + private: + SerializerParamDecl impl_; }; // diff --git a/xsde/cxx/serializer/serializer-header.cxx b/xsde/cxx/serializer/serializer-header.cxx index a849946..9321482 100644 --- a/xsde/cxx/serializer/serializer-header.cxx +++ b/xsde/cxx/serializer/serializer-header.cxx @@ -1147,17 +1147,44 @@ namespace CXX os << "// Serializer construction API." << endl << "//" << endl; + // serializers () + // os << "void" << endl << "serializers ("; { - SerializerParamDecl decl (*this, false); + SerializerParamDecl decl (*this, false, false); decl.traverse (c); } os << ");" << endl; + // serializer_maps () + // + if (poly_code && he) + { + Boolean r (false); + SerializerParamTest test (*this, r, true); + test.traverse (c); + + // Have potentially polymorphic elements. + // + if (r) + { + os << "void" << endl + << "serializer_maps ("; + + { + SerializerParamDecl decl (*this, false, true); + decl.traverse (c); + } + + os << ");" + << endl; + } + } + if (ha) { os << "// Individual attribute serializers." << endl diff --git a/xsde/cxx/serializer/serializer-inline.cxx b/xsde/cxx/serializer/serializer-inline.cxx index 621f8b2..bfc16e2 100644 --- a/xsde/cxx/serializer/serializer-inline.cxx +++ b/xsde/cxx/serializer/serializer-inline.cxx @@ -365,16 +365,22 @@ namespace CXX // struct ParticleMemberSet: Traversal::Element, Context { - ParticleMemberSet (Context& c) - : Context (c) + ParticleMemberSet (Context& c, Boolean poly) + : Context (c), poly_ (poly) { } virtual Void traverse (SemanticGraph::Element& e) { - os << "this->" << emember (e) << " = &" << ename (e) << ";"; + if (poly_) + os << "this->" << emember_map (e) << " = &" << ename (e) << ";"; + else + os << "this->" << emember (e) << " = &" << ename (e) << ";"; } + + private: + Boolean poly_; }; struct AttributeMemberSet: Traversal::Attribute, Context @@ -395,8 +401,8 @@ namespace CXX Traversal::List, Context { - BaseMemberSet (Context& c) - : Context (c) + BaseMemberSet (Context& c, Boolean poly) + : Context (c), poly_ (poly) { inherits_ >> *this; } @@ -416,6 +422,9 @@ namespace CXX virtual Void traverse (SemanticGraph::List& l) { + if (poly_) + return; + String const& name (ename (l)); String item (unclash (name, "item")); @@ -424,6 +433,7 @@ namespace CXX private: Traversal::Inherits inherits_; + Boolean poly_; }; // @@ -493,9 +503,11 @@ namespace CXX : Context (c), particle_accessor_ (c), attribute_accessor_ (c), - base_set_ (c), - particle_set_ (c), - attribute_set_ (c) + base_set_ (c, false), + particle_set_ (c, false), + attribute_set_ (c), + base_set_poly_ (c, true), + particle_set_poly_ (c, true) { // Accessor. // @@ -518,6 +530,16 @@ namespace CXX contains_particle_set_ >> particle_set_; names_attribute_set_ >> attribute_set_; + + // Member set polymorphic. + // + inherits_base_set_poly_ >> base_set_poly_; + base_set_poly_ >> contains_compositor_set_poly_; + + contains_compositor_set_poly_ >> compositor_set_poly_; + compositor_set_poly_ >> contains_particle_set_poly_; + contains_particle_set_poly_ >> compositor_set_poly_; + contains_particle_set_poly_ >> particle_set_poly_; } virtual Void @@ -550,13 +572,12 @@ namespace CXX // serializer () // - os << inl << "void " << name << "::" << endl << "serializers ("; { - SerializerParamDecl decl (*this, true); + SerializerParamDecl decl (*this, true, false); decl.traverse (c); } @@ -572,6 +593,37 @@ namespace CXX contains_compositor (c, contains_compositor_set_); os << "}"; + + // serializer_maps () + // + if (poly_code && he) + { + Boolean r (false); + SerializerParamTest test (*this, r, true); + test.traverse (c); + + // Have potentially polymorphic elements. + // + if (r) + { + os << inl + << "void " << name << "::" << endl + << "serializer_maps ("; + + { + SerializerParamDecl decl (*this, true, true); + decl.traverse (c); + } + + os << ")" + << "{"; + + inherits (c, inherits_base_set_poly_); + contains_compositor (c, contains_compositor_set_poly_); + + os << "}"; + } + } } String fq_base; @@ -726,6 +778,16 @@ namespace CXX AttributeMemberSet attribute_set_; Traversal::Names names_attribute_set_; + + // + // + BaseMemberSet base_set_poly_; + Traversal::Inherits inherits_base_set_poly_; + + Traversal::Compositor compositor_set_poly_; + ParticleMemberSet particle_set_poly_; + Traversal::ContainsCompositor contains_compositor_set_poly_; + Traversal::ContainsParticle contains_particle_set_poly_; }; } -- cgit v1.1