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