From 474046c375d24bfdb51a20b0bfd3ac4ac928ef3e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 29 Aug 2010 15:24:56 +0200 Subject: Implement generation of assignment operators Also add the --suppress-assignment option. We need to generate these operators into the .cxx file instead of relying on the implicit inline ones because in the file-per-type mode types of members are only forward- declared in the header. Also, we don't want to assign the DOMDocument member used to store the wildcard content. --- xsd/cxx/tree/cli.hxx | 2 + xsd/cxx/tree/generator.cxx | 6 +++ xsd/cxx/tree/tree-header.cxx | 49 ++++++++++++++++++++++++ xsd/cxx/tree/tree-source.cxx | 89 +++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 140 insertions(+), 6 deletions(-) (limited to 'xsd') diff --git a/xsd/cxx/tree/cli.hxx b/xsd/cxx/tree/cli.hxx index 171711d..4a826a9 100644 --- a/xsd/cxx/tree/cli.hxx +++ b/xsd/cxx/tree/cli.hxx @@ -36,6 +36,7 @@ namespace CXX extern Key generate_comparison; extern Key generate_default_ctor; extern Key generate_from_base_ctor; + extern Key suppress_assignment; extern Key generate_detach; extern Key generate_wildcard; extern Key generate_insertion; @@ -135,6 +136,7 @@ namespace CXX generate_comparison, Boolean, generate_default_ctor, Boolean, generate_from_base_ctor, Boolean, + suppress_assignment, Boolean, generate_detach, Boolean, generate_wildcard, Boolean, generate_insertion, Cult::Containers::Vector, diff --git a/xsd/cxx/tree/generator.cxx b/xsd/cxx/tree/generator.cxx index c13bf1f..3b0e6cd 100644 --- a/xsd/cxx/tree/generator.cxx +++ b/xsd/cxx/tree/generator.cxx @@ -129,6 +129,7 @@ namespace CXX extern Key generate_comparison = "generate-comparison"; extern Key generate_default_ctor = "generate-default-ctor"; extern Key generate_from_base_ctor = "generate-from-base-ctor"; + extern Key suppress_assignment = "suppress-assignment"; extern Key generate_detach = "generate-detach"; extern Key generate_wildcard = "generate-wildcard"; extern Key generate_insertion = "generate-insertion"; @@ -284,6 +285,11 @@ namespace CXX << " Generate from-base constructors." << endl; + e << "--suppress-assignment" << endl + << " Suppress the generation of copy assignment\n" + << " operators for complex types." + << endl; + e << "--generate-detach" << endl << " Generate detach functions for required members." << endl; diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx index 9b5acc6..8805c8b 100644 --- a/xsd/cxx/tree/tree-header.cxx +++ b/xsd/cxx/tree/tree-header.cxx @@ -2969,12 +2969,61 @@ namespace CXX << container << "* c = 0) const;" << endl; + // operator= + // + bool priv (false); + + if (!simple) + { + if (options.value ()) + { + priv = true; + os << "private:" << endl; + + if (doxygen) + { + os << "/**" << endl + << " * @brief Disabled copy assignment operator." << endl + << " *" << endl + << " * @param x An instance to make a copy of." << endl + << " * @return A reference to itself." << endl + << " */" << endl; + } + + os << name << "&" << endl + << "operator= (const " << name << "& x);" + << endl; + } + else if (has_members || (gen_wildcard && (hae || haa))) + { + if (doxygen) + { + os << "/**" << endl + << " * @brief Copy assignment operator." << endl + << " *" << endl + << " * @param x An instance to make a copy of." << endl + << " * @return A reference to itself." << endl + << " *" << endl + << " * For polymorphic object models use the @c _clone " << + "function instead." << endl + << " */" << endl; + } + + os << name << "&" << endl + << "operator= (const " << name << "& x);" + << endl; + } + } + if (doxygen) { os << "//@}" << endl << endl; } + if (priv) + os << "public:" << endl; + // d-tor // if (doxygen) diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx index 4a17b00..8640121 100644 --- a/xsd/cxx/tree/tree-source.cxx +++ b/xsd/cxx/tree/tree-source.cxx @@ -1558,6 +1558,48 @@ namespace CXX String arg_name; }; + struct AssignMember: Traversal::Member, Context + { + AssignMember (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Member& m) + { + if (skip (m)) + return; + + String const& member (emember (m)); + os << "this->" << member << " = x." << member << ";"; + } + }; + + struct AssignAny: Traversal::Any, + Traversal::AnyAttribute, + Context + { + AssignAny (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Any& a) + { + String const& member (emember (a)); + os << "this->" << member << " = x." << member << ";"; + } + + virtual Void + traverse (SemanticGraph::AnyAttribute& a) + { + String const& member (emember (a)); + os << "this->" << member << " = x." << member << ";"; + } + }; + // Element parsing c-tor initializers. // @@ -2078,18 +2120,22 @@ namespace CXX ctor_member_ (c), element_ctor_any_ (c), element_ctor_member_ (c), + assign_any_ (c), + assign_member_ (c), comparison_any_ (c), comparison_member_ (c), facet_array_ (c) { + Boolean gen_wildcard (options.value ()); + inherits_member_ >> member_name_; names_element_ >> element_; - if (options.value ()) + if (gen_wildcard) names_element_ >> any_; names_element_test_ >> element_test_; - if (options.value ()) + if (gen_wildcard) names_element_test_ >> any_test_; names_attribute_ >> attribute_; @@ -2097,19 +2143,23 @@ namespace CXX names_any_attribute_ >> any_attribute_; default_ctor_init_names_ >> default_ctor_member_init_; - if (options.value ()) + if (gen_wildcard) default_ctor_init_names_ >> default_ctor_any_init_; ctor_names_ >> ctor_member_; - if (options.value ()) + if (gen_wildcard) ctor_names_ >> ctor_any_; element_ctor_names_ >> element_ctor_member_; - if (options.value ()) + if (gen_wildcard) element_ctor_names_ >> element_ctor_any_; + assign_names_ >> assign_member_; + if (gen_wildcard) + assign_names_ >> assign_any_; + comparison_names_ >> comparison_member_; - if (options.value ()) + if (gen_wildcard) comparison_names_ >> comparison_any_; } @@ -2977,6 +3027,29 @@ namespace CXX << "return new class " << name << " (*this, f, c);" << "}"; + // operator= + // + if (!options.value () && + (he || ha || (gen_wildcard && (hae || haa)))) + { + os << name << "& " << name << "::" << endl + << "operator= (const " << name << "& x)" + << "{" + << "if (this != &x)" + << "{" + << "static_cast< " << base << "& > (*this) = x;"; + + // Note that here we don't assign the DOMDocument that is + // used to hold wildcard fragments. Each document has its + // own copy. + // + names (c, assign_names_); + + os << "}" + << "return *this;" + << "}"; + } + // d-tor // os << name << "::" << endl @@ -3088,6 +3161,10 @@ namespace CXX ElementCtorMember element_ctor_member_; Traversal::Names element_ctor_names_; + AssignAny assign_any_; + AssignMember assign_member_; + Traversal::Names assign_names_; + AnyComparison comparison_any_; MemberComparison comparison_member_; Traversal::Names comparison_names_; -- cgit v1.1