From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- libxsd/xsd/cxx/tree/elements.hxx | 1448 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1448 insertions(+) create mode 100644 libxsd/xsd/cxx/tree/elements.hxx (limited to 'libxsd/xsd/cxx/tree/elements.hxx') 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 +// 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 +#include +#include // std::auto_ptr +#include +#include +#include + +#include +#include +#include +#include +#include + +#include // xml::properties +#include // dom::auto_ptr + +#include +#include +#include + +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 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 + class properties: public xml::properties + { + }; + + //@cond + + // DOM user data keys. + // + template + 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 + _type (istream& 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 + _type (const std::basic_string& 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 r ( + dom_info_factory::create ( + *static_cast (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 r ( + dom_info_factory::create ( + *static_cast (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 (&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 + 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* pd ( + reinterpret_cast*> ( + e.getOwnerDocument ()->getUserData (user_data_keys::node))); + + assert (pd != 0); + assert (pd->get () == e.getOwnerDocument ()); + + doc_ = *pd; // Transfer ownership. + } + } + + virtual std::auto_ptr + 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 (0); + + return auto_ptr ( + 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 (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 ( + new dom_element_info (static_cast (*dn), + tree_node, + false)); + } + } + + virtual xercesc::DOMNode* + node () + { + return &e_; + } + + private: + dom_element_info (const xercesc::DOMDocument& d, type& n) + : doc_ (static_cast ( + d.cloneNode (true))), + e_ (*doc_->getDocumentElement ()) + { + e_.setUserData (user_data_keys::node, &n, 0); + } + + private: + xml::dom::auto_ptr 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 + 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 (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 (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 ( + new dom_attribute_info (static_cast (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 + create (const xercesc::DOMElement& e, type& n, bool root) + { + return std::auto_ptr ( + new dom_element_info ( + const_cast (e), n, root)); + } + + static std::auto_ptr + create (const xercesc::DOMAttr& a, type& n) + { + return std::auto_ptr ( + new dom_attribute_info ( + const_cast (a), n)); + } + }; + + //@endcond + + std::auto_ptr 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 + map; + + std::auto_ptr map_; + + private: + container* container_; + }; + + inline _type:: + _type (const type& x, flags, container* c) + : container_ (c) + { + if (x.dom_info_.get ()) + { + std::auto_ptr r (x.dom_info_->clone (*this, c)); + dom_info_ = r; + } + } + + + /** + * @brief Class corresponding to the XML Schema anySimpleType built-in + * type. + * + * @nosubgrouping + */ + template + 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 + simple_type (istream& 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 + simple_type (const std::basic_string& 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 + 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& + _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& + _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 + struct traits + { + typedef T type; + + static std::auto_ptr + create (const xercesc::DOMElement& e, flags f, container* c) + { + return std::auto_ptr (new T (e, f, c)); + } + + static std::auto_ptr + create (const xercesc::DOMAttr& a, flags f, container* c) + { + return std::auto_ptr (new T (a, f, c)); + } + + static std::auto_ptr + create (const std::basic_string& s, + const xercesc::DOMElement* e, + flags f, + container* c) + { + return std::auto_ptr (new T (s, e, f, c)); + } + }; + + //@endcond + + + /** + * @brief Class template that emulates inheritance from a + * fundamental C++ type. + * + * @nosubgrouping + */ + template + 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 + fundamental_base (istream& 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& 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 + operator T2 () const + { + return x_; + } + + /** + * @brief Implicitly convert the instance to another type. + * + * @return A value converted to the target type. + */ + template + 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 + inline bool + operator== (const fundamental_base& x, + const fundamental_base& 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 + inline bool + operator!= (const fundamental_base& x, + const fundamental_base& y) + { + T x_ (x); + T y_ (y); + return x_ != y_; + } + + + //@cond + + // Comparator for enum tables. + // + template + struct enum_comparator + { + enum_comparator (const C* const* table) + : table_ (table) + { + } + + bool + operator() (std::size_t i, const std::basic_string& s) const + { + return table_[i] < s; + } + + bool + operator() (const std::basic_string& 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 (table_[i]) < table_[j]; + } + + private: + const C* const* table_; + }; + + //@endcond + } + } +} + +#include + +#endif // XSD_CXX_TREE_ELEMENTS_HXX -- cgit v1.1