summaryrefslogtreecommitdiff
path: root/libxsd/xsd/cxx/tree/elements.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libxsd/xsd/cxx/tree/elements.hxx')
-rw-r--r--libxsd/xsd/cxx/tree/elements.hxx1448
1 files changed, 1448 insertions, 0 deletions
diff --git a/libxsd/xsd/cxx/tree/elements.hxx b/libxsd/xsd/cxx/tree/elements.hxx
new file mode 100644
index 0000000..3334d5f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/elements.hxx
@@ -0,0 +1,1448 @@
+// file : xsd/cxx/tree/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+/**
+ * @file
+ *
+ * @brief Contains C++ class definitions for XML Schema anyType and
+ * anySimpleType types as well as supporting code.
+ *
+ * This is an internal header and is included by the generated code. You
+ * normally should not include it directly.
+ *
+ */
+
+#ifndef XSD_CXX_TREE_ELEMENTS_HXX
+#define XSD_CXX_TREE_ELEMENTS_HXX
+
+#include <map>
+#include <string>
+#include <memory> // std::auto_ptr
+#include <istream>
+#include <sstream>
+#include <cassert>
+
+#include <xercesc/dom/DOMNode.hpp>
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMNamedNodeMap.hpp>
+
+#include <xsd/cxx/xml/elements.hxx> // xml::properties
+#include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr
+
+#include <xsd/cxx/tree/facet.hxx>
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/istream-fwd.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ /**
+ * @brief C++/Tree mapping runtime namespace.
+ *
+ * This is an internal namespace and normally should not be referenced
+ * directly. Instead you should use the aliases for types in this
+ * namespaces that are created in the generated code.
+ *
+ */
+ namespace tree
+ {
+ /**
+ * @brief Parsing and %serialization %flags.
+ *
+ * Flags are used to modify the default behavior of %parsing and
+ * %serialization functions as well as %parsing constructors.
+ *
+ * @nosubgrouping
+ */
+ class flags
+ {
+ public:
+ /**
+ * @name Flag constants
+ */
+ //@{
+
+ /**
+ * @brief Keep DOM association in the resulting tree.
+ */
+ static const unsigned long keep_dom = 0x00000100UL;
+
+ /**
+ * @brief Assume ownership of the DOM document.
+ *
+ * This flag only makes sense together with the @c keep_dom
+ * flag in the call to the %parsing function with the
+ * @c dom::auto_ptr<DOMDocument> argument.
+ *
+ */
+ static const unsigned long own_dom = 0x00000200UL;
+
+ /**
+ * @brief Turn off XML Schema validation in the underlying XML
+ * parser.
+ */
+ static const unsigned long dont_validate = 0x00000400UL;
+
+ /**
+ * @brief Do not initialize the Xerces-C++ runtime.
+ */
+ static const unsigned long dont_initialize = 0x00000001UL;
+
+ /**
+ * @brief Do not write XML declaration during %serialization.
+ */
+ static const unsigned long no_xml_declaration = 0x00010000UL;
+
+ /**
+ * @brief Do not add extra spaces or new lines that make the
+ * resulting XML easier to read.
+ */
+ static const unsigned long dont_pretty_print = 0x00020000UL;
+
+ //@cond
+
+ // The following flags are for internal use.
+ //
+ static const unsigned long base = 0x01000000UL;
+
+ //@endcond
+
+ // Notes on flag blocks:
+ //
+ // 0x000000FF - common (applicable to both parsing and serialization)
+ // 0x0000FF00 - parsing (values aligned with XML parsing)
+ // 0x00FF0000 - serialization (values aligned with XML serialization)
+ // 0xFF000000 - internal
+
+ //@}
+
+ public:
+ /**
+ * @brief Initialize an instance with an integer value.
+ *
+ * @param x A %flags value as an integer.
+ */
+ flags (unsigned long x = 0)
+ : x_ (x)
+ {
+ }
+
+ /**
+ * @brief Convert an instance to an integer value.
+ *
+ * @return An integer %flags value.
+ */
+ operator unsigned long () const
+ {
+ return x_;
+ }
+
+ /**
+ * @brief Combine two %flags.
+ *
+ * @return A %flags object that is a combination of the arguments.
+ */
+ friend flags
+ operator| (const flags& a, const flags& b)
+ {
+ return flags (a.x_ | b.x_);
+ }
+
+ /**
+ * @brief Combine two %flags.
+ *
+ * @return A %flags object that is a combination of the arguments.
+ */
+ friend flags
+ operator| (const flags& a, unsigned long b)
+ {
+ return flags (a.x_ | b);
+ }
+
+ /**
+ * @brief Combine two %flags.
+ *
+ * @return A %flags object that is a combination of the arguments.
+ */
+ friend flags
+ operator| (unsigned long a, const flags& b)
+ {
+ return flags (a | b.x_);
+ }
+
+ private:
+ unsigned long x_;
+ };
+
+
+ // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for XML-
+ // related properties.
+ //
+ template <typename C>
+ class properties: public xml::properties<C>
+ {
+ };
+
+ //@cond
+
+ // DOM user data keys.
+ //
+ template <int dummy>
+ struct user_data_keys_template
+ {
+ // Back pointers to tree nodes.
+ //
+ static const XMLCh node[21];
+ };
+
+ typedef user_data_keys_template<0> user_data_keys;
+
+ // HP aCC3 complains about unresolved symbols without an explicit
+ // instantiation.
+ //
+#if defined(__HP_aCC) && __HP_aCC <= 39999
+ template struct user_data_keys_template<0>;
+#endif
+ //
+ //
+ struct identity
+ {
+ virtual
+ ~identity ()
+ {
+ }
+
+ identity ()
+ {
+ }
+
+ virtual bool
+ before (const identity&) const = 0;
+
+ virtual void
+ throw_duplicate_id () const = 0;
+
+ private:
+ identity (const identity&);
+
+ identity&
+ operator= (const identity&);
+ };
+
+ //@endcond
+
+
+ // anyType. VC++ has a name injection bug that makes it impossible
+ // to have a member with the same name as a base type. To address
+ // that we will have to choose some unique name for the definition
+ // and typedef it to 'type'.
+ //
+ class _type;
+
+ /**
+ * @brief Class corresponding to the XML Schema anyType built-in type.
+ *
+ */
+ typedef _type type;
+
+ /**
+ * @brief Container type.
+ *
+ */
+ typedef _type container;
+
+ /**
+ * @brief Class corresponding to the XML Schema anyType built-in type.
+ *
+ * This class is a base for every generated and built-in type in the
+ * C++/Tree mapping.
+ *
+ * @nosubgrouping
+ */
+ class _type
+ {
+ public:
+ virtual
+ ~_type ()
+ {
+ // Everything should have been unregistered by now.
+ //
+ assert (map_.get () == 0 || map_->size () == 0);
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ */
+ _type ()
+ : container_ (0)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ _type (const type& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual type*
+ _clone (flags f = 0, container* c = 0) const
+ {
+ return new type (*this, f, c);
+ }
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ _type (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ _type (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ _type (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename C>
+ _type (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ type&
+ operator= (const type& x)
+ {
+ while (&x == 0) /* unused */;
+ return *this;
+ }
+
+ // Container API.
+ //
+ public:
+ /**
+ * @brief Get a constant pointer to container, an object model
+ * node that contains this instance.
+ *
+ * @return A constant pointer to container, or 0 if this instance
+ * is not contained.
+ */
+ const container*
+ _container () const
+ {
+ return container_;
+ }
+
+ /**
+ * @brief Get a pointer to container, an object model node that
+ * contains this instance.
+ *
+ * @return A pointer to container, or 0 if this instance is not
+ * contained.
+ */
+ container*
+ _container ()
+ {
+ return container_;
+ }
+
+ /**
+ * @brief Set this instance's new container, an object model node
+ * that contains this instance.
+ *
+ * @param c A pointer to container.
+ */
+ virtual void
+ _container (container* c)
+ {
+ assert (container_ == 0);
+
+ if (c != 0)
+ {
+ if (map_.get () != 0)
+ {
+ // Propagate our IDs to the new container.
+ //
+ for (map::iterator i (map_->begin ()), e (map_->end ());
+ i != e; ++i)
+ {
+ c->_register_id (*i->first, i->second);
+ }
+ }
+
+ container_ = c;
+ }
+ }
+
+ /**
+ * @brief Get a constant pointer to object model's root node.
+ *
+ * @return A constant pointer to root node, or 0 if this instance
+ * is not contained.
+ */
+ const container*
+ _root () const
+ {
+ const container* r (container_);
+
+ for (const container* c (r); c != 0; c = c->container_)
+ r = c;
+
+ return r;
+ }
+
+ /**
+ * @brief Get a pointer to object model's root node.
+ *
+ * @return A pointer to root node, or 0 if this instance is not
+ * contained.
+ */
+ container*
+ _root ()
+ {
+ container* r (container_);
+
+ for (container* c (r); c != 0; c = c->container_)
+ r = c;
+
+ return r;
+ }
+
+ // DOM association.
+ //
+ public:
+ /**
+ * @brief Get a constant pointer to a DOM node associated with
+ * this object model node.
+ *
+ * @return A constant pointer to DOM node, or 0 if none associated.
+ */
+ const xercesc::DOMNode*
+ _node () const
+ {
+ return dom_info_.get () ? dom_info_->node() : 0;
+ }
+
+ /**
+ * @brief Get a pointer to a DOM node associated with this object
+ * model node.
+ *
+ * @return A pointer to DOM node, or 0 if none associated.
+ */
+ xercesc::DOMNode*
+ _node ()
+ {
+ return dom_info_.get () ? dom_info_->node () : 0;
+ }
+
+ /**
+ * @brief Exception indicating that a DOM node cannot be associated
+ * with an object model node.
+ */
+ class bad_dom_node_type: public std::exception //@@ Inherit exception.
+ {
+ public:
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ()
+ {
+ return "DOM node is not an attribute node or element node";
+ }
+ };
+
+ /**
+ * @brief Manually set a DOM node associated with this object
+ * model node.
+ *
+ * The DOM node should be a child of the parent's DOM node. If
+ * this object model node is a root of the tree, then it will
+ * assume the ownership of the whole DOM document to which this
+ * DOM node belongs.
+ *
+ * @param n A pointer to DOM node (should be either an element or
+ * an attribute).
+ */
+ void
+ _node (xercesc::DOMNode* n)
+ {
+ switch (n->getNodeType ())
+ {
+ case xercesc::DOMNode::ELEMENT_NODE:
+ {
+ if (container_ != 0)
+ {
+ // @@ Should be a throw.
+ //
+ assert (_root ()->_node () != 0);
+ assert (_root ()->_node ()->getOwnerDocument () ==
+ n->getOwnerDocument ());
+ }
+
+ std::auto_ptr<dom_info> r (
+ dom_info_factory::create (
+ *static_cast<xercesc::DOMElement*> (n),
+ *this,
+ container_ == 0));
+
+ dom_info_ = r;
+ break;
+ }
+ case xercesc::DOMNode::ATTRIBUTE_NODE:
+ {
+ //@@ Should be a throw.
+ //
+ assert (container_ != 0);
+ assert (_root ()->_node () != 0);
+ assert (_root ()->_node ()->getOwnerDocument () ==
+ n->getOwnerDocument ());
+
+ std::auto_ptr<dom_info> r (
+ dom_info_factory::create (
+ *static_cast<xercesc::DOMAttr*> (n),
+ *this));
+
+ dom_info_ = r;
+ break;
+ }
+ default:
+ {
+ throw bad_dom_node_type ();
+ }
+ }
+ }
+
+ public:
+ //@cond
+
+ void
+ _register_id (const identity& id, type* t)
+ {
+ if (map_.get () == 0)
+ map_.reset (new map);
+
+ // First register on our container. If there are any duplications,
+ // they will be detected by this call and we don't need to clean
+ // the map.
+ //
+ if (container_ != 0)
+ container_->_register_id (id, t);
+
+ if (!map_->insert (
+ std::pair<const identity*, type*> (&id, t)).second)
+ {
+ id.throw_duplicate_id ();
+ }
+ }
+
+ //@@ Does not inherit from exception.
+ //
+ struct not_registered: std::exception
+ {
+ virtual const char*
+ what () const throw ()
+ {
+ return "attempt to unregister non-existent id";
+ }
+ };
+
+ void
+ _unregister_id (const identity& id)
+ {
+ if (map_.get ())
+ {
+ map::iterator it (map_->find (&id));
+
+ if (it != map_->end ())
+ {
+ map_->erase (it);
+
+ if (container_ != 0)
+ container_->_unregister_id (id);
+
+ return;
+ }
+ }
+
+ throw not_registered ();
+ }
+
+ type*
+ _lookup_id (const identity& id) const
+ {
+ if (map_.get ())
+ {
+ map::const_iterator it (map_->find (&id));
+
+ if (it != map_->end ())
+ return it->second;
+ }
+
+ return 0;
+ }
+
+ //@endcond
+
+ private:
+ //@cond
+
+ struct dom_info
+ {
+ virtual
+ ~dom_info ()
+ {
+ }
+
+ dom_info ()
+ {
+ }
+
+ virtual std::auto_ptr<dom_info>
+ clone (type& tree_node, container*) const = 0;
+
+ virtual xercesc::DOMNode*
+ node () = 0;
+
+ private:
+ dom_info (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)
+ : doc_ (0), e_ (e)
+ {
+ e_.setUserData (user_data_keys::node, &n, 0);
+
+ if (root)
+ {
+ // The caller should have associated a dom::auto_ptr object
+ // that owns this document with the document node using the
+ // xml_schema::dom::tree_node_key key.
+ //
+ xml::dom::auto_ptr<xercesc::DOMDocument>* pd (
+ reinterpret_cast<xml::dom::auto_ptr<xercesc::DOMDocument>*> (
+ e.getOwnerDocument ()->getUserData (user_data_keys::node)));
+
+ assert (pd != 0);
+ assert (pd->get () == e.getOwnerDocument ());
+
+ doc_ = *pd; // Transfer ownership.
+ }
+ }
+
+ virtual std::auto_ptr<dom_info>
+ clone (type& tree_node, container* c) const
+ {
+ using std::auto_ptr;
+
+ // Check if we are a document root.
+ //
+ if (c == 0)
+ {
+ // We preserver DOM associations only in complete
+ // copies from root.
+ //
+ if (doc_.get () == 0)
+ return auto_ptr<dom_info> (0);
+
+ return auto_ptr<dom_info> (
+ new dom_element_info (*doc_, tree_node));
+ }
+
+ // Check if our container does not have DOM association (e.g.,
+ // because it wasn't a complete copy of the tree).
+ //
+ using xercesc::DOMNode;
+
+ DOMNode* cn (c->_node ());
+
+ if (cn == 0)
+ return auto_ptr<dom_info> (0);
+
+
+ // Now we are going to find the corresponding element in
+ // the new tree.
+ //
+ {
+ using xercesc::DOMElement;
+
+ DOMNode& pn (*e_.getParentNode ());
+ assert (pn.getNodeType () == DOMNode::ELEMENT_NODE);
+
+ DOMNode* sn (pn.getFirstChild ()); // Source.
+ DOMNode* dn (cn->getFirstChild ()); // Destination.
+
+ // We should have at least one child.
+ //
+ assert (sn != 0);
+
+ // Move in parallel until we get to the needed node.
+ //
+ for (; sn != 0 && !e_.isSameNode (sn);)
+ {
+ sn = sn->getNextSibling ();
+ dn = dn->getNextSibling ();
+ }
+
+ // e_ should be on the list.
+ //
+ assert (sn != 0);
+
+ assert (dn->getNodeType () == DOMNode::ELEMENT_NODE);
+
+ return auto_ptr<dom_info> (
+ new dom_element_info (static_cast<DOMElement&> (*dn),
+ tree_node,
+ false));
+ }
+ }
+
+ virtual xercesc::DOMNode*
+ node ()
+ {
+ return &e_;
+ }
+
+ private:
+ dom_element_info (const xercesc::DOMDocument& d, type& n)
+ : doc_ (static_cast<xercesc::DOMDocument*> (
+ d.cloneNode (true))),
+ e_ (*doc_->getDocumentElement ())
+ {
+ e_.setUserData (user_data_keys::node, &n, 0);
+ }
+
+ private:
+ xml::dom::auto_ptr<xercesc::DOMDocument> doc_;
+ xercesc::DOMElement& e_;
+ };
+
+
+ struct dom_attribute_info: public dom_info
+ {
+ dom_attribute_info (xercesc::DOMAttr& a, type& n)
+ : a_ (a)
+ {
+ a_.setUserData (user_data_keys::node, &n, 0);
+ }
+
+ virtual std::auto_ptr<dom_info>
+ clone (type& tree_node, container* c) const
+ {
+ using std::auto_ptr;
+
+ // Check if we are a document root.
+ //
+ if (c == 0)
+ {
+ // We preserver DOM associations only in complete
+ // copies from root.
+ //
+ return auto_ptr<dom_info> (0);
+ }
+
+ // Check if our container does not have DOM association (e.g.,
+ // because it wasn't a complete copy of the tree).
+ //
+ using xercesc::DOMNode;
+
+ DOMNode* cn (c->_node ());
+
+ if (cn == 0)
+ return auto_ptr<dom_info> (0);
+
+ // We are going to find the corresponding attribute in
+ // the new tree.
+ //
+ using xercesc::DOMAttr;
+ using xercesc::DOMElement;
+ using xercesc::DOMNamedNodeMap;
+
+ DOMElement& p (*a_.getOwnerElement ());
+ DOMNamedNodeMap& nl (*p.getAttributes ());
+
+ XMLSize_t size (nl.getLength ()), i (0);
+
+ // We should have at least one child.
+ //
+ assert (size != 0);
+
+ for ( ;i < size && !a_.isSameNode (nl.item (i)); ++i)/*noop*/;
+
+ // a_ should be in the list.
+ //
+ assert (i < size);
+
+ DOMNode& n (*cn->getAttributes ()->item (i));
+ assert (n.getNodeType () == DOMNode::ATTRIBUTE_NODE);
+
+ return auto_ptr<dom_info> (
+ new dom_attribute_info (static_cast<DOMAttr&> (n), tree_node));
+ }
+
+ virtual xercesc::DOMNode*
+ node ()
+ {
+ return &a_;
+ }
+
+ private:
+ xercesc::DOMAttr& a_;
+ };
+
+ // For Sun C++ 5.6.
+ //
+ struct dom_info_factory;
+ friend struct _type::dom_info_factory;
+
+ struct dom_info_factory
+ {
+ static std::auto_ptr<dom_info>
+ create (const xercesc::DOMElement& e, type& n, bool root)
+ {
+ return std::auto_ptr<dom_info> (
+ new dom_element_info (
+ const_cast<xercesc::DOMElement&> (e), n, root));
+ }
+
+ static std::auto_ptr<dom_info>
+ create (const xercesc::DOMAttr& a, type& n)
+ {
+ return std::auto_ptr<dom_info> (
+ new dom_attribute_info (
+ const_cast<xercesc::DOMAttr&> (a), n));
+ }
+ };
+
+ //@endcond
+
+ std::auto_ptr<dom_info> dom_info_;
+
+
+ // ID/IDREF map.
+ //
+ private:
+
+ //@cond
+
+ struct identity_comparator
+ {
+ bool operator () (const identity* x, const identity* y) const
+ {
+ return x->before (*y);
+ }
+ };
+
+ //@endcond
+
+ typedef
+ std::map<const identity*, type*, identity_comparator>
+ map;
+
+ std::auto_ptr<map> map_;
+
+ private:
+ container* container_;
+ };
+
+ inline _type::
+ _type (const type& x, flags, container* c)
+ : container_ (c)
+ {
+ if (x.dom_info_.get ())
+ {
+ std::auto_ptr<dom_info> r (x.dom_info_->clone (*this, c));
+ dom_info_ = r;
+ }
+ }
+
+
+ /**
+ * @brief Class corresponding to the XML Schema anySimpleType built-in
+ * type.
+ *
+ * @nosubgrouping
+ */
+ template <typename B>
+ class simple_type: public B
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ */
+ simple_type ()
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ simple_type (const simple_type& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual simple_type*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ simple_type (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ simple_type (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ simple_type (const xercesc::DOMAttr& a,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @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,
+ container* c = 0);
+ //@}
+ };
+
+
+ /**
+ * @brief Base class for element types.
+ *
+ * This class is a base for every generated element type.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename T>
+ class element_type
+ {
+ public:
+ virtual
+ ~element_type ()
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual element_type*
+ _clone (flags f = 0) const = 0;
+
+ /**
+ * @brief Return the element name.
+ *
+ * @return A read-only string reference containing the element
+ * name.
+ */
+ virtual const std::basic_string<C>&
+ _name () const = 0;
+
+ /**
+ * @brief Return the element namespace.
+ *
+ * @return A read-only string reference containing the element
+ * namespace. Empty string is returned if the element is
+ * unqualified.
+ */
+ virtual const std::basic_string<C>&
+ _namespace () const = 0;
+
+ /**
+ * @brief Return the element value.
+ *
+ * @return A pointer to the element value or 0 if the element
+ * is of a fundamental type.
+ */
+ virtual T*
+ _value () = 0;
+
+ /**
+ * @brief Return the element value.
+ *
+ * @return A read-only pointer to the element value or 0 if the
+ * element is of a fundamental type.
+ */
+ virtual const T*
+ _value () const = 0;
+ };
+
+
+ //@cond
+
+ // Extra schema type id to disambiguate certain cases where
+ // different XML Schema types (e.g., double and decimal) are
+ // mapped to the same fundamental C++ type (e.g., double).
+ //
+ struct schema_type
+ {
+ enum value
+ {
+ other,
+ double_,
+ decimal
+ };
+ };
+
+ //@endcond
+
+
+ //@cond
+ template <typename T,
+ typename C,
+ schema_type::value ST = schema_type::other>
+ struct traits
+ {
+ typedef T type;
+
+ static std::auto_ptr<T>
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return std::auto_ptr<T> (new T (e, f, c));
+ }
+
+ static std::auto_ptr<T>
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return std::auto_ptr<T> (new T (a, f, c));
+ }
+
+ static std::auto_ptr<T>
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ {
+ return std::auto_ptr<T> (new T (s, e, f, c));
+ }
+ };
+
+ //@endcond
+
+
+ /**
+ * @brief Class template that emulates inheritance from a
+ * fundamental C++ type.
+ *
+ * @nosubgrouping
+ */
+ template <typename T,
+ typename C,
+ typename B,
+ schema_type::value ST = schema_type::other>
+ class fundamental_base: public B
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ */
+ fundamental_base ()
+ : facet_table_ (0), x_ ()
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with an underlying type value.
+ *
+ * @param x An underlying type value.
+ */
+ fundamental_base (T x)
+ : facet_table_ (0), x_ (x)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ fundamental_base (const fundamental_base& x,
+ flags f = 0,
+ container* c = 0)
+ : B (x, f, c), facet_table_ (0), x_ (x.x_)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual fundamental_base*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ fundamental_base (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ fundamental_base (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ fundamental_base (const xercesc::DOMAttr& a,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ fundamental_base (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign an underlying type value to the instance.
+ *
+ * @param x An underlying type value.
+ * @return A reference to the instance.
+ */
+ fundamental_base&
+ operator= (const T& x)
+ {
+ if (&x_ != &x)
+ x_ = x;
+
+ return *this;
+ }
+
+ public:
+ /**
+ * @brief Implicitly convert the instance to constant reference to
+ * the underlying type.
+ *
+ * @return A constant reference to the underlying type.
+ */
+ operator const T& () const
+ {
+ return x_;
+ }
+
+ /**
+ * @brief Implicitly convert the instance to reference to the
+ * underlying type.
+ *
+ * @return A reference to the underlying type.
+ */
+ operator T& ()
+ {
+ return x_;
+ }
+
+ // The following extra conversion operators causes problems on
+ // some compilers (notably VC 7.1 and 9.0) and are disabled by
+ // default.
+ //
+#ifdef XSD_TREE_EXTRA_FUND_CONV
+ /**
+ * @brief Implicitly convert the instance to another type (const
+ * version).
+ *
+ * @return A value converted to the target type.
+ */
+ template <typename T2>
+ operator T2 () const
+ {
+ return x_;
+ }
+
+ /**
+ * @brief Implicitly convert the instance to another type.
+ *
+ * @return A value converted to the target type.
+ */
+ template <typename T2>
+ operator T2 ()
+ {
+ return x_;
+ }
+#endif // XSD_TREE_EXTRA_FUND_CONV
+
+ public:
+ /**
+ * @brief Get the facet table associated with this type.
+ *
+ * @return A pointer to read-only facet table or 0.
+ */
+ const facet*
+ _facet_table () const
+ {
+ return facet_table_;
+ }
+
+ protected:
+ /**
+ * @brief Set the facet table associated with this type.
+ *
+ * @param ft A pointer to read-only facet table.
+ */
+ void
+ _facet_table (const facet* ft)
+ {
+ facet_table_ = ft;
+ }
+
+ private:
+ const facet* facet_table_;
+ T x_;
+ };
+
+ // While thse operators are not normally necessary, they
+ // help resolve ambiguities between implicit conversion and
+ // construction.
+ //
+
+ /**
+ * @brief %fundamental_base comparison operator.
+ *
+ * @return True if the underlying values are equal, false otherwise.
+ */
+ template <typename T, typename C, typename B, schema_type::value ST>
+ inline bool
+ operator== (const fundamental_base<T, C, B, ST>& x,
+ const fundamental_base<T, C, B, ST>& y)
+ {
+ T x_ (x);
+ T y_ (y);
+ return x_ == y_;
+ }
+
+ /**
+ * @brief %fundamental_base comparison operator.
+ *
+ * @return True if the underlying values are not equal, false otherwise.
+ */
+ template <typename T, typename C, typename B, schema_type::value ST>
+ inline bool
+ operator!= (const fundamental_base<T, C, B, ST>& x,
+ const fundamental_base<T, C, B, ST>& y)
+ {
+ T x_ (x);
+ T y_ (y);
+ return x_ != y_;
+ }
+
+
+ //@cond
+
+ // Comparator for enum tables.
+ //
+ template <typename C>
+ struct enum_comparator
+ {
+ enum_comparator (const C* const* table)
+ : table_ (table)
+ {
+ }
+
+ bool
+ operator() (std::size_t i, const std::basic_string<C>& s) const
+ {
+ return table_[i] < s;
+ }
+
+ bool
+ operator() (const std::basic_string<C>& s, std::size_t i) const
+ {
+ return s < table_[i];
+ }
+
+ bool
+ operator() (std::size_t i, std::size_t j) const
+ {
+ return std::basic_string<C> (table_[i]) < table_[j];
+ }
+
+ private:
+ const C* const* table_;
+ };
+
+ //@endcond
+ }
+ }
+}
+
+#include <xsd/cxx/tree/elements.txx>
+
+#endif // XSD_CXX_TREE_ELEMENTS_HXX