1 // Copyright (c) 1994, 1996 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
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>
~Vector()22 Vector<T>::~Vector()
23 {
24 if (ptr_) {
25 erase(ptr_, ptr_ + size_);
26 ::operator delete((void *)ptr_);
27 }
28 }
29
30 #ifndef NC
31
32 template<class T>
Vector(const Vector<T> & v)33 Vector<T>::Vector(const Vector<T> &v)
34 : ptr_(0), size_(0), alloc_(0)
35 {
36 insert(ptr_ + size_, v.ptr_, v.ptr_ + v.size_);
37 }
38
39 template<class T>
Vector(size_t n,const T & t)40 Vector<T>::Vector(size_t n, const T &t)
41 : ptr_(0), size_(0), alloc_(0)
42 {
43 insert(ptr_ + size_, n, t);
44 }
45
46 template<class T>
operator =(const Vector<T> & v)47 Vector<T> &Vector<T>::operator=(const Vector<T> &v)
48 {
49 if (&v != this) {
50 size_t n = v.size_;
51 if (n > size_) {
52 n = size_;
53 insert(ptr_ + size_, v.ptr_ + size_, v.ptr_ + v.size_);
54 }
55 else if (n < size_)
56 erase(ptr_ + n, ptr_ + size_);
57 while (n-- > 0)
58 ptr_[n] = v.ptr_[n];
59 }
60 return *this;
61 }
62
63 template<class T>
assign(size_t n,const T & t)64 void Vector<T>::assign(size_t n, const T &t)
65 {
66 size_t sz = n;
67 if (n > size_) {
68 sz = size_;
69 insert(ptr_ + size_, n - size_, t);
70 }
71 else if (n < size_)
72 erase(ptr_ + n, ptr_ + size_);
73 while (sz-- > 0)
74 ptr_[sz] = t;
75 }
76
77 template<class T>
insert(const T * p,size_t n,const T & t)78 void Vector<T>::insert(const T *p, size_t n, const T &t)
79 {
80 size_t i = p - ptr_;
81 reserve(size_ + n);
82 if (i != size_)
83 memmove(ptr_ + i + n, ptr_ + i, (size_ - i)*sizeof(T));
84 for (T *pp = ptr_ + i; n-- > 0; pp++) {
85 (void)new (pp) T(t);
86 size_++;
87 }
88 }
89
90 template<class T>
insert(const T * p,const T * q1,const T * q2)91 void Vector<T>::insert(const T *p, const T *q1, const T *q2)
92 {
93 size_t i = p - ptr_;
94 size_t n = q2 - q1;
95 reserve(size_ + n);
96 if (i != size_)
97 memmove(ptr_ + i + n, ptr_ + i, (size_ - i)*sizeof(T));
98 for (T *pp = ptr_ + i; q1 != q2; q1++, pp++) {
99 (void)new (pp) T(*q1);
100 size_++;
101 }
102 }
103
104 #endif
105
106 template<class T>
swap(Vector<T> & v)107 void Vector<T>::swap(Vector<T> &v)
108 {
109 {
110 T *tem = ptr_;
111 ptr_ = v.ptr_;
112 v.ptr_ = tem;
113 }
114 {
115 size_t tem = size_;
116 size_ = v.size_;
117 v.size_ = tem;
118 }
119 {
120 size_t tem = alloc_;
121 alloc_ = v.alloc_;
122 v.alloc_ = tem;
123 }
124 }
125
126 template<class T>
append(size_t n)127 void Vector<T>::append(size_t n)
128 {
129 reserve(size_ + n);
130 while (n-- > 0)
131 (void)new (ptr_ + size_++) T;
132 }
133
134 template<class T>
erase(const T * p1,const T * p2)135 T *Vector<T>::erase(const T *p1, const T *p2)
136 {
137 typedef T X;
138 for (const T *p = p1; p != p2; p++)
139 ((X *)p)->~X();
140 if (p2 != ptr_ + size_)
141 memmove((T *)p1, p2, ((const T *)(ptr_ + size_) - p2)*sizeof(T));
142 size_ -= p2 - p1;
143 return (T *)p1;
144 }
145
146 template<class T>
reserve1(size_t size)147 void Vector<T>::reserve1(size_t size)
148 {
149 // Try to preserve a consistent start in the
150 // event of an out of memory exception.
151 size_t newAlloc = alloc_*2;
152 if (size > newAlloc)
153 newAlloc += size;
154 void *p = ::operator new(newAlloc * sizeof(T));
155 alloc_ = newAlloc;
156 if (ptr_) {
157 memcpy(p, ptr_, size_*sizeof(T));
158 ::operator delete((void *)ptr_);
159 }
160 ptr_ = (T *)p;
161 }
162
163 #ifdef SP_NAMESPACE
164 }
165 #endif
166
167 #endif /* not Vector_DEF_INCLUDED */
168