diff options
44 files changed, 1663 insertions, 389 deletions
@@ -38,6 +38,14 @@ C++/Tree to Section 2.13, "Mapping for Mixed Content Models" in the C++/Tree Mapping User Manual. + * xml_schema::typecan represent anyType content as a DOM fragment, similar + to wildcards. For more information, refer to Section 2.5.2, "Mapping for + anyType" in the C++/Tree Mapping User Manual. + + * xml_schema::simple_type can represent anySimpleType content as a text + string. For more information, refer to Section 2.5.3, "Mapping for + anySimpleType" in the C++/Tree Mapping User Manual. + * New option, --suppress-assignment, suppress the generation of copy assignment operators for complex types. If this option is specified, the copy assignment operators for such types are declared private diff --git a/doc/cxx/tree/manual/index.xhtml b/doc/cxx/tree/manual/index.xhtml index 052f2b3..235c33c 100644 --- a/doc/cxx/tree/manual/index.xhtml +++ b/doc/cxx/tree/manual/index.xhtml @@ -1214,18 +1214,44 @@ public: virtual ~type (); -public: type (); type (const type&); -public: type& operator= (const type&); -public: virtual type* _clone () const; + // anyType DOM content. + // +public: + typedef element_optional dom_content_optional; + + const dom_content_optional& + dom_content () const; + + dom_content_optional& + dom_content (); + + void + dom_content (const xercesc::DOMElement&); + + void + dom_content (xercesc::DOMElement*); + + void + dom_content (const dom_content_optional&); + + const xercesc::DOMDocument& + dom_content_document () const; + + xercesc::DOMDocument& + dom_content_document (); + + bool + null_content () const; + // DOM association. // public: @@ -1237,7 +1263,44 @@ public: }; </pre> - <p>For more information about DOM association refer to + <p>When <code>xml_schema::type</code> is used to create an instance + (as opposed to being a base of a derived type), it represents + the XML Schema <code>anyType</code> type. <code>anyType</code> + allows any attributes and any content in any order. In the + C++/Tree mapping this content can be represented as a DOM + fragment, similar to XML Schema wildcards (<a href="#2.12">Section + 2.12, "Mapping for <code>any</code> and + <code>anyAttribute</code>"</a>).</p> + + <p>To enable automatic extraction of <code>anyType</code> content + during parsing, the <code>--generate-any-type</code> option must be + specified. Because the DOM API is used to access such content, the + Xerces-C++ runtime should be initialized by the application prior to + parsing and should remain initialized for the lifetime of objects + with the DOM content. For more information on the Xerces-C++ runtime + initialization see <a href="#3.1">Section 3.1, "Initializing the + Xerces-C++ Runtime"</a>.</p> + + <p>The DOM content is stored as the optional DOM element container + and the DOM content accessors and modifiers presented above are + identical to those generated for an optional element wildcard. + Refer to <a href="#2.12.2">Section 2.12.2, "Mapping for <code>any</code> + with the Optional Cardinality Class"</a> for details on their + semantics.</p> + + <p>The <code>dom_content_document()</code> function returns the + DOM document used to store the raw XML content corresponding + to the <code>anyType</code> instance. It is equivalent to the + <code>dom_document()</code> function generated for types + with wildcards.</p> + + <p>The <code>null_content()</code> accessor is an optimization function + that allows us to check for the lack of content without actually + creating its empty representation, that is, empty DOM document for + <code>anyType</code> or empty string for <code>anySimpleType</code> + (see the following section for details on <code>anySimpleType</code>).</p> + + <p>For more information on DOM association refer to <a href="#5.1">Section 5.1, "DOM Association"</a>.</p> <h3><a name="2.5.3">2.5.3 Mapping for <code>anySimpleType</code></a></h3> @@ -1250,18 +1313,37 @@ class simple_type: public type { public: simple_type (); + simple_type (const C*); + simple_type (const std::basic_string<C>&); + simple_type (const simple_type&); -public: simple_type& operator= (const simple_type&); -public: virtual simple_type* _clone () const; + + // anySimpleType text content. + // +public: + const std::basic_string<C>& + text_content () const; + + std::basic_string<C>& + text_content (); + + void + text_content (const std::basic_string<C>&); }; </pre> + <p>When <code>xml_schema::simple_type</code> is used to create an instance + (as opposed to being a base of a derived type), it represents + the XML Schema <code>anySimpleType</code> type. <code>anySimpleType</code> + allows any simple content. In the C++/Tree mapping this content can + be represented as a string and accessed or modified with the + <code>text_content()</code> functions shown above.</p> <h3><a name="2.5.4">2.5.4 Mapping for <code>QName</code></a></h3> diff --git a/libxsd/xsd/cxx/tree/comparison-map.txx b/libxsd/xsd/cxx/tree/comparison-map.txx index e996aec..af23d64 100644 --- a/libxsd/xsd/cxx/tree/comparison-map.txx +++ b/libxsd/xsd/cxx/tree/comparison-map.txx @@ -19,18 +19,17 @@ namespace xsd // anyType and anySimpleType. // - //register_type ( - // typeid (type), - // &comparator_impl<type>, - // false); - - typedef simple_type<type> simple_type; + register_type ( + typeid (type), + &comparator_impl<type>, + false); - //register_type ( - // typeid (simple_type), - // &comparator_impl<simple_type>, - // false); + typedef simple_type<C, type> simple_type; + register_type ( + typeid (simple_type), + &comparator_impl<simple_type>, + false); // Strings // diff --git a/libxsd/xsd/cxx/tree/containers-wildcard.hxx b/libxsd/xsd/cxx/tree/containers-wildcard.hxx index f4d3be2..549df73 100644 --- a/libxsd/xsd/cxx/tree/containers-wildcard.hxx +++ b/libxsd/xsd/cxx/tree/containers-wildcard.hxx @@ -15,7 +15,7 @@ #include <xsd/cxx/xml/string.hxx> -#include <xsd/cxx/tree/containers.hxx> // iterator_adapter +#include <xsd/cxx/tree/iterator-adapter.hxx> namespace xsd { diff --git a/libxsd/xsd/cxx/tree/containers.hxx b/libxsd/xsd/cxx/tree/containers.hxx index c89218f..cafd79d 100644 --- a/libxsd/xsd/cxx/tree/containers.hxx +++ b/libxsd/xsd/cxx/tree/containers.hxx @@ -5,17 +5,15 @@ #ifndef XSD_CXX_TREE_CONTAINERS_HXX #define XSD_CXX_TREE_CONTAINERS_HXX -#include <cstddef> // std::ptrdiff_t -#include <string> #include <vector> #include <memory> // std::auto_ptr/unique_ptr -#include <iterator> // std::iterator_traits #include <algorithm> // std::equal, std::lexicographical_compare #include <iosfwd> #include <xsd/cxx/config.hxx> // XSD_AUTO_PTR #include <xsd/cxx/tree/elements.hxx> +#include <xsd/cxx/tree/iterator-adapter.hxx> namespace xsd { @@ -515,7 +513,7 @@ namespace xsd return !(a < b); } - // Provide an ostream insertion opretaor to prevent confusion from + // Provide an ostream insertion operator to prevent confusion from // the implicit bool conversion. // template <typename C, typename T, bool fund> @@ -528,256 +526,6 @@ namespace xsd template <typename T, bool fund = fundamental_p<T>::r> class sequence; - // Sun CC's <iterator> does not have iterator_traits. To overcome - // this, we will wrap std::iterator_traits into our own and also - // specialize it for pointer types. Since Sun CC uses pointer - // for vector::iterator, it will use the specialization and won't - // notice the std::iterator_traits. - // -#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC - template <typename I> - struct iterator_traits - { - typedef - typename std::iterator_traits<I>::iterator_category - iterator_category; - - typedef - typename std::iterator_traits<I>::value_type - value_type; - - typedef - typename std::iterator_traits<I>::difference_type - difference_type; - }; -#else - // The Pointer specialization does not work for reverse and - // set iterators. But these iterators are user-dfined types - // and have suitable typedefs that we can use. - // - template <typename I> - struct iterator_traits - { - typedef typename I::iterator_category iterator_category; - typedef typename I::value_type value_type; - typedef typename I::difference_type difference_type; - }; - - template <typename T> - struct iterator_traits<T*> - { - typedef std::random_access_iterator_tag iterator_category; - typedef T value_type; - typedef std::ptrdiff_t difference_type; - }; -#endif - - // Iterator adapter for complex types. It expects I to point to - // a smart pointer-like object that has operator*() that returns - // a refernce to a type static_cast'able to T and get() that - // returns a pointer to a type static_cast'able to T. - // - - template <typename I, typename T> - struct iterator_adapter - { - typedef T value_type; - typedef value_type& reference; - typedef value_type* pointer; - - typedef - typename iterator_traits<I>::iterator_category - iterator_category; - - typedef - typename iterator_traits<I>::difference_type - difference_type; - - - public: - iterator_adapter () - : i_ () // i_ can be of a pointer type. - { - } - - // Allow iterator to const_iterator conversion. - // - template <typename J, typename T2> - iterator_adapter (const iterator_adapter<J, T2>& j) - : i_ (j.base ()) - { - } - - explicit - iterator_adapter (const I& i) - : i_ (i) - { - } - - public: - // Forward iterator requirements. - // - reference - operator* () const - { - return static_cast<reference> (**i_); - } - - pointer - operator-> () const - { - return static_cast<pointer> (i_->get ()); - } - - iterator_adapter& - operator++ () - { - ++i_; - return *this; - } - - iterator_adapter - operator++ (int) - { - iterator_adapter r (*this); - ++i_; - return r; - } - - // Bidirectional iterator requirements. - // - iterator_adapter& - operator-- () - { - --i_; - return *this; - } - - iterator_adapter - operator-- (int) - { - iterator_adapter r (*this); - --i_; - return r; - } - - // Random access iterator requirements. - // - reference - operator[] (difference_type n) const - { - return static_cast<reference> (*(i_[n])); - } - - iterator_adapter& - operator+= (difference_type n) - { - i_ += n; - return *this; - } - - iterator_adapter - operator+ (difference_type n) const - { - return iterator_adapter (i_ + n); - } - - iterator_adapter& - operator-= (difference_type n) - { - i_ -= n; - return *this; - } - - iterator_adapter - operator- (difference_type n) const - { - return iterator_adapter (i_ - n); - } - - public: - const I& - base () const - { - return i_; - } - - private: - I i_; - }; - - // Note: We use different types for left- and right-hand-side - // arguments to allow comparison between iterator and const_iterator. - // - - // Forward iterator requirements. - // - template <typename I, typename J, typename T1, typename T2> - inline bool - operator== (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () == j.base (); - } - - template <typename I, typename J, typename T1, typename T2> - inline bool - operator!= (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () != j.base (); - } - - // Random access iterator requirements - // - template <typename I, typename J, typename T1, typename T2> - inline bool - operator< (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () < j.base (); - } - - template <typename I, typename J, typename T1, typename T2> - inline bool - operator> (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () > j.base (); - } - - template <typename I, typename J, typename T1, typename T2> - inline bool - operator<= (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () <= j.base (); - } - - template <typename I, typename J, typename T1, typename T2> - inline bool - operator>= (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () >= j.base (); - } - - template <typename I, typename J, typename T1, typename T2> - inline typename iterator_adapter<I, T1>::difference_type - operator- (const iterator_adapter<I, T1>& i, - const iterator_adapter<J, T2>& j) - { - return i.base () - j.base (); - } - - template <typename I, typename T> - inline iterator_adapter<I, T> - operator+ (typename iterator_adapter<I, T>::difference_type n, - const iterator_adapter<I, T>& i) - { - return iterator_adapter<I, T> (i.base () + n); - } - // // class sequence_common diff --git a/libxsd/xsd/cxx/tree/elements.hxx b/libxsd/xsd/cxx/tree/elements.hxx index 89be61e..ee32a62 100644 --- a/libxsd/xsd/cxx/tree/elements.hxx +++ b/libxsd/xsd/cxx/tree/elements.hxx @@ -40,10 +40,12 @@ #include <xsd/cxx/xml/elements.hxx> // xml::properties #include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr/unique_ptr +#include <xsd/cxx/xml/dom/wildcard-source.hxx> // dom::create_document() #include <xsd/cxx/tree/facet.hxx> #include <xsd/cxx/tree/exceptions.hxx> #include <xsd/cxx/tree/istream-fwd.hxx> +#include <xsd/cxx/tree/containers-wildcard.hxx> #if _XERCES_VERSION < 30000 # error Xerces-C++ 2-series is not supported @@ -101,6 +103,12 @@ namespace xsd static const unsigned long dont_validate = 0x00000400UL; /** + * @brief Extract XML content for anyType or anySimpleType. + * Normally you don't need to specify this flag explicitly. + */ + static const unsigned long extract_content = 0x00000800UL; + + /** * @brief Do not initialize the Xerces-C++ runtime. */ static const unsigned long dont_initialize = 0x00000001UL; @@ -330,9 +338,14 @@ namespace xsd _type (); /** - * @brief Create an instance from a string. + * @brief Create an instance from a C string. * * @param s A string to initialize the instance with. + * + * Note that this constructor ignores the string and creates an + * empty anyType instance. In particular, it will not convert the + * string into DOM content. The purpose of such a strange constructor + * is to allow statically-initialized default values of anyType type. */ template <typename C> _type (const C* s); @@ -387,7 +400,9 @@ namespace xsd * @param c A pointer to the object that will contain the new * instance. */ - _type (const xercesc::DOMElement& e, flags f = 0, container* c = 0); + _type (const xercesc::DOMElement& e, + flags f = flags::extract_content, + container* c = 0); /** * @brief Create an instance from a DOM Attribute. @@ -427,6 +442,11 @@ namespace xsd { if (this != &x) { + if (x.content_.get () == 0) + content_.reset (); + else + content_ = x.content_->clone (); + // Drop DOM association. // dom_info_.reset (); @@ -435,6 +455,135 @@ namespace xsd return *this; } + // anyType content API. + // + public: + typedef element_optional dom_content_optional; + + /** + * @brief Return a read-only (constant) reference to the anyType + * DOM content. + * + * @return A constant reference to the optional container. + * + * The DOM content is returned as an optional element container, + * the same container as used for optional element wildcards. + */ + const dom_content_optional& + dom_content () const; + + /** + * @brief Return a read-write reference to the anyType DOM content. + * + * @return A reference to the optional container. + * + * The DOM content is returned as an optional element container, + * the same container as used for optional element wildcards. + */ + dom_content_optional& + dom_content (); + + /** + * @brief Set the anyType DOM content. + * + * @param e A new element to set. + * + * This function makes a copy of its argument and sets it as the + * new DOM content. + */ + void + dom_content (const xercesc::DOMElement& e); + + /** + * @brief Set the anyType DOM content. + * + * @param e A new element to use. + * + * This function will use the passed element directly instead + * of making a copy. For this to work the element should belong + * to the DOM document associated with this anyType instance. + * + * @see dom_content_document + */ + void + dom_content (xercesc::DOMElement* e); + + /** + * @brief Set the anyType DOM content. + * + * @param d An optional container with the new element to set. + * + * If the element is present in @a d then this function makes a + * copy of this element and sets it as the new wildcard content. + * Otherwise the element container is set the 'not present' state. + */ + void + dom_content (const dom_content_optional& d); + + /** + * @brief Return a read-only (constant) reference to the DOM + * document associated with this anyType instance. + * + * @return A constant reference to the DOM document. + * + * The DOM document returned by this function is used to store + * the raw XML content corresponding to the anyType instance. + */ + const xercesc::DOMDocument& + dom_content_document () const; + + /** + * @brief Return a read-write reference to the DOM document + * associated with this anyType instance. + * + * @return A reference to the DOM document. + * + * The DOM document returned by this function is used to store + * the raw XML content corresponding to the anyType instance. + */ + xercesc::DOMDocument& + dom_content_document (); + + /** + * @brief Check for absence of DOM (anyType) and text (anySimpleType) + * content. + * + * @return True if there is no content and false otherwise. + * + * This is an optimization function that allows us to check for the + * lack of content without actually creating its empty representation + * (that is, empty DOM document for DOM or empty string for text). + */ + bool + null_content () const; + + // + // + public: + /** + * @brief Comparison operator. It uses DOM (anyType) or text + * (anySimpleType) content if present. If the content is missing + * then the types are assumed unequal. + * + * @return True if the instances are equal, false otherwise. + */ + friend bool + operator== (const type& x, const type& y) + { + return x.content_.get () != 0 && + x.content_->compare (y.content_.get ()); + } + + /** + * @brief Comparison operator. It uses DOM (anyType) or text + * (anySimpleType) content if present. If the content is missing + * then the types are assumed unequal. + * + * @return True if the instances are not equal, false otherwise. + */ + friend bool + operator!= (const type& x, const type& y) {return !(x == y);} + // Container API. // public: @@ -738,13 +887,9 @@ namespace xsd struct dom_info { virtual - ~dom_info () - { - } + ~dom_info () {} - dom_info () - { - } + dom_info () {} virtual XSD_AUTO_PTR<dom_info> clone (type& tree_node, container*) const = 0; @@ -754,12 +899,9 @@ namespace xsd private: dom_info (const dom_info&); - - dom_info& - operator= (const dom_info&); + dom_info& operator= (const dom_info&); }; - struct dom_element_info: public dom_info { dom_element_info (xercesc::DOMElement& e, type& n, bool root) @@ -994,20 +1136,75 @@ namespace xsd XSD_AUTO_PTR<map> map_; - private: - container* container_; - }; + // anyType and anySimpleType content. + // + protected: - inline _type:: - _type (const type& x, flags f, container* c) - : container_ (c) - { - if (x.dom_info_.get () != 0 && (f & flags::keep_dom)) + //@cond + + struct content_type { - dom_info_ = x.dom_info_->clone (*this, c); - } - } + virtual + ~content_type () {} + + content_type () {} + + virtual XSD_AUTO_PTR<content_type> + clone () const = 0; + + virtual bool + compare (const content_type*) const = 0; + + private: + content_type (const content_type&); + content_type& operator= (const content_type&); + }; + + struct dom_content_type: content_type + { + dom_content_type () + : doc (xml::dom::create_document<char> ()), dom (*doc) {} + explicit + dom_content_type (const xercesc::DOMElement& e) + : doc (xml::dom::create_document<char> ()), dom (e, *doc) {} + + explicit + dom_content_type (xercesc::DOMElement* e) + : doc (xml::dom::create_document<char> ()), dom (e, *doc) {} + + explicit + dom_content_type (const dom_content_optional& d) + : doc (xml::dom::create_document<char> ()), dom (d, *doc) {} + + virtual XSD_AUTO_PTR<content_type> + clone () const + { + return XSD_AUTO_PTR<content_type> (new dom_content_type (dom)); + } + + virtual bool + compare (const content_type* c) const + { + if (const dom_content_type* dc = + dynamic_cast<const dom_content_type*> (c)) + return dom == dc->dom; + + return false; + } + + public: + XSD_DOM_AUTO_PTR<xercesc::DOMDocument> doc; + dom_content_optional dom; + }; + + //@endcond + + mutable XSD_AUTO_PTR<content_type> content_; + + private: + container* container_; + }; /** * @brief Class corresponding to the XML Schema anySimpleType built-in @@ -1015,7 +1212,7 @@ namespace xsd * * @nosubgrouping */ - template <typename B> + template <typename C, typename B> class simple_type: public B { public: @@ -1030,13 +1227,19 @@ namespace xsd simple_type (); /** - * @brief Create an instance from a string. + * @brief Create an instance from a C string. * * @param s A string to initialize the instance with. */ - template <typename C> simple_type (const C* s); + /** + * @brief Create an instance from a string. + * + * @param s A string to initialize the instance with. + */ + simple_type (const std::basic_string<C>& s); + public: /** * @brief Copy constructor. @@ -1074,7 +1277,9 @@ namespace xsd * instance. */ template <typename S> - simple_type (istream<S>& s, flags f = 0, container* c = 0); + simple_type (istream<S>& s, + flags f = flags::extract_content, + container* c = 0); /** * @brief Create an instance from a DOM element. @@ -1085,7 +1290,7 @@ namespace xsd * instance. */ simple_type (const xercesc::DOMElement& e, - flags f = 0, + flags f = flags::extract_content, container* c = 0); /** @@ -1097,7 +1302,7 @@ namespace xsd * instance. */ simple_type (const xercesc::DOMAttr& a, - flags f = 0, + flags f = flags::extract_content, container* c = 0); /** @@ -1109,12 +1314,82 @@ namespace xsd * @param c A pointer to the object that will contain the new * instance. */ - template <typename C> simple_type (const std::basic_string<C>& s, const xercesc::DOMElement* e, - flags f = 0, + flags f = flags::extract_content, container* c = 0); //@} + + // anySimpleType content API. + // + public: + /** + * @brief Return a read-only (constant) reference to the anySimpleType + * text content. + * + * @return A constant reference to the text string. + */ + const std::basic_string<C>& + text_content () const; + + /** + * @brief Return a read-write reference to the anySimpleType text + * content. + * + * @return A reference to the text string. + */ + std::basic_string<C>& + text_content (); + + /** + * @brief Set the anySimpleType text content. + * + * @param e A new text string to set. + */ + void + text_content (const std::basic_string<C>& t); + + protected: + //@cond + + typedef typename B::content_type content_type; + + struct text_content_type: content_type + { + text_content_type () {} + + explicit + text_content_type (const std::basic_string<C>& t): text (t) {} + + explicit + text_content_type (const C* t): text (t) {} + + virtual XSD_AUTO_PTR<content_type> + clone () const + { + return XSD_AUTO_PTR<content_type> (new text_content_type (text)); + } + + virtual bool + compare (const content_type* c) const + { + if (const text_content_type* tc = + dynamic_cast<const text_content_type*> (c)) + return text == tc->text; + + return false; + } + + public: + // It would have been more elegant to store text content as DOMText. + // However, that would require Xerces-C++ initialization. Also + // having a separate DOMDocument for each text node seems like + // an overkill. + // + std::basic_string<C> text; + }; + + //@endcond }; @@ -1233,8 +1508,57 @@ namespace xsd { return XSD_AUTO_PTR<T> (new T (s, e, f, c)); } + + // For now for istream we only go through traits for non- + // fundamental types. + // + template <typename S> + static XSD_AUTO_PTR<T> + create (istream<S>& s, flags f, container* c) + { + return XSD_AUTO_PTR<T> (new T (s, f, c)); + } }; + template <typename B, + typename C, + schema_type::value ST> + struct traits<simple_type<C, B>, C, ST> + { + typedef simple_type<C, B> type; + + static XSD_AUTO_PTR<type> + create (const xercesc::DOMElement& e, flags f, container* c) + { + return XSD_AUTO_PTR<type> ( + new type (e, f | flags::extract_content, c)); + } + + static XSD_AUTO_PTR<type> + create (const xercesc::DOMAttr& a, flags f, container* c) + { + return XSD_AUTO_PTR<type> ( + new type (a, f | flags::extract_content, c)); + } + + static XSD_AUTO_PTR<type> + create (const std::basic_string<C>& s, + const xercesc::DOMElement* e, + flags f, + container* c) + { + return XSD_AUTO_PTR<type> ( + new type (s, e, f | flags::extract_content, c)); + } + + template <typename S> + static XSD_AUTO_PTR<type> + create (istream<S>& s, flags f, container* c) + { + return XSD_AUTO_PTR<type> ( + new type (s, f | flags::extract_content, c)); + } + }; //@endcond diff --git a/libxsd/xsd/cxx/tree/elements.ixx b/libxsd/xsd/cxx/tree/elements.ixx index da8a83e..844ccf7 100644 --- a/libxsd/xsd/cxx/tree/elements.ixx +++ b/libxsd/xsd/cxx/tree/elements.ixx @@ -45,20 +45,221 @@ namespace xsd { } + inline _type:: + _type (const type& x, flags f, container* c) + : container_ (c) + { + if (x.content_.get () != 0) + content_ = x.content_->clone (); + + if (x.dom_info_.get () != 0 && (f & flags::keep_dom)) + { + dom_info_ = x.dom_info_->clone (*this, c); + } + } + + inline const _type::dom_content_optional& _type:: + dom_content () const + { + const content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<const dom_content_type*> (c) != 0); + + return static_cast<const dom_content_type*> (c)->dom; + } + + inline _type::dom_content_optional& _type:: + dom_content () + { + content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<dom_content_type*> (c) != 0); + + return static_cast<dom_content_type*> (c)->dom; + } + + inline void _type:: + dom_content (const xercesc::DOMElement& e) + { + content_type* c (content_.get ()); + + if (c == 0) + content_.reset (new dom_content_type (e)); + else + { + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<dom_content_type*> (c) != 0); + static_cast<dom_content_type*> (c)->dom.set (e); + } + } + + inline void _type:: + dom_content (xercesc::DOMElement* e) + { + content_type* c (content_.get ()); + + if (c == 0) + content_.reset (new dom_content_type (e)); + else + { + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<dom_content_type*> (c) != 0); + static_cast<dom_content_type*> (c)->dom.set (e); + } + } + + inline void _type:: + dom_content (const dom_content_optional& d) + { + content_type* c (content_.get ()); + + if (c == 0) + content_.reset (new dom_content_type (d)); + else + { + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<dom_content_type*> (c) != 0); + static_cast<dom_content_type*> (c)->dom = d; + } + } + + inline const xercesc::DOMDocument& _type:: + dom_content_document () const + { + const content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<const dom_content_type*> (c) != 0); + + return *static_cast<const dom_content_type*> (c)->doc; + } + + inline xercesc::DOMDocument& _type:: + dom_content_document () + { + content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast<dom_content_type*> (c) != 0); + + return *static_cast<dom_content_type*> (c)->doc; + } + + inline bool _type:: + null_content () const + { + return content_.get () == 0; + } + // simple_type // - template <typename B> - inline simple_type<B>:: + template <typename C, typename B> + inline simple_type<C, B>:: simple_type () { } - template <typename B> - template <typename C> - inline simple_type<B>:: - simple_type (const C*) + template <typename C, typename B> + inline simple_type<C, B>:: + simple_type (const C* s) + { + this->content_.reset (new text_content_type (s)); + } + + template <typename C, typename B> + inline simple_type<C, B>:: + simple_type (const std::basic_string<C>& s) { + this->content_.reset (new text_content_type (s)); + } + + template <typename C, typename B> + inline const std::basic_string<C>& simple_type<C, B>:: + text_content () const + { + const content_type* c (this->content_.get ()); + + if (c == 0) + { + this->content_.reset (new text_content_type); + c = this->content_.get (); + } + + // Accessing non-text content via the text API. + // + assert (dynamic_cast<const text_content_type*> (c) != 0); + + return static_cast<const text_content_type*> (c)->text; + } + + template <typename C, typename B> + inline std::basic_string<C>& simple_type<C, B>:: + text_content () + { + content_type* c (this->content_.get ()); + + if (c == 0) + { + this->content_.reset (new text_content_type); + c = this->content_.get (); + } + + // Accessing non-text content via the text API. + // + assert (dynamic_cast<text_content_type*> (c) != 0); + + return static_cast<text_content_type*> (c)->text; + } + + template <typename C, typename B> + inline void simple_type<C, B>:: + text_content (const std::basic_string<C>& t) + { + content_type* c (this->content_.get ()); + + if (c == 0) + this->content_.reset (new text_content_type (t)); + else + { + // Accessing non-text content via the text API. + // + assert (dynamic_cast<text_content_type*> (c) != 0); + static_cast<text_content_type*> (c)->text = t; + } } } } diff --git a/libxsd/xsd/cxx/tree/elements.txx b/libxsd/xsd/cxx/tree/elements.txx index 7389a86..4a8ca6e 100644 --- a/libxsd/xsd/cxx/tree/elements.txx +++ b/libxsd/xsd/cxx/tree/elements.txx @@ -27,8 +27,8 @@ namespace xsd // simple_type // - template <typename B> - simple_type<B>:: + template <typename C, typename B> + simple_type<C, B>:: simple_type (const simple_type& other, flags f, container* c) @@ -36,8 +36,8 @@ namespace xsd { } - template <typename B> - simple_type<B>* simple_type<B>:: + template <typename C, typename B> + simple_type<C, B>* simple_type<C, B>:: _clone (flags f, container* c) const { return new simple_type (*this, f, c); diff --git a/libxsd/xsd/cxx/tree/iterator-adapter.hxx b/libxsd/xsd/cxx/tree/iterator-adapter.hxx new file mode 100644 index 0000000..0a54604 --- /dev/null +++ b/libxsd/xsd/cxx/tree/iterator-adapter.hxx @@ -0,0 +1,270 @@ +// file : xsd/cxx/tree/iterator-adapter.hxx +// copyright : Copyright (c) 2005-2014 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_TREE_ITERATOR_ADAPTER_HXX +#define XSD_CXX_TREE_ITERATOR_ADAPTER_HXX + +#include <cstddef> // std::ptrdiff_t +#include <iterator> // std::iterator_traits + +namespace xsd +{ + namespace cxx + { + namespace tree + { + // Sun CC's <iterator> does not have iterator_traits. To overcome + // this, we will wrap std::iterator_traits into our own and also + // specialize it for pointer types. Since Sun CC uses pointer + // for vector::iterator, it will use the specialization and won't + // notice the std::iterator_traits. + // +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC + template <typename I> + struct iterator_traits + { + typedef + typename std::iterator_traits<I>::iterator_category + iterator_category; + + typedef + typename std::iterator_traits<I>::value_type + value_type; + + typedef + typename std::iterator_traits<I>::difference_type + difference_type; + }; +#else + // The Pointer specialization does not work for reverse and + // set iterators. But these iterators are user-dfined types + // and have suitable typedefs that we can use. + // + template <typename I> + struct iterator_traits + { + typedef typename I::iterator_category iterator_category; + typedef typename I::value_type value_type; + typedef typename I::difference_type difference_type; + }; + + template <typename T> + struct iterator_traits<T*> + { + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef std::ptrdiff_t difference_type; + }; +#endif + + // Iterator adapter for complex types. It expects I to point to + // a smart pointer-like object that has operator*() that returns + // a refernce to a type static_cast'able to T and get() that + // returns a pointer to a type static_cast'able to T. + // + + template <typename I, typename T> + struct iterator_adapter + { + typedef T value_type; + typedef value_type& reference; + typedef value_type* pointer; + + typedef + typename iterator_traits<I>::iterator_category + iterator_category; + + typedef + typename iterator_traits<I>::difference_type + difference_type; + + + public: + iterator_adapter () + : i_ () // i_ can be of a pointer type. + { + } + + // Allow iterator to const_iterator conversion. + // + template <typename J, typename T2> + iterator_adapter (const iterator_adapter<J, T2>& j) + : i_ (j.base ()) + { + } + + explicit + iterator_adapter (const I& i) + : i_ (i) + { + } + + public: + // Forward iterator requirements. + // + reference + operator* () const + { + return static_cast<reference> (**i_); + } + + pointer + operator-> () const + { + return static_cast<pointer> (i_->get ()); + } + + iterator_adapter& + operator++ () + { + ++i_; + return *this; + } + + iterator_adapter + operator++ (int) + { + iterator_adapter r (*this); + ++i_; + return r; + } + + // Bidirectional iterator requirements. + // + iterator_adapter& + operator-- () + { + --i_; + return *this; + } + + iterator_adapter + operator-- (int) + { + iterator_adapter r (*this); + --i_; + return r; + } + + // Random access iterator requirements. + // + reference + operator[] (difference_type n) const + { + return static_cast<reference> (*(i_[n])); + } + + iterator_adapter& + operator+= (difference_type n) + { + i_ += n; + return *this; + } + + iterator_adapter + operator+ (difference_type n) const + { + return iterator_adapter (i_ + n); + } + + iterator_adapter& + operator-= (difference_type n) + { + i_ -= n; + return *this; + } + + iterator_adapter + operator- (difference_type n) const + { + return iterator_adapter (i_ - n); + } + + public: + const I& + base () const + { + return i_; + } + + private: + I i_; + }; + + // Note: We use different types for left- and right-hand-side + // arguments to allow comparison between iterator and const_iterator. + // + + // Forward iterator requirements. + // + template <typename I, typename J, typename T1, typename T2> + inline bool + operator== (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () == j.base (); + } + + template <typename I, typename J, typename T1, typename T2> + inline bool + operator!= (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () != j.base (); + } + + // Random access iterator requirements + // + template <typename I, typename J, typename T1, typename T2> + inline bool + operator< (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () < j.base (); + } + + template <typename I, typename J, typename T1, typename T2> + inline bool + operator> (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () > j.base (); + } + + template <typename I, typename J, typename T1, typename T2> + inline bool + operator<= (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () <= j.base (); + } + + template <typename I, typename J, typename T1, typename T2> + inline bool + operator>= (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () >= j.base (); + } + + template <typename I, typename J, typename T1, typename T2> + inline typename iterator_adapter<I, T1>::difference_type + operator- (const iterator_adapter<I, T1>& i, + const iterator_adapter<J, T2>& j) + { + return i.base () - j.base (); + } + + template <typename I, typename T> + inline iterator_adapter<I, T> + operator+ (typename iterator_adapter<I, T>::difference_type n, + const iterator_adapter<I, T>& i) + { + return iterator_adapter<I, T> (i.base () + n); + } + } + } +} + +#endif // XSD_CXX_TREE_ITERATOR_ADAPTER_HXX diff --git a/libxsd/xsd/cxx/tree/list.hxx b/libxsd/xsd/cxx/tree/list.hxx index 2b3b71e..d1fe907 100644 --- a/libxsd/xsd/cxx/tree/list.hxx +++ b/libxsd/xsd/cxx/tree/list.hxx @@ -10,7 +10,7 @@ #include <xercesc/dom/DOMAttr.hpp> #include <xercesc/dom/DOMElement.hpp> -#include <xsd/cxx/tree/elements.hxx> // tree::istream +#include <xsd/cxx/tree/elements.hxx> #include <xsd/cxx/tree/istream-fwd.hxx> // tree::istream #include <xsd/cxx/tree/containers.hxx> // fundamental_p, sequence diff --git a/libxsd/xsd/cxx/tree/parsing.txx b/libxsd/xsd/cxx/tree/parsing.txx index 628b7fd..02aeda1 100644 --- a/libxsd/xsd/cxx/tree/parsing.txx +++ b/libxsd/xsd/cxx/tree/parsing.txx @@ -36,6 +36,9 @@ namespace xsd _type (const xercesc::DOMElement& e, flags f, container* c) : container_ (c) { + if (f & flags::extract_content) + content_.reset (new dom_content_type (e)); + if (f & flags::keep_dom) dom_info_ = dom_info_factory::create (e, *this, c == 0); } @@ -44,6 +47,8 @@ namespace xsd _type (const xercesc::DOMAttr& a, flags f, container* c) : container_ (c) { + // anyType cannot be an attribute type so no content extraction. + if (f & flags::keep_dom) dom_info_ = dom_info_factory::create (a, *this); } @@ -56,33 +61,41 @@ namespace xsd container* c) : container_ (c) // List elements don't have associated DOM nodes. { + // anyType cannot be a list element type so no content extraction. } // simple_type // - template <typename B> - inline simple_type<B>:: + template <typename C, typename B> + inline simple_type<C, B>:: simple_type (const xercesc::DOMElement& e, flags f, container* c) - : B (e, f, c) + : B (e, (f & ~flags::extract_content), c) { + if (f & flags::extract_content) + this->content_.reset ( + new text_content_type (tree::text_content<C> (e))); } - template <typename B> - inline simple_type<B>:: + template <typename C, typename B> + inline simple_type<C, B>:: simple_type (const xercesc::DOMAttr& a, flags f, container* c) - : B (a, f, c) + : B (a, (f & ~flags::extract_content), c) { + if (f & flags::extract_content) + this->content_.reset (new text_content_type ( + xml::transcode<C> (a.getValue ()))); } - template <typename B> - template <typename C> - inline simple_type<B>:: + template <typename C, typename B> + inline simple_type<C, B>:: simple_type (const std::basic_string<C>& s, const xercesc::DOMElement* e, flags f, container* c) - : B (s, e, f, c) + : B (s, e, (f & ~flags::extract_content), c) { + if (f & flags::extract_content) + this->content_.reset (new text_content_type (s)); } // fundamental_base @@ -161,7 +174,7 @@ namespace xsd } // Individual items of the list have no DOM association. Therefore - // I clear keep_dom from flags. + // we clear keep_dom from flags. // template <typename T, typename C, schema_type::value ST> @@ -203,7 +216,6 @@ namespace xsd return; using std::basic_string; - typedef typename sequence<T>::ptr ptr; typedef typename basic_string<C>::size_type size_type; const C* data (s.c_str ()); @@ -218,13 +230,12 @@ namespace xsd if (j != basic_string<C>::npos) { - ptr r ( - new T (basic_string<C> (data + i, j - i), - parent, - f, - this->container_)); - - this->v_.push_back (r); + this->push_back ( + traits<T, C, ST>::create ( + basic_string<C> (data + i, j - i), + parent, + f, + this->container_)); i = bits::find_ns (data, size, j); } @@ -232,13 +243,12 @@ namespace xsd { // Last element. // - ptr r ( - new T (basic_string<C> (data + i, size - i), - parent, - f, - this->container_)); - - this->v_.push_back (r); + this->push_back ( + traits<T, C, ST>::create ( + basic_string<C> (data + i, size - i), + parent, + f, + this->container_)); break; } diff --git a/libxsd/xsd/cxx/tree/serialization.txx b/libxsd/xsd/cxx/tree/serialization.txx index e6fea1f..055f603 100644 --- a/libxsd/xsd/cxx/tree/serialization.txx +++ b/libxsd/xsd/cxx/tree/serialization.txx @@ -91,9 +91,29 @@ namespace xsd // Insertion operators for type. // inline void - operator<< (xercesc::DOMElement& e, const type&) + operator<< (xercesc::DOMElement& e, const type& x) { xml::dom::clear<char> (e); + + if (!x.null_content () && x.dom_content ().present ()) + { + // Clone the contents of the element. + // + using namespace xercesc; + + DOMDocument& doc (*e.getOwnerDocument ()); + const DOMElement& se (x.dom_content ().get ()); + DOMNamedNodeMap& sa (*se.getAttributes ()); + + for (XMLSize_t i (0), n (sa.getLength ()); i != n; ++i) + e.setAttributeNode ( + static_cast<DOMAttr*> (doc.importNode (sa.item (i), true))); + + for (DOMNode* sn (se.getFirstChild ()); + sn != 0; + sn = sn->getNextSibling ()) + e.appendChild (doc.importNode (sn, true)); + } } inline void @@ -109,23 +129,30 @@ namespace xsd // Insertion operators for simple_type. // - template <typename B> + template <typename C, typename B> inline void - operator<< (xercesc::DOMElement& e, const simple_type<B>&) + operator<< (xercesc::DOMElement& e, const simple_type<C, B>& x) { - xml::dom::clear<char> (e); + if (x.null_content ()) + xml::dom::clear<char> (e); + else + e << x.text_content (); } - template <typename B> + template <typename C, typename B> inline void - operator<< (xercesc::DOMAttr&, const simple_type<B>&) + operator<< (xercesc::DOMAttr& a, const simple_type<C, B>& x) { + if (!x.null_content ()) + a << x.text_content (); } template <typename C, typename B> inline void - operator<< (list_stream<C>&, const simple_type<B>&) + operator<< (list_stream<C>& ls, const simple_type<C, B>& x) { + if (!x.null_content ()) + ls << x.text_content (); } // Insertion operators for list. diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.txx b/libxsd/xsd/cxx/tree/std-ostream-map.txx index c79cdb6..ef65ef2 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-map.txx +++ b/libxsd/xsd/cxx/tree/std-ostream-map.txx @@ -24,7 +24,7 @@ namespace xsd &inserter_impl<C, type>, false); - typedef simple_type<type> simple_type; + typedef simple_type<C, type> simple_type; register_type ( typeid (simple_type), &inserter_impl<C, simple_type>, diff --git a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx index 071d186..9a8f976 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx +++ b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx @@ -24,6 +24,7 @@ namespace xsd inline std::basic_ostream<C>& operator<< (std::basic_ostream<C>& os, const type&) { + // Not printing DOM content even if it's there. return os; } @@ -32,8 +33,11 @@ namespace xsd // template <typename C, typename B> inline std::basic_ostream<C>& - operator<< (std::basic_ostream<C>& os, const simple_type<B>&) + operator<< (std::basic_ostream<C>& os, const simple_type<C, B>& x) { + if (!x.null_content ()) + os << x.text_content (); + return os; } diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.txx b/libxsd/xsd/cxx/tree/stream-extraction-map.txx index 646ef83..61dd306 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction-map.txx +++ b/libxsd/xsd/cxx/tree/stream-extraction-map.txx @@ -30,7 +30,7 @@ namespace xsd &extractor_impl<S, type>, false); - typedef simple_type<type> simple_type; + typedef simple_type<C, type> simple_type; register_type ( qualified_name (bits::any_simple_type<C> (), xsd), &extractor_impl<S, simple_type>, diff --git a/libxsd/xsd/cxx/tree/stream-extraction.hxx b/libxsd/xsd/cxx/tree/stream-extraction.hxx index b55afa0..ee39bcc 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction.hxx +++ b/libxsd/xsd/cxx/tree/stream-extraction.hxx @@ -28,12 +28,18 @@ namespace xsd // simple_type // - template <typename B> + template <typename C, typename B> template <typename S> - inline simple_type<B>:: + inline simple_type<C, B>:: simple_type (istream<S>& s, flags f, container* c) - : type (s, f, c) + : type (s, f & ~flags::extract_content, c) { + if (f & flags::extract_content) + { + std::basic_string<C> t; + s >> t; + this->content_.reset (new text_content_type (t)); + } } // fundamental_base @@ -65,9 +71,7 @@ namespace xsd this->reserve (size); while (size--) - { - this->push_back (XSD_AUTO_PTR<T> (new T (s, f, c))); - } + this->push_back (traits<T, C, ST>::create (s, f, c)); } } diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.txx b/libxsd/xsd/cxx/tree/stream-insertion-map.txx index 1550826..78fbacb 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion-map.txx +++ b/libxsd/xsd/cxx/tree/stream-insertion-map.txx @@ -31,7 +31,7 @@ namespace xsd &inserter_impl<S, type>, false); - typedef simple_type<type> simple_type; + typedef simple_type<C, type> simple_type; register_type ( typeid (simple_type), qualified_name (bits::any_simple_type<C> (), xsd), diff --git a/libxsd/xsd/cxx/tree/stream-insertion.hxx b/libxsd/xsd/cxx/tree/stream-insertion.hxx index 7f1f5df..b04846f 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion.hxx +++ b/libxsd/xsd/cxx/tree/stream-insertion.hxx @@ -23,15 +23,19 @@ namespace xsd inline ostream<S>& operator<< (ostream<S>& s, const type&) { + // Not saving DOM content even if it's there. return s; } // simple_type // - template <typename S, typename B> + template <typename S, typename C, typename B> inline ostream<S>& - operator<< (ostream<S>& s, const simple_type<B>&) + operator<< (ostream<S>& s, const simple_type<C, B>& x) { + if (!x.null_content ()) + s << x.text_content (); + return s; } diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx index 8ccbc63..e1fe0cc 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.txx +++ b/libxsd/xsd/cxx/tree/type-factory-map.txx @@ -37,7 +37,7 @@ namespace xsd &factory_impl<type>, false); - typedef simple_type<type> simple_type; + typedef simple_type<C, type> simple_type; register_type ( qualified_name (bits::any_simple_type<C> (), xsd), &factory_impl<simple_type>, diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.txx b/libxsd/xsd/cxx/tree/type-serializer-map.txx index 353ccae..dd47a00 100644 --- a/libxsd/xsd/cxx/tree/type-serializer-map.txx +++ b/libxsd/xsd/cxx/tree/type-serializer-map.txx @@ -38,7 +38,7 @@ namespace xsd &serializer_impl<type>, false); - typedef simple_type<type> simple_type; + typedef simple_type<C, type> simple_type; register_type ( typeid (simple_type), qualified_name (bits::any_simple_type<C> (), xsd), diff --git a/libxsd/xsd/cxx/tree/types.hxx b/libxsd/xsd/cxx/tree/types.hxx index 61a1e1a..288a291 100644 --- a/libxsd/xsd/cxx/tree/types.hxx +++ b/libxsd/xsd/cxx/tree/types.hxx @@ -271,6 +271,29 @@ namespace xsd } }; + /** + * @brief %string comparison operator. + * + * @return True if the strings are equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator== (const string<C, B>& a, const string<C, B>& b) + { + return static_cast<const std::basic_string<C>&> (a) == b; + } + + /** + * @brief %string comparison operator. + * + * @return True if the strings are not equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator!= (const string<C, B>& a, const string<C, B>& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema normalizedString @@ -1119,6 +1142,31 @@ namespace xsd //@} }; + /** + * @brief %nmtokens comparison operator. + * + * @return True if the lists of nmtokens are equal, false otherwise. + */ + template <typename C, typename B, typename nmtoken> + inline bool + operator== (const nmtokens<C, B, nmtoken>& a, + const nmtokens<C, B, nmtoken>& b) + { + return static_cast<const list<nmtoken, C>&> (a) == b; + } + + /** + * @brief %nmtokens comparison operator. + * + * @return True if the lists of nmtokens are not equal, false otherwise. + */ + template <typename C, typename B, typename nmtoken> + inline bool + operator!= (const nmtokens<C, B, nmtoken>& a, + const nmtokens<C, B, nmtoken>& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema Name built-in @@ -2575,6 +2623,29 @@ namespace xsd //@} }; + /** + * @brief %idrefs comparison operator. + * + * @return True if the lists of idrefs are equal, false otherwise. + */ + template <typename C, typename B, typename idref> + inline bool + operator== (const idrefs<C, B, idref>& a, const idrefs<C, B, idref>& b) + { + return static_cast<const list<idref, C>&> (a) == b; + } + + /** + * @brief %idrefs comparison operator. + * + * @return True if the lists of idrefs are not equal, false otherwise. + */ + template <typename C, typename B, typename idref> + inline bool + operator!= (const idrefs<C, B, idref>& a, const idrefs<C, B, idref>& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema anyURI built-in @@ -2811,6 +2882,29 @@ namespace xsd friend class qname; }; + /** + * @brief %uri comparison operator. + * + * @return True if the uris are equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator== (const uri<C, B>& a, const uri<C, B>& b) + { + return static_cast<const std::basic_string<C>&> (a) == b; + } + + /** + * @brief %uri comparison operator. + * + * @return True if the uris are not equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator!= (const uri<C, B>& a, const uri<C, B>& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema QName built-in @@ -3211,6 +3305,29 @@ namespace xsd decode (const XMLCh*); }; + /** + * @brief %base64_binary comparison operator. + * + * @return True if the binaries are equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator== (const base64_binary<C, B>& a, const base64_binary<C, B>& b) + { + return static_cast<const buffer<C>&> (a) == b; + } + + /** + * @brief %base64_binary comparison operator. + * + * @return True if the binaries are not equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator!= (const base64_binary<C, B>& a, const base64_binary<C, B>& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema hexBinary @@ -3404,6 +3521,29 @@ namespace xsd decode (const XMLCh*); }; + /** + * @brief %hex_binary comparison operator. + * + * @return True if the binaries are equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator== (const hex_binary<C, B>& a, const hex_binary<C, B>& b) + { + return static_cast<const buffer<C>&> (a) == b; + } + + /** + * @brief %hex_binary comparison operator. + * + * @return True if the binaries are not equal, false otherwise. + */ + template <typename C, typename B> + inline bool + operator!= (const hex_binary<C, B>& a, const hex_binary<C, B>& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema ENTITY built-in @@ -3768,6 +3908,32 @@ namespace xsd container* c = 0); //@} }; + + /** + * @brief %entities comparison operator. + * + * @return True if the lists of entities are equal, false otherwise. + */ + template <typename C, typename B, typename entity> + inline bool + operator== (const entities<C, B, entity>& a, + const entities<C, B, entity>& b) + { + return static_cast<const list<entity, C>&> (a) == b; + } + + /** + * @brief %entities comparison operator. + * + * @return True if the lists of entities are not equal, false otherwise. + */ + template <typename C, typename B, typename entity> + inline bool + operator!= (const entities<C, B, entity>& a, + const entities<C, B, entity>& b) + { + return !(a == b); + } } } } diff --git a/libxsd/xsd/cxx/xml/string.hxx b/libxsd/xsd/cxx/xml/string.hxx index dbc78b4..9f4767b 100644 --- a/libxsd/xsd/cxx/xml/string.hxx +++ b/libxsd/xsd/cxx/xml/string.hxx @@ -56,21 +56,16 @@ namespace xsd public : template <typename C> string (const std::basic_string<C>& s) - : s_ (transcode_to_xmlch<C> (s)) - { - } + : s_ (transcode_to_xmlch<C> (s)) {} template <typename C> - string (const C* s) - : s_ (transcode_to_xmlch<C> (s)) - { - } + string (const C* s): s_ (transcode_to_xmlch<C> (s)) {} const XMLCh* - c_str () const - { - return s_.get (); - } + c_str () const {return s_.get ();} + + XMLCh* + release () {return s_.release ();} private: string (const string&); diff --git a/tests/cxx/tree/any-type/driver.cxx b/tests/cxx/tree/any-type/driver.cxx new file mode 100644 index 0000000..1ac5274 --- /dev/null +++ b/tests/cxx/tree/any-type/driver.cxx @@ -0,0 +1,145 @@ +// file : tests/cxx/tree/any-type/driver.cxx +// copyright : Copyright (c) 2006-2014 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Test anyType and anySimpleType content extraction. +// + +#include <memory> // std::auto_ptr/unique_ptr +#include <utility> // std::move +#include <sstream> +#include <iostream> + +#include <xercesc/dom/DOM.hpp> +#include <xercesc/util/PlatformUtils.hpp> + +#include "test.hxx" // Get XSD_CXX11 defined. + +#include <xsd/cxx/xml/string.hxx> + +using namespace std; +using namespace test; +using namespace xercesc; + +namespace xml = xsd::cxx::xml; + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " test.xml" << endl; + return 1; + } + + XMLPlatformUtils::Initialize (); + + try + { + // Test parsing + // + XSD_AUTO_PTR<type> r (root (argv[1])); + + // Test API. + // + { + assert (type::a_default_value ().text_content () == "default value"); + } + + { + xml_schema::simple_type x ("fox"); + assert (x.text_content () == "fox"); + x.text_content ("foo"); + assert (x.text_content () == "foo"); + x.text_content ().clear (); + assert (x.text_content () == ""); + x.text_content () = "baz"; + r->s ().push_back (x); + } + + { + xml_schema::type x; + + DOMDocument& doc (x.dom_content_document ()); + + // Copy. + // + DOMElement* e (doc.createElement (xml::string ("dummy").c_str ())); + e->setAttribute (xml::string ("x").c_str (), + xml::string ("foo").c_str ()); + e->setTextContent (xml::string ("data").c_str ()); + x.dom_content ().set (*e); + e->release (); + + r->t ().push_back (x); + } + + { + XSD_AUTO_PTR<xml_schema::type> x (new xml_schema::type); + + DOMDocument& doc (x->dom_content_document ()); + + // Assume ownership. + // + DOMElement* e (doc.createElement (xml::string ("dummy").c_str ())); + e->setAttribute (xml::string ("x").c_str (), + xml::string ("foo").c_str ()); + e->setTextContent (xml::string ("data").c_str ()); + x->dom_content ().set (e); + +#ifdef XSD_CXX11 + r->t ().push_back (std::move (x)); +#else + r->t ().push_back (x); +#endif + } + + // Test printing. + // + cout << *r << endl + << endl; + + // Test serialization. + // + xml_schema::namespace_infomap map; + + map["t"].name = "test"; + map["t"].schema = "test.xsd"; + map["o"].name = "other"; + + stringstream iostr; + root (iostr, *r, map); + + cout << iostr.str () << endl + << endl; + + { + XSD_AUTO_PTR<type> r1 (root (iostr, argv[1])); + + // Xerces-C++ mis-indentation of mixed content messes this up. + // assert (*r == *r); + + stringstream iostr; + root (iostr, *r1, map); + + cout << iostr.str () << endl + << endl; + } + + // Test comparison. + // + assert (*r == *r); + + // Test copy c-tor. + // + type copy (*r); + assert (copy == *r); + } + catch (xml_schema::exception const& e) + { + cerr << e << endl; + return 1; + } + + XMLPlatformUtils::Terminate (); +} diff --git a/tests/cxx/tree/any-type/makefile b/tests/cxx/tree/any-type/makefile new file mode 100644 index 0000000..1d0590f --- /dev/null +++ b/tests/cxx/tree/any-type/makefile @@ -0,0 +1,87 @@ +# file : tests/cxx/tree/any-type/makefile +# copyright : Copyright (c) 2006-2014 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$(out_base) -I$(src_base) -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-any-type --generate-serialization \ +--generate-ostream --generate-comparison +$(gen): $(out_root)/xsd/xsd + +$(call include-dep,$(dep),$(obj),$(gen)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Test. +# +$(test): driver := $(driver) +$(test): $(driver) $(src_base)/test.xml $(src_base)/output + $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(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,$(bld_root)/cxx/standard.make) # cxx_standard +ifdef cxx_standard +$(gen): xsd_options += --std $(cxx_standard) +$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) +endif + + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile) diff --git a/tests/cxx/tree/any-type/output b/tests/cxx/tree/any-type/output new file mode 100644 index 0000000..580e7db --- /dev/null +++ b/tests/cxx/tree/any-type/output @@ -0,0 +1,73 @@ + +t: +t: +t: +t: +t: +t: +t: +t: +s: +s: simple +s: baz +l: one two three +a: any simple content + +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<t:root xmlns:t="test" a="any simple content" xmlns:o="other" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test test.xsd"> + <t/> + <t x="x"/> + <t>any</t> + <t x="x">any</t> + <t o:y="y" x="x"> + <n1> + <n2>nested 1</n2> + <n2>nested 2</n2> + </n1> + <o:n2 o:x="x">more</o:n2> + </t><t x="x"> + <n1>mi + <n2>nested 1</n2>x + <n2>nested 2</n2>ed + </n1>content + </t> + <t x="foo">data</t> + <t x="foo">data</t> + <s/> + <s>simple</s> + <s>baz</s> + <l>one two three</l> +</t:root> + + +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<t:root xmlns:t="test" a="any simple content" xmlns:o="other" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test test.xsd"> + <t/> + <t x="x"/> + <t>any</t> + <t x="x">any</t> + <t o:y="y" x="x"> + <n1> + <n2>nested 1</n2> + <n2>nested 2</n2> + </n1> + <o:n2 o:x="x">more</o:n2> + </t><t x="x"> + <n1>mi + + <n2>nested 1</n2>x + + <n2>nested 2</n2>ed + + </n1>content + + </t> + <t x="foo">data</t> + <t x="foo">data</t> + <s/> + <s>simple</s> + <s>baz</s> + <l>one two three</l> +</t:root> + + diff --git a/tests/cxx/tree/any-type/test.xml b/tests/cxx/tree/any-type/test.xml new file mode 100644 index 0000000..7c9035a --- /dev/null +++ b/tests/cxx/tree/any-type/test.xml @@ -0,0 +1,26 @@ +<t:root xmlns:t="test" + xmlns:o="other" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="test test.xsd" + + a="any simple content"> + + <t/> + <t x="x"/> + <t>any</t> + <t x="x">any</t> + <t x="x" o:y="y"> + <n1> + <n2>nested 1</n2> + <n2>nested 2</n2> + </n1> + <o:n2 o:x="x">more</o:n2> + </t> + <t x="x"><n1>mi<n2>nested 1</n2>x<n2>nested 2</n2>ed</n1>content</t> + + <s/> + <s>simple</s> + + <l>one two three</l> + +</t:root> diff --git a/tests/cxx/tree/any-type/test.xsd b/tests/cxx/tree/any-type/test.xsd new file mode 100644 index 0000000..37dcc8d --- /dev/null +++ b/tests/cxx/tree/any-type/test.xsd @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test"> + + <simpleType name="any-list"> + <!--Not allowed? list itemType="anySimpleType"/--> + <list itemType="string"/> + </simpleType> + + <complexType name="type"> + <sequence> + <element name="t" type="anyType" maxOccurs="unbounded"/> + <element name="s" type="anySimpleType" maxOccurs="unbounded"/> + <element name="l" type="t:any-list" maxOccurs="unbounded"/> + </sequence> + <attribute name="a" type="anySimpleType" default="default value"/> + </complexType> + + <element name="root" type="t:type"/> +</schema> diff --git a/tests/cxx/tree/binary/cdr/driver.cxx b/tests/cxx/tree/binary/cdr/driver.cxx index 65c88fa..a2d7195 100644 --- a/tests/cxx/tree/binary/cdr/driver.cxx +++ b/tests/cxx/tree/binary/cdr/driver.cxx @@ -127,6 +127,14 @@ main (int argc, char* argv[]) assert (r->time () == c->time ()); assert (r->date_time () == c->date_time ()); assert (r->duration () == c->duration ()); + + // anySimpleType + // + assert (!r->any_simple_type_attr ().text_content ().empty ()); + assert (r->any_simple_type_attr () == c->any_simple_type_attr ()); + + assert (!r->any_simple_type ().text_content ().empty ()); + assert (r->any_simple_type () == c->any_simple_type ()); } catch (xml_schema::exception const& e) { diff --git a/tests/cxx/tree/binary/cdr/makefile b/tests/cxx/tree/binary/cdr/makefile index 9613841..eb80d35 100644 --- a/tests/cxx/tree/binary/cdr/makefile +++ b/tests/cxx/tree/binary/cdr/makefile @@ -37,7 +37,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): xsd := $(out_root)/xsd/xsd $(gen): xsd_options += --generate-insertion ACE_OutputCDR \ ---generate-extraction ACE_InputCDR +--generate-extraction ACE_InputCDR --generate-comparison $(gen): $(out_root)/xsd/xsd $(call include-dep,$(dep),$(obj),$(gen)) diff --git a/tests/cxx/tree/binary/cdr/test.xml b/tests/cxx/tree/binary/cdr/test.xml index 928b4cf..5cedd98 100644 --- a/tests/cxx/tree/binary/cdr/test.xml +++ b/tests/cxx/tree/binary/cdr/test.xml @@ -1,6 +1,7 @@ <t:root xmlns:t="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="test test.xsd"> + xsi:schemaLocation="test test.xsd" + any_simple_type_attr="any simple content"> <list>1 2 3</list> @@ -87,5 +88,6 @@ <year_month>2001-11+02:00</year_month> <time>21:32:52+02:00</time> + <any_simple_type>any simple content in element</any_simple_type> </t:root> diff --git a/tests/cxx/tree/binary/cdr/test.xsd b/tests/cxx/tree/binary/cdr/test.xsd index e593f64..0629e94 100644 --- a/tests/cxx/tree/binary/cdr/test.xsd +++ b/tests/cxx/tree/binary/cdr/test.xsd @@ -112,7 +112,10 @@ <element name="year" type="gYear"/> <element name="year_month" type="gYearMonth"/> <element name="time" type="time"/> + + <element name="any_simple_type" type="anySimpleType"/> </sequence> + <attribute name="any_simple_type_attr" type="anySimpleType" use="required"/> </complexType> <element name="root" type="t:type"/> diff --git a/tests/cxx/tree/binary/polymorphic/makefile b/tests/cxx/tree/binary/polymorphic/makefile index f9ddf67..05c5186 100644 --- a/tests/cxx/tree/binary/polymorphic/makefile +++ b/tests/cxx/tree/binary/polymorphic/makefile @@ -37,7 +37,8 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): xsd := $(out_root)/xsd/xsd $(gen): xsd_options += --generate-polymorphic --root-element-last \ ---generate-insertion ACE_OutputCDR --generate-extraction ACE_InputCDR +--generate-insertion ACE_OutputCDR --generate-extraction ACE_InputCDR \ + --generate-comparison $(gen): $(out_root)/xsd/xsd $(call include-dep,$(dep),$(obj),$(gen)) diff --git a/tests/cxx/tree/binary/xdr/driver.cxx b/tests/cxx/tree/binary/xdr/driver.cxx index ddc196d..623a953 100644 --- a/tests/cxx/tree/binary/xdr/driver.cxx +++ b/tests/cxx/tree/binary/xdr/driver.cxx @@ -171,6 +171,14 @@ main (int argc, char* argv[]) assert (r->year () == c->year ()); assert (r->year_month () == c->year_month ()); assert (r->time () == c->time ()); + + // anySimpleType + // + assert (!r->any_simple_type_attr ().text_content ().empty ()); + assert (r->any_simple_type_attr () == c->any_simple_type_attr ()); + + assert (!r->any_simple_type ().text_content ().empty ()); + assert (r->any_simple_type () == c->any_simple_type ()); } catch (xml_schema::exception const& e) { diff --git a/tests/cxx/tree/binary/xdr/makefile b/tests/cxx/tree/binary/xdr/makefile index 184c5d2..2994134 100644 --- a/tests/cxx/tree/binary/xdr/makefile +++ b/tests/cxx/tree/binary/xdr/makefile @@ -32,7 +32,8 @@ 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-insertion XDR --generate-extraction XDR +$(gen): xsd_options += --generate-insertion XDR --generate-extraction XDR \ +--generate-comparison $(gen): $(out_root)/xsd/xsd $(call include-dep,$(dep),$(obj),$(gen)) diff --git a/tests/cxx/tree/binary/xdr/test.xml b/tests/cxx/tree/binary/xdr/test.xml index 928b4cf..5cedd98 100644 --- a/tests/cxx/tree/binary/xdr/test.xml +++ b/tests/cxx/tree/binary/xdr/test.xml @@ -1,6 +1,7 @@ <t:root xmlns:t="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="test test.xsd"> + xsi:schemaLocation="test test.xsd" + any_simple_type_attr="any simple content"> <list>1 2 3</list> @@ -87,5 +88,6 @@ <year_month>2001-11+02:00</year_month> <time>21:32:52+02:00</time> + <any_simple_type>any simple content in element</any_simple_type> </t:root> diff --git a/tests/cxx/tree/binary/xdr/test.xsd b/tests/cxx/tree/binary/xdr/test.xsd index e593f64..0629e94 100644 --- a/tests/cxx/tree/binary/xdr/test.xsd +++ b/tests/cxx/tree/binary/xdr/test.xsd @@ -112,7 +112,10 @@ <element name="year" type="gYear"/> <element name="year_month" type="gYearMonth"/> <element name="time" type="time"/> + + <element name="any_simple_type" type="anySimpleType"/> </sequence> + <attribute name="any_simple_type_attr" type="anySimpleType" use="required"/> </complexType> <element name="root" type="t:type"/> diff --git a/tests/cxx/tree/compilation/driver.cxx b/tests/cxx/tree/compilation/driver.cxx index c396ec5..c2e6298 100644 --- a/tests/cxx/tree/compilation/driver.cxx +++ b/tests/cxx/tree/compilation/driver.cxx @@ -13,7 +13,7 @@ using namespace std; using namespace test; -template class xsd::cxx::tree::simple_type<xml_schema::type>; +template class xsd::cxx::tree::simple_type<char, xml_schema::type>; // String types. // diff --git a/tests/cxx/tree/makefile b/tests/cxx/tree/makefile index cd081e8..7fd9f63 100644 --- a/tests/cxx/tree/makefile +++ b/tests/cxx/tree/makefile @@ -5,6 +5,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make tests := \ +any-type \ built-in \ chameleon \ comparison \ diff --git a/xsd/cxx/tree/fundamental-header.hxx b/xsd/cxx/tree/fundamental-header.hxx index 1145c0c..925d65e 100644 --- a/xsd/cxx/tree/fundamental-header.hxx +++ b/xsd/cxx/tree/fundamental-header.hxx @@ -241,7 +241,7 @@ namespace CXX traverse (SemanticGraph::AnySimpleType& t) { simple_type_ = built_in_type ( - t, L"::xsd::cxx::tree::simple_type< ", type_); + t, L"::xsd::cxx::tree::simple_type< " + char_type + L", ", type_); if (doxygen) os << "/**" << endl diff --git a/xsd/cxx/tree/options.cli b/xsd/cxx/tree/options.cli index 026e4a1..f1b343a 100644 --- a/xsd/cxx/tree/options.cli +++ b/xsd/cxx/tree/options.cli @@ -170,6 +170,13 @@ namespace CXX this option." }; + bool --generate-any-type + { + "Extract and store content of the XML Schema \cb{anyType} type as a + DOM fragment. Note that you need to initialize the Xerces-C++ runtime + if you are using this option." + }; + NarrowStrings --generate-insertion { "<os>", diff --git a/xsd/cxx/tree/stream-extraction-source.cxx b/xsd/cxx/tree/stream-extraction-source.cxx index a1ca4bc..ceb56c1 100644 --- a/xsd/cxx/tree/stream-extraction-source.cxx +++ b/xsd/cxx/tree/stream-extraction-source.cxx @@ -321,6 +321,7 @@ namespace CXX SemanticGraph::Type& t (e.type ()); String type (etype (e)); + String tr (etraits (e)); // traits type name bool fund (false); { @@ -389,8 +390,8 @@ namespace CXX } else { - os << auto_ptr << "< " << type << " > r (new " << type << - " (s, f, this));"; + os << auto_ptr << "< " << type << " > r (" << endl + << tr << "::create (s, f, this));"; } os << "c.push_back (" << r << ");" @@ -438,8 +439,8 @@ namespace CXX } else { - os << auto_ptr << "< " << type << " > r (new " << type << - " (s, f, this));"; + os << auto_ptr << "< " << type << " > r (" << endl + << tr << "::create (s, f, this));"; } os << "this->" << member << ".set (" << r << ");" @@ -482,8 +483,8 @@ namespace CXX } else { - os << auto_ptr << "< " << type << " > r (new " << type << - " (s, f, this));"; + os << auto_ptr << "< " << type << " > r (" << endl + << tr << "::create (s, f, this));"; } os << "this->" << member << ".set (" << r << ");" @@ -507,6 +508,7 @@ namespace CXX { String const& member (emember (a)); String type (etype (a)); + String tr (etraits (a)); // traits type name bool fund (false); { @@ -530,8 +532,8 @@ namespace CXX } else { - os << "this->" << member << ".set (" << auto_ptr << "< " << - type << " > (new " << type << " (s, f, this)));"; + os << "this->" << member << ".set (" << tr << + "::create (s, f, this));"; } os << "}" // if (p) @@ -549,8 +551,8 @@ namespace CXX } else { - os << "this->" << member << ".set (" << auto_ptr << "< " << - type << " > (new " << type << " (s, f, this)));"; + os << "this->" << member << ".set (" << tr << + "::create (s, f, this));"; } os << "}"; diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx index e6c2411..f0c3560 100644 --- a/xsd/cxx/tree/tree-header.cxx +++ b/xsd/cxx/tree/tree-header.cxx @@ -291,6 +291,22 @@ namespace CXX << "~" << name << " ();"; os << "};"; + + // Comparison operators. + // + if (options.generate_comparison ()) + { + os << inst_exp + << "bool" << endl + << "operator== (const " << name << "&, const " << name << "&);" + << endl; + + os << inst_exp + << "bool" << endl + << "operator!= (const " << name << "&, const " << name << "&);" + << endl + << endl; + } } private: diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/cxx/tree/tree-inline.cxx index e6ed756..500ee73 100644 --- a/xsd/cxx/tree/tree-inline.cxx +++ b/xsd/cxx/tree/tree-inline.cxx @@ -82,6 +82,28 @@ namespace CXX << " " << base_type << " (o, f, this)" << "{" << "}"; + + // Comparison operators. + // + if (options.generate_comparison ()) + { + os << inl + << "bool" << endl + << "operator== (const " << name << "& x, " << + "const " << name << "& y)" + << "{" + << "const " << base_type << "& bx (x);" + << "return bx == y;" + << "}"; + + os << inl + << "bool" << endl + << "operator!= (const " << name << "& x, " << + "const " << name << "& y)" + << "{" + << "return !(x == y);" + << "}"; + } } private: diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx index 110cb25..9524463 100644 --- a/xsd/cxx/tree/tree-source.cxx +++ b/xsd/cxx/tree/tree-source.cxx @@ -756,7 +756,13 @@ namespace CXX if (!fund) { os << auto_ptr << "< " << type << " > r (" << endl - << tr << "::create (i, f, this));" + << tr << "::create (i, f"; + + if (t.is_a<SemanticGraph::AnyType> () && + options.generate_any_type ()) + os << " | " << flags_type << "::extract_content"; + + os << ", this));" << endl; } } |