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
|