diff options
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | documentation/cxx/hybrid/guide/index.xhtml | 64 | ||||
-rw-r--r-- | documentation/xsde.1 | 5 | ||||
-rw-r--r-- | documentation/xsde.xhtml | 6 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/base.hxx | 1 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/sequence.hxx | 12 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/sequence.ixx | 17 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence.hxx | 5 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence.ixx | 7 | ||||
-rw-r--r-- | tests/cxx/hybrid/sequences/driver.cxx | 23 | ||||
-rw-r--r-- | tests/cxx/hybrid/union/makefile | 2 | ||||
-rw-r--r-- | xsde/cxx/hybrid/cli.hxx | 2 | ||||
-rw-r--r-- | xsde/cxx/hybrid/elements.cxx | 1 | ||||
-rw-r--r-- | xsde/cxx/hybrid/elements.hxx | 17 | ||||
-rw-r--r-- | xsde/cxx/hybrid/generator.cxx | 6 | ||||
-rw-r--r-- | xsde/cxx/hybrid/tree-header.cxx | 82 | ||||
-rw-r--r-- | xsde/cxx/hybrid/tree-inline.cxx | 128 | ||||
-rw-r--r-- | xsde/cxx/hybrid/tree-name-processor.cxx | 57 |
18 files changed, 414 insertions, 27 deletions
@@ -13,6 +13,12 @@ Version 3.1.0 Started Guide as well as examples in the examples/cxx/hybrid/binary/ directory. + * New option, --generate-detach, triggers generation of detach functions + for elements and attributes of variable-length types. These functions, + for example, allow you to move sub-trees in the object model either + within the same tree or between different trees. The sequence interfaces + for variable-length types now also provide the detach() function. + * The generated parser and serializer implementations are now capable of parsing/serializing recursive types. The XSD/e compiler detects recursive types and generates stack-based implementations with diff --git a/documentation/cxx/hybrid/guide/index.xhtml b/documentation/cxx/hybrid/guide/index.xhtml index f9ffccb..2aa9a19 100644 --- a/documentation/cxx/hybrid/guide/index.xhtml +++ b/documentation/cxx/hybrid/guide/index.xhtml @@ -1712,7 +1712,10 @@ private: variable-length type, the object model assumes ownership of the pointed to object. It expects you to allocate the object with operator <code>new</code> and will eventually delete it - with operator <code>delete</code>. As an example, let us extend + with operator <code>delete</code>. You can also request generation + of detach functions with the <code>--generate-detach</code> compiler + option. These functions allow you to detach a variable-length + object from the object model. As an example, let us extend our <code>people.xsd</code> schema with the following type:</p> <pre class="xml"> @@ -1724,8 +1727,8 @@ private: </xs:complexType> </pre> - <p>If we compile it with XSD/e, we will get the following C++ - class:</p> + <p>If we compile it with XSD/e and specify the <code>--generate-detach</code> + option, we will get the following C++ class:</p> <pre class="c++"> // staff (variable-length) @@ -1751,6 +1754,9 @@ public: void permanent (people*); + people* + permanent_detach (); + // contract // const people& @@ -1762,6 +1768,9 @@ public: void contract (people*); + people* + contract_detach (); + private: ... }; @@ -2135,31 +2144,43 @@ public: clear (); void - pop_back (); + push_back (T*); iterator - erase (iterator); + insert (iterator, T*); void - push_back (T*); + pop_back (); iterator - insert (iterator, T*); + erase (iterator); - error + void reserve (size_t); + + T* + detach (iterator); + + void + attach (iterator, T*); }; </pre> <p>Most of this interface is identical to the fixed-length type - version except for the <code>push_back()</code> and + version except for the <code>push_back()</code>, and <code>insert()</code> functions. Similar to the modifier functions for elements and attributes of variable-length types, these two functions expect a pointer to the dynamically-allocated instance of the type and assume ownership of the passed object. To simplify error handling, these two functions delete the passed object if the reallocation - of the underlying sequence buffer fails.</p> + of the underlying sequence buffer fails. The <code>var_sequence</code> + interface also provides the <code>detach()</code> and <code>attach()</code> + functions. The <code>detach()</code> function allows you to detach + the contained object at the specified position. A detached object + should eventually be deallocated with operator <code>delete</code>. + Similarly, the <code>attach()</code> function allows you to attach + a new object at the specified position.</p> <p>When C++ exceptions are disabled, the <code>push_back()</code>, <code>insert()</code>, and <code>reserve()</code> functions @@ -2295,12 +2316,11 @@ namespace xml_schema void reserve (size_t); - // Detach a string from the sequence at a given position. - // The string pointer at this position in the sequence is - // set to 0. - // char* detach (iterator); + + void + attach (iterator, char*); }; } </pre> @@ -2313,8 +2333,13 @@ namespace xml_schema free the passed string if the reallocation of the underlying sequence buffer fails. The <code>push_back_copy()</code> function makes a copy of the passed string. - If you detach the underlying element string, then it should - eventually be deallocated with operator <code>delete[]</code>.</p> + The <code>string_sequence</code> interface also provides the + <code>detach()</code> and <code>attach()</code> functions. + The <code>detach()</code> function allows you to detach + the contained string at the specified position. A detached string + should eventually be deallocated with operator <code>delete[]</code>. + Similarly, the <code>attach()</code> function allows you to attach + a new string at the specified position.</p> <p>When C++ exceptions are disabled, the signatures of the <code>push_back()</code>, <code>push_back_copy()</code>, @@ -3714,6 +3739,9 @@ namespace xml_schema void base_value (char* x); + char* + base_value_detach (); + operator const char* () const; operator char* (); }; @@ -3722,7 +3750,9 @@ namespace xml_schema <p>Note that the <code>string_base</code> object assumes ownership of the strings passed to the assignment operator and the - <code>base_value()</code> modifier.</p> + <code>base_value()</code> modifier. If you detach the + string value then it should eventually be deallocated with + operator <code>delete[]</code>.</p> <h2><a name="5.1">5.1 Mapping for <code>QName</code></a></h2> diff --git a/documentation/xsde.1 b/documentation/xsde.1 index 3947beb..e66dcaa 100644 --- a/documentation/xsde.1 +++ b/documentation/xsde.1 @@ -944,6 +944,11 @@ Suppress the generation of validation code in parser. .IP "\fB\--suppress-serializer-val\fR" Suppress the generation of validation code in serializer. +.IP "\fB\--generate-detach\fR" +Generate detach functions for elements and attributes of variable-length +types. 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-insertion \fIos\fR" Generate data representation stream insertion operators for the .I os diff --git a/documentation/xsde.xhtml b/documentation/xsde.xhtml index 2af5983..330bb96 100644 --- a/documentation/xsde.xhtml +++ b/documentation/xsde.xhtml @@ -816,6 +816,12 @@ <dt><code><b>--suppress-serializer-val</b></code></dt> <dd>Suppress the generation of validation code in serializer.</dd> + <dt><code><b>--generate-detach</b></code></dt> + <dd>Generate detach functions for elements and attributes of + variable-length types. These functions, for example, allow + you to move sub-trees in the object model either within the + same tree or between different trees.</dd> + <dt><code><b>--generate-insertion</b> <i>os</i></code></dt> <dd>Generate data representation stream insertion operators for the <code><i>os</i></code> output stream type. Repeat this diff --git a/libxsde/xsde/cxx/hybrid/base.hxx b/libxsde/xsde/cxx/hybrid/base.hxx index 75753bc..ba5090d 100644 --- a/libxsde/xsde/cxx/hybrid/base.hxx +++ b/libxsde/xsde/cxx/hybrid/base.hxx @@ -354,6 +354,7 @@ namespace xsde const char* base_value () const {return x_;} char* base_value () {return x_;} void base_value (char* x) {delete[] x_; x_ = x;} + char* base_value_detach () {char* r = x_; x_ = 0; return r;} operator const char* () const {return x_;} operator char* () {return x_;} diff --git a/libxsde/xsde/cxx/hybrid/sequence.hxx b/libxsde/xsde/cxx/hybrid/sequence.hxx index 6d8f33b..b0cdba2 100644 --- a/libxsde/xsde/cxx/hybrid/sequence.hxx +++ b/libxsde/xsde/cxx/hybrid/sequence.hxx @@ -792,6 +792,18 @@ namespace xsde insert (iterator, T*); #endif + // Detach an object from the sequence at a given position. + // The object pointer at this position in the sequence is + // set to 0. + // + T* + detach (iterator); + + // Attach an object to the sequence at a given position. + // + void + attach (iterator, T*); + #ifndef XSDE_EXCEPTIONS error #else diff --git a/libxsde/xsde/cxx/hybrid/sequence.ixx b/libxsde/xsde/cxx/hybrid/sequence.ixx index 11bc13d..a015e31 100644 --- a/libxsde/xsde/cxx/hybrid/sequence.ixx +++ b/libxsde/xsde/cxx/hybrid/sequence.ixx @@ -569,6 +569,23 @@ namespace xsde return i; } + template <typename T> + inline T* var_seq<T>:: + detach (iterator i) + { + T* r = *i.i_; + *i.i_ = 0; + return r; + } + + template <typename T> + inline void var_seq<T>:: + attach (iterator i, T* x) + { + delete *i.i_; + *i.i_ = x; + } + #ifdef XSDE_EXCEPTIONS template <typename T> inline void var_seq<T>:: diff --git a/libxsde/xsde/cxx/string-sequence.hxx b/libxsde/xsde/cxx/string-sequence.hxx index 50c0025..1278cfc 100644 --- a/libxsde/xsde/cxx/string-sequence.hxx +++ b/libxsde/xsde/cxx/string-sequence.hxx @@ -109,6 +109,11 @@ namespace xsde char* detach (iterator); + // Attach a string to the sequence at a given position. + // + void + attach (iterator, char*); + #ifndef XSDE_EXCEPTIONS error #else diff --git a/libxsde/xsde/cxx/string-sequence.ixx b/libxsde/xsde/cxx/string-sequence.ixx index 58878b7..2a895f8 100644 --- a/libxsde/xsde/cxx/string-sequence.ixx +++ b/libxsde/xsde/cxx/string-sequence.ixx @@ -222,6 +222,13 @@ namespace xsde return r; } + inline void string_sequence:: + attach (iterator p, char* x) + { + delete[] *p; + *p = x; + } + // // inline bool diff --git a/tests/cxx/hybrid/sequences/driver.cxx b/tests/cxx/hybrid/sequences/driver.cxx index 1a27e9b..f3d848e 100644 --- a/tests/cxx/hybrid/sequences/driver.cxx +++ b/tests/cxx/hybrid/sequences/driver.cxx @@ -271,6 +271,16 @@ main () assert (s[0] == "aaa" && s[1] == "ccc" && s[2] == "bbb"); } + { + var s; + s.push_back (new string ("aaa")); + s.push_back (new string ("bbb")); + s.push_back (new string ("ccc")); + delete s.detach (s.begin () + 1); + s.attach (s.begin () + 1, new string ("bbb")); + assert (s[0] == "aaa" && s[1] == "bbb" && s[2] == "ccc"); + } + // // str_seq // @@ -355,6 +365,19 @@ main () s[2] == string ("bbb")); } + { + str s; + s.reserve (2); + s.push_back_copy ("aaa"); + s.push_back_copy ("bbb"); + s.push_back_copy ("ccc"); + delete[] s.detach (s.begin () + 1); + s.attach (s.begin () + 1, strdupc ("bbb")); + assert (s[0] == string ("aaa") && + s[1] == string ("bbb") && + s[2] == string ("ccc")); + } + #else { diff --git a/tests/cxx/hybrid/union/makefile b/tests/cxx/hybrid/union/makefile index c4b0af8..a345fdd 100644 --- a/tests/cxx/hybrid/union/makefile +++ b/tests/cxx/hybrid/union/makefile @@ -43,7 +43,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): $(out_root)/xsde/xsde $(gen): xsde := $(out_root)/xsde/xsde $(gen): xsde_options += --generate-parser --generate-serializer \ ---generate-aggregate +--generate-aggregate --generate-detach $(call include-dep,$(dep)) diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx index be680ea..343e53b 100644 --- a/xsde/cxx/hybrid/cli.hxx +++ b/xsde/cxx/hybrid/cli.hxx @@ -33,6 +33,7 @@ namespace CXX extern Key suppress_validation; extern Key suppress_parser_val; extern Key suppress_serializer_val; + extern Key generate_detach; extern Key generate_insertion; extern Key generate_extraction; extern Key generate_inline; @@ -113,6 +114,7 @@ namespace CXX suppress_validation, Boolean, suppress_parser_val, Boolean, suppress_serializer_val, Boolean, + generate_detach, Boolean, generate_insertion, Cult::Containers::Vector<NarrowString>, generate_extraction, Cult::Containers::Vector<NarrowString>, generate_inline, Boolean, diff --git a/xsde/cxx/hybrid/elements.cxx b/xsde/cxx/hybrid/elements.cxx index 68af8df..68bc0c2 100644 --- a/xsde/cxx/hybrid/elements.cxx +++ b/xsde/cxx/hybrid/elements.cxx @@ -36,6 +36,7 @@ namespace CXX poly_code (false), poly_runtime (false), reset (!ops.value<CLI::suppress_reset> ()), + detach (ops.value<CLI::generate_detach> ()), mixin (ops.value<CLI::reuse_style_mixin> ()), tiein (!mixin), fwd_expr (fe), diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx index f5d959b..cd1a40f 100644 --- a/xsde/cxx/hybrid/elements.hxx +++ b/xsde/cxx/hybrid/elements.hxx @@ -44,6 +44,7 @@ namespace CXX poly_code (c.poly_code), poly_runtime (c.poly_runtime), reset (c.reset), + detach (c.detach), mixin (c.mixin), tiein (c.tiein), fwd_expr (c.fwd_expr), @@ -67,6 +68,7 @@ namespace CXX poly_code (c.poly_code), poly_runtime (c.poly_runtime), reset (c.reset), + detach (c.detach), mixin (c.mixin), tiein (c.tiein), fwd_expr (c.fwd_expr), @@ -109,6 +111,20 @@ namespace CXX return a.context ().get<String> ("member"); } + // Detach. + // + static String const& + edetach (SemanticGraph::Particle& p) + { + return p.context ().get<String> ("detach"); + } + + static String const& + edetach (SemanticGraph::Attribute& a) + { + return a.context ().get<String> ("detach"); + } + // Optional. // static String const& @@ -524,6 +540,7 @@ namespace CXX Boolean poly_code; Boolean poly_runtime; Boolean reset; + Boolean detach; Boolean mixin; Boolean tiein; diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx index 495e649..28d851b 100644 --- a/xsde/cxx/hybrid/generator.cxx +++ b/xsde/cxx/hybrid/generator.cxx @@ -121,6 +121,7 @@ namespace CXX extern Key suppress_validation = "suppress-validation"; extern Key suppress_parser_val = "suppress-parser-val"; extern Key suppress_serializer_val = "suppress-serializer-val"; + extern Key generate_detach = "generate-detach"; extern Key generate_insertion = "generate-insertion"; extern Key generate_extraction = "generate-extraction"; extern Key generate_inline = "generate-inline"; @@ -244,6 +245,11 @@ namespace CXX << " serializer." << endl; + e << "--generate-detach" << endl + << " Generate detach functions for elements and\n" + << " attributes of variable-length types." + << endl; + e << "--generate-insertion <os>" << endl << " Generate data representation stream insertion\n" << " operators for the <os> output stream type." diff --git a/xsde/cxx/hybrid/tree-header.cxx b/xsde/cxx/hybrid/tree-header.cxx index 2412b86..dc378fe 100644 --- a/xsde/cxx/hybrid/tree-header.cxx +++ b/xsde/cxx/hybrid/tree-header.cxx @@ -178,6 +178,16 @@ namespace CXX os << "void" << endl << value << " (char*);" << endl; + + // char* + // detach () + // + if (detach) + { + os << "char*" << endl + << uc.get<String> ("value-detach") << " ();" + << endl; + } } // Custom data. @@ -1050,6 +1060,17 @@ namespace CXX arg_.dispatch (t); os << ");" << endl; + + // type* + // detach () + // + if (detach && !fixed_length (t)) + { + arg_.dispatch (t); + os << endl + << edetach (a) << " ();" + << endl; + } } private: @@ -1150,6 +1171,17 @@ namespace CXX arg_.dispatch (t); os << ");" << endl; + + // type* + // detach () + // + if (detach && !fixed_length (t)) + { + arg_.dispatch (t); + os << endl + << edetach (e) << " ();" + << endl; + } } } @@ -1293,6 +1325,16 @@ namespace CXX os << ");" << endl; + + // type* + // detach () + // + if (detach && !fl) + { + os << type << "*" << endl + << edetach (a) << " ();" + << endl; + } } else All::contains (a); @@ -1571,6 +1613,16 @@ namespace CXX os << ");" << endl; + + // type* + // detach () + // + if (detach && !fl) + { + os << type << "*" << endl + << edetach (c) << " ();" + << endl; + } } } @@ -1786,6 +1838,16 @@ namespace CXX os << ");" << endl; + + // type* + // detach () + // + if (detach && !fl) + { + os << type << "*" << endl + << edetach (c) << " ();" + << endl; + } } } @@ -1970,6 +2032,16 @@ namespace CXX os << ");" << endl; + + // type* + // detach () + // + if (detach && !fl) + { + os << type << "*" << endl + << edetach (s) << " ();" + << endl; + } } } @@ -2149,6 +2221,16 @@ namespace CXX os << ");" << endl; + + // type* + // detach () + // + if (detach && !fl) + { + os << type << "*" << endl + << edetach (s) << " ();" + << endl; + } } } diff --git a/xsde/cxx/hybrid/tree-inline.cxx b/xsde/cxx/hybrid/tree-inline.cxx index 72d2d8f..34d0cc3 100644 --- a/xsde/cxx/hybrid/tree-inline.cxx +++ b/xsde/cxx/hybrid/tree-inline.cxx @@ -177,6 +177,21 @@ namespace CXX << "delete[] this->" << member << ";" << "this->" << member << " = x;" << "}"; + + // char* + // detach () + // + if (detach) + { + os << inl + << "char* " << name << "::" << endl + << uc.get<String> ("value-detach") << " ()" + << "{" + << "char* r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } // Custom data. @@ -326,6 +341,24 @@ namespace CXX os << "this->" << epresent_member (a) << " = true;"; os << "}"; + + + // type* + // detach () + // + if (detach && !fl) + { + os << inl; + arg_.dispatch (t); + os << " " << scope << "::" << endl + << edetach (a) << " ()" + << "{"; + arg_.dispatch (t); + os << " r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } private: @@ -475,6 +508,23 @@ namespace CXX os << "this->" << epresent_member (e) << " = true;"; os << "}"; + + // type* + // detach () + // + if (detach && !fl) + { + os << inl; + arg_.dispatch (t); + os << " " << scope << "::" << endl + << edetach (e) << " ()" + << "{"; + arg_.dispatch (t); + os << " r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } } @@ -691,6 +741,23 @@ namespace CXX } os << "}"; + + // type* + // detach () + // + if (detach && !fl) + { + os << inl; + arg_.dispatch (t); + os << " " << scope << "::" << endl + << edetach (e) << " ()" + << "{"; + arg_.dispatch (t); + os << " r = this->" << umember << "." << member << ";" + << "this->" << umember << "." << member << " = 0;" + << "return r;" + << "}"; + } } } @@ -822,6 +889,21 @@ namespace CXX os << "this->" << epresent_member (a) << " = true;"; os << "}"; + + // type* + // detach () + // + if (detach && !fl) + { + os << inl + << type << "* " << scope << "::" << endl + << edetach (a) << " ()" + << "{" + << type << "* r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } else All::contains (a); @@ -989,6 +1071,21 @@ namespace CXX os << "this->" << epresent_member (c) << " = true;"; os << "}"; + + // type* + // detach () + // + if (detach && !fl) + { + os << inl + << type << "* " << scope << "::" << endl + << edetach (c) << " ()" + << "{" + << type << "* r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } } }; @@ -1142,6 +1239,21 @@ namespace CXX os << "this->" << epresent_member (s) << " = true;"; os << "}"; + + // type* + // detach () + // + if (detach && !fl) + { + os << inl + << type << "* " << scope << "::" << endl + << edetach (s) << " ()" + << "{" + << type << "* r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } } }; @@ -1331,6 +1443,22 @@ namespace CXX } os << "}"; + + + // type* + // detach () + // + if (detach && !fl) + { + os << inl + << type << "* " << scope << "::" << endl + << edetach (c) << " ()" + << "{" + << type << "* r = this->" << umember << "." << member << ";" + << "this->" << umember << "." << member << " = 0;" + << "return r;" + << "}"; + } } } }; diff --git a/xsde/cxx/hybrid/tree-name-processor.cxx b/xsde/cxx/hybrid/tree-name-processor.cxx index c828250..7783ba5 100644 --- a/xsde/cxx/hybrid/tree-name-processor.cxx +++ b/xsde/cxx/hybrid/tree-name-processor.cxx @@ -49,6 +49,8 @@ namespace CXX schema_path_ (file), schema (root), schema_path (schema_path_), + stl (!ops.value<CLI::no_stl> ()), + detach (ops.value<CLI::generate_detach> ()), custom_data_map (custom_data_map_), global_type_names (global_type_names_) { @@ -98,6 +100,8 @@ namespace CXX : CXX::Context (c), schema (c.schema), schema_path (c.schema_path), + stl (c.stl), + detach (c.detach), custom_data_map (c.custom_data_map), global_type_names (c.global_type_names) { @@ -174,6 +178,9 @@ namespace CXX SemanticGraph::Schema& schema; SemanticGraph::Path const& schema_path; + Boolean stl; + Boolean detach; + CustomDataMap& custom_data_map; Cult::Containers::Map<String, NameSet*>& global_type_names; }; @@ -263,7 +270,11 @@ namespace CXX NameSet& set (uc.get<NameSet> (member_set_key)); set.insert (name); - uc.set ("value", find_name ("value", set)); + String v (find_name ("value", set)); + uc.set ("value", v); + + if (detach && !stl) + uc.set ("value-detach", find_name (v + L"_detach", set)); // Check if this type has custom data. // @@ -432,6 +443,12 @@ namespace CXX ac.set ( "present", find_name (ac.get<String> ("name") + L"_present", set_)); + + if (detach && !fixed_length (a.type ())) + ac.set ( + "detach", + find_name (ac.get<String> ("name") + L"_detach", set_)); + } else { @@ -476,11 +493,17 @@ namespace CXX ec.set ("const-iterator", find_name (base + L"_const_iterator", set_)); } - else if (e.min () == 0) + else { - ec.set ( - "present", - find_name (ec.get<String> ("name") + L"_present", set_)); + if (e.min () == 0) + ec.set ( + "present", + find_name (ec.get<String> ("name") + L"_present", set_)); + + if (detach && !fixed_length (e.type ())) + ec.set ( + "detach", + find_name (ec.get<String> ("name") + L"_detach", set_)); } } else @@ -589,6 +612,9 @@ namespace CXX } ac.set ("present", find_name (base + L"_present", set_)); + + if (detach && !fixed_length (a)) + ac.set ("detach", find_name (base + L"_detach", set_)); } else { @@ -819,8 +845,14 @@ namespace CXX cc.set ("const-iterator", find_name (base + L"_const_iterator", set_)); } - else if (c.min () == 0) - cc.set ("present", find_name (base + L"_present", set_)); + else + { + if (c.min () == 0) + cc.set ("present", find_name (base + L"_present", set_)); + + if (detach && !fixed_length (c)) + cc.set ("detach", find_name (base + L"_detach", set_)); + } } else { @@ -1018,8 +1050,15 @@ namespace CXX sc.set ("const-iterator", find_name (base + L"_const_iterator", set_)); } - else if (s.min () == 0) - sc.set ("present", find_name (base + L"_present", set_)); + else + { + if (s.min () == 0) + sc.set ("present", find_name (base + L"_present", set_)); + + if (detach && !fixed_length (s)) + sc.set ("detach", find_name (base + L"_detach", set_)); + } + } else { |