From f60df03e3cedb86508645357e17003eb9281f31a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 22 Jan 2010 15:40:12 +0200 Subject: Add support for detaching subtrees in C++/Tree New option: --generate-detach. New test: cxx/tree/detach. --- NEWS | 9 +++ documentation/cxx/tree/manual/index.xhtml | 89 ++++++++++++++++++++++---- documentation/xsd.1 | 7 +++ documentation/xsd.xhtml | 7 +++ libxsd/xsd/cxx/tree/containers.hxx | 59 ++++++++++++++++- libxsd/xsd/cxx/tree/elements.hxx | 58 +++++++++++++---- tests/cxx/tree/detach/driver.cxx | 101 ++++++++++++++++++++++++++++++ tests/cxx/tree/detach/makefile | 82 ++++++++++++++++++++++++ tests/cxx/tree/detach/test.xsd | 32 ++++++++++ tests/cxx/tree/makefile | 1 + xsd/cxx/tree/cli.hxx | 2 + xsd/cxx/tree/elements.cxx | 3 + xsd/cxx/tree/elements.hxx | 9 +++ xsd/cxx/tree/generator.cxx | 5 ++ xsd/cxx/tree/name-processor.cxx | 47 +++++++++++--- xsd/cxx/tree/tree-header.cxx | 52 ++++++++++++++- xsd/cxx/tree/tree-inline.cxx | 24 +++++++ 17 files changed, 550 insertions(+), 37 deletions(-) create mode 100644 tests/cxx/tree/detach/driver.cxx create mode 100644 tests/cxx/tree/detach/makefile create mode 100644 tests/cxx/tree/detach/test.xsd diff --git a/NEWS b/NEWS index 956a9fd..d202c00 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,15 @@ Version 3.3.0 on this change see Section 2.11, "Mapping for xsi:type and Substitution Groups" in the C++/Tree Mapping User Manual. + * New option, --generate-detach, triggers generation of detach functions + for required elements and attributes. For optional and sequence + cardinalities the detach functions are now provided by the respective + containers even without this option. These functions, for example, + allow one to move sub-trees in the object model either within the + same tree or between different trees without copying. For more + information refer to Section 2.8 "Mapping for Local Elements and + Attributes" in the C++/Tree Mapping User Manual. + * New option, --export-xml-schema, causes the compiler to export/import types in the XML Schema namespace using the export symbol provided with the --export-symbol option. diff --git a/documentation/cxx/tree/manual/index.xhtml b/documentation/cxx/tree/manual/index.xhtml index c00be9e..695a72e 100644 --- a/documentation/cxx/tree/manual/index.xhtml +++ b/documentation/cxx/tree/manual/index.xhtml @@ -2737,6 +2737,27 @@ public: }; +

In addition, if requested by specifying the --generate-detach + option and only for members of non-fundamental C++ types, the mapping + provides a detach function that returns an automatic pointer to the + member's type, for example:

+ +
+class object: xml_schema::type
+{
+public:
+  ...
+
+  std::auto_ptr<member_type>
+  detach_member ();
+  ...
+
+};
+  
+ +

This function detaches the value from the tree leaving the member + value uninitialized. Accessing such an uninitialized value prior to + re-initializing it results in undefined behavior.

The following code shows how one could use this mapping:

