aboutsummaryrefslogtreecommitdiff
path: root/xsde
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-05-11 12:20:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-05-11 12:20:11 +0200
commit2e501c68a8641a2b3c430b55f13491a9c1c5d0f5 (patch)
tree49c2748443fe3c1f01108756b647440e0647a11b /xsde
parent161beba6cdb0d91b15ad19fa8b3e51d986203915 (diff)
Add support for custom allocators
New example: examples/cxx/hybrid/allocator.
Diffstat (limited to 'xsde')
-rw-r--r--xsde/cxx/elements.cxx2
-rw-r--r--xsde/cxx/elements.hxx5
-rw-r--r--xsde/cxx/hybrid/cli.hxx2
-rw-r--r--xsde/cxx/hybrid/default-value.cxx24
-rw-r--r--xsde/cxx/hybrid/elements.cxx1
-rw-r--r--xsde/cxx/hybrid/elements.hxx353
-rw-r--r--xsde/cxx/hybrid/extraction-source.cxx189
-rw-r--r--xsde/cxx/hybrid/generator.cxx27
-rw-r--r--xsde/cxx/hybrid/parser-name-processor.cxx1
-rw-r--r--xsde/cxx/hybrid/parser-source.cxx496
-rw-r--r--xsde/cxx/hybrid/serializer-name-processor.cxx1
-rw-r--r--xsde/cxx/hybrid/tree-forward.cxx18
-rw-r--r--xsde/cxx/hybrid/tree-inline.cxx212
-rw-r--r--xsde/cxx/hybrid/tree-name-processor.cxx1
-rw-r--r--xsde/cxx/hybrid/tree-source.cxx93
-rw-r--r--xsde/cxx/hybrid/tree-type-map.cxx1
-rw-r--r--xsde/cxx/parser/cli.hxx2
-rw-r--r--xsde/cxx/parser/elements.cxx1
-rw-r--r--xsde/cxx/parser/generator.cxx25
-rw-r--r--xsde/cxx/parser/name-processor.cxx1
-rw-r--r--xsde/cxx/parser/parser-header.cxx21
-rw-r--r--xsde/cxx/parser/print-impl-common.hxx35
-rw-r--r--xsde/cxx/serializer/attribute-validation-source.cxx16
-rw-r--r--xsde/cxx/serializer/cli.hxx2
-rw-r--r--xsde/cxx/serializer/element-validation-source.cxx16
-rw-r--r--xsde/cxx/serializer/elements.cxx1
-rw-r--r--xsde/cxx/serializer/generator.cxx25
-rw-r--r--xsde/cxx/serializer/name-processor.cxx1
-rw-r--r--xsde/cxx/serializer/serializer-header.cxx20
-rw-r--r--xsde/cxx/serializer/serializer-source.cxx28
30 files changed, 1185 insertions, 435 deletions
diff --git a/xsde/cxx/elements.cxx b/xsde/cxx/elements.cxx
index 49d7f34..3da9392 100644
--- a/xsde/cxx/elements.cxx
+++ b/xsde/cxx/elements.cxx
@@ -125,6 +125,7 @@ namespace CXX
Containers::Vector<NarrowString> const& ir,
Boolean trace_include_regex_,
Boolean inline_,
+ Boolean custom_allocator,
Containers::Vector<NarrowString> const& reserved_name)
: os (o),
schema_root (root),
@@ -139,6 +140,7 @@ namespace CXX
type_exp (type_exp_),
inst_exp (inst_exp_),
inl (inl_),
+ custom_alloc (custom_allocator),
ns_mapping_cache (ns_mapping_cache_),
schema_path_ (path),
xs_ns_ (0),
diff --git a/xsde/cxx/elements.hxx b/xsde/cxx/elements.hxx
index a708cca..098bd84 100644
--- a/xsde/cxx/elements.hxx
+++ b/xsde/cxx/elements.hxx
@@ -159,6 +159,7 @@ namespace CXX
Containers::Vector<NarrowString> const& include_regex,
Boolean trace_include_regex_,
Boolean inline_,
+ Boolean custom_allocator,
Containers::Vector<NarrowString> const& reserved_name);
protected:
@@ -176,6 +177,7 @@ namespace CXX
type_exp (c.type_exp),
inst_exp (c.inst_exp),
inl (c.inl),
+ custom_alloc (c.custom_alloc),
ns_mapping_cache (c.ns_mapping_cache),
xs_ns_ (c.xs_ns_),
cxx_id_expr (c.cxx_id_expr),
@@ -204,6 +206,7 @@ namespace CXX
type_exp (c.type_exp),
inst_exp (c.inst_exp),
inl (c.inl),
+ custom_alloc (c.custom_alloc),
ns_mapping_cache (c.ns_mapping_cache),
xs_ns_ (c.xs_ns_),
cxx_id_expr (c.cxx_id_expr),
@@ -338,6 +341,8 @@ namespace CXX
String& inst_exp;
String& inl;
+ Boolean custom_alloc;
+
public:
MappingCache& ns_mapping_cache;
diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx
index 3834767..5de1692 100644
--- a/xsde/cxx/hybrid/cli.hxx
+++ b/xsde/cxx/hybrid/cli.hxx
@@ -44,6 +44,7 @@ namespace CXX
extern Key generate_xml_schema;
extern Key extern_xml_schema;
extern Key suppress_reset;
+ extern Key custom_allocator;
extern Key generate_polymorphic;
extern Key runtime_polymorphic;
extern Key polymorphic_type;
@@ -134,6 +135,7 @@ namespace CXX
generate_xml_schema, Boolean,
extern_xml_schema, NarrowString,
suppress_reset, Boolean,
+ custom_allocator, Boolean,
generate_polymorphic, Boolean,
runtime_polymorphic, Boolean,
polymorphic_type, Cult::Containers::Vector<NarrowString>,
diff --git a/xsde/cxx/hybrid/default-value.cxx b/xsde/cxx/hybrid/default-value.cxx
index a255c92..58a5507 100644
--- a/xsde/cxx/hybrid/default-value.cxx
+++ b/xsde/cxx/hybrid/default-value.cxx
@@ -499,7 +499,29 @@ namespace CXX
member_ = "tmp.";
else
{
- os << "tmp = new " << fq_name (t) << ";";
+ String tn (fq_name (t));
+
+ if (!custom_alloc)
+ os << "tmp = new " << tn << ";";
+ else
+ {
+ os << "tmp = static_cast< " << tn << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << tn << ")));";
+
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard tmpg (tmp);";
+ else
+ os << endl
+ << "if (tmp)" << endl;
+
+ os << "new (tmp) " << fq_name (t) << ";";
+
+ if (exceptions)
+ os << "tmpg.release ();";
+ else
+ os << endl;
+
+ }
if (!exceptions)
{
diff --git a/xsde/cxx/hybrid/elements.cxx b/xsde/cxx/hybrid/elements.cxx
index 3607c37..fe5c97e 100644
--- a/xsde/cxx/hybrid/elements.cxx
+++ b/xsde/cxx/hybrid/elements.cxx
@@ -32,6 +32,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
options (ops),
exceptions (!ops.value<CLI::no_exceptions> ()),
diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx
index 01030d5..60211e8 100644
--- a/xsde/cxx/hybrid/elements.hxx
+++ b/xsde/cxx/hybrid/elements.hxx
@@ -1611,76 +1611,63 @@ namespace CXX
String xs_ns_;
};
- struct TypeOps: Traversal::Type,
- Traversal::AnyType,
- Traversal::AnySimpleType,
-
- Traversal::Fundamental::Byte,
- Traversal::Fundamental::UnsignedByte,
- Traversal::Fundamental::Short,
- Traversal::Fundamental::UnsignedShort,
- Traversal::Fundamental::Int,
- Traversal::Fundamental::UnsignedInt,
- Traversal::Fundamental::Long,
- Traversal::Fundamental::UnsignedLong,
- Traversal::Fundamental::Integer,
- Traversal::Fundamental::NonPositiveInteger,
- Traversal::Fundamental::NonNegativeInteger,
- Traversal::Fundamental::PositiveInteger,
- Traversal::Fundamental::NegativeInteger,
-
- Traversal::Fundamental::Boolean,
-
- Traversal::Fundamental::Float,
- Traversal::Fundamental::Double,
- Traversal::Fundamental::Decimal,
-
- Traversal::Fundamental::String,
- Traversal::Fundamental::NormalizedString,
- Traversal::Fundamental::Token,
- Traversal::Fundamental::Name,
- Traversal::Fundamental::NameToken,
- Traversal::Fundamental::NameTokens,
- Traversal::Fundamental::NCName,
- Traversal::Fundamental::Language,
-
- Traversal::Fundamental::QName,
-
- Traversal::Fundamental::Id,
- Traversal::Fundamental::IdRef,
- Traversal::Fundamental::IdRefs,
-
- Traversal::Fundamental::AnyURI,
-
- Traversal::Fundamental::Base64Binary,
- Traversal::Fundamental::HexBinary,
-
- Traversal::Fundamental::Date,
- Traversal::Fundamental::DateTime,
- Traversal::Fundamental::Duration,
- Traversal::Fundamental::Day,
- Traversal::Fundamental::Month,
- Traversal::Fundamental::MonthDay,
- Traversal::Fundamental::Year,
- Traversal::Fundamental::YearMonth,
- Traversal::Fundamental::Time,
-
- Traversal::Fundamental::Entity,
- Traversal::Fundamental::Entities,
-
- Context
+ struct TypeOpsBase: Traversal::Type,
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities
{
- enum Use
- {
- deref,
- delete_
- };
-
- TypeOps (Context& c, Use use)
- : Context (c), use_ (use)
- {
- }
-
virtual Void
traverse (SemanticGraph::Type& t)
{
@@ -1704,135 +1691,135 @@ namespace CXX
// Boolean.
//
virtual Void
- traverse (SemanticGraph::Fundamental::Boolean&)
+ traverse (SemanticGraph::Fundamental::Boolean& t)
{
- fund_type ();
+ fund_type (t);
}
// Integral types.
//
virtual Void
- traverse (SemanticGraph::Fundamental::Byte&)
+ traverse (SemanticGraph::Fundamental::Byte& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::UnsignedByte&)
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Short&)
+ traverse (SemanticGraph::Fundamental::Short& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::UnsignedShort&)
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Int&)
+ traverse (SemanticGraph::Fundamental::Int& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::UnsignedInt&)
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Long&)
+ traverse (SemanticGraph::Fundamental::Long& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::UnsignedLong&)
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Integer&)
+ traverse (SemanticGraph::Fundamental::Integer& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::NonPositiveInteger&)
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::NonNegativeInteger&)
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::PositiveInteger&)
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::NegativeInteger&)
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
{
- fund_type ();
+ fund_type (t);
}
// Floats.
//
virtual Void
- traverse (SemanticGraph::Fundamental::Float&)
+ traverse (SemanticGraph::Fundamental::Float& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Double&)
+ traverse (SemanticGraph::Fundamental::Double& t)
{
- fund_type ();
+ fund_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Decimal&)
+ traverse (SemanticGraph::Fundamental::Decimal& t)
{
- fund_type ();
+ fund_type (t);
}
// Strings.
//
virtual Void
- traverse (SemanticGraph::Fundamental::String&)
+ traverse (SemanticGraph::Fundamental::String& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::NormalizedString&)
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Token&)
+ traverse (SemanticGraph::Fundamental::Token& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::NameToken&)
+ traverse (SemanticGraph::Fundamental::NameToken& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
@@ -1842,21 +1829,21 @@ namespace CXX
}
virtual Void
- traverse (SemanticGraph::Fundamental::Name&)
+ traverse (SemanticGraph::Fundamental::Name& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::NCName&)
+ traverse (SemanticGraph::Fundamental::NCName& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::Language&)
+ traverse (SemanticGraph::Fundamental::Language& t)
{
- string_type ();
+ string_type (t);
}
// Qualified name.
@@ -1870,15 +1857,15 @@ namespace CXX
// ID/IDREF.
//
virtual Void
- traverse (SemanticGraph::Fundamental::Id&)
+ traverse (SemanticGraph::Fundamental::Id& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
- traverse (SemanticGraph::Fundamental::IdRef&)
+ traverse (SemanticGraph::Fundamental::IdRef& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
@@ -1890,9 +1877,9 @@ namespace CXX
// URI.
//
virtual Void
- traverse (SemanticGraph::Fundamental::AnyURI&)
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
{
- string_type ();
+ string_type (t);
}
// Binary.
@@ -1968,9 +1955,9 @@ namespace CXX
// Entity.
//
virtual Void
- traverse (SemanticGraph::Fundamental::Entity&)
+ traverse (SemanticGraph::Fundamental::Entity& t)
{
- string_type ();
+ string_type (t);
}
virtual Void
@@ -1979,66 +1966,96 @@ namespace CXX
type (t);
}
- private:
- Void
+ protected:
+ virtual Void
+ type (SemanticGraph::Type&) = 0;
+
+ virtual Void
+ fund_type (SemanticGraph::Type&) = 0;
+
+ virtual Void
+ string_type (SemanticGraph::Type&) = 0;
+ };
+
+ struct TypeDeref: TypeOpsBase, Context
+ {
+ TypeDeref (Context& c)
+ : Context (c)
+ {
+ }
+
+ protected:
+ virtual Void
type (SemanticGraph::Type& t)
{
- switch (use_)
- {
- case deref:
- {
- if (!fixed_length (t))
- os << "*";
+ if (!fixed_length (t))
+ os << "*";
+ }
- break;
- }
- case delete_:
- {
- os << "delete";
- break;
- }
- }
+ virtual Void
+ fund_type (SemanticGraph::Type&)
+ {
+ }
+
+ virtual Void
+ string_type (SemanticGraph::Type&)
+ {
+ }
+ };
+
+ struct TypeDelete: TypeOpsBase, Context
+ {
+ TypeDelete (Context& c)
+ : Context (c)
+ {
}
Void
- fund_type ()
+ dispatch (SemanticGraph::Node& type, String const& var)
{
- switch (use_)
+ var_ = var;
+ Traversal::NodeBase::dispatch (type);
+ }
+
+ protected:
+ virtual Void
+ type (SemanticGraph::Type& t)
+ {
+ if (!custom_alloc)
+ os << "delete " << var_ << ";";
+ else
{
- case deref:
- {
- break;
- }
- case delete_:
- {
- os << "delete";
- break;
- }
+ os << "if (" << var_ << ")"
+ << "{"
+ << "typedef " << fq_name (t) << " _dtor;"
+ << var_ << "->~_dtor ();"
+ << "::xsde::cxx::free (" << var_ << ");"
+ << "}";
}
}
- Void
- string_type ()
+ virtual Void
+ fund_type (SemanticGraph::Type& t)
{
- switch (use_)
+ type (t);
+ }
+
+ virtual Void
+ string_type (SemanticGraph::Type& t)
+ {
+ if (stl)
+ type (t);
+ else
{
- case deref:
- {
- break;
- }
- case delete_:
- {
- if (stl)
- os << "delete";
- else
- os << "delete[]";
- break;
- }
+ if (!custom_alloc)
+ os << "delete[] " << var_ << ";";
+ else
+ os << "::xsde::cxx::free (" << var_ << ");";
}
}
private:
- Use use_;
+ String var_;
};
//
diff --git a/xsde/cxx/hybrid/extraction-source.cxx b/xsde/cxx/hybrid/extraction-source.cxx
index 3b98100..1e2a602 100644
--- a/xsde/cxx/hybrid/extraction-source.cxx
+++ b/xsde/cxx/hybrid/extraction-source.cxx
@@ -239,15 +239,30 @@ namespace CXX
{
String fq (fq_name (t));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
@@ -354,15 +369,30 @@ namespace CXX
{
String fq (fq_name (t));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
@@ -423,15 +453,30 @@ namespace CXX
{
String fq (scope (a) + L"::" + etype (a));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
@@ -529,15 +574,30 @@ namespace CXX
{
String fq (fq_name (t));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
@@ -604,15 +664,30 @@ namespace CXX
{
String fq (scope (c) + L"::" + etype (c));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
@@ -681,15 +756,30 @@ namespace CXX
{
String fq (scope (c) + L"::" + etype (c));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
@@ -784,15 +874,30 @@ namespace CXX
{
String fq (scope (s) + L"::" + etype (s));
- if (exceptions)
- os << "x." << name << " (new " << fq << ");";
+ if (!custom_alloc)
+ os << fq << "* i = new " << fq << ";";
else
- os << fq << "* i = new " << fq << ";"
- << endl
+ os << fq << "* i = static_cast< " << fq << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << fq << ")));";
+
+ if (!exceptions)
+ os << endl
<< "if (i == 0)" << endl
<< "return false;"
- << endl
- << "x." << name << " (i);";
+ << endl;
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ig (i);";
+
+ os << "new (i) " << fq << ";";
+
+ if (exceptions)
+ os << "ig.release ();";
+ }
+
+ os << "x." << name << " (i);";
}
if (exceptions)
diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx
index 34cfa2d..0ccbb91 100644
--- a/xsde/cxx/hybrid/generator.cxx
+++ b/xsde/cxx/hybrid/generator.cxx
@@ -132,6 +132,7 @@ namespace CXX
extern Key generate_xml_schema = "generate-xml-schema";
extern Key extern_xml_schema = "extern-xml-schema";
extern Key suppress_reset = "suppress-reset";
+ extern Key custom_allocator = "custom-allocator";
extern Key generate_polymorphic = "generate-polymorphic";
extern Key runtime_polymorphic = "runtime-polymorphic";
extern Key polymorphic_type = "polymorphic-type";
@@ -309,6 +310,11 @@ namespace CXX
<< " reset code."
<< endl;
+ e << "--custom-allocator" << endl
+ << " Generate code that uses custom allocator functions\n"
+ << " instead of operator new/delete."
+ << endl;
+
e << "--generate-polymorphic" << endl
<< " Generate polymorphism-aware code. Specify this\n"
<< " option if you use substitution groups or xsi:type."
@@ -836,6 +842,7 @@ namespace CXX
r->value<P::generate_xml_schema> () = h.value<H::generate_xml_schema> ();
r->value<P::extern_xml_schema> () = h.value<H::extern_xml_schema> ();
r->value<P::suppress_reset> () = h.value<H::suppress_reset> ();
+ r->value<P::custom_allocator> () = h.value<H::custom_allocator> ();
r->value<P::generate_polymorphic> () = h.value<H::generate_polymorphic> ();
r->value<P::runtime_polymorphic> () = h.value<H::runtime_polymorphic> ();
r->value<P::output_dir> () = h.value<H::output_dir> ();
@@ -918,6 +925,7 @@ namespace CXX
r->value<S::generate_xml_schema> () = h.value<H::generate_xml_schema> ();
r->value<S::extern_xml_schema> () = h.value<H::extern_xml_schema> ();
r->value<S::suppress_reset> () = h.value<H::suppress_reset> ();
+ r->value<S::custom_allocator> () = h.value<H::custom_allocator> ();
r->value<S::generate_polymorphic> () = h.value<H::generate_polymorphic> ();
r->value<S::runtime_polymorphic> () = h.value<H::runtime_polymorphic> ();
r->value<S::output_dir> () = h.value<H::output_dir> ();
@@ -1634,6 +1642,25 @@ namespace CXX
<< endl;
}
+ if (ops.value<CLI::custom_allocator> ())
+ {
+ hxx << "#ifndef XSDE_CUSTOM_ALLOCATOR" << endl
+ << "#error the generated code uses custom allocator while " <<
+ "the XSD/e runtime does not (reconfigure the runtime or " <<
+ "remove --custom-allocator)" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else
+ {
+ hxx << "#ifdef XSDE_CUSTOM_ALLOCATOR" << endl
+ << "#error the XSD/e runtime uses custom allocator while " <<
+ "the generated code does not (reconfigure the runtime or " <<
+ "add --custom-allocator)" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
//
//
diff --git a/xsde/cxx/hybrid/parser-name-processor.cxx b/xsde/cxx/hybrid/parser-name-processor.cxx
index 15b0459..3dce6fe 100644
--- a/xsde/cxx/hybrid/parser-name-processor.cxx
+++ b/xsde/cxx/hybrid/parser-name-processor.cxx
@@ -47,6 +47,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
impl_suffix_ (ops.value<CLI::pimpl_type_suffix> ()),
aggr_suffix_ (ops.value<CLI::paggr_type_suffix> ()),
diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx
index 525f364..94f05df 100644
--- a/xsde/cxx/hybrid/parser-source.cxx
+++ b/xsde/cxx/hybrid/parser-source.cxx
@@ -165,14 +165,25 @@ namespace CXX
if (!fl)
{
+ String p (L"this->" + state + L".x_");
+
// d-tor
//
os << name << "::" << endl
<< "~" << name << " ()"
<< "{"
- << "if (!this->" << epstate_base (e) << ")" << endl
- << "delete this->" << state << ".x_;"
- << "}";
+ << "if (!this->" << epstate_base (e) << " && " << p << ")";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";";
+ else
+ os << "{"
+ << p << "->~" << ename (e) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << "}";
// reset
//
@@ -188,10 +199,16 @@ namespace CXX
os << epskel (e) << "::_reset ();"
<< endl;
- os << "if (!this->" << epstate_base (e) << ")"
- << "{"
- << "delete this->" << state << ".x_;"
- << "this->" << state << ".x_ = 0;"
+ os << "if (!this->" << epstate_base (e) << " && " << p << ")"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << p << "->~" << ename (e) << " ();"
+ << "::xsde::cxx::free (" << p << ");";
+
+ os << p << " = 0;"
<< "}"
<< "}";
}
@@ -269,12 +286,32 @@ namespace CXX
}
else
{
- if (exceptions)
- os << "this->" << pre_impl_name (e) << " (new " << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << type << "* x = new " << type << ";"
- << "if (x)" << endl
- << "this->" << pre_impl_name (e) << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << "this->" << pre_impl_name (e) << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
}
@@ -455,6 +492,8 @@ namespace CXX
String const& member (epstate_member (l));
String item (unclash (epskel (l), "item"));
+ String p (L"this->" + member);
+
os << "// " << name << endl
<< "//" << endl
<< endl;
@@ -465,7 +504,7 @@ namespace CXX
<< name << " (bool b)"
<< "{"
<< "this->" << base << " = b;"
- << "this->" << member << " = 0;"
+ << p << " = 0;"
<< "}";
// d-tor
@@ -473,31 +512,48 @@ namespace CXX
os << name << "::" << endl
<< "~" << name << " ()"
<< "{"
- << "if (!this->" << base << ")" << endl
- << "delete this->" << member << ";"
- << "}";
+ << "if (!this->" << base << " && " << p << ")";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";";
+ else
+ os << "{"
+ << p << "->~" << ename (l) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << "}";
// reset
//
if (reset)
+ {
os << "void " << name << "::" << endl
<< "_reset ()"
<< "{"
<< epskel (l) << "::_reset ();"
<< endl
- << "if (!this->" << base << ")"
- << "{"
- << "delete this->" << member << ";"
- << "this->" << member << " = 0;"
+ << "if (!this->" << base << " && " << p << ")"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << p << "->~" << ename (l) << " ();"
+ << "::xsde::cxx::free (" << p << ");";
+
+ os << p << " = 0;"
<< "}"
<< "}";
+ }
// pre_impl
//
os << "void " << name << "::" << endl
<< pre_impl_name (l) << " (" << type << "* x)"
<< "{"
- << "this->" << member << " = x;"
+ << p << " = x;"
<< "}";
// pre
@@ -506,12 +562,32 @@ namespace CXX
<< "pre ()"
<< "{";
- if (exceptions)
- os << "this->" << pre_impl_name (l) << " (new " << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << type << "* x = new " << type << ";"
- << "if (x)" << endl
- << "this->" << pre_impl_name (l) << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << "this->" << pre_impl_name (l) << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
@@ -526,9 +602,9 @@ namespace CXX
<< "{";
if (exceptions)
- os << "this->" << member << "->push_back (i);";
+ os << p << "->push_back (i);";
else
- os << "if (this->" << member << "->push_back (i))" << endl
+ os << "if (" << p << "->push_back (i))" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
os << "}";
@@ -540,8 +616,8 @@ namespace CXX
os << ret << " " << name << "::" << endl
<< post_name (l) << " ()"
<< "{"
- << type << "* r = this->" << member << ";"
- << "this->" << member << " = 0;"
+ << type << "* r = " << p << ";"
+ << p << " = 0;"
<< "return r;"
<< "}";
}
@@ -606,6 +682,7 @@ namespace CXX
else
{
String const& base (epstate_base (u));
+ String p (L"this->" + state + L".x_");
// c-tor
//
@@ -613,7 +690,7 @@ namespace CXX
<< name << " (bool b)"
<< "{"
<< "this->" << base << " = b;"
- << "this->" << state << ".x_ = 0;"
+ << p << " = 0;"
<< "}";
// d-tor
@@ -621,31 +698,48 @@ namespace CXX
os << name << "::" << endl
<< "~" << name << " ()"
<< "{"
- << "if (!this->" << base << ")" << endl
- << "delete this->" << state << ".x_;"
- << "}";
+ << "if (!this->" << base << " && " << p << ")";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";";
+ else
+ os << "{"
+ << p << "->~" << ename (u) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << "}";
// reset
//
if (reset)
+ {
os << "void " << name << "::" << endl
<< "_reset ()"
<< "{"
<< epskel (u) << "::_reset ();"
<< endl
- << "if (!this->" << base << ")"
- << "{"
- << "delete this->" << state << ".x_;"
- << "this->" << state << ".x_ = 0;"
+ << "if (!this->" << base << " && " << p << ")"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << p << "->~" << ename (u) << " ();"
+ << "::xsde::cxx::free (" << p << ");";
+
+ os << p << " = 0;"
<< "}"
<< "}";
+ }
// pre_impl
//
os << "void " << name << "::" << endl
<< pre_impl_name (u) << " (" << type << "* x)"
<< "{"
- << "this->" << state << ".x_ = x;";
+ << p << " = x;";
if (exceptions)
os << "this->" << state << ".str_.assign (\"\", 0);";
@@ -664,12 +758,32 @@ namespace CXX
<< "pre ()"
<< "{";
- if (exceptions)
- os << "this->" << pre_impl_name (u) << " (new " << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << type << "* x = new " << type << ";"
- << "if (x)" << endl
- << "this->" << pre_impl_name (u) << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << "this->" << pre_impl_name (u) << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
@@ -697,8 +811,8 @@ namespace CXX
os << ret << " " << name << "::" << endl
<< post_name (u) << " ()"
<< "{"
- << type << "* r = this->" << state << ".x_;"
- << "this->" << state << ".x_ = 0;"
+ << type << "* r = " << p << ";"
+ << p << " = 0;"
<< "r->" << value << " (this->" << state << ".str_.detach ());"
<< "return r;"
<< "}";
@@ -946,17 +1060,35 @@ namespace CXX
else
{
String const& name (ename (a));
- String const& type (etype (a));
String const& scope (fq_scope (a));
+ String type (scope + L"::" + etype (a));
- if (exceptions)
- os << access << name << " (new " <<
- scope << "::" << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << scope << "::" << type << "* x = new " <<
- scope << "::" << type << ";"
- << "if (x)" << endl
- << access << name << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << access << name << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
}
@@ -981,18 +1113,17 @@ namespace CXX
if (c.max () != 1)
{
String const& name (ename (c));
- String const& type (etype (c));
String const& access_s (access_seq (c, false));
String const& ptr (epstate_member (c));
+ String type (type_scope + L"::" + etype (c));
if (fixed_length (c))
{
if (exceptions)
- os << access_s << name << " ().push_back (" <<
- type_scope << "::" << type << " ());";
+ os << access_s << name << " ().push_back (" << type << " ());";
else
os << "if (" << access_s << name << " ().push_back (" <<
- type_scope << "::" << type << " ()))"
+ type << " ()))"
<< "{"
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
<< "return;"
@@ -1003,8 +1134,27 @@ namespace CXX
}
else
{
- os << access << ptr << " = new " << type_scope << "::" <<
- type << ";";
+ if (!custom_alloc)
+ os << access << ptr << " = new " << type << ";";
+ else
+ {
+ os << access << ptr << " = static_cast< " << type <<
+ "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (" << access << ptr << ");";
+ else
+ os << endl
+ << "if (" << access << ptr << ")" << endl;
+
+ os << "new (" << access << ptr << ") " << type << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ else
+ os << endl;
+ }
if (exceptions)
os << access_s << name << " ().push_back (" <<
@@ -1029,16 +1179,34 @@ namespace CXX
os << access << epresent (c) << " (true);";
else
{
- String const& type (etype (c));
+ String type (type_scope + L"::" + etype (c));
- if (exceptions)
- os << access << name << " (new " << type_scope << "::" <<
- type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << type_scope << "::" << type << "* x = new " <<
- type_scope << "::" << type << ";"
- << "if (x)" << endl
- << access << name << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << access << name << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else"
<< "{"
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
@@ -1103,17 +1271,35 @@ namespace CXX
os << "case " << eptag (p) << ":"
<< "{";
- String const& type (etype (p));
String const& scope (fq_scope (p));
+ String type (scope + L"::" + etype (p));
- if (exceptions)
- os << access_seq (p) << ename (p) <<
- " (new " << scope << "::" << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << scope << "::" << type << "* x = new " <<
- scope << "::" << type << ";"
- << "if (x)" << endl
- << access_seq (p) << ename (p) << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << access_seq (p) << ename (p) << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
@@ -1144,9 +1330,9 @@ namespace CXX
String const& access (access_seq (s));
String const& access_s (access_seq (s, false));
String const& name (ename (s));
- String const& type (etype (s));
String const& scope (fq_scope (s));
String const& ptr (epstate_member (s));
+ String type (scope + L"::" + etype (s));
os << "void " << sc << "::" << endl
<< epnext (s) << " ()"
@@ -1155,11 +1341,10 @@ namespace CXX
if (fixed_length (s))
{
if (exceptions)
- os << access_s << name << " ().push_back (" <<
- scope << "::" << type << " ());";
+ os << access_s << name << " ().push_back (" << type << " ());";
else
os << "if (" << access_s << name << " ().push_back (" <<
- scope << "::" << type << " ()))"
+ type << " ()))"
<< "{"
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
<< "return;"
@@ -1170,8 +1355,27 @@ namespace CXX
}
else
{
- os << access << ptr << " = new " << scope << "::" <<
- type << ";";
+ if (!custom_alloc)
+ os << access << ptr << " = new " << type << ";";
+ else
+ {
+ os << access << ptr << " = static_cast< " << type <<
+ "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard ag (" << access << ptr << ");";
+ else
+ os << endl
+ << "if (" << access << ptr << ")" << endl;
+
+ os << "new (" << access << ptr << ") " << type << ";";
+
+ if (exceptions)
+ os << "ag.release ();";
+ else
+ os << endl;
+ }
if (exceptions)
os << access_s << name << " ().push_back (" <<
@@ -1200,17 +1404,35 @@ namespace CXX
else
{
String const& name (ename (s));
- String const& type (etype (s));
String const& scope (fq_scope (s));
+ String type (scope + L"::" + etype (s));
- if (exceptions)
- os << access << name << " (new " <<
- scope << "::" << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << scope << "::" << type << "* x = new " <<
- scope << "::" << type << ";"
- << "if (x)" << endl
- << access << name << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << access << name << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
}
@@ -1450,17 +1672,38 @@ namespace CXX
if (!rec)
{
- os << "if (!this->" << epstate_base (c) << ")" << endl
- << "delete this->" << state << "." << member << ";";
+ String p (L"this->" + state + L"." + member);
+
+ os << "if (!this->" << epstate_base (c) << " && " << p << ")";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";";
+ else
+ os << "{"
+ << p << "->~" << ename (c) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
}
else
{
+ String p (top_member);
+
os << "for (; !this->" << state << ".empty (); " <<
"this->" << state << ".pop ())"
<< "{"
- << "if (!this->" << epstate_base (c) << ")" << endl
- << "delete " << top_member << ";"
- << "}";
+ << "if (!this->" << epstate_base (c) << " && " << p << ")";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";";
+ else
+ os << "{"
+ << p << "->~" << ename (c) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << "}";
}
os << "}";
@@ -1481,22 +1724,41 @@ namespace CXX
if (!rec)
{
- os << "if (!this->" << epstate_base (c) << ")"
- << "{"
- << "delete this->" << state << "." << member << ";"
- << "this->" << state << "." << member << " = 0;"
+ String p (L"this->" + state + L"." + member);
+
+ os << "if (!this->" << epstate_base (c) << " && " << p << ")"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << p << "->~" << ename (c) << " ();"
+ << "::xsde::cxx::free (" << p << ");";
+
+ os << p << " = 0;"
<< "}";
}
else
{
// Same code as in d-tor.
//
+ String p (top_member);
+
os << "for (; !this->" << state << ".empty (); " <<
"this->" << state << ".pop ())"
<< "{"
- << "if (!this->" << epstate_base (c) << ")" << endl
- << "delete " << top_member << ";"
- << "}";
+ << "if (!this->" << epstate_base (c) << " && " << p << ")";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";";
+ else
+ os << "{"
+ << p << "->~" << ename (c) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << "}";
}
os << "}";
@@ -1633,12 +1895,32 @@ namespace CXX
}
else
{
- if (exceptions)
- os << "this->" << pre_impl_name (c) << " (new " << type << ");";
+ if (!custom_alloc)
+ os << type << "* x = new " << type << ";";
else
- os << type << "* x = new " << type << ";"
- << "if (x)" << endl
- << "this->" << pre_impl_name (c) << " (x);"
+ os << type << "* x = static_cast< " << type << "* > (" << endl
+ << "::xsde::cxx::alloc (sizeof (" << type << ")));";
+
+ if (!exceptions)
+ os << endl
+ << "if (x)"
+ << "{";
+
+ if (custom_alloc)
+ {
+ if (exceptions)
+ os << "::xsde::cxx::alloc_guard xg (x);";
+
+ os << "new (x) " << type << ";";
+
+ if (exceptions)
+ os << "xg.release ();";
+ }
+
+ os << "this->" << pre_impl_name (c) << " (x);";
+
+ if (!exceptions)
+ os << "}"
<< "else" << endl
<< "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
}
diff --git a/xsde/cxx/hybrid/serializer-name-processor.cxx b/xsde/cxx/hybrid/serializer-name-processor.cxx
index 17522cf..41f8885 100644
--- a/xsde/cxx/hybrid/serializer-name-processor.cxx
+++ b/xsde/cxx/hybrid/serializer-name-processor.cxx
@@ -46,6 +46,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
impl_suffix_ (ops.value<CLI::simpl_type_suffix> ()),
aggr_suffix_ (ops.value<CLI::saggr_type_suffix> ()),
diff --git a/xsde/cxx/hybrid/tree-forward.cxx b/xsde/cxx/hybrid/tree-forward.cxx
index 24d7b21..dbfdd7e 100644
--- a/xsde/cxx/hybrid/tree-forward.cxx
+++ b/xsde/cxx/hybrid/tree-forward.cxx
@@ -628,6 +628,20 @@ namespace CXX
pre (ns);
names (ns);
+ // Custom allocator.
+ //
+ if (custom_alloc)
+ {
+ os << endl
+ << "// Custom allocator." << endl
+ << "//" << endl
+ << "using ::xsde::cxx::alloc;"
+ << "using ::xsde::cxx::free;";
+
+ if (exceptions)
+ os << "using ::xsde::cxx::alloc_guard;";
+ }
+
// strdupx
//
if (!stl)
@@ -718,6 +732,10 @@ namespace CXX
}
else
{
+ if (ctx.custom_alloc)
+ ctx.os << "#include <xsde/cxx/allocator.hxx>" << endl
+ << endl;
+
if (ctx.stl)
ctx.os << "#include <string>" << endl;
else
diff --git a/xsde/cxx/hybrid/tree-inline.cxx b/xsde/cxx/hybrid/tree-inline.cxx
index 1da9261..fa55403 100644
--- a/xsde/cxx/hybrid/tree-inline.cxx
+++ b/xsde/cxx/hybrid/tree-inline.cxx
@@ -260,6 +260,8 @@ namespace CXX
}
else
{
+ String p (L"this->" + member);
+
// const char*
// name () const
//
@@ -267,7 +269,7 @@ namespace CXX
<< "const char* " << name << "::" << endl
<< value << " () const"
<< "{"
- << "return this->" << member << ";"
+ << "return " << p << ";"
<< "}";
// char*
@@ -277,7 +279,7 @@ namespace CXX
<< "char* " << name << "::" << endl
<< value << " ()"
<< "{"
- << "return this->" << member << ";"
+ << "return " << p << ";"
<< "}";
// void
@@ -286,9 +288,14 @@ namespace CXX
os << inl
<< "void " << name << "::" << endl
<< value << " (char* x)"
- << "{"
- << "delete[] this->" << member << ";"
- << "this->" << member << " = x;"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete[] " << p << ";";
+ else
+ os << "::xsde::cxx::free (" << p << ");";
+
+ os << p << " = x;"
<< "}";
// char*
@@ -300,8 +307,8 @@ namespace CXX
<< "char* " << name << "::" << endl
<< uc.get<String> ("value-detach") << " ()"
<< "{"
- << "char* r = this->" << member << ";"
- << "this->" << member << " = 0;"
+ << "char* r = " << p << ";"
+ << p << " = 0;"
<< "return r;"
<< "}";
}
@@ -348,8 +355,8 @@ namespace CXX
ro_ret_ (c, TypeName::ro_ret),
ret_ (c, TypeName::ret),
arg_ (c, TypeName::arg),
- deref_ (c, TypeOps::deref),
- delete_ (c, TypeOps::delete_),
+ deref_ (c),
+ delete_ (c),
compare_value_ (c)
{
}
@@ -425,9 +432,8 @@ namespace CXX
else
{
os << "{";
- delete_.dispatch (t);
- os << " this->" << member << ";"
- << "this->" << member << " = 0;"
+ delete_.dispatch (t, L"this->" + member);
+ os << "this->" << member << " = 0;"
<< "}";
}
}
@@ -439,9 +445,8 @@ namespace CXX
{
os << "if (!x)"
<< "{";
- delete_.dispatch (t);
- os << " this->" << member << ";"
- << "this->" << member << " = 0;"
+ delete_.dispatch (t, L"this->" + member);
+ os << "this->" << member << " = 0;"
<< "}";
}
}
@@ -530,10 +535,7 @@ namespace CXX
<< "{";
if (!fl)
- {
- delete_.dispatch (t);
- os << " this->" << member << ";";
- }
+ delete_.dispatch (t, L"this->" + member);
os << "this->" << member << " = x;";
@@ -566,8 +568,8 @@ namespace CXX
TypeName ro_ret_;
TypeName ret_;
TypeName arg_;
- TypeOps deref_;
- TypeOps delete_;
+ TypeDeref deref_;
+ TypeDelete delete_;
CompareValue compare_value_;
};
@@ -578,8 +580,8 @@ namespace CXX
ro_ret_ (c, TypeName::ro_ret),
ret_ (c, TypeName::ret),
arg_ (c, TypeName::arg),
- deref_ (c, TypeOps::deref),
- delete_ (c, TypeOps::delete_)
+ deref_ (c),
+ delete_ (c)
{
}
@@ -653,9 +655,8 @@ namespace CXX
{
os << "if (!x)"
<< "{";
- delete_.dispatch (t);
- os << " this->" << member << ";"
- << "this->" << member << " = 0;"
+ delete_.dispatch (t, L"this->" + member);
+ os << "this->" << member << " = 0;"
<< "}";
}
@@ -699,10 +700,7 @@ namespace CXX
<< "{";
if (!fl)
- {
- delete_.dispatch (t);
- os << " this->" << member << ";";
- }
+ delete_.dispatch (t, L"this->" + member);
os << "this->" << member << " = x;";
@@ -734,8 +732,8 @@ namespace CXX
TypeName ro_ret_;
TypeName ret_;
TypeName arg_;
- TypeOps deref_;
- TypeOps delete_;
+ TypeDeref deref_;
+ TypeDelete delete_;
};
struct ElementInChoiceFunc: Traversal::Element, Context
@@ -746,8 +744,8 @@ namespace CXX
ret_ (c, TypeName::ret),
arg_ (c, TypeName::arg),
var_ (c, TypeName::var),
- deref_ (c, TypeOps::deref),
- delete_ (c, TypeOps::delete_)
+ deref_ (c),
+ delete_ (c)
{
}
@@ -849,9 +847,8 @@ namespace CXX
{
os << "else if (!x)"
<< "{";
- delete_.dispatch (t);
- os << " this->" << umember << "." << member << ";"
- << "this->" << umember << "." << member << " = 0;"
+ delete_.dispatch (t, L"this->" + umember + L"." + member);
+ os << "this->" << umember << "." << member << " = 0;"
<< "}";
}
@@ -935,10 +932,10 @@ namespace CXX
}
else
{
- os << "else" << endl;
- delete_.dispatch (t);
- os << " this->" << umember << "." << member << ";"
- << endl
+ os << "else"
+ << "{";
+ delete_.dispatch (t, L"this->" + umember + L"." + member);
+ os << "}"
<< "this->" << umember << "." << member << " = x;";
}
@@ -968,8 +965,8 @@ namespace CXX
TypeName ret_;
TypeName arg_;
TypeName var_;
- TypeOps deref_;
- TypeOps delete_;
+ TypeDeref deref_;
+ TypeDelete delete_;
};
struct AllFunc: Traversal::All, Context
@@ -1013,7 +1010,7 @@ namespace CXX
// void
- // preset (bool);
+ // present (bool);
//
os << inl
<< "void " << scope << "::" << endl
@@ -1024,10 +1021,21 @@ namespace CXX
os << "this->" << epresent_member (a) << " = x;";
else
{
+ String p (L"this->" + member);
+
os << "if (!x)"
- << "{"
- << "delete this->" << member << ";"
- << "this->" << member << " = 0;"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << p << " = 0;"
<< "}";
}
@@ -1083,7 +1091,18 @@ namespace CXX
<< "{";
if (!fl)
- os << "delete this->" << member << ";";
+ {
+ String p (L"this->" + member);
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
os << "this->" << member << " = x;";
@@ -1206,10 +1225,21 @@ namespace CXX
os << "this->" << epresent_member (c) << " = x;";
else
{
+ String p (L"this->" + member);
+
os << "if (!x)"
- << "{"
- << "delete this->" << member << ";"
- << "this->" << member << " = 0;"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << p << " = 0;"
<< "}";
}
@@ -1265,7 +1295,18 @@ namespace CXX
<< "{";
if (!fl)
- os << "delete this->" << member << ";";
+ {
+ String p (L"this->" + member);
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
os << "this->" << member << " = x;";
@@ -1374,10 +1415,21 @@ namespace CXX
os << "this->" << epresent_member (s) << " = x;";
else
{
+ String p (L"this->" + member);
+
os << "if (!x)"
- << "{"
- << "delete this->" << member << ";"
- << "this->" << member << " = 0;"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << p << " = 0;"
<< "}";
}
@@ -1433,7 +1485,18 @@ namespace CXX
<< "{";
if (!fl)
- os << "delete this->" << member << ";";
+ {
+ String p (L"this->" + member);
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
os << "this->" << member << " = x;";
@@ -1562,10 +1625,21 @@ namespace CXX
}
else
{
+ String p (L"this->" + umember + L"." + member);
+
os << "else if (!x)"
- << "{"
- << "delete this->" << umember << "." << member << ";"
- << "this->" << umember << "." << member << " = 0;"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << p << " = 0;"
<< "}";
}
@@ -1638,10 +1712,22 @@ namespace CXX
}
else
{
- os << "else" << endl
- << "delete this->" << umember << "." << member << ";"
- << endl
- << "this->" << umember << "." << member << " = x;";
+ String p (L"this->" + umember + L"." + member);
+
+ os << "else";
+
+ if (!custom_alloc)
+ os << endl
+ << "delete " << p << ";"
+ << endl;
+ else
+ os << " if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+
+ os << p << " = x;";
}
os << "}";
diff --git a/xsde/cxx/hybrid/tree-name-processor.cxx b/xsde/cxx/hybrid/tree-name-processor.cxx
index 95aab7b..8fa6aa6 100644
--- a/xsde/cxx/hybrid/tree-name-processor.cxx
+++ b/xsde/cxx/hybrid/tree-name-processor.cxx
@@ -49,6 +49,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
stl (!ops.value<CLI::no_stl> ()),
detach (ops.value<CLI::generate_detach> ()),
diff --git a/xsde/cxx/hybrid/tree-source.cxx b/xsde/cxx/hybrid/tree-source.cxx
index ba2562d..5887d32 100644
--- a/xsde/cxx/hybrid/tree-source.cxx
+++ b/xsde/cxx/hybrid/tree-source.cxx
@@ -252,8 +252,14 @@ namespace CXX
<< "{";
if (!stl)
- os << "delete[] this->" <<
- u.context ().get<String> ("value-member") << ";";
+ {
+ String p (L"this->" + u.context ().get<String> ("value-member"));
+
+ if (!custom_alloc)
+ os << "delete[] " << p << ";";
+ else
+ os << "::xsde::cxx::free (" << p << ");";
+ }
os << "}";
@@ -382,7 +388,7 @@ namespace CXX
: Context (c),
action_ (action),
var_ (c, TypeName::var),
- delete_ (c, TypeOps::delete_)
+ delete_ (c)
{
}
@@ -487,10 +493,7 @@ namespace CXX
<< "~_dtor ();";
}
else
- {
- delete_.dispatch (t);
- os << " this->" << umember << "." << member << ";";
- }
+ delete_.dispatch (t, L"this->" + umember + L"." + member);
}
break;
@@ -626,15 +629,26 @@ namespace CXX
}
else
{
+ String const& type (etype (c));
+
if (fixed_length (c))
{
- String const& type (etype (c));
-
os << "reinterpret_cast< " << type << "& > (this->" <<
umember << "." << member << ").~" << type << " ();";
}
else
- os << "delete this->" << umember << "." << member << ";";
+ {
+ String p (L"this->" + umember + L"." + member);
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << type << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
}
break;
@@ -691,7 +705,7 @@ namespace CXX
private:
Action action_;
TypeName var_;
- TypeOps delete_;
+ TypeDelete delete_;
};
//
@@ -927,7 +941,7 @@ namespace CXX
struct AttributeDtor: Traversal::Attribute, Context
{
AttributeDtor (Context& c)
- : Context (c), delete_ (c, TypeOps::delete_)
+ : Context (c), delete_ (c)
{
}
@@ -939,22 +953,19 @@ namespace CXX
SemanticGraph::Type& t (a.type ());
if (!fixed_length (t))
- {
- delete_.dispatch (t);
- os << " this->" << emember (a) << ";";
- }
+ delete_.dispatch (t, L"this->" + emember (a));
}
}
private:
- TypeOps delete_;
+ TypeDelete delete_;
};
struct ElementDtor: Traversal::Element, Context
{
ElementDtor (Context& c)
- : Context (c), delete_ (c, TypeOps::delete_)
+ : Context (c), delete_ (c)
{
}
@@ -966,15 +977,12 @@ namespace CXX
SemanticGraph::Type& t (e.type ());
if (!fixed_length (t))
- {
- delete_.dispatch (t);
- os << " this->" << emember (e) << ";";
- }
+ delete_.dispatch (t, L"this->" + emember (e));
}
}
private:
- TypeOps delete_;
+ TypeDelete delete_;
};
struct AllDtor: Traversal::All, Context
@@ -993,7 +1001,18 @@ namespace CXX
if (a.min () == 0)
{
if (!fixed_length (a))
- os << "delete this->" << emember (a) << ";";
+ {
+ String p (L"this->" + emember (a));
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << etype (a) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
}
else
All::contains (a);
@@ -1015,7 +1034,18 @@ namespace CXX
if (c.min () == 0)
{
if (!fixed_length (c))
- os << "delete this->" << emember (c) << ";";
+ {
+ String p (L"this->" + emember (c));
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << etype (c) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
}
else
{
@@ -1041,7 +1071,18 @@ namespace CXX
if (s.min () == 0)
{
if (!fixed_length (s))
- os << "delete this->" << emember (s) << ";";
+ {
+ String p (L"this->" + emember (s));
+
+ if (!custom_alloc)
+ os << "delete " << p << ";";
+ else
+ os << "if (" << p << ")"
+ << "{"
+ << p << "->~" << etype (s) << " ();"
+ << "::xsde::cxx::free (" << p << ");"
+ << "}";
+ }
}
else
Sequence::contains (s);
diff --git a/xsde/cxx/hybrid/tree-type-map.cxx b/xsde/cxx/hybrid/tree-type-map.cxx
index 12b83de..cf36ce2 100644
--- a/xsde/cxx/hybrid/tree-type-map.cxx
+++ b/xsde/cxx/hybrid/tree-type-map.cxx
@@ -40,6 +40,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ())
{
}
diff --git a/xsde/cxx/parser/cli.hxx b/xsde/cxx/parser/cli.hxx
index a50c3ff..d4d42c7 100644
--- a/xsde/cxx/parser/cli.hxx
+++ b/xsde/cxx/parser/cli.hxx
@@ -36,6 +36,7 @@ namespace CXX
extern Key generate_polymorphic;
extern Key runtime_polymorphic;
extern Key suppress_reset;
+ extern Key custom_allocator;
extern Key generate_noop_impl;
extern Key generate_print_impl;
extern Key generate_test_driver;
@@ -99,6 +100,7 @@ namespace CXX
generate_polymorphic, Boolean,
runtime_polymorphic, Boolean,
suppress_reset, Boolean,
+ custom_allocator, Boolean,
generate_noop_impl, Boolean,
generate_print_impl, Boolean,
generate_test_driver, Boolean,
diff --git a/xsde/cxx/parser/elements.cxx b/xsde/cxx/parser/elements.cxx
index 0b98370..7cf1fec 100644
--- a/xsde/cxx/parser/elements.cxx
+++ b/xsde/cxx/parser/elements.cxx
@@ -32,6 +32,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
options (ops),
xml_parser (xml_parser_),
diff --git a/xsde/cxx/parser/generator.cxx b/xsde/cxx/parser/generator.cxx
index c8a9f68..74ba2ea 100644
--- a/xsde/cxx/parser/generator.cxx
+++ b/xsde/cxx/parser/generator.cxx
@@ -125,6 +125,7 @@ namespace CXX
extern Key generate_polymorphic = "generate-polymorphic";
extern Key runtime_polymorphic = "runtime-polymorphic";
extern Key suppress_reset = "suppress-reset";
+ extern Key custom_allocator = "custom-allocator";
extern Key generate_noop_impl = "generate-noop-impl";
extern Key generate_print_impl = "generate-print-impl";
extern Key generate_test_driver = "generate-test-driver";
@@ -246,6 +247,11 @@ namespace CXX
<< " Suppress the generation of parser reset code."
<< endl;
+ e << "--custom-allocator" << endl
+ << " Generate code that uses custom allocator functions\n"
+ << " instead of operator new/delete."
+ << endl;
+
e << "--generate-noop-impl" << endl
<< " Generate a sample parser implementation that\n"
<< " does nothing (no operation)."
@@ -1396,6 +1402,25 @@ namespace CXX
<< endl;
}
+ if (ops.value<CLI::custom_allocator> ())
+ {
+ hxx << "#ifndef XSDE_CUSTOM_ALLOCATOR" << endl
+ << "#error the generated code uses custom allocator while " <<
+ "the XSD/e runtime does not (reconfigure the runtime or " <<
+ "remove --custom-allocator)" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else
+ {
+ hxx << "#ifdef XSDE_CUSTOM_ALLOCATOR" << endl
+ << "#error the XSD/e runtime uses custom allocator while " <<
+ "the generated code does not (reconfigure the runtime or " <<
+ "add --custom-allocator)" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
//
//
diff --git a/xsde/cxx/parser/name-processor.cxx b/xsde/cxx/parser/name-processor.cxx
index 2cd1020..42b2863 100644
--- a/xsde/cxx/parser/name-processor.cxx
+++ b/xsde/cxx/parser/name-processor.cxx
@@ -45,6 +45,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
skel_suffix_ (ops.value<CLI::skel_type_suffix> ()),
impl_suffix_ (ops.value<CLI::impl_type_suffix> ()),
diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx
index 5062337..e3b4aeb 100644
--- a/xsde/cxx/parser/parser-header.cxx
+++ b/xsde/cxx/parser/parser-header.cxx
@@ -1589,6 +1589,21 @@ namespace CXX
String const c (char_type);
+ // Custom allocator.
+ //
+ if (custom_alloc)
+ {
+ os << "// Custom allocator." << endl
+ << "//" << endl
+ << "using ::xsde::cxx::alloc;"
+ << "using ::xsde::cxx::free;";
+
+ if (exceptions)
+ os << "using ::xsde::cxx::alloc_guard;";
+
+ os << endl;
+ }
+
os << "// Built-in XML Schema types mapping." << endl
<< "//" << endl
<< "using ::xsde::cxx::string_sequence;"
@@ -1739,8 +1754,10 @@ namespace CXX
}
else
{
- ctx.os << "#include <xsde/config.h>" << endl
- << "#include <xsde/cxx/ro-string.hxx>" << endl;
+ if (ctx.custom_alloc)
+ ctx.os << "#include <xsde/cxx/allocator.hxx>" << endl;
+
+ ctx.os << "#include <xsde/cxx/ro-string.hxx>" << endl;
if (ctx.char_encoding == L"iso8859-1")
ctx.os << "#include <xsde/cxx/iso8859-1.hxx>" << endl;
diff --git a/xsde/cxx/parser/print-impl-common.hxx b/xsde/cxx/parser/print-impl-common.hxx
index b997f74..13325bd 100644
--- a/xsde/cxx/parser/print-impl-common.hxx
+++ b/xsde/cxx/parser/print-impl-common.hxx
@@ -998,8 +998,13 @@ namespace CXX
if (options.value<CLI::no_stl> () &&
default_type (t, xs_ns_name () + L"::qname*"))
{
- os << endl
- << "delete " << arg_ << ";";
+ os << endl;
+
+ if (!custom_alloc)
+ os << "delete " << arg_ << ";";
+ else
+ os << arg_ << "->~qname ();"
+ << xs_ns_name () << "::free (" << arg_ << ");";
}
}
@@ -1029,8 +1034,12 @@ namespace CXX
{
if (options.value<CLI::no_stl> () && default_type (t, "char*"))
{
- os << endl
- << "delete[] " << arg_ << ";";
+ os << endl;
+
+ if (!custom_alloc)
+ os << "delete[] " << arg_ << ";";
+ else
+ os << xs_ns_name () << "::free (" << arg_ << ");";
}
}
@@ -1039,8 +1048,13 @@ namespace CXX
{
if (default_type (t, xs_ns_name () + L"::string_sequence*"))
{
- os << endl
- << "delete " << arg_ << ";";
+ os << endl;
+
+ if (!custom_alloc)
+ os << "delete " << arg_ << ";";
+ else
+ os << arg_ << "->~string_sequence ();"
+ << xs_ns_name () << "::free (" << arg_ << ");";
}
}
@@ -1049,8 +1063,13 @@ namespace CXX
{
if (default_type (t, xs_ns_name () + L"::buffer*"))
{
- os << endl
- << "delete " << arg_ << ";";
+ os << endl;
+
+ if (!custom_alloc)
+ os << "delete " << arg_ << ";";
+ else
+ os << arg_ << "->~buffer ();"
+ << xs_ns_name () << "::free (" << arg_ << ");";
}
}
diff --git a/xsde/cxx/serializer/attribute-validation-source.cxx b/xsde/cxx/serializer/attribute-validation-source.cxx
index 79ae256..7dea3c3 100644
--- a/xsde/cxx/serializer/attribute-validation-source.cxx
+++ b/xsde/cxx/serializer/attribute-validation-source.cxx
@@ -329,6 +329,7 @@ namespace CXX
<< "this->_start_attribute (ns, name);"
<< endl;
else
+ {
os << "bool r;"
<< "if (ns == 0 || *ns == '\\0')" << endl
<< "r = this->_start_attribute (name);"
@@ -336,13 +337,20 @@ namespace CXX
<< "r = this->_start_attribute (ns, name);"
<< endl
<< "if (free)"
- << "{"
- << "delete[] ns;"
- << "delete[] name;"
- << "}"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete[] ns;"
+ << "delete[] name;";
+ else
+ os << "::xsde::cxx::free (ns);"
+ << "::xsde::cxx::free (name);";
+
+ os << "}"
<< "if (!r)" << endl
<< "return;"
<< endl;
+ }
os << "this->" << eserialize (a) << " ();"
<< endl
diff --git a/xsde/cxx/serializer/cli.hxx b/xsde/cxx/serializer/cli.hxx
index d65ca1a..ca6f779 100644
--- a/xsde/cxx/serializer/cli.hxx
+++ b/xsde/cxx/serializer/cli.hxx
@@ -36,6 +36,7 @@ namespace CXX
extern Key generate_polymorphic;
extern Key runtime_polymorphic;
extern Key suppress_reset;
+ extern Key custom_allocator;
extern Key generate_empty_impl;
extern Key generate_test_driver;
extern Key force_overwrite;
@@ -98,6 +99,7 @@ namespace CXX
generate_polymorphic, Boolean,
runtime_polymorphic, Boolean,
suppress_reset, Boolean,
+ custom_allocator, Boolean,
generate_empty_impl, Boolean,
generate_test_driver, Boolean,
force_overwrite, Boolean,
diff --git a/xsde/cxx/serializer/element-validation-source.cxx b/xsde/cxx/serializer/element-validation-source.cxx
index b39fed7..ea5fec2 100644
--- a/xsde/cxx/serializer/element-validation-source.cxx
+++ b/xsde/cxx/serializer/element-validation-source.cxx
@@ -736,6 +736,7 @@ namespace CXX
<< "this->_start_element (ns, name);"
<< endl;
else
+ {
os << "bool r;"
<< "if (ns == 0 || *ns == '\\0')" << endl
<< "r = this->_start_element (name);"
@@ -743,13 +744,20 @@ namespace CXX
<< "r = this->_start_element (ns, name);"
<< endl
<< "if (free)"
- << "{"
- << "delete[] ns;"
- << "delete[] name;"
- << "}"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete[] ns;"
+ << "delete[] name;";
+ else
+ os << "::xsde::cxx::free (ns);"
+ << "::xsde::cxx::free (name);";
+
+ os << "}"
<< "if (!r)" << endl
<< "return;"
<< endl;
+ }
os << "this->" << eserialize (a) << " ();"
<< endl
diff --git a/xsde/cxx/serializer/elements.cxx b/xsde/cxx/serializer/elements.cxx
index 12a715c..5395953 100644
--- a/xsde/cxx/serializer/elements.cxx
+++ b/xsde/cxx/serializer/elements.cxx
@@ -32,6 +32,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
options (ops),
xml_serializer (xml_serializer_),
diff --git a/xsde/cxx/serializer/generator.cxx b/xsde/cxx/serializer/generator.cxx
index 92e5197..5c94c98 100644
--- a/xsde/cxx/serializer/generator.cxx
+++ b/xsde/cxx/serializer/generator.cxx
@@ -123,6 +123,7 @@ namespace CXX
extern Key generate_polymorphic = "generate-polymorphic";
extern Key runtime_polymorphic = "runtime-polymorphic";
extern Key suppress_reset = "suppress-reset";
+ extern Key custom_allocator = "custom-allocator";
extern Key generate_empty_impl = "generate-empty-impl";
extern Key generate_test_driver = "generate-test-driver";
extern Key force_overwrite = "force-overwrite";
@@ -243,6 +244,11 @@ namespace CXX
<< " Suppress the generation of serializer reset code."
<< endl;
+ e << "--custom-allocator" << endl
+ << " Generate code that uses custom allocator functions\n"
+ << " instead of operator new/delete."
+ << endl;
+
e << "--generate-empty-impl" << endl
<< " Generate a sample serializer implementation with\n"
<< " empty function bodies."
@@ -1382,6 +1388,25 @@ namespace CXX
<< endl;
}
+ if (ops.value<CLI::custom_allocator> ())
+ {
+ hxx << "#ifndef XSDE_CUSTOM_ALLOCATOR" << endl
+ << "#error the generated code uses custom allocator while " <<
+ "the XSD/e runtime does not (reconfigure the runtime or " <<
+ "remove --custom-allocator)" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else
+ {
+ hxx << "#ifdef XSDE_CUSTOM_ALLOCATOR" << endl
+ << "#error the XSD/e runtime uses custom allocator while " <<
+ "the generated code does not (reconfigure the runtime or " <<
+ "add --custom-allocator)" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
//
//
diff --git a/xsde/cxx/serializer/name-processor.cxx b/xsde/cxx/serializer/name-processor.cxx
index ec4c442..f7f63a2 100644
--- a/xsde/cxx/serializer/name-processor.cxx
+++ b/xsde/cxx/serializer/name-processor.cxx
@@ -45,6 +45,7 @@ namespace CXX
ops.value<CLI::include_regex> (),
ops.value<CLI::include_regex_trace> (),
ops.value<CLI::generate_inline> (),
+ ops.value<CLI::custom_allocator> (),
ops.value<CLI::reserved_name> ()),
skel_suffix_ (ops.value<CLI::skel_type_suffix> ()),
impl_suffix_ (ops.value<CLI::impl_type_suffix> ()),
diff --git a/xsde/cxx/serializer/serializer-header.cxx b/xsde/cxx/serializer/serializer-header.cxx
index dd20289..3a10942 100644
--- a/xsde/cxx/serializer/serializer-header.cxx
+++ b/xsde/cxx/serializer/serializer-header.cxx
@@ -1756,6 +1756,21 @@ namespace CXX
String const c (char_type);
+ // Custom allocator.
+ //
+ if (custom_alloc)
+ {
+ os << "// Custom allocator." << endl
+ << "//" << endl
+ << "using ::xsde::cxx::alloc;"
+ << "using ::xsde::cxx::free;";
+
+ if (exceptions)
+ os << "using ::xsde::cxx::alloc_guard;";
+
+ os << endl;
+ }
+
os << "// Built-in XML Schema types mapping." << endl
<< "//" << endl
<< "using ::xsde::cxx::string_sequence;"
@@ -1898,8 +1913,9 @@ namespace CXX
}
else
{
- ctx.os << "#include <xsde/config.h>" << endl
- << endl;
+ if (ctx.custom_alloc)
+ ctx.os << "#include <xsde/cxx/allocator.hxx>" << endl
+ << endl;
// std::string or xsde::cxx::string is used in wildcard API.
//
diff --git a/xsde/cxx/serializer/serializer-source.cxx b/xsde/cxx/serializer/serializer-source.cxx
index a5765a0..1dbe496 100644
--- a/xsde/cxx/serializer/serializer-source.cxx
+++ b/xsde/cxx/serializer/serializer-source.cxx
@@ -1386,10 +1386,16 @@ namespace CXX
<< "r = this->_start_element (ns, name);"
<< endl
<< "if (free)"
- << "{"
- << "delete[] ns;"
- << "delete[] name;"
- << "}"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete[] ns;"
+ << "delete[] name;";
+ else
+ os << "::xsde::cxx::free (ns);"
+ << "::xsde::cxx::free (name);";
+
+ os << "}"
<< "if (!r)" << endl
<< "return;"
<< endl
@@ -1640,10 +1646,16 @@ namespace CXX
<< "r = this->_start_attribute (ns, name);"
<< endl
<< "if (free)"
- << "{"
- << "delete[] ns;"
- << "delete[] name;"
- << "}"
+ << "{";
+
+ if (!custom_alloc)
+ os << "delete[] ns;"
+ << "delete[] name;";
+ else
+ os << "::xsde::cxx::free (ns);"
+ << "::xsde::cxx::free (name);";
+
+ os << "}"
<< "if (!r)" << endl
<< "return;"
<< endl