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