Line data Source code
1 : // file : xsd/cxx/tree/containers-wildcard.hxx
2 : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 : // license : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 :
5 : #ifndef XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
6 : #define XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
7 :
8 : #include <set>
9 : #include <string>
10 :
11 : #include <xercesc/dom/DOMAttr.hpp>
12 : #include <xercesc/dom/DOMElement.hpp>
13 : #include <xercesc/dom/DOMDocument.hpp>
14 : #include <xercesc/util/XMLString.hpp>
15 :
16 : #include <xsd/cxx/xml/string.hxx>
17 :
18 : #include <xsd/cxx/tree/iterator-adapter.hxx>
19 :
20 : namespace xsd
21 : {
22 : namespace cxx
23 : {
24 : namespace tree
25 : {
26 : // one (for internal use only)
27 : //
28 : class element_one
29 : {
30 : public:
31 : typedef xercesc::DOMElement value_type;
32 :
33 : ~element_one ()
34 : {
35 : if (x_)
36 : x_->release ();
37 : }
38 :
39 : explicit
40 : element_one (xercesc::DOMDocument& doc)
41 : : x_ (0), doc_ (doc)
42 : {
43 : }
44 :
45 : element_one (const xercesc::DOMElement& x, xercesc::DOMDocument& doc)
46 : : x_ (0), doc_ (doc)
47 : {
48 : set (x);
49 : }
50 :
51 : element_one (const element_one& x, xercesc::DOMDocument& doc)
52 : : x_ (0), doc_ (doc)
53 : {
54 : if (x.present ())
55 : set (x.get ());
56 : }
57 :
58 : element_one&
59 : operator= (const element_one& x)
60 : {
61 : if (this == &x)
62 : return *this;
63 :
64 : if (x.present ())
65 : set (x.get ());
66 : else if (x_)
67 : {
68 : x_->release ();
69 : x_ = 0;
70 : }
71 :
72 : return *this;
73 : }
74 :
75 : public:
76 : const xercesc::DOMElement&
77 : get () const
78 : {
79 : return *x_;
80 : }
81 :
82 : xercesc::DOMElement&
83 : get ()
84 : {
85 : return *x_;
86 : }
87 :
88 : void
89 : set (const xercesc::DOMElement& x)
90 : {
91 : using xercesc::DOMElement;
92 :
93 : DOMElement* r (
94 : static_cast<DOMElement*> (
95 : doc_.importNode (const_cast<DOMElement*> (&x), true)));
96 :
97 : if (x_)
98 : x_->release ();
99 :
100 : x_ = r;
101 : }
102 :
103 : void
104 : set (xercesc::DOMElement* x)
105 : {
106 : assert (x->getOwnerDocument () == &doc_);
107 :
108 : if (x_)
109 : x_->release ();
110 :
111 : x_ = x;
112 : }
113 :
114 : bool
115 : present () const
116 : {
117 : return x_ != 0;
118 : }
119 :
120 : protected:
121 : xercesc::DOMElement* x_;
122 : xercesc::DOMDocument& doc_;
123 : };
124 :
125 :
126 : //
127 : //
128 : class element_optional
129 : {
130 : public:
131 : typedef xercesc::DOMElement value_type;
132 :
133 0 : ~element_optional ()
134 : {
135 0 : if (x_)
136 0 : x_->release ();
137 0 : }
138 :
139 : explicit
140 0 : element_optional (xercesc::DOMDocument& doc)
141 0 : : x_ (0), doc_ (doc)
142 : {
143 0 : }
144 :
145 0 : element_optional (const xercesc::DOMElement& x,
146 : xercesc::DOMDocument& doc)
147 0 : : x_ (0), doc_ (doc)
148 : {
149 0 : set (x);
150 0 : }
151 :
152 : element_optional (xercesc::DOMElement* x, xercesc::DOMDocument& doc)
153 : : x_ (0), doc_ (doc)
154 : {
155 : set (x);
156 : }
157 :
158 0 : element_optional (const element_optional& x,
159 : xercesc::DOMDocument& doc)
160 0 : : x_ (0), doc_ (doc)
161 : {
162 0 : if (x)
163 0 : set (*x);
164 0 : }
165 :
166 : element_optional&
167 : operator= (const xercesc::DOMElement& x)
168 : {
169 : if (x_ == &x)
170 : return *this;
171 :
172 : set (x);
173 :
174 : return *this;
175 : }
176 :
177 : element_optional&
178 : operator= (const element_optional& x)
179 : {
180 : if (this == &x)
181 : return *this;
182 :
183 : if (x)
184 : set (*x);
185 : else
186 : reset ();
187 :
188 : return *this;
189 : }
190 :
191 : // Pointer-like interface.
192 : //
193 : public:
194 : const xercesc::DOMElement*
195 0 : operator-> () const
196 : {
197 0 : return x_;
198 : }
199 :
200 : xercesc::DOMElement*
201 : operator-> ()
202 : {
203 : return x_;
204 : }
205 :
206 : const xercesc::DOMElement&
207 0 : operator* () const
208 : {
209 0 : return *x_;
210 : }
211 :
212 : xercesc::DOMElement&
213 : operator* ()
214 : {
215 : return *x_;
216 : }
217 :
218 : typedef void (element_optional::*bool_convertible) ();
219 :
220 0 : operator bool_convertible () const
221 : {
222 0 : return x_ != 0 ? &element_optional::true_ : 0;
223 : }
224 :
225 : // Get/set interface.
226 : //
227 : public:
228 : bool
229 0 : present () const
230 : {
231 0 : return x_ != 0;
232 : }
233 :
234 : const xercesc::DOMElement&
235 0 : get () const
236 : {
237 0 : return *x_;
238 : }
239 :
240 : xercesc::DOMElement&
241 : get ()
242 : {
243 : return *x_;
244 : }
245 :
246 : void
247 0 : set (const xercesc::DOMElement& x)
248 : {
249 : using xercesc::DOMElement;
250 :
251 : DOMElement* r (
252 : static_cast<DOMElement*> (
253 0 : doc_.importNode (const_cast<DOMElement*> (&x), true)));
254 :
255 0 : if (x_)
256 0 : x_->release ();
257 :
258 0 : x_ = r;
259 0 : }
260 :
261 : void
262 : set (xercesc::DOMElement* x)
263 : {
264 : assert (x->getOwnerDocument () == &doc_);
265 :
266 : if (x_)
267 : x_->release ();
268 :
269 : x_ = x;
270 : }
271 :
272 : void
273 : reset ()
274 : {
275 : if (x_)
276 : x_->release ();
277 :
278 : x_ = 0;
279 : }
280 :
281 : private:
282 : void
283 0 : true_ ()
284 : {
285 0 : }
286 :
287 : private:
288 : xercesc::DOMElement* x_;
289 : xercesc::DOMDocument& doc_;
290 : };
291 :
292 : // Comparison operators.
293 : //
294 :
295 : inline bool
296 0 : operator== (const element_optional& a, const element_optional& b)
297 : {
298 0 : return !a || !b
299 0 : ? a.present () == b.present ()
300 0 : : a->isEqualNode (&b.get ());
301 : }
302 :
303 : inline bool
304 : operator!= (const element_optional& a, const element_optional& b)
305 : {
306 : return !(a == b);
307 : }
308 :
309 :
310 : //
311 : //
312 : class element_sequence
313 : {
314 : protected:
315 : // This is a dangerously destructive automatic pointer. We are going
316 : // to use it in a controlled environment to save us a lot of coding.
317 : //
318 : struct ptr
319 : {
320 : ~ptr ()
321 : {
322 : if (x_)
323 : x_->release ();
324 : }
325 :
326 : explicit
327 : ptr (xercesc::DOMElement* x = 0)
328 : : x_ (x)
329 : {
330 : }
331 :
332 : ptr (const ptr& y)
333 : : x_ (y.x_)
334 : {
335 : // Yes, hostile takeover.
336 : //
337 : y.x_ = 0;
338 : }
339 :
340 : ptr&
341 : operator= (const ptr& y)
342 : {
343 : if (this != &y)
344 : {
345 : // Yes, hostile takeover.
346 : //
347 : if (x_)
348 : x_->release ();
349 :
350 : x_ = y.x_;
351 : y.x_ = 0;
352 : }
353 :
354 : return *this;
355 : }
356 :
357 : public:
358 : xercesc::DOMElement&
359 : operator* () const
360 : {
361 : return *x_;
362 : }
363 :
364 : xercesc::DOMElement*
365 : get () const
366 : {
367 : return x_;
368 : }
369 :
370 : private:
371 : mutable xercesc::DOMElement* x_;
372 : };
373 :
374 : typedef std::vector<ptr> base_sequence;
375 : typedef base_sequence::iterator base_iterator;
376 : typedef base_sequence::const_iterator base_const_iterator;
377 :
378 : public:
379 : typedef xercesc::DOMElement value_type;
380 : typedef xercesc::DOMElement* pointer;
381 : typedef const xercesc::DOMElement* const_pointer;
382 : typedef xercesc::DOMElement& reference;
383 : typedef const xercesc::DOMElement& const_reference;
384 :
385 : typedef
386 : iterator_adapter<base_sequence::iterator, xercesc::DOMElement>
387 : iterator;
388 :
389 : typedef
390 : iterator_adapter<base_sequence::const_iterator,
391 : const xercesc::DOMElement>
392 : const_iterator;
393 :
394 : typedef
395 : iterator_adapter<base_sequence::reverse_iterator, xercesc::DOMElement>
396 : reverse_iterator;
397 :
398 : typedef
399 : iterator_adapter<base_sequence::const_reverse_iterator,
400 : const xercesc::DOMElement>
401 : const_reverse_iterator;
402 :
403 : typedef base_sequence::size_type size_type;
404 : typedef base_sequence::difference_type difference_type;
405 : typedef base_sequence::allocator_type allocator_type;
406 :
407 : public:
408 : explicit
409 : element_sequence (xercesc::DOMDocument& doc)
410 : : doc_ (doc)
411 : {
412 : }
413 :
414 : // DOMElement cannot be default-constructed.
415 : //
416 : // explicit
417 : // element_sequence (size_type n);
418 :
419 : element_sequence (size_type n,
420 : const xercesc::DOMElement& x,
421 : xercesc::DOMDocument& doc)
422 : : doc_ (doc)
423 : {
424 : assign (n, x);
425 : }
426 :
427 : template <typename I>
428 : element_sequence (const I& begin, const I& end,
429 : xercesc::DOMDocument& doc)
430 : : doc_ (doc)
431 : {
432 : assign (begin, end);
433 : }
434 :
435 : element_sequence (const element_sequence& v,
436 : xercesc::DOMDocument& doc)
437 : : doc_ (doc)
438 : {
439 : v_.reserve (v.v_.size ());
440 :
441 : for (base_const_iterator i (v.v_.begin ()), e (v.v_.end ());
442 : i != e; ++i)
443 : {
444 : ptr p (static_cast<xercesc::DOMElement*> (
445 : doc_.importNode (i->get (), true)));
446 :
447 : v_.push_back (p);
448 : }
449 : }
450 :
451 : element_sequence&
452 : operator= (const element_sequence& v)
453 : {
454 : if (this == &v)
455 : return *this;
456 :
457 : v_.assign (v.v_.size (), ptr ());
458 :
459 : base_iterator di (v_.begin ()), de (v_.end ());
460 : base_const_iterator si (v.v_.begin ()), se (v.v_.end ());
461 :
462 : for (; si != se && di != de; ++si, ++di)
463 : {
464 : ptr p (static_cast<xercesc::DOMElement*> (
465 : doc_.importNode (si->get (), true)));
466 : *di = p;
467 : }
468 :
469 : return *this;
470 : }
471 :
472 : public:
473 : void
474 : assign (size_type n, const xercesc::DOMElement& x)
475 : {
476 : v_.assign (n, ptr ());
477 :
478 : for (base_iterator i (v_.begin ()), e (v_.end ()); i != e; ++i)
479 : {
480 : ptr p (static_cast<xercesc::DOMElement*> (
481 : doc_.importNode (
482 : const_cast<xercesc::DOMElement*> (&x), true)));
483 : *i = p;
484 : }
485 : }
486 :
487 : template <typename I>
488 : void
489 : assign (const I& begin, const I& end)
490 : {
491 : // This is not the fastest way to do it.
492 : //
493 : v_.clear ();
494 :
495 : for (I i (begin); i != end; ++i)
496 : {
497 : ptr p (static_cast<xercesc::DOMElement*> (
498 : doc_.importNode (
499 : const_cast<xercesc::DOMElement*> (&(*i)), true)));
500 : v_.push_back (p);
501 : }
502 : }
503 :
504 : public:
505 : // This version of resize can only be used to shrink the
506 : // sequence because DOMElement cannot be default-constructed.
507 : //
508 : void
509 : resize (size_type n)
510 : {
511 : assert (n <= v_.size ());
512 : v_.resize (n, ptr ());
513 : }
514 :
515 : void
516 : resize (size_type n, const xercesc::DOMElement& x)
517 : {
518 : size_type old (v_.size ());
519 : v_.resize (n, ptr ());
520 :
521 : if (old < n)
522 : {
523 : for (base_iterator i (v_.begin () + old), e (v_.end ());
524 : i != e; ++i)
525 : {
526 : ptr p (static_cast<xercesc::DOMElement*> (
527 : doc_.importNode (
528 : const_cast<xercesc::DOMElement*> (&x), true)));
529 : *i = p;
530 : }
531 : }
532 : }
533 :
534 : public:
535 : size_type
536 : size () const
537 : {
538 : return v_.size ();
539 : }
540 :
541 : size_type
542 : max_size () const
543 : {
544 : return v_.max_size ();
545 : }
546 :
547 : size_type
548 : capacity () const
549 : {
550 : return v_.capacity ();
551 : }
552 :
553 : bool
554 : empty () const
555 : {
556 : return v_.empty ();
557 : }
558 :
559 : void
560 : reserve (size_type n)
561 : {
562 : v_.reserve (n);
563 : }
564 :
565 : void
566 : clear ()
567 : {
568 : v_.clear ();
569 : }
570 :
571 : public:
572 : const_iterator
573 : begin () const
574 : {
575 : return const_iterator (v_.begin ());
576 : }
577 :
578 : const_iterator
579 : end () const
580 : {
581 : return const_iterator (v_.end ());
582 : }
583 :
584 : iterator
585 : begin ()
586 : {
587 : return iterator (v_.begin ());
588 : }
589 :
590 : iterator
591 : end ()
592 : {
593 : return iterator (v_.end ());
594 : }
595 :
596 : // reverse
597 : //
598 :
599 : const_reverse_iterator
600 : rbegin () const
601 : {
602 : return const_reverse_iterator (v_.rbegin ());
603 : }
604 :
605 : const_reverse_iterator
606 : rend () const
607 : {
608 : return const_reverse_iterator (v_.rend ());
609 : }
610 :
611 : reverse_iterator
612 : rbegin ()
613 : {
614 : return reverse_iterator (v_.rbegin ());
615 : }
616 :
617 : reverse_iterator
618 : rend ()
619 : {
620 : return reverse_iterator (v_.rend ());
621 : }
622 :
623 : public:
624 : xercesc::DOMElement&
625 : operator[] (size_type n)
626 : {
627 : return *(v_[n]);
628 : }
629 :
630 : const xercesc::DOMElement&
631 : operator[] (size_type n) const
632 : {
633 : return *(v_[n]);
634 : }
635 :
636 : xercesc::DOMElement&
637 : at (size_type n)
638 : {
639 : return *(v_.at (n));
640 : }
641 :
642 : const xercesc::DOMElement&
643 : at (size_type n) const
644 : {
645 : return *(v_.at (n));
646 : }
647 :
648 : xercesc::DOMElement&
649 : front ()
650 : {
651 : return *(v_.front ());
652 : }
653 :
654 : const xercesc::DOMElement&
655 : front () const
656 : {
657 : return *(v_.front ());
658 : }
659 :
660 : xercesc::DOMElement&
661 : back ()
662 : {
663 : return *(v_.back ());
664 : }
665 :
666 : const xercesc::DOMElement&
667 : back () const
668 : {
669 : return *(v_.back ());
670 : }
671 :
672 : public:
673 : // Makes a deep copy.
674 : //
675 : void
676 : push_back (const xercesc::DOMElement& x)
677 : {
678 : ptr p (static_cast<xercesc::DOMElement*> (
679 : doc_.importNode (
680 : const_cast<xercesc::DOMElement*> (&x), true)));
681 :
682 : v_.push_back (p);
683 : }
684 :
685 : // Assumes ownership.
686 : //
687 : void
688 : push_back (xercesc::DOMElement* x)
689 : {
690 : assert (x->getOwnerDocument () == &doc_);
691 : v_.push_back (ptr (x));
692 : }
693 :
694 : void
695 : pop_back ()
696 : {
697 : v_.pop_back ();
698 : }
699 :
700 : // Makes a deep copy.
701 : //
702 : iterator
703 : insert (iterator position, const xercesc::DOMElement& x)
704 : {
705 : ptr p (static_cast<xercesc::DOMElement*> (
706 : doc_.importNode (
707 : const_cast<xercesc::DOMElement*> (&x), true)));
708 :
709 : return iterator (v_.insert (position.base (), p));
710 : }
711 :
712 : // Assumes ownership.
713 : //
714 : iterator
715 : insert (iterator position, xercesc::DOMElement* x)
716 : {
717 : assert (x->getOwnerDocument () == &doc_);
718 : return iterator (v_.insert (position.base (), ptr (x)));
719 : }
720 :
721 : void
722 : insert (iterator position, size_type n, const xercesc::DOMElement& x)
723 : {
724 : difference_type d (v_.end () - position.base ());
725 : v_.insert (position.base (), n, ptr ());
726 :
727 : for (base_iterator i (v_.end () - d); n != 0; --n)
728 : {
729 : ptr r (static_cast<xercesc::DOMElement*> (
730 : doc_.importNode (
731 : const_cast<xercesc::DOMElement*> (&x), true)));
732 : *(--i) = r;
733 : }
734 : }
735 :
736 : template <typename I>
737 : void
738 : insert (iterator position, const I& begin, const I& end)
739 : {
740 : // This is not the fastest way to do it.
741 : //
742 : if (begin != end)
743 : {
744 : base_iterator p (position.base ());
745 :
746 : for (I i (end);;)
747 : {
748 : --i;
749 : ptr r (static_cast<xercesc::DOMElement*> (
750 : doc_.importNode (i->get (), true)));
751 :
752 : p = v_.insert (p, r);
753 :
754 : if (i == begin)
755 : break;
756 : }
757 : }
758 : }
759 :
760 : iterator
761 : erase (iterator position)
762 : {
763 : return iterator (v_.erase (position.base ()));
764 : }
765 :
766 : iterator
767 : erase (iterator begin, iterator end)
768 : {
769 : return iterator (v_.erase (begin.base (), end.base ()));
770 : }
771 :
772 : public:
773 : // Note that the DOMDocument object of the two sequences being
774 : // swapped should be the same.
775 : //
776 : void
777 : swap (element_sequence& x)
778 : {
779 : assert (&doc_ == &x.doc_);
780 : v_.swap (x.v_);
781 : }
782 :
783 : private:
784 : base_sequence v_;
785 : xercesc::DOMDocument& doc_;
786 : };
787 :
788 : // Comparison operators.
789 : //
790 :
791 : inline bool
792 : operator== (const element_sequence& a, const element_sequence& b)
793 : {
794 : if (a.size () != b.size ())
795 : return false;
796 :
797 : element_sequence::const_iterator
798 : ai (a.begin ()), ae (a.end ()), bi (b.begin ());
799 :
800 : for (; ai != ae; ++ai, ++bi)
801 : if (!ai->isEqualNode (&(*bi)))
802 : return false;
803 :
804 : return true;
805 : }
806 :
807 : inline bool
808 : operator!= (const element_sequence& a, const element_sequence& b)
809 : {
810 : return !(a == b);
811 : }
812 :
813 :
814 : // Attribute set.
815 : //
816 :
817 : class attribute_set_common
818 : {
819 : protected:
820 : // Set entry. It can either act as a dangerously destructive
821 : // automatic pointer for DOMAttr or as an entry containing the
822 : // name we are searching for.
823 : //
824 : struct entry
825 : {
826 : ~entry ()
827 : {
828 : if (a_)
829 : a_->release ();
830 : }
831 :
832 : explicit
833 : entry (xercesc::DOMAttr* a)
834 : : a_ (a), ns_ (0), name_ (0)
835 : {
836 : ns_ = a->getNamespaceURI ();
837 : name_ = ns_ == 0 ? a->getName () : a->getLocalName ();
838 : }
839 :
840 : // Note: uses shallow copy.
841 : //
842 : explicit
843 : entry (const XMLCh* ns, const XMLCh* name)
844 : : a_ (0), ns_ (ns), name_ (name)
845 : {
846 : }
847 :
848 : entry (const entry& y)
849 : : a_ (y.a_), ns_ (y.ns_), name_ (y.name_)
850 : {
851 : // Yes, hostile takeover.
852 : //
853 : y.a_ = 0;
854 : y.ns_ = 0;
855 : y.name_ = 0;
856 : }
857 :
858 : entry&
859 : operator= (const entry& y)
860 : {
861 : if (this != &y)
862 : {
863 : // Yes, hostile takeover.
864 : //
865 : if (a_)
866 : a_->release ();
867 :
868 : a_ = y.a_;
869 : ns_ = y.ns_;
870 : name_ = y.name_;
871 :
872 : y.a_ = 0;
873 : y.ns_ = 0;
874 : y.name_ = 0;
875 : }
876 :
877 : return *this;
878 : }
879 :
880 : public:
881 : xercesc::DOMAttr&
882 : operator* () const
883 : {
884 : return *a_;
885 : }
886 :
887 : xercesc::DOMAttr*
888 : get () const
889 : {
890 : return a_;
891 : }
892 :
893 : const XMLCh*
894 : ns () const
895 : {
896 : return ns_;
897 : }
898 :
899 : const XMLCh*
900 : name () const
901 : {
902 : return name_;
903 : }
904 :
905 : void
906 : release ()
907 : {
908 : a_ = 0;
909 : }
910 :
911 : private:
912 : mutable xercesc::DOMAttr* a_;
913 : mutable const XMLCh* ns_;
914 : mutable const XMLCh* name_;
915 : };
916 :
917 : struct entry_cmp
918 : {
919 : bool
920 : operator() (const entry& a, const entry& b) const
921 : {
922 : using xercesc::XMLString;
923 :
924 : const XMLCh* ans (a.ns ());
925 : const XMLCh* bns (b.ns ());
926 :
927 : const XMLCh* an (a.name ());
928 : const XMLCh* bn (b.name ());
929 :
930 : if (ans == 0)
931 : return bns != 0
932 : ? true
933 : : (XMLString::compareString (an, bn) < 0);
934 :
935 : if (ans != 0 && bns == 0)
936 : return false;
937 :
938 : int r (XMLString::compareString (ans, bns));
939 :
940 : return r < 0
941 : ? true
942 : : (r > 0 ? false : XMLString::compareString (an, bn) < 0);
943 : }
944 : };
945 :
946 : typedef std::set<entry, entry_cmp> base_set;
947 : typedef base_set::iterator base_iterator;
948 : typedef base_set::const_iterator base_const_iterator;
949 : };
950 :
951 : template <typename C>
952 : class attribute_set: public attribute_set_common
953 : {
954 : public:
955 : typedef xercesc::DOMAttr key_type;
956 : typedef xercesc::DOMAttr value_type;
957 : typedef xercesc::DOMAttr* pointer;
958 : typedef const xercesc::DOMAttr* const_pointer;
959 : typedef xercesc::DOMAttr& reference;
960 : typedef const xercesc::DOMAttr& const_reference;
961 :
962 : typedef
963 : iterator_adapter<base_set::iterator, xercesc::DOMAttr>
964 : iterator;
965 :
966 : typedef
967 : iterator_adapter<base_set::const_iterator, const xercesc::DOMAttr>
968 : const_iterator;
969 :
970 : typedef
971 : iterator_adapter<base_set::reverse_iterator, xercesc::DOMAttr>
972 : reverse_iterator;
973 :
974 : typedef
975 : iterator_adapter<base_set::const_reverse_iterator,
976 : const xercesc::DOMAttr>
977 : const_reverse_iterator;
978 :
979 : typedef base_set::size_type size_type;
980 : typedef base_set::difference_type difference_type;
981 : typedef base_set::allocator_type allocator_type;
982 :
983 : public:
984 : attribute_set (xercesc::DOMDocument& doc)
985 : : doc_ (doc)
986 : {
987 : }
988 :
989 : template <typename I>
990 : attribute_set (const I& begin,
991 : const I& end,
992 : xercesc::DOMDocument& doc)
993 : : doc_ (doc)
994 : {
995 : insert (begin, end);
996 : }
997 :
998 : attribute_set (const attribute_set& s, xercesc::DOMDocument& doc)
999 : : doc_ (doc)
1000 : {
1001 : // Can be done faster with the "hinted" insert.
1002 : //
1003 : insert (s.begin (), s.end ());
1004 : }
1005 :
1006 : attribute_set&
1007 : operator= (const attribute_set& s)
1008 : {
1009 : if (this == &s)
1010 : return *this;
1011 :
1012 : // Can be done faster with the "hinted" insert.
1013 : //
1014 : clear ();
1015 : insert (s.begin (), s.end ());
1016 :
1017 : return *this;
1018 : }
1019 :
1020 : public:
1021 : const_iterator
1022 : begin () const
1023 : {
1024 : return const_iterator (s_.begin ());
1025 : }
1026 :
1027 : const_iterator
1028 : end () const
1029 : {
1030 : return const_iterator (s_.end ());
1031 : }
1032 :
1033 : iterator
1034 : begin ()
1035 : {
1036 : return iterator (s_.begin ());
1037 : }
1038 :
1039 : iterator
1040 : end ()
1041 : {
1042 : return iterator (s_.end ());
1043 : }
1044 :
1045 : // reverse
1046 : //
1047 :
1048 : const_reverse_iterator
1049 : rbegin () const
1050 : {
1051 : return const_reverse_iterator (s_.rbegin ());
1052 : }
1053 :
1054 : const_reverse_iterator
1055 : rend () const
1056 : {
1057 : return const_reverse_iterator (s_.rend ());
1058 : }
1059 :
1060 : reverse_iterator
1061 : rbegin ()
1062 : {
1063 : return reverse_iterator (s_.rbegin ());
1064 : }
1065 :
1066 : reverse_iterator
1067 : rend ()
1068 : {
1069 : return reverse_iterator (s_.rend ());
1070 : }
1071 :
1072 : public:
1073 : size_type
1074 : size () const
1075 : {
1076 : return s_.size ();
1077 : }
1078 :
1079 : size_type
1080 : max_size () const
1081 : {
1082 : return s_.max_size ();
1083 : }
1084 :
1085 : bool
1086 : empty () const
1087 : {
1088 : return s_.empty ();
1089 : }
1090 :
1091 : void
1092 : clear ()
1093 : {
1094 : s_.clear ();
1095 : }
1096 :
1097 : public:
1098 : // Makes a deep copy.
1099 : //
1100 : std::pair<iterator, bool>
1101 : insert (const xercesc::DOMAttr& a)
1102 : {
1103 : entry e (static_cast<xercesc::DOMAttr*> (
1104 : doc_.importNode (
1105 : const_cast<xercesc::DOMAttr*> (&a), true)));
1106 :
1107 : std::pair<base_iterator, bool> r (s_.insert (e));
1108 :
1109 : return std::pair<iterator, bool> (iterator (r.first), r.second);
1110 : }
1111 :
1112 : // Assumes ownership.
1113 : //
1114 : std::pair<iterator, bool>
1115 : insert (xercesc::DOMAttr* a)
1116 : {
1117 : assert (a->getOwnerDocument () == &doc_);
1118 : entry e (a);
1119 : std::pair<base_iterator, bool> r (s_.insert (e));
1120 :
1121 : if (!r.second)
1122 : e.release (); // Detach the attribute of insert failed.
1123 :
1124 : return std::pair<iterator, bool> (iterator (r.first), r.second);
1125 : }
1126 :
1127 : // Makes a deep copy.
1128 : //
1129 : iterator
1130 : insert (iterator position, const xercesc::DOMAttr& a)
1131 : {
1132 : entry e (static_cast<xercesc::DOMAttr*> (
1133 : doc_.importNode (
1134 : const_cast<xercesc::DOMAttr*> (&a), true)));
1135 :
1136 : return iterator (s_.insert (position.base (), e));
1137 : }
1138 :
1139 : // Assumes ownership.
1140 : //
1141 : iterator
1142 : insert (iterator position, xercesc::DOMAttr* a)
1143 : {
1144 : assert (a->getOwnerDocument () == &doc_);
1145 : entry e (a);
1146 : base_iterator r (s_.insert (position.base (), e));
1147 :
1148 : if (r->get () != a)
1149 : e.release (); // Detach the attribute of insert failed.
1150 :
1151 : return iterator (r);
1152 : }
1153 :
1154 : template <typename I>
1155 : void
1156 : insert (const I& begin, const I& end)
1157 : {
1158 : for (I i (begin); i != end; ++i)
1159 : {
1160 : entry e (static_cast<xercesc::DOMAttr*> (
1161 : doc_.importNode (
1162 : const_cast<xercesc::DOMAttr*> (&(*i)), true)));
1163 :
1164 : s_.insert (e);
1165 : }
1166 : }
1167 :
1168 : public:
1169 : void
1170 : erase (iterator position)
1171 : {
1172 : s_.erase (position.base ());
1173 : }
1174 :
1175 : size_type
1176 : erase (const std::basic_string<C>& name)
1177 : {
1178 : return s_.erase (entry (0, xml::string (name).c_str ()));
1179 : }
1180 :
1181 : size_type
1182 : erase (const std::basic_string<C>& namespace_,
1183 : const std::basic_string<C>& name)
1184 : {
1185 : return s_.erase (entry (xml::string (namespace_).c_str (),
1186 : xml::string (name).c_str ()));
1187 : }
1188 :
1189 : size_type
1190 : erase (const XMLCh* name)
1191 : {
1192 : return s_.erase (entry (0, name));
1193 : }
1194 :
1195 : size_type
1196 : erase (const XMLCh* namespace_, const XMLCh* name)
1197 : {
1198 : return s_.erase (entry (namespace_, name));
1199 : }
1200 :
1201 : void
1202 : erase (iterator begin, iterator end)
1203 : {
1204 : s_.erase (begin.base (), end.base ());
1205 : }
1206 :
1207 : public:
1208 : size_type
1209 : count (const std::basic_string<C>& name) const
1210 : {
1211 : return s_.count (entry (0, xml::string (name).c_str ()));
1212 : }
1213 :
1214 : size_type
1215 : count (const std::basic_string<C>& namespace_,
1216 : const std::basic_string<C>& name) const
1217 : {
1218 : return s_.count (entry (xml::string (namespace_).c_str (),
1219 : xml::string (name).c_str ()));
1220 : }
1221 :
1222 : size_type
1223 : count (const XMLCh* name) const
1224 : {
1225 : return s_.count (entry (0, name));
1226 : }
1227 :
1228 : size_type
1229 : count (const XMLCh* namespace_, const XMLCh* name) const
1230 : {
1231 : return s_.count (entry (namespace_, name));
1232 : }
1233 :
1234 : // find
1235 : //
1236 :
1237 : iterator
1238 : find (const std::basic_string<C>& name)
1239 : {
1240 : return iterator (s_.find (entry (0, xml::string (name).c_str ())));
1241 : }
1242 :
1243 : iterator
1244 : find (const std::basic_string<C>& namespace_,
1245 : const std::basic_string<C>& name)
1246 : {
1247 : return iterator (
1248 : s_.find (entry (xml::string (namespace_).c_str (),
1249 : xml::string (name).c_str ())));
1250 : }
1251 :
1252 : iterator
1253 : find (const XMLCh* name)
1254 : {
1255 : return iterator (s_.find (entry (0, name)));
1256 : }
1257 :
1258 : iterator
1259 : find (const XMLCh* namespace_, const XMLCh* name)
1260 : {
1261 : return iterator (s_.find (entry (namespace_, name)));
1262 : }
1263 :
1264 : const_iterator
1265 : find (const std::basic_string<C>& name) const
1266 : {
1267 : return const_iterator (
1268 : s_.find (entry (0, xml::string (name).c_str ())));
1269 : }
1270 :
1271 : const_iterator
1272 : find (const std::basic_string<C>& namespace_,
1273 : const std::basic_string<C>& name) const
1274 : {
1275 : return const_iterator (
1276 : s_.find (entry (xml::string (namespace_).c_str (),
1277 : xml::string (name).c_str ())));
1278 : }
1279 :
1280 : const_iterator
1281 : find (const XMLCh* name) const
1282 : {
1283 : return const_iterator (s_.find (entry (0, name)));
1284 : }
1285 :
1286 : const_iterator
1287 : find (const XMLCh* namespace_, const XMLCh* name) const
1288 : {
1289 : return const_iterator (s_.find (entry (namespace_, name)));
1290 : }
1291 :
1292 : public:
1293 : // Note that the DOMDocument object of the two sets being
1294 : // swapped should be the same.
1295 : //
1296 : void
1297 : swap (attribute_set& x)
1298 : {
1299 : assert (&doc_ == &x.doc_);
1300 : s_.swap (x.s_);
1301 : }
1302 :
1303 : private:
1304 : base_set s_;
1305 : xercesc::DOMDocument& doc_;
1306 : };
1307 :
1308 : // Comparison operators.
1309 : //
1310 :
1311 : template <typename C>
1312 : inline bool
1313 : operator== (const attribute_set<C>& a, const attribute_set<C>& b)
1314 : {
1315 : if (a.size () != b.size ())
1316 : return false;
1317 :
1318 : typename attribute_set<C>::const_iterator
1319 : ai (a.begin ()), ae (a.end ()), bi (b.begin ());
1320 :
1321 : for (; ai != ae; ++ai, ++bi)
1322 : if (!ai->isEqualNode (&(*bi)))
1323 : return false;
1324 :
1325 : return true;
1326 : }
1327 :
1328 : template <typename C>
1329 : inline bool
1330 : operator!= (const attribute_set<C>& a, const attribute_set<C>& b)
1331 : {
1332 : return !(a == b);
1333 : }
1334 : }
1335 : }
1336 : }
1337 :
1338 : #endif // XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
|