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