aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx/hybrid
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-10-07 14:48:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-10-07 14:48:13 +0200
commit4f38adc11ab1a3a1ab2dd3f958c917182be7d71f (patch)
treefd4242b2fb5648536a6307a18442abfcaf280573 /xsde/cxx/hybrid
parent0baca4b033509b6c4ebfabfb74bf6518c3b1182c (diff)
Implement generation of clone functions
New test: clone.
Diffstat (limited to 'xsde/cxx/hybrid')
-rw-r--r--xsde/cxx/hybrid/cli.hxx2
-rw-r--r--xsde/cxx/hybrid/elements.cxx1
-rw-r--r--xsde/cxx/hybrid/elements.hxx70
-rw-r--r--xsde/cxx/hybrid/generator.cxx6
-rw-r--r--xsde/cxx/hybrid/tree-header.cxx234
-rw-r--r--xsde/cxx/hybrid/tree-source.cxx1201
6 files changed, 1425 insertions, 89 deletions
diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx
index 5de1692..5d691d6 100644
--- a/xsde/cxx/hybrid/cli.hxx
+++ b/xsde/cxx/hybrid/cli.hxx
@@ -36,6 +36,7 @@ namespace CXX
extern Key suppress_serializer_val;
extern Key omit_default_attributes;
extern Key suppress_enum;
+ extern Key generate_clone;
extern Key generate_detach;
extern Key generate_insertion;
extern Key generate_extraction;
@@ -127,6 +128,7 @@ namespace CXX
suppress_serializer_val, Boolean,
omit_default_attributes, Boolean,
suppress_enum, Boolean,
+ generate_clone, Boolean,
generate_detach, Boolean,
generate_insertion, Cult::Containers::Vector<NarrowString>,
generate_extraction, Cult::Containers::Vector<NarrowString>,
diff --git a/xsde/cxx/hybrid/elements.cxx b/xsde/cxx/hybrid/elements.cxx
index fe5c97e..b8c109a 100644
--- a/xsde/cxx/hybrid/elements.cxx
+++ b/xsde/cxx/hybrid/elements.cxx
@@ -40,6 +40,7 @@ namespace CXX
poly_code (ops.value<CLI::generate_polymorphic> ()),
poly_runtime (poly_code || ops.value<CLI::runtime_polymorphic> ()),
reset (!ops.value<CLI::suppress_reset> ()),
+ clone (ops.value<CLI::generate_clone> ()),
detach (ops.value<CLI::generate_detach> ()),
mixin (ops.value<CLI::reuse_style_mixin> ()),
tiein (!mixin),
diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx
index 60211e8..7bd8bd1 100644
--- a/xsde/cxx/hybrid/elements.hxx
+++ b/xsde/cxx/hybrid/elements.hxx
@@ -45,6 +45,7 @@ namespace CXX
poly_code (c.poly_code),
poly_runtime (c.poly_runtime),
reset (c.reset),
+ clone (c.clone),
detach (c.detach),
typeinfo (c.typeinfo),
mixin (c.mixin),
@@ -76,6 +77,7 @@ namespace CXX
poly_code (c.poly_code),
poly_runtime (c.poly_runtime),
reset (c.reset),
+ clone (c.clone),
detach (c.detach),
typeinfo (c.typeinfo),
mixin (c.mixin),
@@ -594,6 +596,7 @@ namespace CXX
Boolean poly_code;
Boolean poly_runtime;
Boolean reset;
+ Boolean clone;
Boolean detach;
Boolean typeinfo;
Boolean mixin;
@@ -2060,6 +2063,73 @@ namespace CXX
//
//
+ struct TypeClone: TypeOpsBase, Context
+ {
+ TypeClone (Context& c)
+ : Context (c)
+ {
+ }
+
+ // Copy member from 'this' to 'c'.
+ //
+ Void
+ dispatch (SemanticGraph::Node& type, SemanticGraph::Member& member)
+ {
+ member_ = &member;
+ Traversal::NodeBase::dispatch (type);
+ }
+
+ protected:
+ virtual Void
+ type (SemanticGraph::Type& t)
+ {
+ String const& name (ename (*member_));
+
+ os << "{"
+ << fq_name (t) << "* m = this->" << name << " ()._clone ();";
+
+ if (!exceptions)
+ os << endl
+ << "if (m == 0)" << endl
+ << "return false;"
+ << endl;
+
+ os << "c." << name << " (m);"
+ << "}";
+ }
+
+ virtual Void
+ fund_type (SemanticGraph::Type& t)
+ {
+ type (t);
+ }
+
+ virtual Void
+ string_type (SemanticGraph::Type&)
+ {
+ // We can only get here if STL is disabled.
+ //
+ String const& name (ename (*member_));
+
+ os << "{"
+ << "char* m = ::xsde::cxx::strdupx (this->" << name << " ());";
+
+ if (!exceptions)
+ os << endl
+ << "if (m == 0)" << endl
+ << "return false;"
+ << endl;
+
+ os << "c." << name << " (m);"
+ << "}";
+ }
+
+ private:
+ SemanticGraph::Member* member_;
+ };
+
+ //
+ //
struct TypeForward: Traversal::Type, Context
{
TypeForward (Context& c)
diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx
index 0ccbb91..ee39079 100644
--- a/xsde/cxx/hybrid/generator.cxx
+++ b/xsde/cxx/hybrid/generator.cxx
@@ -124,6 +124,7 @@ namespace CXX
extern Key suppress_serializer_val = "suppress-serializer-val";
extern Key omit_default_attributes = "omit-default-attributes";
extern Key suppress_enum = "suppress-enum";
+ extern Key generate_clone = "generate-clone";
extern Key generate_detach = "generate-detach";
extern Key generate_insertion = "generate-insertion";
extern Key generate_extraction = "generate-extraction";
@@ -271,6 +272,11 @@ namespace CXX
<< " enumeration to C++ enum mapping."
<< endl;
+ e << "--generate-clone" << endl
+ << " Generate clone functions for variable-length\n"
+ << " types."
+ << endl;
+
e << "--generate-detach" << endl
<< " Generate detach functions for elements and\n"
<< " attributes of variable-length types."
diff --git a/xsde/cxx/hybrid/tree-header.cxx b/xsde/cxx/hybrid/tree-header.cxx
index 7e748bb..c596ab0 100644
--- a/xsde/cxx/hybrid/tree-header.cxx
+++ b/xsde/cxx/hybrid/tree-header.cxx
@@ -112,6 +112,13 @@ namespace CXX
<< name << " (" << vt << ");"
<< endl;
+ // _clone
+ //
+ if (!fl && clone)
+ os << (poly ? "virtual " : "") << name << "*" << endl
+ << "_clone () const;"
+ << endl;
+
// value (value_type)
//
if (!base_enum)
@@ -197,6 +204,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << name << "&) const;"
+ << endl;
+
if (!base_enum || cd)
os << "private:" << endl;
@@ -274,15 +288,22 @@ namespace CXX
// c-tor
//
os << "public:" << endl
- << name << " ();";
+ << name << " ();"
+ << endl;
+
+ // _clone
+ //
+ if (clone)
+ os << (poly ? "virtual " : "") << name << "*" << endl
+ << "_clone () const;"
+ << endl;
// d-tor
//
if (poly)
os << "virtual" << endl
- << "~" << name << " ();";
-
- os << endl;
+ << "~" << name << " ();"
+ << endl;
// Custom data.
//
@@ -335,6 +356,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << name << "&) const;"
+ << endl;
+
if (cd)
{
os << "private:" << endl
@@ -401,7 +429,15 @@ namespace CXX
// c-tor
//
- os << name << " ();";
+ os << name << " ();"
+ << endl;
+
+ // _clone
+ //
+ if (!fl && clone)
+ os << (poly ? "virtual " : "") << name << "*" << endl
+ << "_clone () const;"
+ << endl;
// d-tor
//
@@ -521,6 +557,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << name << "&) const;"
+ << endl;
+
if (stl)
{
os << "private:" << endl
@@ -634,7 +677,7 @@ namespace CXX
belongs_ >> *this;
}
- // Type alignment ranking (the high the rank, the stricter
+ // Type alignment ranking (the higher the rank, the stricter
// the alignment requirements):
//
// char 1
@@ -1315,7 +1358,7 @@ namespace CXX
traverse (SemanticGraph::Attribute& a)
{
os << "// " << comment (a.name ()) << endl
- << "// " << endl;
+ << "//" << endl;
Boolean def (a.default_p ());
Boolean fix (a.fixed_p ());
@@ -1413,7 +1456,7 @@ namespace CXX
traverse (SemanticGraph::Element& e)
{
os << "// " << comment (e.name ()) << endl
- << "// " << endl;
+ << "//" << endl;
String const& name (ename (e));
SemanticGraph::Type& t (e.type ());
@@ -1535,22 +1578,33 @@ namespace CXX
os << "// " << comment (name) << " (" <<
(fl ? "fixed-length" : "variable-length") << ")" << endl
- << "// " << endl;
+ << "//" << endl;
os << "class " << type
<< "{";
- // c-tor & d-tor
+ // c-tor
//
os << "public:" << endl
<< type << " ();"
- << "~" << type << " ();";
+ << endl;
+
+ // _clone
+ //
+ if (!fl && clone)
+ os << type << "*" << endl
+ << "_clone () const;"
+ << endl;
+
+ // d-tor
+ //
+ os << "~" << type << " ();"
+ << endl;
// copy c-tor & operator=
//
if (!fl)
- os << endl
- << "private:" << endl;
+ os << "private:" << endl;
os << type << " (const " << type << "&);"
<< type << "& operator= (const " << type << "&);"
@@ -1596,6 +1650,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << type << "&) const;"
+ << endl;
+
os << "private:" << endl;
All::contains (a, contains_data_);
@@ -1739,22 +1800,33 @@ namespace CXX
os << "// " << comment (name) << " (" <<
(fl ? "fixed-length" : "variable-length") << ")" << endl
- << "// " << endl;
+ << "//" << endl;
os << "class " << type
<< "{";
- // c-tor & d-tor
+ // c-tor
//
os << "public:" << endl
<< type << " ();"
- << "~" << type << " ();";
+ << endl;
+
+ // _clone
+ //
+ if (!fl && clone)
+ os << type << "*" << endl
+ << "_clone () const;"
+ << endl;
+
+ // d-tor
+ //
+ os << "~" << type << " ();"
+ << endl;
// copy c-tor & operator=
//
if (!fl)
- os << endl
- << "private:" << endl;
+ os << "private:" << endl;
os << type << " (const " << type << "&);"
<< type << "& operator= (const " << type << "&);"
@@ -1766,7 +1838,7 @@ namespace CXX
else
{
os << "// " << comment (name) << endl
- << "// " << endl;
+ << "//" << endl;
}
String const& arm_tag (earm_tag (c));
@@ -1838,6 +1910,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << type << "&) const;"
+ << endl;
+
os << "private:" << endl
<< "union"
<< "{";
@@ -1967,22 +2046,33 @@ namespace CXX
os << "// " << comment (name) << " (" <<
(fl ? "fixed-length" : "variable-length") << ")" << endl
- << "// " << endl;
+ << "//" << endl;
os << "class " << type
<< "{";
- // c-tor & d-tor
+ // c-tor
//
os << "public:" << endl
<< type << " ();"
- << "~" << type << " ();";
+ << endl;
+
+ // _clone
+ //
+ if (!fl && clone)
+ os << type << "*" << endl
+ << "_clone () const;"
+ << endl;
+
+ // d-tor
+ //
+ os << "~" << type << " ();"
+ << endl;
// copy c-tor & operator=
//
if (!fl)
- os << endl
- << "private:" << endl;
+ os << "private:" << endl;
os << type << " (const " << type << "&);"
<< type << "& operator= (const " << type << "&);"
@@ -2056,6 +2146,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << type << "&) const;"
+ << endl;
+
os << "private:" << endl
<< "union"
<< "{";
@@ -2190,22 +2287,33 @@ namespace CXX
os << "// " << comment (name) << " (" <<
(fl ? "fixed-length" : "variable-length") << ")" << endl
- << "// " << endl;
+ << "//" << endl;
os << "class " << type
<< "{";
- // c-tor & d-tor
+ // c-tor
//
os << "public:" << endl
<< type << " ();"
- << "~" << type << " ();";
+ << endl;
+
+ // _clone
+ //
+ if (!fl && clone)
+ os << type << "*" << endl
+ << "_clone () const;"
+ << endl;
+
+ // d-tor
+ //
+ os << "~" << type << " ();"
+ << endl;
// copy c-tor & operator=
//
if (!fl)
- os << endl
- << "private:" << endl;
+ os << "private:" << endl;
os << type << " (const " << type << "&);"
<< type << "& operator= (const " << type << "&);"
@@ -2251,6 +2359,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << type << "&) const;"
+ << endl;
+
os << "private:" << endl;
Sequence::contains (s, contains_data_);
@@ -2372,22 +2487,33 @@ namespace CXX
os << "// " << comment (name) << " (" <<
(fl ? "fixed-length" : "variable-length") << ")" << endl
- << "// " << endl;
+ << "//" << endl;
os << "class " << type
<< "{";
- // c-tor & d-tor
+ // c-tor
//
os << "public:" << endl
<< type << " ();"
- << "~" << type << " ();";
+ << endl;
+
+ // _clone
+ //
+ if (!fl && clone)
+ os << type << "*" << endl
+ << "_clone () const;"
+ << endl;
+
+ // d-tor
+ //
+ os << "~" << type << " ();"
+ << endl;
// copy c-tor & operator=
//
if (!fl)
- os << endl
- << "private:" << endl;
+ os << "private:" << endl;
os << type << " (const " << type << "&);"
<< type << "& operator= (const " << type << "&);"
@@ -2431,6 +2557,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << type << "&) const;"
+ << endl;
+
os << "private:" << endl;
Sequence::contains (s, contains_data_);
@@ -2533,7 +2666,7 @@ namespace CXX
Traversal::ContainsParticle& contains_data_;
};
- struct Complex : Traversal::Complex, Context
+ struct Complex: Traversal::Complex, Context
{
Complex (Context& c)
: Context (c),
@@ -2646,20 +2779,28 @@ namespace CXX
// c-tor
//
os << "public:" << endl
- << name << " ();";
-
- // d-tor
- //
- if (!restriction || poly)
- os << (poly ? "virtual\n" : "") << "~" << name << " ();";
+ << name << " ();"
+ << endl;
// copy c-tor & operator= (public)
//
if (fl && !restriction)
os << name << " (const " << name << "&);"
- << name << "& operator= (const " << name << "&);";
+ << name << "& operator= (const " << name << "&);"
+ << endl;
- os << endl;
+ // _clone
+ //
+ if (!fl && clone)
+ os << (poly ? "virtual " : "") << name << "*" << endl
+ << "_clone () const;"
+ << endl;
+
+ // d-tor
+ //
+ if (!restriction || poly)
+ os << (poly ? "virtual\n" : "") << "~" << name << " ();"
+ << endl;
if (!restriction)
{
@@ -2720,6 +2861,13 @@ namespace CXX
<< endl;
}
+ // _copy
+ //
+ if (!fl && clone)
+ os << (exceptions ? "void" : "bool") << endl
+ << "_copy (" << name << "&) const;"
+ << endl;
+
if (!restriction || cd)
os << "private:" << endl;
diff --git a/xsde/cxx/hybrid/tree-source.cxx b/xsde/cxx/hybrid/tree-source.cxx
index 5887d32..33995c5 100644
--- a/xsde/cxx/hybrid/tree-source.cxx
+++ b/xsde/cxx/hybrid/tree-source.cxx
@@ -32,7 +32,10 @@ namespace CXX
struct Enumeration: Traversal::Enumeration, Context
{
Enumeration (Context& c, Traversal::Complex& complex)
- : Context (c), complex_ (complex), enumerator_ (c)
+ : Context (c),
+ complex_ (complex),
+ base_name_ (c, TypeName::base),
+ enumerator_ (c)
{
names_ >> enumerator_;
}
@@ -129,6 +132,123 @@ namespace CXX
<< "}";
}
}
+
+ // _clone
+ //
+ if (clone && !fixed_length (e))
+ {
+ //
+ // _copy
+ //
+
+ os << (exceptions ? "void " : "bool ") << name << "::" << endl
+ << "_copy (" << name << "& c) const"
+ << "{";
+
+ // Copy the base or enum value.
+ //
+ if (base_enum)
+ {
+ SemanticGraph::Type& b (e.inherits ().base ());
+
+ if (fixed_length (b))
+ {
+ os << "static_cast< ";
+ base_name_.dispatch (b);
+ os << "& > (c) = *this;";
+ }
+ else
+ {
+ os << "const ";
+ base_name_.dispatch (b);
+ os << "& b = *this;";
+
+ if (exceptions)
+ os << "b._copy (c);";
+ else
+ os << "if (!b._copy (c))" << endl
+ << "return false;"
+ << endl;
+ }
+ }
+ else
+ {
+ String const& m (ec.get<String> ("value-member"));
+ os << "c." << m << " = this->" << m << ";";
+ }
+
+ // Copy custom data.
+ //
+ if (ec.count ("cd-name"))
+ {
+ String const& m (ecd_member (e));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
+
+ os << "}";
+
+ //
+ // _clone
+ //
+
+ os << name << "* " << name << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << name << "* c = new " << name << ";";
+ else
+ os << name << "* c = static_cast< " << name << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << name << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
+
+ os << "new (c) " << name << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ }
+
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << name << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << name << " ();"
+ << "::xsde::cxx::free (c);";
+
+ os << "return 0;"
+ << "}";
+ }
+
+ os << "return c;"
+ << "}";
+ }
}
virtual Void
@@ -140,6 +260,8 @@ namespace CXX
private:
Traversal::Complex& complex_;
+ TypeName base_name_;
+
Traversal::Names names_;
Enumerator enumerator_;
};
@@ -147,7 +269,7 @@ namespace CXX
struct List : Traversal::List, Context
{
List (Context& c)
- : Context (c)
+ : Context (c), base_name_ (c, TypeName::seq)
{
}
@@ -162,12 +284,16 @@ namespace CXX
if (!name)
return;
- if (polymorphic (l))
- {
+ Boolean poly (polymorphic (l));
+ SemanticGraph::Context& lc (l.context ());
+
+ if (poly || clone)
os << "// " << comment (l.name ()) << endl
<< "//" << endl
<< endl;
+ if (poly)
+ {
// d-tor
//
os << name << "::" << endl
@@ -214,7 +340,108 @@ namespace CXX
<< "}";
}
}
+
+ // _clone
+ //
+ if (clone)
+ {
+ //
+ // _copy
+ //
+
+ os << (exceptions ? "void " : "bool ") << name << "::" << endl
+ << "_copy (" << name << "& c) const"
+ << "{";
+
+ // Copy the base.
+ //
+ os << "const ";
+ base_name_.dispatch (l.argumented ().type ());
+ os << "& b = *this;";
+
+ if (exceptions)
+ os << "b.copy (c);";
+ else
+ os << "if (b.copy (c))" << endl
+ << "return false;"
+ << endl;
+
+ // Copy custom data.
+ //
+ if (lc.count ("cd-name"))
+ {
+ String const& m (ecd_member (l));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
+
+ os << "}";
+
+ //
+ // _clone
+ //
+
+ os << name << "* " << name << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << name << "* c = new " << name << ";";
+ else
+ os << name << "* c = static_cast< " << name << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << name << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
+
+ os << "new (c) " << name << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ }
+
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << name << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << name << " ();"
+ << "::xsde::cxx::free (c);";
+
+ os << "return 0;"
+ << "}";
+ }
+
+ os << "return c;"
+ << "}";
+ }
}
+
+ private:
+ TypeName base_name_;
};
//
@@ -238,13 +465,14 @@ namespace CXX
return;
Boolean poly (polymorphic (u));
+ SemanticGraph::Context& uc (u.context ());
+
+ os << "// " << comment (u.name ()) << endl
+ << "//" << endl
+ << endl;
if (!stl || poly)
{
- os << "// " << comment (u.name ()) << endl
- << "//" << endl
- << endl;
-
// d-tor
//
os << name << "::" << endl
@@ -302,6 +530,108 @@ namespace CXX
<< "}";
}
}
+
+ // _clone
+ //
+ if (clone && !fixed_length (u))
+ {
+ //
+ // _copy
+ //
+
+ os << (exceptions ? "void " : "bool ") << name << "::" << endl
+ << "_copy (" << name << "& c) const"
+ << "{";
+
+ // Copy the value.
+ //
+ String const& m (uc.get<String> ("value-member"));
+
+ if (stl)
+ os << "c." << m << " = this->" << m << ";";
+ else
+ {
+ os << "c." << m << " = ::xsde::cxx::strdupx (this->" << m << ");";
+
+ if (!exceptions)
+ os << endl
+ << "if (c." << m << " == 0)" << endl
+ << "return false;"
+ << endl;
+ }
+
+ // Copy custom data.
+ //
+ if (uc.count ("cd-name"))
+ {
+ String const& m (ecd_member (u));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
+
+ os << "}";
+
+ //
+ // _clone
+ //
+
+ os << name << "* " << name << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << name << "* c = new " << name << ";";
+ else
+ os << name << "* c = static_cast< " << name << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << name << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
+
+ os << "new (c) " << name << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ }
+
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << name << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << name << " ();"
+ << "::xsde::cxx::free (c);";
+
+ os << "return 0;"
+ << "}";
+ }
+
+ os << "return c;"
+ << "}";
+ }
}
};
@@ -1379,6 +1709,324 @@ namespace CXX
};
//
+ // Clone.
+ //
+
+ struct AttributeClone: Traversal::Attribute, Context
+ {
+ AttributeClone (Context& c)
+ : Context (c), clone_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ if (!a.fixed_p ())
+ {
+ String const& name (ename (a));
+ SemanticGraph::Type& t (a.type ());
+
+ Boolean opt (a.optional_p () && !a.default_p ());
+
+ if (opt)
+ os << "if (this->" << epresent (a) << " ())";
+
+ if (fixed_length (t))
+ os << (opt ? "\n" : "")
+ << "c." << name << " (this->" << name << " ());"
+ << endl;
+ else
+ clone_.dispatch (t, a);
+ }
+ }
+
+ private:
+ TypeClone clone_;
+ };
+
+
+ struct ElementClone: Traversal::Element, Context
+ {
+ ElementClone (Context& c)
+ : Context (c), clone_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ String const& name (ename (e));
+
+ if (e.max () != 1)
+ {
+ if (exceptions)
+ os << "this->" << name << " ().copy (c." << name << " ());"
+ << endl;
+ else
+ os << "if (this->" << name << " ().copy (c." << name << " ()))" << endl
+ << "return false;"
+ << endl;
+ }
+ else
+ {
+ SemanticGraph::Type& t (e.type ());
+
+ Boolean opt (e.min () == 0);
+
+ if (opt)
+ os << "if (this->" << epresent (e) << " ())";
+
+ if (fixed_length (t))
+ os << (opt ? "\n" : "")
+ << "c." << name << " (this->" << name << " ());"
+ << endl;
+ else
+ clone_.dispatch (t, e);
+ }
+ }
+
+ private:
+ TypeClone clone_;
+ };
+
+ struct AllClone: Traversal::All, Context
+ {
+ AllClone (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ // For the all compositor, maxOccurs=1 and minOccurs={0,1}
+ // and it can only contain particles.
+ //
+ if (a.min () == 0)
+ {
+ String const& name (ename (a));
+
+ os << "if (this->" << epresent (a) << " ())";
+
+ if (fixed_length (a))
+ os << endl
+ << "c." << name << " (this->" << name << " ());"
+ << endl;
+ else
+ {
+ os << "{"
+ << etype (a) << "* m = this->" << name << " ()._clone ();";
+
+ if (!exceptions)
+ os << endl
+ << "if (m == 0)" << endl
+ << "return false;"
+ << endl;
+
+ os << "c." << name << " (m);"
+ << "}";
+ }
+ }
+ else
+ All::contains (a);
+ }
+ };
+
+ struct SequenceInSequenceClone: Traversal::Sequence, Context
+ {
+ SequenceInSequenceClone (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (s.max () != 1)
+ {
+ String const& name (ename (s));
+
+ if (exceptions)
+ os << "this->" << name << " ().copy (c." << name << " ());"
+ << endl;
+ else
+ os << "if (this->" << name << " ().copy (c." << name << " ()))" << endl
+ << "return false;"
+ << endl;
+ }
+ else if (s.min () == 0)
+ {
+ String const& name (ename (s));
+
+ os << "if (this->" << epresent (s) << " ())";
+
+ if (fixed_length (s))
+ os << endl
+ << "c." << name << " (this->" << name << " ());"
+ << endl;
+ else
+ {
+ os << "{"
+ << etype (s) << "* m = this->" << name << " ()._clone ();";
+
+ if (!exceptions)
+ os << endl
+ << "if (m == 0)" << endl
+ << "return false;"
+ << endl;
+
+ os << "c." << name << " (m);"
+ << "}";
+ }
+ }
+ else
+ Sequence::contains (s);
+ }
+ };
+
+ struct ParticleInChoiceClone: ElementClone, Traversal::Compositor
+ {
+ ParticleInChoiceClone (Context& c)
+ : ElementClone (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ os << "case " << etag (e) << ":"
+ << "{";
+
+ ElementClone::traverse (e);
+
+ os << "break;"
+ << "}";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c)
+ {
+ // In choice there are no inline compositors.
+ //
+ os << "case " << etag (c) << ":"
+ << "{";
+
+ String const& name (ename (c));
+
+ if (c.max () != 1)
+ {
+ if (exceptions)
+ os << "this->" << name << " ().copy (c." << name << " ());";
+ else
+ os << "if (this->" << name << " ().copy (c." << name << " ()))" << endl
+ << "return false;";
+ }
+ else
+ {
+ Boolean opt (c.min () == 0);
+
+ if (opt)
+ os << "if (this->" << epresent (c) << " ())";
+
+ if (fixed_length (c))
+ os << (opt ? "\n" : "")
+ << "c." << name << " (this->" << name << " ());"
+ << endl;
+ else
+ {
+ os << "{"
+ << etype (c) << "* m = this->" << name << " ()._clone ();";
+
+ if (!exceptions)
+ os << endl
+ << "if (m == 0)" << endl
+ << "return false;"
+ << endl;
+
+ os << "c." << name << " (m);"
+ << "}";
+ }
+ }
+
+ os << "break;"
+ << "}";
+ }
+ };
+
+ struct ChoiceInSequenceClone: Traversal::Choice, Context
+ {
+ ChoiceInSequenceClone (Context& c)
+ : Context (c), particle_ (c)
+ {
+ contains_particle_ >> particle_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ if (c.max () != 1)
+ {
+ String const& name (ename (c));
+
+ if (exceptions)
+ os << "this->" << name << " ().copy (c." << name << " ());"
+ << endl;
+ else
+ os << "if (this->" << name << " ().copy (c." << name << " ()))" << endl
+ << "return false;"
+ << endl;
+ }
+ else if (c.min () == 0)
+ {
+ String const& name (ename (c));
+
+ os << "if (this->" << epresent (c) << " ())";
+
+ if (fixed_length (c))
+ os << endl
+ << "c." << name << " (this->" << name << " ());"
+ << endl;
+ else
+ {
+ os << "{"
+ << etype (c) << "* m = this->" << name << " ()._clone ();";
+
+ if (!exceptions)
+ os << endl
+ << "if (m == 0)" << endl
+ << "return false;"
+ << endl;
+
+ os << "c." << name << " (m);"
+ << "}";
+ }
+ }
+ else
+ {
+ // Inline choice.
+ //
+ String const& arm (earm (c));
+
+ os << "c." << arm << " (this->" << arm << " ());"
+ << endl
+ << "switch (this->" << arm << " ())"
+ << "{";
+
+ Choice::contains (c, contains_particle_);
+
+ os << "default:" << endl
+ << "break;"
+ << "}";
+ }
+ }
+
+ private:
+ ParticleInChoiceClone particle_;
+ Traversal::ContainsParticle contains_particle_;
+ };
+
+ //
// Nested classes.
//
@@ -1388,12 +2036,14 @@ namespace CXX
Traversal::ContainsParticle& contains_ctor,
Traversal::ContainsParticle& contains_dtor,
Traversal::ContainsParticle& contains_copy,
- Traversal::ContainsParticle& contains_assign)
+ Traversal::ContainsParticle& contains_assign,
+ Traversal::ContainsParticle& contains_clone)
: Context (c),
contains_ctor_ (contains_ctor),
contains_dtor_ (contains_dtor),
contains_copy_ (contains_copy),
- contains_assign_ (contains_assign)
+ contains_assign_ (contains_assign),
+ contains_clone_ (contains_clone)
{
}
@@ -1403,57 +2053,147 @@ namespace CXX
// For the all compositor, maxOccurs=1 and minOccurs={0,1}
// and it can only contain particles.
//
- if (a.min () == 0)
- {
- String const& type (etype (a));
- String const& scope (Context::scope (a));
+ if (a.min () != 0)
+ return;
+
+ Boolean fl (fixed_length (a));
+ String const& type (etype (a));
+ String const& scope (Context::scope (a));
+
+ // c-tor
+ //
+ os << scope << "::" << type << "::" << endl
+ << type << " ()"
+ << "{";
+
+ All::contains (a, contains_ctor_);
+
+ os << "}";
- // c-tor
+ // d-tor
+ //
+ os << scope << "::" << type << "::" << endl
+ << "~" << type << " ()"
+ << "{";
+
+ All::contains (a, contains_dtor_);
+
+ os << "}";
+
+ if (fl)
+ {
+ // copy c-tor
//
os << scope << "::" << type << "::" << endl
- << type << " ()"
- << "{";
+ << type << " (const " << type << "& x)"
+ << "{"
+ << "XSDE_UNUSED (x);";
- All::contains (a, contains_ctor_);
+ All::contains (a, contains_copy_);
os << "}";
- // d-tor
+ // operator=
//
- os << scope << "::" << type << "::" << endl
- << "~" << type << " ()"
+ os << scope << "::" << type << "& " << scope << "::" <<
+ type << "::" << endl
+ << "operator= (const " << type << "& x)"
+ << "{"
+ << "XSDE_UNUSED (x);";
+
+ All::contains (a, contains_assign_);
+
+ os << "return *this;"
+ << "}";
+ }
+
+ // _clone
+ //
+ if (!fl && clone)
+ {
+ //
+ // _copy
+ //
+
+ os << (exceptions ? "void " : "bool ") << scope << "::" <<
+ type << "::" << endl
+ << "_copy (" << type << "& c) const"
<< "{";
- All::contains (a, contains_dtor_);
+ All::contains (a, contains_clone_);
+
+ // Copy custom data.
+ //
+ if (a.context ().count ("cd-name"))
+ {
+ String const& m (ecd_member (a));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
os << "}";
- if (fixed_length (a))
+ //
+ // _clone
+ //
+
+ os << scope << "::" << type << "* " << scope << "::" <<
+ type << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << type << "* c = new " << type << ";";
+ else
+ os << type << "* c = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
{
- // copy c-tor
- //
- os << scope << "::" << type << "::" << endl
- << type << " (const " << type << "& x)"
- << "{"
- << "XSDE_UNUSED (x);";
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
- All::contains (a, contains_copy_);
+ os << "new (c) " << type << ";";
- os << "}";
+ if (exceptions)
+ os << "ag.release ();";
+ }
- // operator=
- //
- os << scope << "::" << type << "& " << scope << "::" <<
- type << "::" << endl
- << "operator= (const " << type << "& x)"
- << "{"
- << "XSDE_UNUSED (x);";
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << type << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
- All::contains (a, contains_assign_);
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << type << " ();"
+ << "::xsde::cxx::free (c);";
- os << "return *this;"
+ os << "return 0;"
<< "}";
}
+
+ os << "return c;"
+ << "}";
}
}
@@ -1462,6 +2202,7 @@ namespace CXX
Traversal::ContainsParticle& contains_dtor_;
Traversal::ContainsParticle& contains_copy_;
Traversal::ContainsParticle& contains_assign_;
+ Traversal::ContainsParticle& contains_clone_;
};
struct Choice: Traversal::Choice, Context
@@ -1475,12 +2216,14 @@ namespace CXX
particle_free_ (c, ChoiceParticle::free),
particle_alloc_ (c, ChoiceParticle::alloc),
particle_copy_ (c, ChoiceParticle::copy),
- particle_assign_ (c, ChoiceParticle::assign)
+ particle_assign_ (c, ChoiceParticle::assign),
+ particle_clone_ (c)
{
contains_free_ >> particle_free_;
contains_alloc_ >> particle_alloc_;
contains_copy_ >> particle_copy_;
contains_assign_ >> particle_assign_;
+ contains_clone_ >> particle_clone_;
}
virtual Void
@@ -1499,6 +2242,8 @@ namespace CXX
String const& scope (Context::scope (c));
+ Boolean fl (fixed_length (c));
+
// c-tor ()
//
os << scope << "::" << type << "::" << endl
@@ -1517,7 +2262,7 @@ namespace CXX
arm_tag << " (" << bad_tag << "));"
<< "}";
- if (fixed_length (c))
+ if (fl)
{
// copy c-tor
//
@@ -1586,6 +2331,104 @@ namespace CXX
<< "}";
Choice::contains (c, contains_func_);
+
+ // _clone
+ //
+ if (!fl && clone)
+ {
+ //
+ // _copy
+ //
+ String const& arm (earm (c));
+
+ os << (exceptions ? "void " : "bool ") << scope << "::" <<
+ type << "::" << endl
+ << "_copy (" << type << "& c) const"
+ << "{"
+ << "c." << arm << " (this->" << arm << " ());"
+ << endl
+ << "switch (this->" << arm << " ())"
+ << "{";
+
+ Choice::contains (c, contains_clone_);
+
+ os << "default:" << endl
+ << "break;"
+ << "}";
+
+ // Copy custom data.
+ //
+ if (c.context ().count ("cd-name"))
+ {
+ String const& m (ecd_member (c));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
+
+ os << "}";
+
+ //
+ // _clone
+ //
+
+ os << scope << "::" << type << "* " << scope << "::" <<
+ type << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << type << "* c = new " << type << ";";
+ else
+ os << type << "* c = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
+
+ os << "new (c) " << type << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ }
+
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << type << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << type << " ();"
+ << "::xsde::cxx::free (c);";
+
+ os << "return 0;"
+ << "}";
+ }
+
+ os << "return c;"
+ << "}";
+ }
}
Choice::contains (c);
@@ -1606,6 +2449,9 @@ namespace CXX
ChoiceParticle particle_assign_;
Traversal::ContainsParticle contains_assign_;
+
+ ParticleInChoiceClone particle_clone_;
+ Traversal::ContainsParticle contains_clone_;
};
@@ -1617,6 +2463,7 @@ namespace CXX
Traversal::ContainsParticle& contains_dtor,
Traversal::ContainsParticle& contains_copy,
Traversal::ContainsParticle& contains_assign,
+ Traversal::ContainsParticle& contains_clone,
Traversal::ContainsParticle& contains_func)
: Context (c),
in_choice_ (in_choice),
@@ -1624,6 +2471,7 @@ namespace CXX
contains_dtor_ (contains_dtor),
contains_copy_ (contains_copy),
contains_assign_ (contains_assign),
+ contains_clone_ (contains_clone),
contains_func_ (contains_func)
{
}
@@ -1639,6 +2487,8 @@ namespace CXX
String const& type (etype (s));
String const& scope (Context::scope (s));
+ Boolean fl (fixed_length (s));
+
// c-tor ()
//
os << scope << "::" << type << "::" << endl
@@ -1659,7 +2509,7 @@ namespace CXX
os << "}";
- if (fixed_length (s))
+ if (fl)
{
// copy c-tor
//
@@ -1686,6 +2536,95 @@ namespace CXX
<< "}";
}
+ // _clone
+ //
+ if (!fl && clone)
+ {
+ //
+ // _copy
+ //
+
+ os << (exceptions ? "void " : "bool ") << scope << "::" <<
+ type << "::" << endl
+ << "_copy (" << type << "& c) const"
+ << "{";
+
+ Sequence::contains (s, contains_clone_);
+
+ // Copy custom data.
+ //
+ if (s.context ().count ("cd-name"))
+ {
+ String const& m (ecd_member (s));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
+
+ os << "}";
+
+ //
+ // _clone
+ //
+
+ os << scope << "::" << type << "* " << scope << "::" <<
+ type << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << type << "* c = new " << type << ";";
+ else
+ os << type << "* c = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
+
+ os << "new (c) " << type << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ }
+
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << type << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << type << " ();"
+ << "::xsde::cxx::free (c);";
+
+ os << "return 0;"
+ << "}";
+ }
+
+ os << "return c;"
+ << "}";
+ }
+
Sequence::contains (s, contains_func_);
}
@@ -1698,10 +2637,11 @@ namespace CXX
Traversal::ContainsParticle& contains_dtor_;
Traversal::ContainsParticle& contains_copy_;
Traversal::ContainsParticle& contains_assign_;
+ Traversal::ContainsParticle& contains_clone_;
Traversal::ContainsParticle& contains_func_;
};
- struct Complex : Traversal::Complex, Context
+ struct Complex: Traversal::Complex, Context
{
Complex (Context& c)
: Context (c),
@@ -1747,13 +2687,22 @@ namespace CXX
choice_in_sequence_assign_ (c),
sequence_in_sequence_assign_ (c),
+ // Clone.
+ //
+ attribute_clone_ (c),
+ element_clone_ (c),
+ all_clone_ (c),
+ choice_in_sequence_clone_ (c),
+ sequence_in_sequence_clone_ (c),
+
// Nested c-tors, etc.
//
all_ (c,
all_contains_ctor_,
all_contains_dtor_,
all_contains_copy_,
- all_contains_assign_),
+ all_contains_assign_,
+ all_contains_clone_),
choice_in_choice_ (c, true, choice_contains_func_),
choice_in_sequence_ (c, false, choice_contains_func_),
sequence_in_choice_ (
@@ -1763,6 +2712,7 @@ namespace CXX
sequence_contains_dtor_,
sequence_contains_copy_,
sequence_contains_assign_,
+ sequence_contains_clone_,
sequence_contains_func_),
sequence_in_sequence_ (
c,
@@ -1771,6 +2721,7 @@ namespace CXX
sequence_contains_dtor_,
sequence_contains_copy_,
sequence_contains_assign_,
+ sequence_contains_clone_,
sequence_contains_func_)
{
// Functions.
@@ -1850,6 +2801,21 @@ namespace CXX
contains_compositor_assign_ >> choice_in_sequence_assign_;
contains_compositor_assign_ >> sequence_in_sequence_assign_;
+ // Clone.
+ //
+ attribute_names_clone_ >> attribute_clone_;
+
+ all_clone_ >> all_contains_clone_ >> element_clone_;
+
+ sequence_in_sequence_clone_ >> sequence_contains_clone_;
+ sequence_contains_clone_ >> element_clone_;
+ sequence_contains_clone_ >> choice_in_sequence_clone_;
+ sequence_contains_clone_ >> sequence_in_sequence_clone_;
+
+ contains_compositor_clone_ >> all_clone_;
+ contains_compositor_clone_ >> choice_in_sequence_clone_;
+ contains_compositor_clone_ >> sequence_in_sequence_clone_;
+
// Nested c-tors, etc.
//
all_ >> all_contains_;
@@ -1880,6 +2846,7 @@ namespace CXX
if (!name)
return;
+ Boolean fl (fixed_length (c));
Boolean poly (polymorphic (c));
Boolean restriction (restriction_p (c));
@@ -1924,7 +2891,7 @@ namespace CXX
if (!restriction)
{
- if (fixed_length (c))
+ if (fl)
{
// copy c-tor
//
@@ -1980,6 +2947,130 @@ namespace CXX
Complex::contains_compositor (c, contains_compositor_func_);
}
+ // _clone
+ //
+ if (!fl && clone)
+ {
+ //
+ // _copy
+ //
+
+ os << (exceptions ? "void " : "bool ") << name << "::" << endl
+ << "_copy (" << name << "& c) const"
+ << "{"
+ << "XSDE_UNUSED (c);"
+ << endl;
+
+ // Copy the base.
+ //
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ if (fixed_length (b))
+ {
+ os << "static_cast< ";
+ base_name_.dispatch (b);
+ os << "& > (c) = *this;";
+ }
+ else
+ {
+ os << "const ";
+ base_name_.dispatch (b);
+ os << "& b = *this;";
+
+ if (exceptions)
+ os << "b._copy (c);";
+ else
+ os << "if (!b._copy (c))" << endl
+ << "return false;"
+ << endl;
+ }
+ }
+
+ // Copy members.
+ //
+ if (!restriction)
+ {
+ Complex::names (c, attribute_names_clone_);
+
+ if (c.contains_compositor_p ())
+ Complex::contains_compositor (c, contains_compositor_clone_);
+ }
+
+ // Copy custom data.
+ //
+ if (c.context ().count ("cd-name"))
+ {
+ String const& m (ecd_member (c));
+
+ if (exceptions)
+ os << "this->" << m << ".copy (c." << m << ");";
+ else
+ os << "if (this->" << m << ".copy (c." << m << "))" << endl
+ << "return false;"
+ << endl;
+ }
+
+ if (!exceptions)
+ os << "return true;";
+
+ os << "}";
+
+ //
+ // _clone
+ //
+
+ os << name << "* " << name << "::" << endl
+ << "_clone () const"
+ << "{";
+
+ if (!custom_alloc)
+ os << name << "* c = new " << name << ";";
+ else
+ os << name << "* c = static_cast< " << name << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << name << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (c == 0)" << endl
+ << "return 0;"
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (c);";
+
+ os << "new (c) " << name << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ }
+
+ if (exceptions)
+ os << "::xsde::cxx::guard< " << name << " > g (c);"
+ << "this->_copy (*c);"
+ << "g.release ();";
+ else
+ {
+ os << "if (!this->_copy (*c))"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete c;";
+ else
+ os << "c->~" << name << " ();"
+ << "::xsde::cxx::free (c);";
+
+ os << "return 0;"
+ << "}";
+ }
+
+ os << "return c;"
+ << "}";
+ }
+
if (poly && typeinfo)
{
String id (c.name ());
@@ -2101,6 +3192,20 @@ namespace CXX
Traversal::ContainsCompositor contains_compositor_assign_;
+ // Clone.
+ //
+ AttributeClone attribute_clone_;
+ Traversal::Names attribute_names_clone_;
+
+ ElementClone element_clone_;
+ AllClone all_clone_;
+ ChoiceInSequenceClone choice_in_sequence_clone_;
+ SequenceInSequenceClone sequence_in_sequence_clone_;
+ Traversal::ContainsParticle all_contains_clone_;
+ Traversal::ContainsParticle sequence_contains_clone_;
+
+ Traversal::ContainsCompositor contains_compositor_clone_;
+
// Nested c-tors, etc.
//
All all_;
@@ -2129,6 +3234,10 @@ namespace CXX
ctx.os << "#include <new>" << endl
<< endl;
+ if (ctx.clone && ctx.exceptions)
+ ctx.os << "#include <xsde/cxx/guard.hxx>" << endl
+ << endl;
+
Traversal::Schema schema;
Traversal::Sources sources;
Traversal::Names names_ns, names;