root/win32/xsd-3.1.0-i686/libxsd/xsd/cxx/tree/elements.hxx @ 111

Revision 111, 34.9 kB (checked in by mido, 16 years ago)

pridana knihovna XSD (a jeji chlebodarkyne XERCES), v ramci Win32 zprovoznen priklad tests/test_xsd_hello.cxx

Line 
1// file      : xsd/cxx/tree/elements.hxx
2// author    : Boris Kolpackov <boris@codesynthesis.com>
3// copyright : Copyright (c) 2005-2008 Code Synthesis Tools CC
4// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
5
6/**
7 * @file
8 *
9 * @brief Contains C++ class definitions for XML Schema anyType and
10 * anySimpleType types as well as supporting code.
11 *
12 * This is an internal header and is included by the generated code. You
13 * normally should not include it directly.
14 *
15 */
16
17#ifndef XSD_CXX_TREE_ELEMENTS_HXX
18#define XSD_CXX_TREE_ELEMENTS_HXX
19
20#include <map>
21#include <string>
22#include <memory>  // std::auto_ptr
23#include <istream>
24#include <sstream>
25#include <cassert>
26
27#include <xercesc/dom/DOMNode.hpp>
28#include <xercesc/dom/DOMAttr.hpp>
29#include <xercesc/dom/DOMElement.hpp>
30#include <xercesc/dom/DOMDocument.hpp>
31#include <xercesc/dom/DOMNamedNodeMap.hpp>
32
33#include <xsd/cxx/xml/elements.hxx> // xml::properties
34#include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr
35
36#include <xsd/cxx/tree/exceptions.hxx>
37#include <xsd/cxx/tree/istream-fwd.hxx>
38
39namespace xsd
40{
41  namespace cxx
42  {
43    /**
44     * @brief C++/Tree mapping runtime namespace.
45     *
46     * This is an internal namespace and normally should not be referenced
47     * directly. Instead you should use the aliases for types in this
48     * namespaces that are created in the generated code.
49     *
50     */
51    namespace tree
52    {
53      /**
54       * @brief Parsing and %serialization %flags.
55       *
56       * Flags are used to modify the default behavior of %parsing and
57       * %serialization functions as well as %parsing constructors.
58       *
59       * @nosubgrouping
60       */
61      class flags
62      {
63      public:
64        /**
65         * @name Flag constants
66         */
67        //@{
68
69        /**
70         * @brief Keep DOM association in the resulting tree.
71         */
72        static const unsigned long keep_dom = 0x00000100UL;
73
74        /**
75         * @brief Assume ownership of the DOM document.
76         *
77         * This flag only makes sense together with the @c keep_dom
78         * flag in the call to the %parsing function with the
79         * @c dom::auto_ptr<DOMDocument> argument.
80         *
81         */
82        static const unsigned long own_dom = 0x00000200UL;
83
84        /**
85         * @brief Turn off XML Schema validation in the underlying XML
86         * parser.
87         */
88        static const unsigned long dont_validate = 0x00000400UL;
89
90        /**
91         * @brief Do not initialize the Xerces-C++ runtime.
92         */
93        static const unsigned long dont_initialize = 0x00000001UL;
94
95        /**
96         * @brief Do not write XML declaration during %serialization.
97         */
98        static const unsigned long no_xml_declaration = 0x00010000UL;
99
100
101        //@cond
102
103        // The following flags are for internal use.
104        //
105        static const unsigned long base = 0x01000000UL;
106
107        //@endcond
108
109        // Notes on flag blocks:
110        //
111        // 0x000000FF - common (applicable to both parsing and serialization)
112        // 0x0000FF00 - parsing (values aligned with XML parsing)
113        // 0x00FF0000 - serialization (values aligned with XML serialization)
114        // 0xFF000000 - internal
115
116        //@}
117
118      public:
119        /**
120         * @brief Initialize an instance with an integer value.
121         *
122         * @param x A %flags value as an integer.
123         */
124        flags (unsigned long x = 0)
125            : x_ (x)
126        {
127        }
128
129        /**
130         * @brief Convert an instance to an integer value.
131         *
132         * @return An integer %flags value.
133         */
134        operator unsigned long () const
135        {
136          return x_;
137        }
138
139        /**
140         * @brief Combine two %flags.
141         *
142         * @return A %flags object that is a combination of the arguments.
143         */
144        friend flags
145        operator| (const flags& a, const flags& b)
146        {
147          return flags (a.x_ | b.x_);
148        }
149
150        /**
151         * @brief Combine two %flags.
152         *
153         * @return A %flags object that is a combination of the arguments.
154         */
155        friend flags
156        operator| (const flags& a, unsigned long b)
157        {
158          return flags (a.x_ | b);
159        }
160
161        /**
162         * @brief Combine two %flags.
163         *
164         * @return A %flags object that is a combination of the arguments.
165         */
166        friend flags
167        operator| (unsigned long a, const flags& b)
168        {
169          return flags (a | b.x_);
170        }
171
172      private:
173        unsigned long x_;
174      };
175
176
177      // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for XML-
178      // related properties.
179      //
180      template <typename C>
181      class properties: public xml::properties<C>
182      {
183      };
184
185      //@cond
186
187      // DOM user data keys.
188      //
189      template <int dummy>
190      struct user_data_keys_template
191      {
192        // Back pointers to tree nodes.
193        //
194        static const XMLCh node[21];
195      };
196
197      typedef user_data_keys_template<0> user_data_keys;
198
199      // HP aCC3 complains about unresolved symbols without an explicit
200      // instantiation.
201      //
202#if defined(__HP_aCC) && __HP_aCC <= 39999
203      template struct user_data_keys_template<0>;
204#endif
205      //
206      //
207      struct identity
208      {
209        virtual
210        ~identity ()
211        {
212        }
213
214        identity ()
215        {
216        }
217
218        virtual bool
219        before (const identity&) const = 0;
220
221        virtual void
222        throw_duplicate_id () const = 0;
223
224      private:
225        identity (const identity&);
226
227        identity&
228        operator= (const identity&);
229      };
230
231      //@endcond
232
233
234      // anyType. VC++ has a name injection bug that makes it impossible
235      // to have a member with the same name as a base type. To address
236      // that we will have to choose some unique name for the definition
237      // and typedef it to 'type'.
238      //
239      class _type;
240
241      /**
242       * @brief Class corresponding to the XML Schema anyType built-in type.
243       *
244       */
245      typedef _type type;
246
247      /**
248       * @brief Container type.
249       *
250       */
251      typedef _type container;
252
253      /**
254       * @brief Class corresponding to the XML Schema anyType built-in type.
255       *
256       * This class is a base for every generated and built-in type in the
257       * C++/Tree mapping.
258       *
259       * @nosubgrouping
260       */
261      class _type
262      {
263      public:
264        virtual
265        ~_type ()
266        {
267          // Everything should have been unregistered by now.
268          //
269          assert (map_.get () == 0 || map_->size () == 0);
270        }
271
272      public:
273        /**
274         * @name Constructors
275         */
276        //@{
277
278        /**
279         * @brief Default constructor.
280         */
281        _type ()
282            : container_ (0)
283        {
284        }
285
286      public:
287        /**
288         * @brief Copy constructor.
289         *
290         * @param x An instance to make a copy of.
291         * @param f Flags to create the copy with.
292         * @param c A pointer to the object that will contain the copy.
293         *
294         * For polymorphic object models use the @c _clone function instead.
295         */
296        _type (const type& x, flags f = 0, container* c = 0)
297            : container_ (c)
298        {
299          while (&f == 0) /* unused */;
300
301          if (x.dom_info_.get ())
302          {
303            std::auto_ptr<dom_info> r (x.dom_info_->clone (*this, c));
304            dom_info_ = r;
305          }
306        }
307
308        /**
309         * @brief Copy the instance polymorphically.
310         *
311         * @param f Flags to create the copy with.
312         * @param c A pointer to the object that will contain the copy.
313         * @return A pointer to the dynamically allocated copy.
314         *
315         * This function ensures that the dynamic type of the instance
316         * is used for copying and should be used for polymorphic object
317         * models instead of the copy constructor.
318         */
319        virtual type*
320        _clone (flags f = 0, container* c = 0) const
321        {
322          return new type (*this, f, c);
323        }
324
325      public:
326        /**
327         * @brief Create an instance from a data representation
328         * stream.
329         *
330         * @param s A stream to extract the data from.
331         * @param f Flags to create the new instance with.
332         * @param c A pointer to the object that will contain the new
333         * instance.
334         */
335        template <typename S>
336        _type (istream<S>& s, flags f = 0, container* c = 0);
337
338        /**
339         * @brief Create an instance from a DOM element.
340         *
341         * @param e A DOM element to extract the data from.
342         * @param f Flags to create the new instance with.
343         * @param c A pointer to the object that will contain the new
344         * instance.
345         */
346        _type (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
347
348        /**
349         * @brief Create an instance from a DOM Attribute.
350         *
351         * @param a A DOM attribute to extract the data from.
352         * @param f Flags to create the new instance with.
353         * @param c A pointer to the object that will contain the new
354         * instance.
355         */
356        _type (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
357
358        /**
359         * @brief Create an instance from a %string fragment.
360         *
361         * @param s A %string fragment to extract the data from.
362         * @param e A pointer to DOM element containing the %string fragment.
363         * @param f Flags to create the new instance with.
364         * @param c A pointer to the object that will contain the new
365         * instance.
366         */
367        template <typename C>
368        _type (const std::basic_string<C>& s,
369               const xercesc::DOMElement* e,
370               flags f = 0,
371               container* c = 0);
372        //@}
373
374      public:
375        /**
376         * @brief Copy assignment operator.
377         *
378         * @param x An instance to assign.
379         * @return A reference to the instance.
380         */
381        type&
382        operator= (const type& x)
383        {
384          while (&x == 0) /* unused */;
385          return *this;
386        }
387
388        // Container API.
389        //
390      public:
391        /**
392         * @brief Get a constant pointer to container, an object model
393         * node that contains this instance.
394         *
395         * @return A constant pointer to container, or 0 if this instance
396         * is not contained.
397         */
398        const container*
399        _container () const
400        {
401          return container_;
402        }
403
404        /**
405         * @brief Get a pointer to container, an object model node that
406         * contains this instance.
407         *
408         * @return A pointer to container, or 0 if this instance is not
409         * contained.
410         */
411        container*
412        _container ()
413        {
414          return container_;
415        }
416
417        /**
418         * @brief Set this instance's new container, an object model node
419         * that contains this instance.
420         *
421         * @param c A pointer to container.
422         */
423        virtual void
424        _container (container* c)
425        {
426          assert (container_ == 0);
427
428          if (c != 0)
429          {
430            if (map_.get () != 0)
431            {
432              // Propagate our IDs to the new container.
433              //
434              for (map::iterator i (map_->begin ()), e (map_->end ());
435                   i != e; ++i)
436              {
437                c->_register_id (*i->first, i->second);
438              }
439            }
440
441            container_ = c;
442          }
443        }
444
445        /**
446         * @brief Get a constant pointer to object model's root node.
447         *
448         * @return A constant pointer to root node, or 0 if this instance
449         * is not contained.
450         */
451        const container*
452        _root () const
453        {
454          const container* r (container_);
455
456          for (const container* c (r); c != 0; c = c->container_)
457            r = c;
458
459          return r;
460        }
461
462        /**
463         * @brief Get a pointer to object model's root node.
464         *
465         * @return A pointer to root node, or 0 if this instance is not
466         * contained.
467         */
468        container*
469        _root ()
470        {
471          container* r (container_);
472
473          for (container* c (r); c != 0; c = c->container_)
474            r = c;
475
476          return r;
477        }
478
479        // DOM association.
480        //
481      public:
482        /**
483         * @brief Get a constant pointer to a DOM node associated with
484         * this object model node.
485         *
486         * @return A constant pointer to DOM node, or 0 if none associated.
487         */
488        const xercesc::DOMNode*
489        _node () const
490        {
491          return dom_info_.get () ? dom_info_->node() : 0;
492        }
493
494        /**
495         * @brief Get a pointer to a DOM node associated with this object
496         * model node.
497         *
498         * @return A pointer to DOM node, or 0 if none associated.
499         */
500        xercesc::DOMNode*
501        _node ()
502        {
503          return dom_info_.get () ? dom_info_->node () : 0;
504        }
505
506        /**
507         * @brief Exception indicating that a DOM node cannot be associated
508         * with an object model node.
509         */
510        class bad_dom_node_type: public std::exception //@@ Inherit exception.
511        {
512        public:
513          /**
514           * @brief Get %exception description.
515           *
516           * @return A C %string describing the %exception.
517           */
518          virtual const char*
519          what () const throw ()
520          {
521            return "DOM node is not an attribute node or element node";
522          }
523        };
524
525        /**
526         * @brief Manually set a DOM node associated with this object
527         * model node.
528         *
529         * The DOM node should be a child of the parent's DOM node. If
530         * this object model node is a root of the tree, then it will
531         * assume the ownership of the whole DOM document to which this
532         * DOM node belongs.
533         *
534         * @param n A pointer to DOM node (should be either an element or
535         * an attribute).
536         */
537        void
538        _node (xercesc::DOMNode* n)
539        {
540          switch (n->getNodeType ())
541          {
542          case xercesc::DOMNode::ELEMENT_NODE:
543            {
544              if (container_ != 0)
545              {
546                // @@ Should be a throw.
547                //
548                assert (_root ()->_node () != 0);
549                assert (_root ()->_node ()->getOwnerDocument () ==
550                        n->getOwnerDocument ());
551              }
552
553              std::auto_ptr<dom_info> r (
554                dom_info_factory::create (
555                  *static_cast<xercesc::DOMElement*> (n),
556                  *this,
557                  container_ == 0));
558
559              dom_info_ = r;
560              break;
561            }
562          case xercesc::DOMNode::ATTRIBUTE_NODE:
563            {
564              //@@ Should be a throw.
565              //
566              assert (container_ != 0);
567              assert (_root ()->_node () != 0);
568              assert (_root ()->_node ()->getOwnerDocument () ==
569                      n->getOwnerDocument ());
570
571              std::auto_ptr<dom_info> r (
572                dom_info_factory::create (
573                  *static_cast<xercesc::DOMAttr*> (n),
574                  *this));
575
576              dom_info_ = r;
577              break;
578            }
579          default:
580            {
581              throw bad_dom_node_type ();
582            }
583          }
584        }
585
586      public:
587        //@cond
588
589        void
590        _register_id (const identity& id, type* t)
591        {
592          if (map_.get () == 0)
593            map_.reset (new map);
594
595          // First register on our container. If there are any duplications,
596          // they will be detected by this call and we don't need to clean
597          // the map.
598          //
599          if (container_ != 0)
600            container_->_register_id (id, t);
601
602          if (!map_->insert (
603                std::pair<const identity*, type*> (&id, t)).second)
604          {
605            id.throw_duplicate_id ();
606          }
607        }
608
609        //@@ Does not inherit from exception.
610        //
611        struct not_registered: std::exception
612        {
613          virtual const char*
614          what () const throw ()
615          {
616            return "attempt to unregister non-existent id";
617          }
618        };
619
620        void
621        _unregister_id (const identity& id)
622        {
623          if (map_.get ())
624          {
625            map::iterator it (map_->find (&id));
626
627            if (it != map_->end ())
628            {
629              map_->erase (it);
630
631              if (container_ != 0)
632                container_->_unregister_id (id);
633
634              return;
635            }
636          }
637
638          throw not_registered ();
639        }
640
641        type*
642        _lookup_id (const identity& id) const
643        {
644          if (map_.get ())
645          {
646            map::const_iterator it (map_->find (&id));
647
648            if (it != map_->end ())
649              return it->second;
650          }
651
652          return 0;
653        }
654
655        //@endcond
656
657      private:
658        //@cond
659
660        struct dom_info
661        {
662          virtual
663          ~dom_info ()
664          {
665          }
666
667          dom_info ()
668          {
669          }
670
671          virtual std::auto_ptr<dom_info>
672          clone (type& tree_node, container*) const = 0;
673
674          virtual xercesc::DOMNode*
675          node () = 0;
676
677        private:
678          dom_info (const dom_info&);
679
680          dom_info&
681          operator= (const dom_info&);
682        };
683
684
685        struct dom_element_info: public dom_info
686        {
687          dom_element_info (xercesc::DOMElement& e, type& n, bool root)
688              : doc_ (0), e_ (e)
689          {
690            e_.setUserData (user_data_keys::node, &n, 0);
691
692            if (root)
693            {
694              // The caller should have associated a dom::auto_ptr object
695              // that owns this document with the document node using the
696              // xml_schema::dom::tree_node_key key.
697              //
698              xml::dom::auto_ptr<xercesc::DOMDocument>* pd (
699                reinterpret_cast<xml::dom::auto_ptr<xercesc::DOMDocument>*> (
700                  e.getOwnerDocument ()->getUserData (user_data_keys::node)));
701
702              assert (pd != 0);
703              assert (pd->get () == e.getOwnerDocument ());
704
705              doc_ = *pd; // Transfer ownership.
706            }
707          }
708
709          virtual std::auto_ptr<dom_info>
710          clone (type& tree_node, container* c) const
711          {
712            using std::auto_ptr;
713
714            // Check if we are a document root.
715            //
716            if (c == 0)
717            {
718              // We preserver DOM associations only in complete
719              // copies from root.
720              //
721              if (doc_.get () == 0)
722                return auto_ptr<dom_info> (0);
723
724              return auto_ptr<dom_info> (
725                new dom_element_info (*doc_, tree_node));
726            }
727
728            // Check if our container does not have DOM association (e.g.,
729            // because it wasn't a complete copy of the tree).
730            //
731            using xercesc::DOMNode;
732
733            DOMNode* cn (c->_node ());
734
735            if (cn == 0)
736              return auto_ptr<dom_info> (0);
737
738
739            // Now we are going to find the corresponding element in
740            // the new tree.
741            //
742            {
743              using xercesc::DOMElement;
744
745              DOMNode& pn (*e_.getParentNode ());
746              assert (pn.getNodeType () == DOMNode::ELEMENT_NODE);
747
748              DOMNode* sn (pn.getFirstChild ()); // Source.
749              DOMNode* dn (cn->getFirstChild ()); // Destination.
750
751              // We should have at least one child.
752              //
753              assert (sn != 0);
754
755              // Move in parallel until we get to the needed node.
756              //
757              for (; sn != 0 && !e_.isSameNode (sn);)
758              {
759                sn = sn->getNextSibling ();
760                dn = dn->getNextSibling ();
761              }
762
763              // e_ should be on the list.
764              //
765              assert (sn != 0);
766
767              assert (dn->getNodeType () == DOMNode::ELEMENT_NODE);
768
769              return auto_ptr<dom_info> (
770                new dom_element_info (static_cast<DOMElement&> (*dn),
771                                      tree_node,
772                                      false));
773            }
774          }
775
776          virtual xercesc::DOMNode*
777          node ()
778          {
779            return &e_;
780          }
781
782        private:
783          dom_element_info (const xercesc::DOMDocument& d, type& n)
784              : doc_ (static_cast<xercesc::DOMDocument*> (
785                        d.cloneNode (true))),
786                e_ (*doc_->getDocumentElement ())
787          {
788            e_.setUserData (user_data_keys::node, &n, 0);
789          }
790
791        private:
792          xml::dom::auto_ptr<xercesc::DOMDocument> doc_;
793          xercesc::DOMElement& e_;
794        };
795
796
797        struct dom_attribute_info: public dom_info
798        {
799          dom_attribute_info (xercesc::DOMAttr& a, type& n)
800              : a_ (a)
801          {
802            a_.setUserData (user_data_keys::node, &n, 0);
803          }
804
805          virtual std::auto_ptr<dom_info>
806          clone (type& tree_node, container* c) const
807          {
808            using std::auto_ptr;
809
810            // Check if we are a document root.
811            //
812            if (c == 0)
813            {
814              // We preserver DOM associations only in complete
815              // copies from root.
816              //
817              return auto_ptr<dom_info> (0);
818            }
819
820            // Check if our container does not have DOM association (e.g.,
821            // because it wasn't a complete copy of the tree).
822            //
823            using xercesc::DOMNode;
824
825            DOMNode* cn (c->_node ());
826
827            if (cn == 0)
828              return auto_ptr<dom_info> (0);
829
830            // We are going to find the corresponding attribute in
831            // the new tree.
832            //
833            using xercesc::DOMAttr;
834            using xercesc::DOMElement;
835            using xercesc::DOMNamedNodeMap;
836
837            DOMElement& p (*a_.getOwnerElement ());
838            DOMNamedNodeMap& nl (*p.getAttributes ());
839
840            XMLSize_t size (nl.getLength ()), i (0);
841
842            // We should have at least one child.
843            //
844            assert (size != 0);
845
846            for ( ;i < size && !a_.isSameNode (nl.item (i)); ++i);
847
848            // a_ should be in the list.
849            //
850            assert (i < size);
851
852            DOMNode& n (*cn->getAttributes ()->item (i));
853            assert (n.getNodeType () == DOMNode::ATTRIBUTE_NODE);
854
855            return auto_ptr<dom_info> (
856              new dom_attribute_info (static_cast<DOMAttr&> (n), tree_node));
857          }
858
859          virtual xercesc::DOMNode*
860          node ()
861          {
862            return &a_;
863          }
864
865        private:
866          xercesc::DOMAttr& a_;
867        };
868
869        // For Sun C++ 5.6.
870        //
871        struct dom_info_factory;
872        friend struct _type::dom_info_factory;
873
874        struct dom_info_factory
875        {
876          static std::auto_ptr<dom_info>
877          create (const xercesc::DOMElement& e, type& n, bool root)
878          {
879            return std::auto_ptr<dom_info> (
880              new dom_element_info (
881                const_cast<xercesc::DOMElement&> (e), n, root));
882          }
883
884          static std::auto_ptr<dom_info>
885          create (const xercesc::DOMAttr& a, type& n)
886          {
887            return std::auto_ptr<dom_info> (
888              new dom_attribute_info (
889                const_cast<xercesc::DOMAttr&> (a), n));
890          }
891        };
892
893        //@endcond
894
895        std::auto_ptr<dom_info> dom_info_;
896
897
898        // ID/IDREF map.
899        //
900      private:
901
902        //@cond
903
904        struct identity_comparator
905        {
906          bool operator () (const identity* x, const identity* y) const
907          {
908            return x->before (*y);
909          }
910        };
911
912        //@endcond
913
914        typedef
915        std::map<const identity*, type*, identity_comparator>
916        map;
917
918        std::auto_ptr<map> map_;
919
920      private:
921        container* container_;
922      };
923
924
925      /**
926       * @brief Class corresponding to the XML Schema anySimpleType built-in
927       * type.
928       *
929       * @nosubgrouping
930       */
931      template <typename B>
932      class simple_type: public B
933      {
934      public:
935        /**
936         * @name Constructors
937         */
938        //@{
939
940        /**
941         * @brief Default constructor.
942         */
943        simple_type ()
944        {
945        }
946
947      public:
948        /**
949         * @brief Copy constructor.
950         *
951         * @param x An instance to make a copy of.
952         * @param f Flags to create the copy with.
953         * @param c A pointer to the object that will contain the copy.
954         *
955         * For polymorphic object models use the @c _clone function instead.
956         */
957        simple_type (const simple_type& x, flags f = 0, container* c = 0);
958
959        /**
960         * @brief Copy the instance polymorphically.
961         *
962         * @param f Flags to create the copy with.
963         * @param c A pointer to the object that will contain the copy.
964         * @return A pointer to the dynamically allocated copy.
965         *
966         * This function ensures that the dynamic type of the instance
967         * is used for copying and should be used for polymorphic object
968         * models instead of the copy constructor.
969         */
970        virtual simple_type*
971        _clone (flags f = 0, container* c = 0) const;
972
973      public:
974        /**
975         * @brief Create an instance from a data representation
976         * stream.
977         *
978         * @param s A stream to extract the data from.
979         * @param f Flags to create the new instance with.
980         * @param c A pointer to the object that will contain the new
981         * instance.
982         */
983        template <typename S>
984        simple_type (istream<S>& s, flags f = 0, container* c = 0);
985
986        /**
987         * @brief Create an instance from a DOM element.
988         *
989         * @param e A DOM element to extract the data from.
990         * @param f Flags to create the new instance with.
991         * @param c A pointer to the object that will contain the new
992         * instance.
993         */
994        simple_type (const xercesc::DOMElement& e,
995                     flags f = 0,
996                     container* c = 0);
997
998        /**
999         * @brief Create an instance from a DOM Attribute.
1000         *
1001         * @param a A DOM attribute to extract the data from.
1002         * @param f Flags to create the new instance with.
1003         * @param c A pointer to the object that will contain the new
1004         * instance.
1005         */
1006        simple_type (const xercesc::DOMAttr& a,
1007                     flags f = 0,
1008                     container* c = 0);
1009
1010        /**
1011         * @brief Create an instance from a %string fragment.
1012         *
1013         * @param s A %string fragment to extract the data from.
1014         * @param e A pointer to DOM element containing the %string fragment.
1015         * @param f Flags to create the new instance with.
1016         * @param c A pointer to the object that will contain the new
1017         * instance.
1018         */
1019        template <typename C>
1020        simple_type (const std::basic_string<C>& s,
1021                     const xercesc::DOMElement* e,
1022                     flags f = 0,
1023                     container* c = 0);
1024        //@}
1025      };
1026
1027
1028      //@cond
1029
1030      template <typename T, typename C>
1031      struct traits
1032      {
1033        typedef T type;
1034
1035        static std::auto_ptr<T>
1036        create (const xercesc::DOMElement& e, flags f, container* c)
1037        {
1038          return std::auto_ptr<T> (new T (e, f, c));
1039        }
1040
1041        static std::auto_ptr<T>
1042        create (const xercesc::DOMAttr& a, flags f, container* c)
1043        {
1044          return std::auto_ptr<T> (new T (a, f, c));
1045        }
1046
1047        static std::auto_ptr<T>
1048        create (const std::basic_string<C>& s,
1049                const xercesc::DOMElement* e,
1050                flags f,
1051                container* c)
1052        {
1053          return std::auto_ptr<T> (new T (s, e, f, c));
1054        }
1055      };
1056
1057      //@endcond
1058
1059
1060      /**
1061       * @brief Class template that emulates inheritance from a
1062       * fundamental C++ type.
1063       *
1064       * @nosubgrouping
1065       */
1066      template <typename X, typename C, typename B>
1067      class fundamental_base: public B
1068      {
1069      public:
1070        /**
1071         * @name Constructors
1072         */
1073        //@{
1074
1075        /**
1076         * @brief Default constructor.
1077         */
1078        fundamental_base ()
1079            : x_ ()
1080        {
1081        }
1082
1083        /**
1084         * @brief Initialize an instance with an underlying type value.
1085         *
1086         * @param x An underlying type value.
1087         */
1088        fundamental_base (X x)
1089            : x_ (x)
1090        {
1091        }
1092
1093      public:
1094        /**
1095         * @brief Copy constructor.
1096         *
1097         * @param x An instance to make a copy of.
1098         * @param f Flags to create the copy with.
1099         * @param c A pointer to the object that will contain the copy.
1100         *
1101         * For polymorphic object models use the @c _clone function instead.
1102         */
1103        fundamental_base (const fundamental_base& x,
1104                          flags f = 0,
1105                          container* c = 0)
1106            : B (x, f, c), x_ (x.x_)
1107        {
1108        }
1109
1110        /**
1111         * @brief Copy the instance polymorphically.
1112         *
1113         * @param f Flags to create the copy with.
1114         * @param c A pointer to the object that will contain the copy.
1115         * @return A pointer to the dynamically allocated copy.
1116         *
1117         * This function ensures that the dynamic type of the instance
1118         * is used for copying and should be used for polymorphic object
1119         * models instead of the copy constructor.
1120         */
1121        virtual fundamental_base*
1122        _clone (flags f = 0, container* c = 0) const;
1123
1124      public:
1125        /**
1126         * @brief Create an instance from a data representation
1127         * stream.
1128         *
1129         * @param s A stream to extract the data from.
1130         * @param f Flags to create the new instance with.
1131         * @param c A pointer to the object that will contain the new
1132         * instance.
1133         */
1134        template <typename S>
1135        fundamental_base (istream<S>& s, flags f = 0, container* c = 0);
1136
1137        /**
1138         * @brief Create an instance from a DOM element.
1139         *
1140         * @param e A DOM element to extract the data from.
1141         * @param f Flags to create the new instance with.
1142         * @param c A pointer to the object that will contain the new
1143         * instance.
1144         */
1145        fundamental_base (const xercesc::DOMElement& e,
1146                          flags f = 0,
1147                          container* c = 0);
1148
1149        /**
1150         * @brief Create an instance from a DOM Attribute.
1151         *
1152         * @param a A DOM attribute to extract the data from.
1153         * @param f Flags to create the new instance with.
1154         * @param c A pointer to the object that will contain the new
1155         * instance.
1156         */
1157        fundamental_base (const xercesc::DOMAttr& a,
1158                          flags f = 0,
1159                          container* c = 0);
1160
1161        /**
1162         * @brief Create an instance from a %string fragment.
1163         *
1164         * @param s A %string fragment to extract the data from.
1165         * @param e A pointer to DOM element containing the %string fragment.
1166         * @param f Flags to create the new instance with.
1167         * @param c A pointer to the object that will contain the new
1168         * instance.
1169         */
1170        fundamental_base (const std::basic_string<C>& s,
1171                          const xercesc::DOMElement* e,
1172                          flags f = 0,
1173                          container* c = 0);
1174        //@}
1175
1176      public:
1177        /**
1178         * @brief Assign an underlying type value to the instance.
1179         *
1180         * @param x An underlying type value.
1181         * @return A reference to the instance.
1182         */
1183        fundamental_base&
1184        operator= (const X& x)
1185        {
1186          if (&x_ != &x)
1187            x_ = x;
1188
1189          return *this;
1190        }
1191
1192      public:
1193        /**
1194         * @brief Implicitly convert the instance to constant reference to
1195         * the underlying type.
1196         *
1197         * @return A constant reference to the underlying type.
1198         */
1199        operator const X& () const
1200        {
1201          return x_;
1202        }
1203
1204        /**
1205         * @brief Implicitly convert the instance to reference to the
1206         * underlying type.
1207         *
1208         * @return A reference to the underlying type.
1209         */
1210        operator X& ()
1211        {
1212          return x_;
1213        }
1214
1215        // A call to one of the following operators causes ICE on VC++ 7.1.
1216        // Refer to the following discussion for details:
1217        //
1218        // http://codesynthesis.com/pipermail/xsd-users/2006-June/000399.html
1219        //
1220#if defined(_MSC_VER) && _MSC_VER >= 1400
1221
1222        /**
1223         * @brief Implicitly convert the instance to another type (const
1224         * version).
1225         *
1226         * @return A value converted to the target type.
1227         */
1228        template <typename Y>
1229        operator Y () const
1230        {
1231          return x_;
1232        }
1233
1234        /**
1235         * @brief Implicitly convert the instance to another type.
1236         *
1237         * @return A value converted to the target type.
1238         */
1239        template <typename Y>
1240        operator Y ()
1241        {
1242          return x_;
1243        }
1244#endif
1245
1246      private:
1247        X x_;
1248      };
1249
1250      // While this operators are not normally necessary, they
1251      // help resolve ambiguities between implicit conversion and
1252      // construction.
1253      //
1254
1255      /**
1256       * @brief %fundamental_base comparison operator.
1257       *
1258       * @return True if the underlying values are equal, false otherwise.
1259       */
1260      template <typename X, typename C, typename B>
1261      inline bool
1262      operator== (const fundamental_base<X, C, B>& x,
1263                  const fundamental_base<X, C, B>& y)
1264      {
1265        X x_ (x);
1266        X y_ (y);
1267        return x_ == y_;
1268      }
1269
1270      /**
1271       * @brief %fundamental_base comparison operator.
1272       *
1273       * @return True if the underlying values are not equal, false otherwise.
1274       */
1275      template <typename X, typename C, typename B>
1276      inline bool
1277      operator!= (const fundamental_base<X, C, B>& x,
1278                  const fundamental_base<X, C, B>& y)
1279      {
1280        X x_ (x);
1281        X y_ (y);
1282        return x_ != y_;
1283      }
1284
1285      //@cond
1286
1287      // Comparator for enum tables.
1288      //
1289      template <typename C>
1290      struct enum_comparator
1291      {
1292        enum_comparator (const C* const* table)
1293            : table_ (table)
1294        {
1295        }
1296
1297        bool
1298        operator() (std::size_t i, const std::basic_string<C>& s) const
1299        {
1300          return table_[i] < s;
1301        }
1302
1303        bool
1304        operator() (const std::basic_string<C>& s, std::size_t i) const
1305        {
1306          return s < table_[i];
1307        }
1308
1309        bool
1310        operator() (std::size_t i, std::size_t j) const
1311        {
1312          return std::basic_string<C> (table_[i]) < table_[j];
1313        }
1314
1315      private:
1316        const C* const* table_;
1317      };
1318
1319      //@endcond
1320    }
1321  }
1322}
1323
1324#include <xsd/cxx/tree/elements.txx>
1325
1326#endif  // XSD_CXX_TREE_ELEMENTS_HXX
Note: See TracBrowser for help on using the browser.