Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / nsgmls / Vector.C
1 /* $XConsortium: Vector.C /main/3 1996/08/17 08:15:28 mgreess $ */
2 // Copyright (c) 1994, 1996 James Clark
3 // See the file COPYING for copying permission.
4
5 #ifndef Vector_DEF_INCLUDED
6 #define Vector_DEF_INCLUDED 1
7
8 #include <stddef.h>
9 #include <string.h>
10
11 #ifdef SP_QUAL_TEMPLATE_DTOR_BROKEN
12 #define DTOR(T) ~T
13 #else
14 #define DTOR(T) T::~T
15 #endif
16
17 #ifdef SP_NAMESPACE
18 namespace SP_NAMESPACE {
19 #endif
20
21 template<class T>
22 Vector<T>::~Vector()
23 {
24   if (ptr_) {
25     erase(ptr_, ptr_ + size_);
26     ::operator delete((void *)ptr_);
27   }
28 }
29
30 template<class T>
31 Vector<T>::Vector(const Vector<T> &v)
32 : ptr_(0), size_(0), alloc_(0)
33 {
34   insert(ptr_ + size_, v.ptr_, v.ptr_ + v.size_);
35 }
36
37 template<class T>
38 Vector<T>::Vector(size_t n, const T &t)
39 : ptr_(0), size_(0), alloc_(0)
40 {
41   insert(ptr_ + size_, n, t);
42 }
43
44 template<class T>
45 Vector<T> &Vector<T>::operator=(const Vector<T> &v)
46 {
47   if (&v != this) {
48     size_t n = v.size_;
49     if (n > size_) {
50       n = size_;
51       insert(ptr_ + size_, v.ptr_ + size_, v.ptr_ + v.size_);
52     }
53     else if (n < size_)
54       erase(ptr_ + n, ptr_ + size_);
55     while (n-- > 0)
56       ptr_[n] = v.ptr_[n];
57   }
58   return *this;
59 }
60
61 template<class T>
62 void Vector<T>::assign(size_t n, const T &t)
63 {
64   size_t sz = n;
65   if (n > size_) {
66     sz = size_;
67     insert(ptr_ + size_, n - size_, t);
68   }
69   else if (n < size_)
70     erase(ptr_ + n, ptr_ + size_);
71   while (sz-- > 0)
72     ptr_[sz] = t;
73 }
74
75 template<class T>
76 void Vector<T>::insert(const T *p, size_t n, const T &t)
77 {
78   size_t i = p - ptr_;
79   reserve(size_ + n);
80   if (i != size_)
81     memmove(ptr_ + i + n, ptr_ + i, (size_ - i)*sizeof(T));
82   size_ += n;
83   for (T *pp = ptr_ + i; n-- > 0; pp++)
84     (void)new (pp) T(t);
85 }
86
87 template<class T>
88 void Vector<T>::insert(const T *p, const T *q1, const T *q2)
89 {
90   size_t i = p - ptr_;
91   size_t n = q2 - q1;
92   reserve(size_ + n);
93   if (i != size_)
94     memmove(ptr_ + i + n, ptr_ + i, (size_ - i)*sizeof(T));
95   size_ += n;
96   for (T *pp = ptr_ + i; q1 != q2; q1++, pp++)
97     (void)new (pp) T(*q1);
98 }
99
100 template<class T>
101 void Vector<T>::swap(Vector<T> &v)
102 {
103   {
104     T *tem = ptr_;
105     ptr_ = v.ptr_;
106     v.ptr_ = tem;
107   }
108   {
109     size_t tem = size_;
110     size_ = v.size_;
111     v.size_ = tem;
112   }
113   {
114     size_t tem = alloc_;
115     alloc_ = v.alloc_;
116     v.alloc_ = tem;
117   }
118 }
119
120 template<class T>
121 void Vector<T>::append(size_t n)
122 {
123   reserve(size_ + n);
124   while (n-- > 0)
125     (void)new (ptr_ + size_++) T;
126 }
127
128 template<class T>
129 T *Vector<T>::erase(const T *p1, const T *p2)
130 {
131 #if !defined(SP_TEMPLATE_DESTRUCTOR_COMPILER_BUG)
132   for (const T *p = p1; p != p2; p++)
133     p->~T();
134 #endif
135   if (p2 != ptr_ + size_)
136     memmove((T *)p1, p2, ((const T *)(ptr_ + size_) - p2)*sizeof(T));
137   size_ -= p2 - p1;
138   return (T *)p1;
139 }
140
141 template<class T>
142 void Vector<T>::reserve1(size_t size)
143 {
144   alloc_ *= 2;
145   if (size > alloc_)
146     alloc_ += size;
147   void *p = ::operator new(alloc_*sizeof(T));
148   if (ptr_) {
149     memcpy(p, ptr_, size_*sizeof(T));
150     ::operator delete((void *)ptr_);
151   }
152   ptr_ = (T *)p;
153 }
154
155 #ifdef SP_NAMESPACE
156 }
157 #endif
158
159 #endif /* not Vector_DEF_INCLUDED */