LCOV - code coverage report
Current view: top level - /usr/include/xsd/cxx/tree - elements.hxx (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 147 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 41 0

            Line data    Source code
       1              : // file      : xsd/cxx/tree/elements.hxx
       2              : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
       3              : // license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
       4              : 
       5              : /**
       6              :  * @file
       7              :  *
       8              :  * @brief Contains C++ class definitions for XML Schema anyType and
       9              :  * anySimpleType types as well as supporting code.
      10              :  *
      11              :  * This is an internal header and is included by the generated code. You
      12              :  * normally should not include it directly.
      13              :  *
      14              :  */
      15              : 
      16              : #ifndef XSD_CXX_TREE_ELEMENTS_HXX
      17              : #define XSD_CXX_TREE_ELEMENTS_HXX
      18              : 
      19              : #include <xsd/cxx/config.hxx> // XSD_AUTO_PTR, XSD_CXX11
      20              : 
      21              : #include <map>
      22              : #include <string>
      23              : #include <memory>  // std::auto_ptr/unique_ptr
      24              : #include <cstddef> // std::size_t
      25              : #include <istream>
      26              : #include <sstream>
      27              : #include <cassert>
      28              : 
      29              : #ifdef XSD_CXX11
      30              : #  include <utility> // std::move
      31              : #endif
      32              : 
      33              : #include <xercesc/dom/DOMNode.hpp>
      34              : #include <xercesc/dom/DOMAttr.hpp>
      35              : #include <xercesc/dom/DOMElement.hpp>
      36              : #include <xercesc/dom/DOMDocument.hpp>
      37              : #include <xercesc/dom/DOMNamedNodeMap.hpp>
      38              : 
      39              : #include <xercesc/util/XercesVersion.hpp>
      40              : 
      41              : #include <xsd/cxx/xml/elements.hxx> // xml::properties
      42              : #include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr/unique_ptr
      43              : #include <xsd/cxx/xml/dom/wildcard-source.hxx> // dom::create_document()
      44              : 
      45              : #include <xsd/cxx/tree/facet.hxx>
      46              : #include <xsd/cxx/tree/exceptions.hxx>
      47              : #include <xsd/cxx/tree/istream-fwd.hxx>
      48              : #include <xsd/cxx/tree/containers-wildcard.hxx>
      49              : 
      50              : #if _XERCES_VERSION < 30000
      51              : #  error Xerces-C++ 2-series is not supported
      52              : #endif
      53              : 
      54              : namespace xsd
      55              : {
      56              :   namespace cxx
      57              :   {
      58              :     /**
      59              :      * @brief C++/Tree mapping runtime namespace.
      60              :      *
      61              :      * This is an internal namespace and normally should not be referenced
      62              :      * directly. Instead you should use the aliases for types in this
      63              :      * namespaces that are created in the generated code.
      64              :      *
      65              :      */
      66              :     namespace tree
      67              :     {
      68              :       /**
      69              :        * @brief Parsing and %serialization %flags.
      70              :        *
      71              :        * Flags are used to modify the default behavior of %parsing and
      72              :        * %serialization functions as well as %parsing constructors.
      73              :        *
      74              :        * @nosubgrouping
      75              :        */
      76              :       class flags
      77              :       {
      78              :       public:
      79              :         /**
      80              :          * @name Flag constants
      81              :          */
      82              :         //@{
      83              : 
      84              :         /**
      85              :          * @brief Keep DOM association in the resulting tree.
      86              :          */
      87              :         static const unsigned long keep_dom = 0x00000100UL;
      88              : 
      89              :         /**
      90              :          * @brief Assume ownership of the DOM document.
      91              :          *
      92              :          * This flag only makes sense together with the @c keep_dom
      93              :          * flag in the call to the %parsing function with the
      94              :          * @c dom::auto_ptr/unique_ptr\<DOMDocument> argument.
      95              :          *
      96              :          */
      97              :         static const unsigned long own_dom = 0x00000200UL;
      98              : 
      99              :         /**
     100              :          * @brief Turn off XML Schema validation in the underlying XML
     101              :          * parser.
     102              :          */
     103              :         static const unsigned long dont_validate = 0x00000400UL;
     104              : 
     105              :         /**
     106              :          * @brief Extract XML content for anyType or anySimpleType.
     107              :          * Normally you don't need to specify this flag explicitly.
     108              :          */
     109              :         static const unsigned long extract_content = 0x00000800UL;
     110              : 
     111              :         /**
     112              :          * @brief Do not initialize the Xerces-C++ runtime.
     113              :          */
     114              :         static const unsigned long dont_initialize = 0x00000001UL;
     115              : 
     116              :         /**
     117              :          * @brief Do not write XML declaration during %serialization.
     118              :          */
     119              :         static const unsigned long no_xml_declaration = 0x00010000UL;
     120              : 
     121              :         /**
     122              :          * @brief Do not add extra spaces or new lines that make the
     123              :          * resulting XML easier to read.
     124              :          */
     125              :         static const unsigned long dont_pretty_print = 0x00020000UL;
     126              : 
     127              :         //@cond
     128              : 
     129              :         // The following flags are for internal use.
     130              :         //
     131              :         static const unsigned long base = 0x01000000UL;
     132              : 
     133              :         //@endcond
     134              : 
     135              :         // Notes on flag blocks:
     136              :         //
     137              :         // 0x000000FF - common (applicable to both parsing and serialization)
     138              :         // 0x0000FF00 - parsing (values aligned with XML parsing)
     139              :         // 0x00FF0000 - serialization (values aligned with XML serialization)
     140              :         // 0xFF000000 - internal
     141              : 
     142              :         //@}
     143              : 
     144              :       public:
     145              :         /**
     146              :          * @brief Initialize an instance with an integer value.
     147              :          *
     148              :          * @param x A %flags value as an integer.
     149              :          */
     150            0 :         flags (unsigned long x = 0)
     151            0 :             : x_ (x)
     152              :         {
     153            0 :         }
     154              : 
     155              :         /**
     156              :          * @brief Convert an instance to an integer value.
     157              :          *
     158              :          * @return An integer %flags value.
     159              :          */
     160            0 :         operator unsigned long () const
     161              :         {
     162            0 :           return x_;
     163              :         }
     164              : 
     165              :         /**
     166              :          * @brief Combine two %flags.
     167              :          *
     168              :          * @return A %flags object that is a combination of the arguments.
     169              :          */
     170              :         friend flags
     171              :         operator| (const flags& a, const flags& b)
     172              :         {
     173              :           return flags (a.x_ | b.x_);
     174              :         }
     175              : 
     176              :         /**
     177              :          * @brief Combine two %flags.
     178              :          *
     179              :          * @return A %flags object that is a combination of the arguments.
     180              :          */
     181              :         friend flags
     182            0 :         operator| (const flags& a, unsigned long b)
     183              :         {
     184            0 :           return flags (a.x_ | b);
     185              :         }
     186              : 
     187              :         /**
     188              :          * @brief Combine two %flags.
     189              :          *
     190              :          * @return A %flags object that is a combination of the arguments.
     191              :          */
     192              :         friend flags
     193              :         operator| (unsigned long a, const flags& b)
     194              :         {
     195              :           return flags (a | b.x_);
     196              :         }
     197              : 
     198              :       private:
     199              :         unsigned long x_;
     200              :       };
     201              : 
     202              :       // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for XML-
     203              :       // related properties.
     204              :       //
     205              :       template <typename C>
     206              :       class properties: public xml::properties<C>
     207              :       {
     208              :       };
     209              : 
     210              :       /**
     211              :        * @brief Content order sequence entry.
     212              :        *
     213              :        * @nosubgrouping
     214              :        */
     215              :       struct content_order
     216              :       {
     217              :         /**
     218              :          * @brief Initialize an instance with passed id and index.
     219              :          *
     220              :          * @param id Content id.
     221              :          * @param index Content index in the corresponding sequence.
     222              :          */
     223              :         content_order (std::size_t id, std::size_t index = 0)
     224              :             : id (id), index (index)
     225              :         {
     226              :         }
     227              : 
     228              :         /**
     229              :          * @brief Content id.
     230              :          */
     231              :         std::size_t id;
     232              : 
     233              :         /**
     234              :          * @brief Content index.
     235              :          */
     236              :         std::size_t index;
     237              :       };
     238              : 
     239              :       bool
     240              :       operator== (const content_order&, const content_order&);
     241              : 
     242              :       bool
     243              :       operator!= (const content_order&, const content_order&);
     244              : 
     245              :       bool
     246              :       operator< (const content_order&, const content_order&);
     247              : 
     248              :       //@cond
     249              : 
     250              :       // DOM user data keys.
     251              :       //
     252              :       template <int dummy>
     253              :       struct user_data_keys_template
     254              :       {
     255              :         // Back pointers to tree nodes.
     256              :         //
     257              :         static const XMLCh node[21];
     258              :       };
     259              : 
     260              :       typedef user_data_keys_template<0> user_data_keys;
     261              : 
     262              :       //
     263              :       //
     264              :       struct identity
     265              :       {
     266              :         virtual
     267              :         ~identity ()
     268              :         {
     269              :         }
     270              : 
     271              :         identity ()
     272              :         {
     273              :         }
     274              : 
     275              :         virtual bool
     276              :         before (const identity&) const = 0;
     277              : 
     278              :         virtual void
     279              :         throw_duplicate_id () const = 0;
     280              : 
     281              :       private:
     282              :         identity (const identity&);
     283              : 
     284              :         identity&
     285              :         operator= (const identity&);
     286              :       };
     287              : 
     288              :       //@endcond
     289              : 
     290              : 
     291              :       // anyType. VC++ has a name injection bug that makes it impossible
     292              :       // to have a member with the same name as a base type. To address
     293              :       // that we will have to choose some unique name for the definition
     294              :       // and typedef it to 'type'.
     295              :       //
     296              :       class _type;
     297              : 
     298              :       /**
     299              :        * @brief Class corresponding to the XML Schema anyType built-in type.
     300              :        *
     301              :        */
     302              :       typedef _type type;
     303              : 
     304              :       /**
     305              :        * @brief Container type.
     306              :        *
     307              :        */
     308              :       typedef _type container;
     309              : 
     310              :       /**
     311              :        * @brief Class corresponding to the XML Schema anyType built-in type.
     312              :        *
     313              :        * This class is a base for every generated and built-in type in the
     314              :        * C++/Tree mapping.
     315              :        *
     316              :        * @nosubgrouping
     317              :        */
     318              :       class _type
     319              :       {
     320              :       public:
     321              :         virtual
     322            0 :         ~_type ()
     323            0 :         {
     324              :           // Everything should have been unregistered by now.
     325              :           //
     326            0 :           assert (map_.get () == 0 || map_->size () == 0);
     327            0 :         }
     328              : 
     329              :       public:
     330              :         /**
     331              :          * @name Constructors
     332              :          */
     333              :         //@{
     334              : 
     335              :         /**
     336              :          * @brief Default constructor.
     337              :          */
     338              :         _type ();
     339              : 
     340              :         /**
     341              :          * @brief Create an instance from a C string.
     342              :          *
     343              :          * @param s A string to initialize the instance with.
     344              :          *
     345              :          * Note that this constructor ignores the string and creates an
     346              :          * empty anyType instance. In particular, it will not convert the
     347              :          * string into DOM content. The purpose of such a strange constructor
     348              :          * is to allow statically-initialized default values of anyType type.
     349              :          */
     350              :         template <typename C>
     351              :         explicit
     352              :         _type (const C* s);
     353              : 
     354              :       public:
     355              :         /**
     356              :          * @brief Copy constructor.
     357              :          *
     358              :          * @param x An instance to make a copy of.
     359              :          * @param f Flags to create the copy with.
     360              :          * @param c A pointer to the object that will contain the copy.
     361              :          *
     362              :          * For polymorphic object models use the @c _clone function instead.
     363              :          */
     364              :         _type (const type& x, flags f = 0, container* c = 0);
     365              : 
     366              :         /**
     367              :          * @brief Copy the instance polymorphically.
     368              :          *
     369              :          * @param f Flags to create the copy with.
     370              :          * @param c A pointer to the object that will contain the copy.
     371              :          * @return A pointer to the dynamically allocated copy.
     372              :          *
     373              :          * This function ensures that the dynamic type of the instance
     374              :          * is used for copying and should be used for polymorphic object
     375              :          * models instead of the copy constructor.
     376              :          */
     377              :         virtual type*
     378            0 :         _clone (flags f = 0, container* c = 0) const
     379              :         {
     380            0 :           return new type (*this, f, c);
     381              :         }
     382              : 
     383              :       public:
     384              :         /**
     385              :          * @brief Create an instance from a data representation
     386              :          * stream.
     387              :          *
     388              :          * @param s A stream to extract the data from.
     389              :          * @param f Flags to create the new instance with.
     390              :          * @param c A pointer to the object that will contain the new
     391              :          * instance.
     392              :          */
     393              :         template <typename S>
     394              :         _type (istream<S>& s, flags f = 0, container* c = 0);
     395              : 
     396              :         /**
     397              :          * @brief Create an instance from a DOM element.
     398              :          *
     399              :          * @param e A DOM element to extract the data from.
     400              :          * @param f Flags to create the new instance with.
     401              :          * @param c A pointer to the object that will contain the new
     402              :          * instance.
     403              :          */
     404              :         _type (const xercesc::DOMElement& e,
     405              :                flags f = flags::extract_content,
     406              :                container* c = 0);
     407              : 
     408              :         /**
     409              :          * @brief Create an instance from a DOM Attribute.
     410              :          *
     411              :          * @param a A DOM attribute to extract the data from.
     412              :          * @param f Flags to create the new instance with.
     413              :          * @param c A pointer to the object that will contain the new
     414              :          * instance.
     415              :          */
     416              :         _type (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
     417              : 
     418              :         /**
     419              :          * @brief Create an instance from a %string fragment.
     420              :          *
     421              :          * @param s A %string fragment to extract the data from.
     422              :          * @param e A pointer to DOM element containing the %string fragment.
     423              :          * @param f Flags to create the new instance with.
     424              :          * @param c A pointer to the object that will contain the new
     425              :          * instance.
     426              :          */
     427              :         template <typename C>
     428              :         _type (const std::basic_string<C>& s,
     429              :                const xercesc::DOMElement* e,
     430              :                flags f = 0,
     431              :                container* c = 0);
     432              :         //@}
     433              : 
     434              :       public:
     435              :         /**
     436              :          * @brief Copy assignment operator.
     437              :          *
     438              :          * @param x An instance to assign.
     439              :          * @return A reference to the instance.
     440              :          */
     441              :         type&
     442            0 :         operator= (const type& x)
     443              :         {
     444            0 :           if (this != &x)
     445              :           {
     446            0 :             if (x.content_.get () == 0)
     447            0 :               content_.reset ();
     448              :             else
     449            0 :               content_ = x.content_->clone ();
     450              : 
     451              :             // Drop DOM association.
     452              :             //
     453            0 :             dom_info_.reset ();
     454              :           }
     455              : 
     456            0 :           return *this;
     457              :         }
     458              : 
     459              :         // anyType content API.
     460              :         //
     461              :       public:
     462              :         typedef element_optional dom_content_optional;
     463              : 
     464              :         /**
     465              :          * @brief Return a read-only (constant) reference to the anyType
     466              :          * DOM content.
     467              :          *
     468              :          * @return A constant reference to the optional container.
     469              :          *
     470              :          * The DOM content is returned as an optional element container,
     471              :          * the same container as used for optional element wildcards.
     472              :          */
     473              :         const dom_content_optional&
     474              :         dom_content () const;
     475              : 
     476              :         /**
     477              :          * @brief Return a read-write reference to the anyType DOM content.
     478              :          *
     479              :          * @return A reference to the optional container.
     480              :          *
     481              :          * The DOM content is returned as an optional element container,
     482              :          * the same container as used for optional element wildcards.
     483              :          */
     484              :         dom_content_optional&
     485              :         dom_content ();
     486              : 
     487              :         /**
     488              :          * @brief Set the anyType DOM content.
     489              :          *
     490              :          * @param e A new element to set.
     491              :          *
     492              :          * This function makes a copy of its argument and sets it as the
     493              :          * new DOM content.
     494              :          */
     495              :         void
     496              :         dom_content (const xercesc::DOMElement& e);
     497              : 
     498              :         /**
     499              :          * @brief Set the anyType DOM content.
     500              :          *
     501              :          * @param e A new element to use.
     502              :          *
     503              :          * This function will use the passed element directly instead
     504              :          * of making a copy. For this to work the element should belong
     505              :          * to the DOM document associated with this anyType instance.
     506              :          *
     507              :          * @see dom_content_document
     508              :          */
     509              :         void
     510              :         dom_content (xercesc::DOMElement* e);
     511              : 
     512              :         /**
     513              :          * @brief Set the anyType DOM content.
     514              :          *
     515              :          * @param d An optional container with the new element to set.
     516              :          *
     517              :          * If the element is present in @a d then this function makes a
     518              :          * copy of this element and sets it as the new wildcard content.
     519              :          * Otherwise the element container is set the 'not present' state.
     520              :          */
     521              :         void
     522              :         dom_content (const dom_content_optional& d);
     523              : 
     524              :         /**
     525              :          * @brief Return a read-only (constant) reference to the DOM
     526              :          * document associated with this anyType instance.
     527              :          *
     528              :          * @return A constant reference to the DOM document.
     529              :          *
     530              :          * The DOM document returned by this function is used to store
     531              :          * the raw XML content corresponding to the anyType instance.
     532              :          */
     533              :         const xercesc::DOMDocument&
     534              :         dom_content_document () const;
     535              : 
     536              :         /**
     537              :          * @brief Return a read-write reference to the DOM document
     538              :          * associated with this anyType instance.
     539              :          *
     540              :          * @return A reference to the DOM document.
     541              :          *
     542              :          * The DOM document returned by this function is used to store
     543              :          * the raw XML content corresponding to the anyType instance.
     544              :          */
     545              :         xercesc::DOMDocument&
     546              :         dom_content_document ();
     547              : 
     548              :         /**
     549              :          * @brief Check for absence of DOM (anyType) and text (anySimpleType)
     550              :          * content.
     551              :          *
     552              :          * @return True if there is no content and false otherwise.
     553              :          *
     554              :          * This is an optimization function that allows us to check for the
     555              :          * lack of content without actually creating its empty representation
     556              :          * (that is, empty DOM document for DOM or empty string for text).
     557              :          */
     558              :         bool
     559              :         null_content () const;
     560              : 
     561              :         //
     562              :         //
     563              :       public:
     564              :         /**
     565              :          * @brief Comparison operator. It uses DOM (anyType) or text
     566              :          * (anySimpleType) content if present. If the content is missing
     567              :          * then the types are assumed unequal.
     568              :          *
     569              :          * @return True if the instances are equal, false otherwise.
     570              :          */
     571              :         friend bool
     572              :         operator== (const type& x, const type& y)
     573              :         {
     574              :           return x.content_.get () != 0 &&
     575              :             x.content_->compare (y.content_.get ());
     576              :         }
     577              : 
     578              :         /**
     579              :          * @brief Comparison operator. It uses DOM (anyType) or text
     580              :          * (anySimpleType) content if present. If the content is missing
     581              :          * then the types are assumed unequal.
     582              :          *
     583              :          * @return True if the instances are not equal, false otherwise.
     584              :          */
     585              :         friend bool
     586              :         operator!= (const type& x, const type& y) {return !(x == y);}
     587              : 
     588              :         // Container API.
     589              :         //
     590              :       public:
     591              :         /**
     592              :          * @brief Get a constant pointer to container, an object model
     593              :          * node that contains this instance.
     594              :          *
     595              :          * @return A constant pointer to container, or 0 if this instance
     596              :          * is not contained.
     597              :          */
     598              :         const container*
     599              :         _container () const
     600              :         {
     601              :           return container_;
     602              :         }
     603              : 
     604              :         /**
     605              :          * @brief Get a pointer to container, an object model node that
     606              :          * contains this instance.
     607              :          *
     608              :          * @return A pointer to container, or 0 if this instance is not
     609              :          * contained.
     610              :          */
     611              :         container*
     612            0 :         _container ()
     613              :         {
     614            0 :           return container_;
     615              :         }
     616              : 
     617              :         /**
     618              :          * @brief Set this instance's new container, an object model node
     619              :          * that contains this instance.
     620              :          *
     621              :          * @param c A pointer to container.
     622              :          */
     623              :         virtual void
     624            0 :         _container (container* c)
     625              :         {
     626            0 :           container* dr (0);
     627              : 
     628            0 :           if (c != 0)
     629              :           {
     630            0 :             dr = c->_root ();
     631              : 
     632            0 :             if (dr == 0)
     633            0 :               dr = c;
     634              :           }
     635              : 
     636            0 :           XSD_AUTO_PTR<map>& m (dr ? dr->map_ : map_);
     637              : 
     638            0 :           if (container_ == 0)
     639              :           {
     640            0 :             if (c != 0 && map_.get () != 0)
     641              :             {
     642              :               // Transfer our IDs to the new root.
     643              :               //
     644            0 :               if (m.get () != 0)
     645              :               {
     646            0 :                 m->insert (map_->begin (), map_->end ());
     647            0 :                 map_.reset ();
     648              :               }
     649              :               else
     650              :               {
     651              : #ifdef XSD_CXX11
     652            0 :                 m = std::move (map_);
     653              : #else
     654              :                 m = map_;
     655              : #endif
     656              :               }
     657              :             }
     658              :           }
     659              :           else
     660              :           {
     661            0 :             container* sr (_root ());
     662              : 
     663            0 :             if (sr->map_.get () != 0)
     664              :             {
     665              :               // Transfer IDs that belong to this subtree.
     666              :               //
     667            0 :               for (map::iterator i (sr->map_->begin ()), e (sr->map_->end ());
     668            0 :                    i != e;)
     669              :               {
     670            0 :                 type* x (i->second);
     671            0 :                 for (; x != this && x != sr; x = x->_container ()) ;
     672              : 
     673            0 :                 if (x != sr)
     674              :                 {
     675              :                   // Part of our subtree.
     676              :                   //
     677            0 :                   if (m.get () == 0)
     678            0 :                     m.reset (new map);
     679              : 
     680            0 :                   m->insert (*i);
     681            0 :                   sr->map_->erase (i++);
     682              :                 }
     683              :                 else
     684            0 :                   ++i;
     685              :               }
     686              :             }
     687              :           }
     688              : 
     689            0 :           container_ = c;
     690            0 :         }
     691              : 
     692              :         /**
     693              :          * @brief Get a constant pointer to object model's root node.
     694              :          *
     695              :          * @return A constant pointer to root node, or 0 if this instance
     696              :          * is not contained.
     697              :          */
     698              :         const container*
     699              :         _root () const
     700              :         {
     701              :           const container* r (container_);
     702              : 
     703              :           for (const container* c (r); c != 0; c = c->container_)
     704              :             r = c;
     705              : 
     706              :           return r;
     707              :         }
     708              : 
     709              :         /**
     710              :          * @brief Get a pointer to object model's root node.
     711              :          *
     712              :          * @return A pointer to root node, or 0 if this instance is not
     713              :          * contained.
     714              :          */
     715              :         container*
     716            0 :         _root ()
     717              :         {
     718            0 :           container* r (container_);
     719              : 
     720            0 :           for (container* c (r); c != 0; c = c->container_)
     721            0 :             r = c;
     722              : 
     723            0 :           return r;
     724              :         }
     725              : 
     726              :         // DOM association.
     727              :         //
     728              :       public:
     729              :         /**
     730              :          * @brief Get a constant pointer to a DOM node associated with
     731              :          * this object model node.
     732              :          *
     733              :          * @return A constant pointer to DOM node, or 0 if none associated.
     734              :          */
     735              :         const xercesc::DOMNode*
     736              :         _node () const
     737              :         {
     738              :           return dom_info_.get () ? dom_info_->node() : 0;
     739              :         }
     740              : 
     741              :         /**
     742              :          * @brief Get a pointer to a DOM node associated with this object
     743              :          * model node.
     744              :          *
     745              :          * @return A pointer to DOM node, or 0 if none associated.
     746              :          */
     747              :         xercesc::DOMNode*
     748            0 :         _node ()
     749              :         {
     750            0 :           return dom_info_.get () ? dom_info_->node () : 0;
     751              :         }
     752              : 
     753              :         /**
     754              :          * @brief Exception indicating that a DOM node cannot be associated
     755              :          * with an object model node.
     756              :          */
     757              :         class bad_dom_node_type: public std::exception //@@ Inherit exception<C>.
     758              :         {
     759              :         public:
     760              :           /**
     761              :            * @brief Get %exception description.
     762              :            *
     763              :            * @return A C %string describing the %exception.
     764              :            */
     765              :           virtual const char*
     766              :           what () const throw ()
     767              :           {
     768              :             return "DOM node is not an attribute node or element node";
     769              :           }
     770              :         };
     771              : 
     772              :         /**
     773              :          * @brief Manually set a DOM node associated with this object
     774              :          * model node.
     775              :          *
     776              :          * The DOM node should be a child of the parent's DOM node. If
     777              :          * this object model node is a root of the tree, then it will
     778              :          * assume the ownership of the whole DOM document to which this
     779              :          * DOM node belongs.
     780              :          *
     781              :          * @param n A pointer to DOM node (should be either an element or
     782              :          * an attribute).
     783              :          */
     784              :         void
     785              :         _node (xercesc::DOMNode* n)
     786              :         {
     787              :           switch (n->getNodeType ())
     788              :           {
     789              :           case xercesc::DOMNode::ELEMENT_NODE:
     790              :             {
     791              :               if (container_ != 0)
     792              :               {
     793              :                 assert (_root ()->_node () != 0);
     794              :                 assert (_root ()->_node ()->getOwnerDocument () ==
     795              :                         n->getOwnerDocument ());
     796              :               }
     797              : 
     798              :               dom_info_ =
     799              :                 dom_info_factory::create (
     800              :                   *static_cast<xercesc::DOMElement*> (n),
     801              :                   *this,
     802              :                   container_ == 0);
     803              : 
     804              :               break;
     805              :             }
     806              :           case xercesc::DOMNode::ATTRIBUTE_NODE:
     807              :             {
     808              :               assert (container_ != 0);
     809              :               assert (_root ()->_node () != 0);
     810              :               assert (_root ()->_node ()->getOwnerDocument () ==
     811              :                       n->getOwnerDocument ());
     812              : 
     813              :               dom_info_ =
     814              :                 dom_info_factory::create (
     815              :                   *static_cast<xercesc::DOMAttr*> (n),
     816              :                   *this);
     817              : 
     818              :               break;
     819              :             }
     820              :           default:
     821              :             {
     822              :               throw bad_dom_node_type ();
     823              :             }
     824              :           }
     825              :         }
     826              : 
     827              :       public:
     828              :         //@cond
     829              : 
     830              :         void
     831              :         _register_id (const identity& i, type* t)
     832              :         {
     833              :           // We should be the root.
     834              :           //
     835              :           assert (container_ == 0);
     836              : 
     837              :           if (map_.get () == 0)
     838              :             map_.reset (new map);
     839              : 
     840              :           if (!map_->insert (
     841              :                 std::pair<const identity*, type*> (&i, t)).second)
     842              :           {
     843              :             i.throw_duplicate_id ();
     844              :           }
     845              :         }
     846              : 
     847              :         //@@ Does not inherit from exception<C>.
     848              :         //
     849              :         struct not_registered: std::exception
     850              :         {
     851              :           virtual const char*
     852              :           what () const throw ()
     853              :           {
     854              :             return "attempt to unregister non-existent id";
     855              :           }
     856              :         };
     857              : 
     858              :         void
     859              :         _unregister_id (const identity& id)
     860              :         {
     861              :           // We should be the root.
     862              :           //
     863              :           assert (container_ == 0);
     864              : 
     865              :           if (map_.get () == 0 || map_->erase (&id) == 0)
     866              :             throw not_registered ();
     867              :         }
     868              : 
     869              :         type*
     870              :         _lookup_id (const identity& id) const
     871              :         {
     872              :           if (map_.get ())
     873              :           {
     874              :             map::const_iterator it (map_->find (&id));
     875              : 
     876              :             if (it != map_->end ())
     877              :               return it->second;
     878              :           }
     879              : 
     880              :           return 0;
     881              :         }
     882              : 
     883              :         //@endcond
     884              : 
     885              :       private:
     886              :         //@cond
     887              : 
     888              :         struct dom_info
     889              :         {
     890              :           virtual
     891            0 :           ~dom_info () {}
     892              : 
     893            0 :           dom_info () {}
     894              : 
     895              :           virtual XSD_AUTO_PTR<dom_info>
     896              :           clone (type& tree_node, container*) const = 0;
     897              : 
     898              :           virtual xercesc::DOMNode*
     899              :           node () = 0;
     900              : 
     901              :         private:
     902              :           dom_info (const dom_info&);
     903              :           dom_info& operator= (const dom_info&);
     904              :         };
     905              : 
     906              :         struct dom_element_info: public dom_info
     907              :         {
     908            0 :           dom_element_info (xercesc::DOMElement& e, type& n, bool root)
     909            0 :               : e_ (e)
     910              :           {
     911            0 :             e_.setUserData (user_data_keys::node, &n, 0);
     912              : 
     913            0 :             if (root)
     914              :             {
     915              :               // The caller should have associated a dom::auto/unique_ptr
     916              :               // object that owns this document with the document node
     917              :               // using the xml_schema::dom::tree_node_key key.
     918              :               //
     919              :               XSD_DOM_AUTO_PTR<xercesc::DOMDocument>* pd (
     920              :                 reinterpret_cast<XSD_DOM_AUTO_PTR<xercesc::DOMDocument>*> (
     921            0 :                   e.getOwnerDocument ()->getUserData (user_data_keys::node)));
     922              : 
     923            0 :               assert (pd != 0);
     924            0 :               assert (pd->get () == e.getOwnerDocument ());
     925              : 
     926              :               // Transfer ownership.
     927              : #ifdef XSD_CXX11
     928            0 :               doc_ = std::move (*pd);
     929              : #else
     930              :               doc_ = *pd;
     931              : #endif
     932              :             }
     933            0 :           }
     934              : 
     935              :           virtual XSD_AUTO_PTR<dom_info>
     936            0 :           clone (type& tree_node, container* c) const
     937              :           {
     938              :             // Check if we are a document root.
     939              :             //
     940            0 :             if (c == 0)
     941              :             {
     942              :               // We preserver DOM associations only in complete
     943              :               // copies from root.
     944              :               //
     945              :               return XSD_AUTO_PTR<dom_info> (
     946            0 :                 doc_.get () == 0
     947              :                 ? 0
     948            0 :                 : new dom_element_info (*doc_, tree_node));
     949              :             }
     950              : 
     951              :             // Check if our container does not have DOM association (e.g.,
     952              :             // because it wasn't a complete copy of the tree).
     953              :             //
     954              :             using xercesc::DOMNode;
     955              : 
     956            0 :             DOMNode* cn (c->_node ());
     957              : 
     958            0 :             if (cn == 0)
     959            0 :               return XSD_AUTO_PTR<dom_info> ();
     960              : 
     961              :             // Now we are going to find the corresponding element in
     962              :             // the new tree.
     963              :             //
     964              :             {
     965              :               using xercesc::DOMElement;
     966              : 
     967            0 :               DOMNode& pn (*e_.getParentNode ());
     968            0 :               assert (pn.getNodeType () == DOMNode::ELEMENT_NODE);
     969              : 
     970            0 :               DOMNode* sn (pn.getFirstChild ()); // Source.
     971            0 :               DOMNode* dn (cn->getFirstChild ()); // Destination.
     972              : 
     973              :               // We should have at least one child.
     974              :               //
     975            0 :               assert (sn != 0);
     976              : 
     977              :               // Move in parallel until we get to the needed node.
     978              :               //
     979            0 :               for (; sn != 0 && !e_.isSameNode (sn);)
     980              :               {
     981            0 :                 sn = sn->getNextSibling ();
     982            0 :                 dn = dn->getNextSibling ();
     983              :               }
     984              : 
     985              :               // e_ should be on the list.
     986              :               //
     987            0 :               assert (sn != 0);
     988              : 
     989            0 :               assert (dn->getNodeType () == DOMNode::ELEMENT_NODE);
     990              : 
     991              :               return XSD_AUTO_PTR<dom_info> (
     992              :                 new dom_element_info (static_cast<DOMElement&> (*dn),
     993              :                                       tree_node,
     994            0 :                                       false));
     995              :             }
     996              :           }
     997              : 
     998              :           virtual xercesc::DOMNode*
     999            0 :           node ()
    1000              :           {
    1001            0 :             return &e_;
    1002              :           }
    1003              : 
    1004              :         private:
    1005            0 :           dom_element_info (const xercesc::DOMDocument& d, type& n)
    1006            0 :               : doc_ (static_cast<xercesc::DOMDocument*> (
    1007            0 :                         d.cloneNode (true))),
    1008            0 :                 e_ (*doc_->getDocumentElement ())
    1009              :           {
    1010            0 :             e_.setUserData (user_data_keys::node, &n, 0);
    1011            0 :           }
    1012              : 
    1013              :         private:
    1014              :           XSD_DOM_AUTO_PTR<xercesc::DOMDocument> doc_;
    1015              :           xercesc::DOMElement& e_;
    1016              :         };
    1017              : 
    1018              : 
    1019              :         struct dom_attribute_info: public dom_info
    1020              :         {
    1021            0 :           dom_attribute_info (xercesc::DOMAttr& a, type& n)
    1022            0 :               : a_ (a)
    1023              :           {
    1024            0 :             a_.setUserData (user_data_keys::node, &n, 0);
    1025            0 :           }
    1026              : 
    1027              :           virtual XSD_AUTO_PTR<dom_info>
    1028            0 :           clone (type& tree_node, container* c) const
    1029              :           {
    1030              :             // Check if we are a document root.
    1031              :             //
    1032            0 :             if (c == 0)
    1033              :             {
    1034              :               // We preserver DOM associations only in complete
    1035              :               // copies from root.
    1036              :               //
    1037            0 :               return XSD_AUTO_PTR<dom_info> ();
    1038              :             }
    1039              : 
    1040              :             // Check if our container does not have DOM association (e.g.,
    1041              :             // because it wasn't a complete copy of the tree).
    1042              :             //
    1043              :             using xercesc::DOMNode;
    1044              : 
    1045            0 :             DOMNode* cn (c->_node ());
    1046              : 
    1047            0 :             if (cn == 0)
    1048            0 :               return XSD_AUTO_PTR<dom_info> ();
    1049              : 
    1050              :             // We are going to find the corresponding attribute in
    1051              :             // the new tree.
    1052              :             //
    1053              :             using xercesc::DOMAttr;
    1054              :             using xercesc::DOMElement;
    1055              :             using xercesc::DOMNamedNodeMap;
    1056              : 
    1057            0 :             DOMElement& p (*a_.getOwnerElement ());
    1058            0 :             DOMNamedNodeMap& nl (*p.getAttributes ());
    1059              : 
    1060            0 :             XMLSize_t size (nl.getLength ()), i (0);
    1061              : 
    1062              :             // We should have at least one child.
    1063              :             //
    1064            0 :             assert (size != 0);
    1065              : 
    1066            0 :             for ( ;i < size && !a_.isSameNode (nl.item (i)); ++i)/*noop*/;
    1067              : 
    1068              :             // a_ should be in the list.
    1069              :             //
    1070            0 :             assert (i < size);
    1071              : 
    1072            0 :             DOMNode& n (*cn->getAttributes ()->item (i));
    1073            0 :             assert (n.getNodeType () == DOMNode::ATTRIBUTE_NODE);
    1074              : 
    1075              :             return XSD_AUTO_PTR<dom_info> (
    1076            0 :               new dom_attribute_info (static_cast<DOMAttr&> (n), tree_node));
    1077              :           }
    1078              : 
    1079              :           virtual xercesc::DOMNode*
    1080            0 :           node ()
    1081              :           {
    1082            0 :             return &a_;
    1083              :           }
    1084              : 
    1085              :         private:
    1086              :           xercesc::DOMAttr& a_;
    1087              :         };
    1088              : 
    1089              :         // For Sun C++ 5.6.
    1090              :         //
    1091              :         struct dom_info_factory;
    1092              :         friend struct _type::dom_info_factory;
    1093              : 
    1094              :         struct dom_info_factory
    1095              :         {
    1096              :           static XSD_AUTO_PTR<dom_info>
    1097            0 :           create (const xercesc::DOMElement& e, type& n, bool root)
    1098              :           {
    1099              :             return XSD_AUTO_PTR<dom_info> (
    1100              :               new dom_element_info (
    1101            0 :                 const_cast<xercesc::DOMElement&> (e), n, root));
    1102              :           }
    1103              : 
    1104              :           static XSD_AUTO_PTR<dom_info>
    1105            0 :           create (const xercesc::DOMAttr& a, type& n)
    1106              :           {
    1107              :             return XSD_AUTO_PTR<dom_info> (
    1108              :               new dom_attribute_info (
    1109            0 :                 const_cast<xercesc::DOMAttr&> (a), n));
    1110              :           }
    1111              :         };
    1112              : 
    1113              :         //@endcond
    1114              : 
    1115              :         XSD_AUTO_PTR<dom_info> dom_info_;
    1116              : 
    1117              : 
    1118              :         // ID/IDREF map.
    1119              :         //
    1120              :       private:
    1121              : 
    1122              :         //@cond
    1123              : 
    1124              :         struct identity_comparator
    1125              :         {
    1126            0 :           bool operator () (const identity* x, const identity* y) const
    1127              :           {
    1128            0 :             return x->before (*y);
    1129              :           }
    1130              :         };
    1131              : 
    1132              :         //@endcond
    1133              : 
    1134              :         typedef
    1135              :         std::map<const identity*, type*, identity_comparator>
    1136              :         map;
    1137              : 
    1138              :         XSD_AUTO_PTR<map> map_;
    1139              : 
    1140              :         // anyType and anySimpleType content.
    1141              :         //
    1142              :       protected:
    1143              : 
    1144              :         //@cond
    1145              : 
    1146              :         struct content_type
    1147              :         {
    1148              :           virtual
    1149            0 :           ~content_type () {}
    1150              : 
    1151            0 :           content_type () {}
    1152              : 
    1153              :           virtual XSD_AUTO_PTR<content_type>
    1154              :           clone () const = 0;
    1155              : 
    1156              :           virtual bool
    1157              :           compare (const content_type*) const = 0;
    1158              : 
    1159              :         private:
    1160              :           content_type (const content_type&);
    1161              :           content_type& operator= (const content_type&);
    1162              :         };
    1163              : 
    1164              :         struct dom_content_type: content_type
    1165              :         {
    1166            0 :           dom_content_type ()
    1167            0 :               : doc (xml::dom::create_document<char> ()), dom (*doc) {}
    1168              : 
    1169              :           explicit
    1170            0 :           dom_content_type (const xercesc::DOMElement& e)
    1171            0 :               : doc (xml::dom::create_document<char> ()), dom (e, *doc) {}
    1172              : 
    1173              :           explicit
    1174              :           dom_content_type (xercesc::DOMElement* e)
    1175              :               : doc (xml::dom::create_document<char> ()), dom (e, *doc) {}
    1176              : 
    1177              :           explicit
    1178            0 :           dom_content_type (const dom_content_optional& d)
    1179            0 :               : doc (xml::dom::create_document<char> ()), dom (d, *doc) {}
    1180              : 
    1181              :           virtual XSD_AUTO_PTR<content_type>
    1182            0 :           clone () const
    1183              :           {
    1184            0 :             return XSD_AUTO_PTR<content_type> (new dom_content_type (dom));
    1185              :           }
    1186              : 
    1187              :           virtual bool
    1188            0 :           compare (const content_type* c) const
    1189              :           {
    1190            0 :             if (const dom_content_type* dc =
    1191            0 :                 dynamic_cast<const dom_content_type*> (c))
    1192            0 :               return dom == dc->dom;
    1193              : 
    1194            0 :             return false;
    1195              :           }
    1196              : 
    1197              :         public:
    1198              :           XSD_DOM_AUTO_PTR<xercesc::DOMDocument> doc;
    1199              :           dom_content_optional dom;
    1200              :         };
    1201              : 
    1202              :         //@endcond
    1203              : 
    1204              :         mutable XSD_AUTO_PTR<content_type> content_;
    1205              : 
    1206              :       private:
    1207              :         container* container_;
    1208              :       };
    1209              : 
    1210              :       /**
    1211              :        * @brief Class corresponding to the XML Schema anySimpleType built-in
    1212              :        * type.
    1213              :        *
    1214              :        * @nosubgrouping
    1215              :        */
    1216              :       template <typename C, typename B>
    1217              :       class simple_type: public B
    1218              :       {
    1219              :       public:
    1220              :         /**
    1221              :          * @name Constructors
    1222              :          */
    1223              :         //@{
    1224              : 
    1225              :         /**
    1226              :          * @brief Default constructor.
    1227              :          */
    1228              :         simple_type ();
    1229              : 
    1230              :         /**
    1231              :          * @brief Create an instance from a C string.
    1232              :          *
    1233              :          * @param s A string to initialize the instance with.
    1234              :          */
    1235              :         simple_type (const C* s);
    1236              : 
    1237              :         /**
    1238              :          * @brief Create an instance from a string.
    1239              :          *
    1240              :          * @param s A string to initialize the instance with.
    1241              :          */
    1242              :         simple_type (const std::basic_string<C>& s);
    1243              : 
    1244              :       public:
    1245              :         /**
    1246              :          * @brief Copy constructor.
    1247              :          *
    1248              :          * @param x An instance to make a copy of.
    1249              :          * @param f Flags to create the copy with.
    1250              :          * @param c A pointer to the object that will contain the copy.
    1251              :          *
    1252              :          * For polymorphic object models use the @c _clone function instead.
    1253              :          */
    1254              :         simple_type (const simple_type& x, flags f = 0, container* c = 0);
    1255              : 
    1256              :         /**
    1257              :          * @brief Copy the instance polymorphically.
    1258              :          *
    1259              :          * @param f Flags to create the copy with.
    1260              :          * @param c A pointer to the object that will contain the copy.
    1261              :          * @return A pointer to the dynamically allocated copy.
    1262              :          *
    1263              :          * This function ensures that the dynamic type of the instance
    1264              :          * is used for copying and should be used for polymorphic object
    1265              :          * models instead of the copy constructor.
    1266              :          */
    1267              :         virtual simple_type*
    1268              :         _clone (flags f = 0, container* c = 0) const;
    1269              : 
    1270              :       public:
    1271              :         /**
    1272              :          * @brief Create an instance from a data representation
    1273              :          * stream.
    1274              :          *
    1275              :          * @param s A stream to extract the data from.
    1276              :          * @param f Flags to create the new instance with.
    1277              :          * @param c A pointer to the object that will contain the new
    1278              :          * instance.
    1279              :          */
    1280              :         template <typename S>
    1281              :         simple_type (istream<S>& s,
    1282              :                      flags f = flags::extract_content,
    1283              :                      container* c = 0);
    1284              : 
    1285              :         /**
    1286              :          * @brief Create an instance from a DOM element.
    1287              :          *
    1288              :          * @param e A DOM element to extract the data from.
    1289              :          * @param f Flags to create the new instance with.
    1290              :          * @param c A pointer to the object that will contain the new
    1291              :          * instance.
    1292              :          */
    1293              :         simple_type (const xercesc::DOMElement& e,
    1294              :                      flags f = flags::extract_content,
    1295              :                      container* c = 0);
    1296              : 
    1297              :         /**
    1298              :          * @brief Create an instance from a DOM Attribute.
    1299              :          *
    1300              :          * @param a A DOM attribute to extract the data from.
    1301              :          * @param f Flags to create the new instance with.
    1302              :          * @param c A pointer to the object that will contain the new
    1303              :          * instance.
    1304              :          */
    1305              :         simple_type (const xercesc::DOMAttr& a,
    1306              :                      flags f = flags::extract_content,
    1307              :                      container* c = 0);
    1308              : 
    1309              :         /**
    1310              :          * @brief Create an instance from a %string fragment.
    1311              :          *
    1312              :          * @param s A %string fragment to extract the data from.
    1313              :          * @param e A pointer to DOM element containing the %string fragment.
    1314              :          * @param f Flags to create the new instance with.
    1315              :          * @param c A pointer to the object that will contain the new
    1316              :          * instance.
    1317              :          */
    1318              :         simple_type (const std::basic_string<C>& s,
    1319              :                      const xercesc::DOMElement* e,
    1320              :                      flags f = flags::extract_content,
    1321              :                      container* c = 0);
    1322              :         //@}
    1323              : 
    1324              :         // anySimpleType content API.
    1325              :         //
    1326              :       public:
    1327              :         /**
    1328              :          * @brief Return a read-only (constant) reference to the anySimpleType
    1329              :          * text content.
    1330              :          *
    1331              :          * @return A constant reference to the text string.
    1332              :          */
    1333              :         const std::basic_string<C>&
    1334              :         text_content () const;
    1335              : 
    1336              :         /**
    1337              :          * @brief Return a read-write reference to the anySimpleType text
    1338              :          * content.
    1339              :          *
    1340              :          * @return A reference to the text string.
    1341              :          */
    1342              :         std::basic_string<C>&
    1343              :         text_content ();
    1344              : 
    1345              :         /**
    1346              :          * @brief Set the anySimpleType text content.
    1347              :          *
    1348              :          * @param t A new text string to set.
    1349              :          */
    1350              :         void
    1351              :         text_content (const std::basic_string<C>& t);
    1352              : 
    1353              :       protected:
    1354              :         //@cond
    1355              : 
    1356              :         typedef typename B::content_type content_type;
    1357              : 
    1358              :         struct text_content_type: content_type
    1359              :         {
    1360              :           text_content_type () {}
    1361              : 
    1362              :           explicit
    1363            0 :           text_content_type (const std::basic_string<C>& t): text (t) {}
    1364              : 
    1365              :           explicit
    1366              :           text_content_type (const C* t): text (t) {}
    1367              : 
    1368              :           virtual XSD_AUTO_PTR<content_type>
    1369            0 :           clone () const
    1370              :           {
    1371            0 :             return XSD_AUTO_PTR<content_type> (new text_content_type (text));
    1372              :           }
    1373              : 
    1374              :           virtual bool
    1375            0 :           compare (const content_type* c) const
    1376              :           {
    1377            0 :             if (const text_content_type* tc =
    1378            0 :                 dynamic_cast<const text_content_type*> (c))
    1379            0 :               return text == tc->text;
    1380              : 
    1381            0 :             return false;
    1382              :           }
    1383              : 
    1384              :         public:
    1385              :           // It would have been more elegant to store text content as DOMText.
    1386              :           // However, that would require Xerces-C++ initialization. Also
    1387              :           // having a separate DOMDocument for each text node seems like
    1388              :           // an overkill.
    1389              :           //
    1390              :           std::basic_string<C> text;
    1391              :         };
    1392              : 
    1393              :         //@endcond
    1394              :       };
    1395              : 
    1396              : 
    1397              :       /**
    1398              :        * @brief Base class for element types.
    1399              :        *
    1400              :        * This class is a base for every generated element type.
    1401              :        *
    1402              :        * @nosubgrouping
    1403              :        */
    1404              :       template <typename C, typename T>
    1405              :       class element_type
    1406              :       {
    1407              :       public:
    1408              :         virtual
    1409              :         ~element_type ()
    1410              :         {
    1411              :         }
    1412              : 
    1413              :         /**
    1414              :          * @brief Copy the instance polymorphically.
    1415              :          *
    1416              :          * @param f Flags to create the copy with.
    1417              :          * @return A pointer to the dynamically allocated copy.
    1418              :          *
    1419              :          * This function ensures that the dynamic type of the instance
    1420              :          * is used for copying and should be used for polymorphic object
    1421              :          * models instead of the copy constructor.
    1422              :          */
    1423              :         virtual element_type*
    1424              :         _clone (flags f = 0) const = 0;
    1425              : 
    1426              :         /**
    1427              :          * @brief Return the element name.
    1428              :          *
    1429              :          * @return A read-only string reference containing the element
    1430              :          * name.
    1431              :          */
    1432              :         virtual const std::basic_string<C>&
    1433              :         _name () const = 0;
    1434              : 
    1435              :         /**
    1436              :          * @brief Return the element namespace.
    1437              :          *
    1438              :          * @return A read-only string reference containing the element
    1439              :          * namespace. Empty string is returned if the element is
    1440              :          * unqualified.
    1441              :          */
    1442              :         virtual const std::basic_string<C>&
    1443              :         _namespace () const = 0;
    1444              : 
    1445              :         /**
    1446              :          * @brief Return the element value.
    1447              :          *
    1448              :          * @return A pointer to the element value or 0 if the element
    1449              :          * is of a fundamental type.
    1450              :          */
    1451              :         virtual T*
    1452              :         _value () = 0;
    1453              : 
    1454              :         /**
    1455              :          * @brief Return the element value.
    1456              :          *
    1457              :          * @return A read-only pointer to the element value or 0 if the
    1458              :          * element is of a fundamental type.
    1459              :          */
    1460              :         virtual const T*
    1461              :         _value () const = 0;
    1462              :       };
    1463              : 
    1464              : 
    1465              :       //@cond
    1466              : 
    1467              :       // Extra schema type id to disambiguate certain cases where
    1468              :       // different XML Schema types (e.g., double and decimal) are
    1469              :       // mapped to the same fundamental C++ type (e.g., double).
    1470              :       //
    1471              :       struct schema_type
    1472              :       {
    1473              :         enum value
    1474              :         {
    1475              :           other,
    1476              :           double_,
    1477              :           decimal
    1478              :         };
    1479              :       };
    1480              : 
    1481              :       //@endcond
    1482              : 
    1483              : 
    1484              :       //@cond
    1485              :       template <typename T,
    1486              :                 typename C,
    1487              :                 schema_type::value ST = schema_type::other>
    1488              :       struct traits
    1489              :       {
    1490              :         typedef T type;
    1491              : 
    1492              :         static XSD_AUTO_PTR<T>
    1493            0 :         create (const xercesc::DOMElement& e, flags f, container* c)
    1494              :         {
    1495            0 :           return XSD_AUTO_PTR<T> (new T (e, f, c));
    1496              :         }
    1497              : 
    1498              :         static XSD_AUTO_PTR<T>
    1499            0 :         create (const xercesc::DOMAttr& a, flags f, container* c)
    1500              :         {
    1501            0 :           return XSD_AUTO_PTR<T> (new T (a, f, c));
    1502              :         }
    1503              : 
    1504              :         static XSD_AUTO_PTR<T>
    1505              :         create (const std::basic_string<C>& s,
    1506              :                 const xercesc::DOMElement* e,
    1507              :                 flags f,
    1508              :                 container* c)
    1509              :         {
    1510              :           return XSD_AUTO_PTR<T> (new T (s, e, f, c));
    1511              :         }
    1512              : 
    1513              :         // For now for istream we only go through traits for non-
    1514              :         // fundamental types.
    1515              :         //
    1516              :         template <typename S>
    1517              :         static XSD_AUTO_PTR<T>
    1518              :         create (istream<S>& s, flags f, container* c)
    1519              :         {
    1520              :           return XSD_AUTO_PTR<T> (new T (s, f, c));
    1521              :         }
    1522              :       };
    1523              : 
    1524              :       template <typename B,
    1525              :                 typename C,
    1526              :                 schema_type::value ST>
    1527              :       struct traits<simple_type<C, B>, C, ST>
    1528              :       {
    1529              :         typedef simple_type<C, B> type;
    1530              : 
    1531              :         static XSD_AUTO_PTR<type>
    1532              :         create (const xercesc::DOMElement& e, flags f, container* c)
    1533              :         {
    1534              :           return XSD_AUTO_PTR<type> (
    1535              :             new type (e, f | flags::extract_content, c));
    1536              :         }
    1537              : 
    1538              :         static XSD_AUTO_PTR<type>
    1539              :         create (const xercesc::DOMAttr& a, flags f, container* c)
    1540              :         {
    1541              :           return XSD_AUTO_PTR<type> (
    1542              :             new type (a, f | flags::extract_content, c));
    1543              :         }
    1544              : 
    1545              :         static XSD_AUTO_PTR<type>
    1546              :         create (const std::basic_string<C>& s,
    1547              :                 const xercesc::DOMElement* e,
    1548              :                 flags f,
    1549              :                 container* c)
    1550              :         {
    1551              :           return XSD_AUTO_PTR<type> (
    1552              :             new type (s, e, f | flags::extract_content, c));
    1553              :         }
    1554              : 
    1555              :         template <typename S>
    1556              :         static XSD_AUTO_PTR<type>
    1557              :         create (istream<S>& s, flags f, container* c)
    1558              :         {
    1559              :           return XSD_AUTO_PTR<type> (
    1560              :             new type (s, f | flags::extract_content, c));
    1561              :         }
    1562              :       };
    1563              :       //@endcond
    1564              : 
    1565              : 
    1566              :       /**
    1567              :        * @brief Class template that emulates inheritance from a
    1568              :        * fundamental C++ type.
    1569              :        *
    1570              :        * @nosubgrouping
    1571              :        */
    1572              :       template <typename T,
    1573              :                 typename C,
    1574              :                 typename B,
    1575              :                 schema_type::value ST = schema_type::other>
    1576              :       class fundamental_base: public B
    1577              :       {
    1578              :       public:
    1579              :         /**
    1580              :          * @name Constructors
    1581              :          */
    1582              :         //@{
    1583              : 
    1584              :         /**
    1585              :          * @brief Default constructor.
    1586              :          */
    1587              :         fundamental_base ()
    1588              :             : facet_table_ (0), x_ ()
    1589              :         {
    1590              :         }
    1591              : 
    1592              :         /**
    1593              :          * @brief Initialize an instance with an underlying type value.
    1594              :          *
    1595              :          * @param x An underlying type value.
    1596              :          */
    1597              :         fundamental_base (T x)
    1598              :             : facet_table_ (0), x_ (x)
    1599              :         {
    1600              :         }
    1601              : 
    1602              :       public:
    1603              :         /**
    1604              :          * @brief Copy constructor.
    1605              :          *
    1606              :          * @param x An instance to make a copy of.
    1607              :          * @param f Flags to create the copy with.
    1608              :          * @param c A pointer to the object that will contain the copy.
    1609              :          *
    1610              :          * For polymorphic object models use the @c _clone function instead.
    1611              :          */
    1612              :         fundamental_base (const fundamental_base& x,
    1613              :                           flags f = 0,
    1614              :                           container* c = 0)
    1615              :             : B (x, f, c), facet_table_ (0), x_ (x.x_)
    1616              :         {
    1617              :         }
    1618              : 
    1619              :         /**
    1620              :          * @brief Copy the instance polymorphically.
    1621              :          *
    1622              :          * @param f Flags to create the copy with.
    1623              :          * @param c A pointer to the object that will contain the copy.
    1624              :          * @return A pointer to the dynamically allocated copy.
    1625              :          *
    1626              :          * This function ensures that the dynamic type of the instance
    1627              :          * is used for copying and should be used for polymorphic object
    1628              :          * models instead of the copy constructor.
    1629              :          */
    1630              :         virtual fundamental_base*
    1631              :         _clone (flags f = 0, container* c = 0) const;
    1632              : 
    1633              :       public:
    1634              :         /**
    1635              :          * @brief Create an instance from a data representation
    1636              :          * stream.
    1637              :          *
    1638              :          * @param s A stream to extract the data from.
    1639              :          * @param f Flags to create the new instance with.
    1640              :          * @param c A pointer to the object that will contain the new
    1641              :          * instance.
    1642              :          */
    1643              :         template <typename S>
    1644              :         fundamental_base (istream<S>& s, flags f = 0, container* c = 0);
    1645              : 
    1646              :         /**
    1647              :          * @brief Create an instance from a DOM element.
    1648              :          *
    1649              :          * @param e A DOM element to extract the data from.
    1650              :          * @param f Flags to create the new instance with.
    1651              :          * @param c A pointer to the object that will contain the new
    1652              :          * instance.
    1653              :          */
    1654              :         fundamental_base (const xercesc::DOMElement& e,
    1655              :                           flags f = 0,
    1656              :                           container* c = 0);
    1657              : 
    1658              :         /**
    1659              :          * @brief Create an instance from a DOM Attribute.
    1660              :          *
    1661              :          * @param a A DOM attribute to extract the data from.
    1662              :          * @param f Flags to create the new instance with.
    1663              :          * @param c A pointer to the object that will contain the new
    1664              :          * instance.
    1665              :          */
    1666              :         fundamental_base (const xercesc::DOMAttr& a,
    1667              :                           flags f = 0,
    1668              :                           container* c = 0);
    1669              : 
    1670              :         /**
    1671              :          * @brief Create an instance from a %string fragment.
    1672              :          *
    1673              :          * @param s A %string fragment to extract the data from.
    1674              :          * @param e A pointer to DOM element containing the %string fragment.
    1675              :          * @param f Flags to create the new instance with.
    1676              :          * @param c A pointer to the object that will contain the new
    1677              :          * instance.
    1678              :          */
    1679              :         fundamental_base (const std::basic_string<C>& s,
    1680              :                           const xercesc::DOMElement* e,
    1681              :                           flags f = 0,
    1682              :                           container* c = 0);
    1683              :         //@}
    1684              : 
    1685              :       public:
    1686              :         /**
    1687              :          * @brief Assign an underlying type value to the instance.
    1688              :          *
    1689              :          * @param x An underlying type value.
    1690              :          * @return A reference to the instance.
    1691              :          */
    1692              :         fundamental_base&
    1693              :         operator= (const T& x)
    1694              :         {
    1695              :           if (&x_ != &x)
    1696              :             x_ = x;
    1697              : 
    1698              :           return *this;
    1699              :         }
    1700              : 
    1701              :       public:
    1702              :         /**
    1703              :          * @brief Implicitly convert the instance to constant reference to
    1704              :          * the underlying type.
    1705              :          *
    1706              :          * @return A constant reference to the underlying type.
    1707              :          */
    1708              :         operator const T& () const
    1709              :         {
    1710              :           return x_;
    1711              :         }
    1712              : 
    1713              :         /**
    1714              :          * @brief Implicitly convert the instance to reference to the
    1715              :          * underlying type.
    1716              :          *
    1717              :          * @return A reference to the underlying type.
    1718              :          */
    1719              :         operator T& ()
    1720              :         {
    1721              :           return x_;
    1722              :         }
    1723              : 
    1724              :         // The following extra conversion operators causes problems on
    1725              :         // some compilers (notably VC 9.0) and are disabled by default.
    1726              :         //
    1727              : #ifdef XSD_TREE_EXTRA_FUND_CONV
    1728              :         /**
    1729              :          * @brief Implicitly convert the instance to another type (const
    1730              :          * version).
    1731              :          *
    1732              :          * @return A value converted to the target type.
    1733              :          */
    1734              :         template <typename T2>
    1735              :         operator T2 () const
    1736              :         {
    1737              :           return x_;
    1738              :         }
    1739              : 
    1740              :         /**
    1741              :          * @brief Implicitly convert the instance to another type.
    1742              :          *
    1743              :          * @return A value converted to the target type.
    1744              :          */
    1745              :         template <typename T2>
    1746              :         operator T2 ()
    1747              :         {
    1748              :           return x_;
    1749              :         }
    1750              : #endif // XSD_TREE_EXTRA_FUND_CONV
    1751              : 
    1752              :       public:
    1753              :         /**
    1754              :          * @brief Get the facet table associated with this type.
    1755              :          *
    1756              :          * @return A pointer to read-only facet table or 0.
    1757              :          */
    1758              :         const facet*
    1759              :         _facet_table () const
    1760              :         {
    1761              :           return facet_table_;
    1762              :         }
    1763              : 
    1764              :       protected:
    1765              :         /**
    1766              :          * @brief Set the facet table associated with this type.
    1767              :          *
    1768              :          * @param ft A pointer to read-only facet table.
    1769              :          */
    1770              :         void
    1771              :         _facet_table (const facet* ft)
    1772              :         {
    1773              :           facet_table_ = ft;
    1774              :         }
    1775              : 
    1776              :       private:
    1777              :         const facet* facet_table_;
    1778              :         T x_;
    1779              :       };
    1780              : 
    1781              :       // While thse operators are not normally necessary, they
    1782              :       // help resolve ambiguities between implicit conversion and
    1783              :       // construction.
    1784              :       //
    1785              : 
    1786              :       /**
    1787              :        * @brief %fundamental_base comparison operator.
    1788              :        *
    1789              :        * @return True if the underlying values are equal, false otherwise.
    1790              :        */
    1791              :       template <typename T, typename C, typename B, schema_type::value ST>
    1792              :       inline bool
    1793              :       operator== (const fundamental_base<T, C, B, ST>& x,
    1794              :                   const fundamental_base<T, C, B, ST>& y)
    1795              :       {
    1796              :         T x_ (x);
    1797              :         T y_ (y);
    1798              :         return x_ == y_;
    1799              :       }
    1800              : 
    1801              :       /**
    1802              :        * @brief %fundamental_base comparison operator.
    1803              :        *
    1804              :        * @return True if the underlying values are not equal, false otherwise.
    1805              :        */
    1806              :       template <typename T, typename C, typename B, schema_type::value ST>
    1807              :       inline bool
    1808              :       operator!= (const fundamental_base<T, C, B, ST>& x,
    1809              :                   const fundamental_base<T, C, B, ST>& y)
    1810              :       {
    1811              :         T x_ (x);
    1812              :         T y_ (y);
    1813              :         return x_ != y_;
    1814              :       }
    1815              : 
    1816              : 
    1817              :       //@cond
    1818              : 
    1819              :       // Comparator for enum tables.
    1820              :       //
    1821              :       template <typename C>
    1822              :       struct enum_comparator
    1823              :       {
    1824              :         enum_comparator (const C* const* table)
    1825              :             : table_ (table)
    1826              :         {
    1827              :         }
    1828              : 
    1829              :         bool
    1830              :         operator() (std::size_t i, const std::basic_string<C>& s) const
    1831              :         {
    1832              :           return table_[i] < s;
    1833              :         }
    1834              : 
    1835              :         bool
    1836              :         operator() (const std::basic_string<C>& s, std::size_t i) const
    1837              :         {
    1838              :           return s < table_[i];
    1839              :         }
    1840              : 
    1841              :         // This overload shouldn't be necessary according to the standard
    1842              :         // and removing it doesn't appear to trip any old compilers that
    1843              :         // we still support. But let's keeps preprocessed-out until we
    1844              :         // go C++11-only.
    1845              :         //
    1846              : #if 0
    1847              :         bool
    1848              :         operator() (std::size_t i, std::size_t j) const
    1849              :         {
    1850              :           return std::basic_string<C> (table_[i]) < table_[j];
    1851              :         }
    1852              : #endif
    1853              : 
    1854              :       private:
    1855              :         const C* const* table_;
    1856              :       };
    1857              : 
    1858              :       //@endcond
    1859              :     }
    1860              :   }
    1861              : }
    1862              : 
    1863              : #include <xsd/cxx/tree/elements.ixx>
    1864              : #include <xsd/cxx/tree/elements.txx>
    1865              : 
    1866              : #endif  // XSD_CXX_TREE_ELEMENTS_HXX
        

Generated by: LCOV version 2.0-1