@@ -2746,14 +2767,16 @@ f (object& o) { using xml_schema::string; - string s (o.member ()); // get + string s (o.member ()); // get object::member_type& sr (o.member ()); // get - o.member ("hello"); // set, deep copy - o.member () = "hello"; // set, deep copy + o.member ("hello"); // set, deep copy + o.member () = "hello"; // set, deep copy std::auto_ptr<string> p (new string ("hello")); - o.member (p); // set, assumes ownership + o.member (p); // set, assumes ownership + p = o.detach_member (); // detach, member is uninitialized + o.member (p); // re-attach } @@ -2907,6 +2930,11 @@ public: void set (std::auto_ptr<X>); + // Detach and return the contained value. + // + std::auto_ptr<X> + detach (); + void reset (); }; @@ -2968,6 +2996,9 @@ f (object& o) p = new string ("hello"); o.member ().set (p); // set, assumes ownership + + p = o.member ().detach (); // detach, member is reset + o.member ().set (p); // re-attach } @@ -3042,15 +3073,45 @@ public: sequence interface as defined by the ISO/ANSI Standard for C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). Practically, this means that you can treat such a sequence - as if it was std::vector. One notable extension - to the standard interface that is available only for - sequences of non-fundamental C++ types is the addition of + as if it was std::vector. Two notable extensions + to the standard interface that are available only for + sequences of non-fundamental C++ types are the addition of the overloaded push_back and insert - member functions which instead of the constant reference - to the element type accept automatic pointer to the element - type. These functions assume ownership of the pointed to - object and resets the passed automatic pointer. -

+ as well as the detach_back and detach + member functions. The additional push_back and + insert functions accept an automatic pointer to the + element type instead of the constant reference. They assume + ownership of the pointed to object and resets the passed + automatic pointer. The detach_back and + detach functions detach the element + value from the sequence container and, by default, remove + the element from the sequence. These additional functions + have the following signatures:

+ +
+template <typename X>
+class sequence
+{
+public:
+  ...
+
+  void
+  push_back (std::auto_ptr<X>)
+
+  iterator
+  insert (iterator position, std::auto_ptr<X>)
+
+  std::auto_ptr<X>
+  detach_back (bool pop = true);
+
+  iterator
+  detach (iterator position,
+          std::auto_ptr<X>& result,
+          bool erase = true)
+
+  ...
+}
+  

The following code shows how one could use this mapping:

@@ -3074,7 +3135,9 @@ f (object& o) s.push_back ("hello"); // deep copy std::auto_ptr<string> p (new string ("hello")); - s.push_back (o); // assumes ownership + s.push_back (p); // assumes ownership + p = s.detach_back (); // detach and pop + s.push_back (p); // re-append // Setting a new container. // diff --git a/documentation/xsd.1 b/documentation/xsd.1 index 762d865..7536bb6 100644 --- a/documentation/xsd.1 +++ b/documentation/xsd.1 @@ -800,6 +800,13 @@ not initialized and accessing them results in undefined behavior. Generate constructors that expect an instance of a base type followed by all required members. +.IP "\fB\--generate-detach\fR" +Generate detach functions for required elements and attributes (detach +functions for optional and sequence cardinalities are provided by the +respective containers). These functions, for example, allow you to move +sub-trees in the object model either within the same tree or between +different trees. + .IP "\fB\--generate-wildcard\fR" Generate accessors and modifiers as well as parsing and serialization code for XML Schema wildcards diff --git a/documentation/xsd.xhtml b/documentation/xsd.xhtml index 46e8c1a..1330509 100644 --- a/documentation/xsd.xhtml +++ b/documentation/xsd.xhtml @@ -711,6 +711,13 @@
Generate constructors that expect an instance of a base type followed by all required members.
+
--generate-detach
+
Generate detach functions for required elements and attributes + (detach functions for optional and sequence cardinalities are + provided by the respective containers). These functions, for + example, allow you to move sub-trees in the object model either + within the same tree or between different trees.
+
--generate-wildcard
Generate accessors and modifiers as well as parsing and serialization code for XML Schema wildcards (any and diff --git a/libxsd/xsd/cxx/tree/containers.hxx b/libxsd/xsd/cxx/tree/containers.hxx index 1399c5d..8ea04d2 100644 --- a/libxsd/xsd/cxx/tree/containers.hxx +++ b/libxsd/xsd/cxx/tree/containers.hxx @@ -6,7 +6,6 @@ #ifndef XSD_CXX_TREE_CONTAINERS_HXX #define XSD_CXX_TREE_CONTAINERS_HXX - #include // std::ptrdiff_t #include #include @@ -169,6 +168,15 @@ namespace xsd return x_ != 0; } + std::auto_ptr + detach () + { + T* x (x_); + x->_container (0); + x_ = 0; + return std::auto_ptr (x); + } + protected: T* x_; flags flags_; @@ -332,6 +340,15 @@ namespace xsd void reset (); + std::auto_ptr + detach () + { + T* x (x_); + x->_container (0); + x_ = 0; + return std::auto_ptr (x); + } + private: void true_ (); @@ -809,11 +826,25 @@ namespace xsd } type* + operator-> () const + { + return x_; + } + + type* get () const { return x_; } + type* + release () + { + type* x (x_); + x_ = 0; + return x; + } + private: mutable type* x_; }; @@ -1247,6 +1278,19 @@ namespace xsd v_.pop_back (); } + std::auto_ptr + detach_back (bool pop = true) + { + ptr& p (v_.back ()); + p->_container (0); + T* x (static_cast (p.release ())); + + if (pop) + v_.pop_back (); + + return std::auto_ptr (x); + } + iterator insert (iterator position, const T& x) { @@ -1289,6 +1333,19 @@ namespace xsd return iterator (v_.erase (begin.base (), end.base ())); } + iterator + detach (iterator position, std::auto_ptr& r, bool erase = true) + { + ptr& p (*position.base ()); + p->_container (0); + r.reset (static_cast (p.release ())); + + if (erase) + return iterator (v_.erase (position.base ())); + else + return ++position; + } + // Note that the container object of the two sequences being // swapped should be the same. // diff --git a/libxsd/xsd/cxx/tree/elements.hxx b/libxsd/xsd/cxx/tree/elements.hxx index 273e847..598a756 100644 --- a/libxsd/xsd/cxx/tree/elements.hxx +++ b/libxsd/xsd/cxx/tree/elements.hxx @@ -419,30 +419,64 @@ namespace xsd virtual void _container (container* c) { - assert (container_ == 0); + container* dr (0); if (c != 0) { - if (map_.get () != 0) - { - // Propagate our IDs to the new root. - // - container* r (c->_root ()); + dr = c->_root (); + + if (dr == 0) + dr = c; + } - if (r == 0) - r = c; + std::auto_ptr& m (dr ? dr->map_ : map_); - if (r->map_.get () != 0) + if (container_ == 0) + { + if (c != 0 && map_.get () != 0) + { + // Transfer our IDs to the new root. + // + if (m.get () != 0) { - r->map_->insert (map_->begin (), map_->end ()); + m->insert (map_->begin (), map_->end ()); map_.reset (); } else - r->map_ = map_; + m = map_; } + } + else + { + container* sr (_root ()); - container_ = c; + if (sr->map_.get () != 0) + { + // Transfer IDs that belong to this subtree. + // + for (map::iterator i (sr->map_->begin ()), e (sr->map_->end ()); + i != e;) + { + type* x (i->second); + for (; x != this && x != sr; x = x->_container ()) ; + + if (x != sr) + { + // Part of our subtree. + // + if (m.get () == 0) + m.reset (new map); + + m->insert (*i); + sr->map_->erase (i++); + } + else + ++i; + } + } } + + container_ = c; } /** diff --git a/tests/cxx/tree/detach/driver.cxx b/tests/cxx/tree/detach/driver.cxx new file mode 100644 index 0000000..afcb90d --- /dev/null +++ b/tests/cxx/tree/detach/driver.cxx @@ -0,0 +1,101 @@ +// file : tests/cxx/tree/detach/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Test the detach functionality. +// + +#include // std::auto_ptr +#include + +#include "test.hxx" + +using namespace std; +using namespace test; + +int +main () +{ + // Construct the model. + // + object o1 ("o1"); + o1.data ().push_back ("1-1"); + o1.data ().push_back ("1-2"); + o1.data ().push_back ("1-3"); + + object o2 ("o2"); + o1.data ().push_back ("2-1"); + o1.data ().push_back ("2-2"); + o1.data ().push_back ("2-3"); + + object o3 ("o3"); + o1.data ().push_back ("3-1"); + o1.data ().push_back ("3-2"); + o1.data ().push_back ("3-3"); + + object o4 ("o4"); + o1.data ().push_back ("4-1"); + o1.data ().push_back ("4-2"); + o1.data ().push_back ("4-3"); + + subtree s1; + s1.o ().push_back (o1); + s1.o ().push_back (o2); + s1.r ().push_back (ref ("o2")); + s1.r ().push_back (ref ("o3")); + + subtree s2; + s2.o ().push_back (o3); + s2.o ().push_back (o4); + s2.r ().push_back (ref ("o4")); + s2.r ().push_back (ref ("o1")); + + model m; + m.one (s1); + m.opt (s2); + + // Detach one. + // + auto_ptr p (m.detach_one ()); + assert (p->_container () == 0); + assert (p->r ()[0].get () == &p->o ()[1]); + assert (m.opt ()->r ()[1].get () == 0); + + m.one (p); + assert (m.opt ()->r ()[1].get () == &m.one ().o ()[0]); + p = m.detach_one (); + + model m1; + m1.one (p); + m1.opt (s2); + assert (m1.opt ()->r ()[1].get () == &m1.one ().o ()[0]); + + p = m1.detach_one (); + m.seq ().push_back (p); + + // Detach opt. + // + p = m.opt ().detach (); + assert (!m.opt ()); + assert (p->_container () == 0); + assert (p->r ()[0].get () == &p->o ()[1]); + assert (m.seq ()[0].r ()[1].get () == 0); + + m.seq ().push_back (p); + + // Detach seq. + // + p = m.seq ().detach_back (); + assert (p->_container () == 0); + assert (p->r ()[0].get () == &p->o ()[1]); + assert (m.seq ()[0].r ()[1].get () == 0); + + m.seq ().push_back (p); + assert (m.seq ()[0].r ()[1].get () == &m.seq ()[1].o ()[0]); + + m.seq ().detach (m.seq ().begin (), p); + assert (p->_container () == 0); + assert (p->r ()[0].get () == &p->o ()[1]); + assert (m.seq ()[0].r ()[1].get () == 0); +} diff --git a/tests/cxx/tree/detach/makefile b/tests/cxx/tree/detach/makefile new file mode 100644 index 0000000..938fba2 --- /dev/null +++ b/tests/cxx/tree/detach/makefile @@ -0,0 +1,82 @@ +# file : tests/cxx/tree/detach/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make + +xsd := test.xsd +cxx := driver.cxx + +obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o)) +dep := $(obj:.o=.o.d) + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + + +# Import. +# +$(call import,\ + $(scf_root)/import/libxerces-c/stub.make,\ + l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) + + +# Build. +# +$(driver): $(obj) $(xerces_c.l) + +$(obj) $(dep): cpp_options := -I$(src_root)/libxsd +$(obj) $(dep): $(xerces_c.l.cpp-options) + +genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx) +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): xsd := $(out_root)/xsd/xsd +$(gen): xsd_options := --generate-detach --generate-default-ctor +$(gen): $(out_root)/xsd/xsd + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Test. +# +$(test): driver := $(driver) +$(test): $(driver) + $(call message,test $$1,$$1,$(driver)) + +# Clean. +# +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(obj)) \ + $(addsuffix .cxx.clean,$(dep)) \ + $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile) diff --git a/tests/cxx/tree/detach/test.xsd b/tests/cxx/tree/detach/test.xsd new file mode 100644 index 0000000..b9f5166 --- /dev/null +++ b/tests/cxx/tree/detach/test.xsd @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cxx/tree/makefile b/tests/cxx/tree/makefile index da848e8..9b79424 100644 --- a/tests/cxx/tree/makefile +++ b/tests/cxx/tree/makefile @@ -13,6 +13,7 @@ compilation \ complex \ containment \ default \ +detach \ encoding \ enumeration \ float \ diff --git a/xsd/cxx/tree/cli.hxx b/xsd/cxx/tree/cli.hxx index c4294b6..171711d 100644 --- a/xsd/cxx/tree/cli.hxx +++ b/xsd/cxx/tree/cli.hxx @@ -36,6 +36,7 @@ namespace CXX extern Key generate_comparison; extern Key generate_default_ctor; extern Key generate_from_base_ctor; + extern Key generate_detach; extern Key generate_wildcard; extern Key generate_insertion; extern Key generate_extraction; @@ -134,6 +135,7 @@ namespace CXX generate_comparison, Boolean, generate_default_ctor, Boolean, generate_from_base_ctor, Boolean, + generate_detach, Boolean, generate_wildcard, Boolean, generate_insertion, Cult::Containers::Vector, generate_extraction, Cult::Containers::Vector, diff --git a/xsd/cxx/tree/elements.cxx b/xsd/cxx/tree/elements.cxx index 0072e07..aafc442 100644 --- a/xsd/cxx/tree/elements.cxx +++ b/xsd/cxx/tree/elements.cxx @@ -86,6 +86,7 @@ namespace CXX doxygen (doxygen_), polymorphic (ops.value ()), polymorphic_all (ops.value ()), + detach (ops.value ()), fwd_expr (fe), hxx_expr (he), ixx_expr (ie), @@ -324,6 +325,7 @@ namespace CXX doxygen (c.doxygen), polymorphic (c.polymorphic), polymorphic_all (c.polymorphic_all), + detach (c.detach), fwd_expr (c.fwd_expr), hxx_expr (c.hxx_expr), ixx_expr (c.ixx_expr), @@ -364,6 +366,7 @@ namespace CXX doxygen (c.doxygen), polymorphic (c.polymorphic), polymorphic_all (c.polymorphic_all), + detach (c.detach), fwd_expr (c.fwd_expr), hxx_expr (c.hxx_expr), ixx_expr (c.ixx_expr), diff --git a/xsd/cxx/tree/elements.hxx b/xsd/cxx/tree/elements.hxx index 2160baf..d081139 100644 --- a/xsd/cxx/tree/elements.hxx +++ b/xsd/cxx/tree/elements.hxx @@ -213,6 +213,14 @@ namespace CXX return a.context ().get ("mname"); } + // Detach name. + // + static String const& + edname (SemanticGraph::Member const& m) + { + return m.context ().get ("dname"); + } + // // static String const& @@ -413,6 +421,7 @@ namespace CXX Boolean& doxygen; Boolean polymorphic; Boolean polymorphic_all; + Boolean detach; Regex const* fwd_expr; Regex const* hxx_expr; diff --git a/xsd/cxx/tree/generator.cxx b/xsd/cxx/tree/generator.cxx index a70214c..ae86767 100644 --- a/xsd/cxx/tree/generator.cxx +++ b/xsd/cxx/tree/generator.cxx @@ -129,6 +129,7 @@ namespace CXX extern Key generate_comparison = "generate-comparison"; extern Key generate_default_ctor = "generate-default-ctor"; extern Key generate_from_base_ctor = "generate-from-base-ctor"; + extern Key generate_detach = "generate-detach"; extern Key generate_wildcard = "generate-wildcard"; extern Key generate_insertion = "generate-insertion"; extern Key generate_extraction = "generate-extraction"; @@ -283,6 +284,10 @@ namespace CXX << " Generate from-base constructors." << endl; + e << "--generate-detach" << endl + << " Generate detach functions for required members." + << endl; + e << "--generate-wildcard" << endl << " Generate accessors/modifiers as well as parsing\n" << " and serialization code for XML Schema wildcards." diff --git a/xsd/cxx/tree/name-processor.cxx b/xsd/cxx/tree/name-processor.cxx index 1949c5d..a9427a6 100644 --- a/xsd/cxx/tree/name-processor.cxx +++ b/xsd/cxx/tree/name-processor.cxx @@ -31,9 +31,6 @@ namespace CXX // typedef Cult::Containers::Set NameSet; - - - class Context: public Tree::Context { public: @@ -57,6 +54,7 @@ namespace CXX 0), global_type_names (global_type_names_), global_element_names (global_element_names_), + detach (options.value ()), type_regex (type_regex_), accessor_regex (accessor_regex_), one_accessor_regex (one_accessor_regex_), @@ -189,6 +187,7 @@ namespace CXX // modifier_regex.push_back ("/([^,]+),([^,]+)/set\\u$1\\u$2/"); modifier_regex.push_back ("/([^,]+)/set\\u$1/"); + modifier_regex.push_back ("/detach,([^,]+)/detach\\u$1/"); } compile_regex (options.value (), @@ -271,6 +270,7 @@ namespace CXX : Tree::Context (c), global_type_names (c.global_type_names), global_element_names (c.global_element_names), + detach (c.detach), type_regex (c.type_regex), accessor_regex (c.accessor_regex), one_accessor_regex (c.one_accessor_regex), @@ -537,6 +537,8 @@ namespace CXX Cult::Containers::Map& global_type_names; Cult::Containers::Map& global_element_names; + Boolean detach; + RegexVector& type_regex; RegexVector& accessor_regex; RegexVector& one_accessor_regex; @@ -670,8 +672,8 @@ namespace CXX Boolean def_attr (m.default_ () && m.is_a ()); - // Accessors/modifiers. Note that we postpone inserting the - // names into the name_set to avoid over-escaping. + // Accessors/modifiers. Note that we postpone inserting + // the names into the name_set to avoid over-escaping. // String an, mn; @@ -741,6 +743,19 @@ namespace CXX if (mn != b && mn != an) name_set_.insert (mn); + // Detach. + // + if (detach && max == 1 && (min == 1 || def_attr)) + { + String dn (find_name ( + escape (process_regex (L"detach," + s, + one_modifier_regex, + modifier_regex, + L"one modifier")), + name_set_)); + + m.context ().set ("dname", dn); + } // Types. // @@ -1281,21 +1296,21 @@ namespace CXX escape (process_regex (L"value,traits", type_regex, L"type")), set)); - String an = Context::find_name ( + String an (Context::find_name ( escape (process_regex ("value", one_accessor_regex, accessor_regex, L"one accessor")), set, - false); + false)); - String mn = Context::find_name ( + String mn (Context::find_name ( escape (process_regex ("value", one_modifier_regex, modifier_regex, L"one modifier")), set, - false); + false)); ec.set ("aname", an); ec.set ("mname", mn); @@ -1305,6 +1320,20 @@ namespace CXX if (an != mn) set.insert (mn); + // Detach. + // + if (detach) + { + String dn (Context::find_name ( + escape (process_regex (L"detach,value", + one_modifier_regex, + modifier_regex, + L"one modifier")), + set)); + + ec.set ("dname", dn); + } + // Assign name() and namespace_() names. // ec.set ( diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx index 7e884c8..100a81c 100644 --- a/xsd/cxx/tree/tree-header.cxx +++ b/xsd/cxx/tree/tree-header.cxx @@ -1332,14 +1332,39 @@ namespace CXX << " * @param p A new value to use." << endl << " *" << endl << " * This function will try to use the passed value " << - "directly instead" << endl - << " * of making a copy." << endl + "directly" << endl + << " * instead of making a copy." << endl << " */" << endl; } os << "void" << endl << mname << " (::std::auto_ptr< " << type << " > p);" << endl; + + } + + // auto_ptr + // detach_name (); + // + if (detach && !fund) + { + if (doxygen) + { + os << "/**" << endl + << " * @brief Detach the " << kind << " value from " << + "the object model." << endl + << " *" << endl + << " * @return A pointer to the " << kind << " value." << endl + << " *" << endl + << " * Note that this function leaves the required " << + kind << " in " << endl + << " * the original object model uninitialized." << endl + << " */" << endl; + } + + os << "::std::auto_ptr< " << type << " >" << endl + << edname (m) << " ();" + << endl; } } } @@ -3247,6 +3272,29 @@ namespace CXX << endl; } + // auto_ptr + // detach_name (); + // + if (detach && !fund) + { + if (doxygen) + { + os << "/**" << endl + << " * @brief Detach the element value from " << + "the object." << endl + << " *" << endl + << " * @return A pointer to the element value." << endl + << " *" << endl + << " * Note that this function leaves the element " << + "object uninitialized." << endl + << " */" << endl; + } + + os << "::std::auto_ptr< " << type << " >" << endl + << edname (e) << " ();" + << endl; + } + if (doxygen) { os << "/**" << endl diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/cxx/tree/tree-inline.cxx index a075d3f..6a983af 100644 --- a/xsd/cxx/tree/tree-inline.cxx +++ b/xsd/cxx/tree/tree-inline.cxx @@ -593,6 +593,18 @@ namespace CXX << "{" << "this->" << member << ".set (x);" << "}"; + + // auto_ptr + // detach_name (); + // + if (detach && !fund) + os << inl + << "::std::auto_ptr< " << q_type << " > " << + scope_ << "::" << endl + << edname (m) << " ()" + << "{" + << "return this->" << member << ".detach ();" + << "}"; } } @@ -979,6 +991,18 @@ namespace CXX << "return this->" << member << ".set (p);" << "}"; } + + // auto_ptr + // detach_name (); + // + if (detach && !fund) + os << inl + << "::std::auto_ptr< " << name << "::" << type << " > " << + name << "::" << endl + << edname (e) << " ()" + << "{" + << "return this->" << member << ".detach ();" + << "}"; } }; } -- cgit v1.1