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