1 // RUN: %clangxx -emit-llvm -c -o - %s
2 #include <stddef.h>
3 #include <stdlib.h>
4 #include <assert.h>
5
6 // Placement new requires <new> to be included, but we don't support that yet.
operator new(size_t,void * ptr)7 void* operator new(size_t, void* ptr) throw() {
8 return ptr;
9 }
operator delete(void *,void *)10 void operator delete(void*, void*) throw() {
11 }
12
13 template<typename T>
14 class dynarray {
15 public:
dynarray()16 dynarray() { Start = Last = End = 0; }
17
dynarray(const dynarray & other)18 dynarray(const dynarray &other) {
19 Start = (T*)malloc(sizeof(T) * other.size());
20 Last = End = Start + other.size();
21
22 for (unsigned I = 0, N = other.size(); I != N; ++I)
23 new (Start + I) T(other[I]);
24 }
25
~dynarray()26 ~dynarray() {
27 for (unsigned I = 0, N = size(); I != N; ++I)
28 Start[I].~T();
29
30 free(Start);
31 }
32
operator =(const dynarray & other)33 dynarray &operator=(const dynarray &other) {
34 T* NewStart = (T*)malloc(sizeof(T) * other.size());
35
36 for (unsigned I = 0, N = other.size(); I != N; ++I)
37 new (NewStart + I) T(other[I]);
38
39 for (unsigned I = 0, N = size(); I != N; ++I)
40 Start[I].~T();
41
42 free(Start);
43 Start = NewStart;
44 Last = End = NewStart + other.size();
45 return *this;
46 }
47
size() const48 unsigned size() const { return Last - Start; }
capacity() const49 unsigned capacity() const { return End - Start; }
50
51 void push_back(const T& value);
52
pop_back()53 void pop_back() {
54 --Last;
55 Last->~T();
56 }
57
operator [](unsigned Idx)58 T& operator[](unsigned Idx) {
59 return Start[Idx];
60 }
61
operator [](unsigned Idx) const62 const T& operator[](unsigned Idx) const {
63 return Start[Idx];
64 }
65
66 typedef T* iterator;
67 typedef const T* const_iterator;
68
begin()69 iterator begin() { return Start; }
begin() const70 const_iterator begin() const { return Start; }
71
end()72 iterator end() { return Last; }
end() const73 const_iterator end() const { return Last; }
74
operator ==(const dynarray & other) const75 bool operator==(const dynarray &other) const {
76 if (size() != other.size())
77 return false;
78
79 for (unsigned I = 0, N = size(); I != N; ++I)
80 if ((*this)[I] != other[I])
81 return false;
82
83 return true;
84 }
85
operator !=(const dynarray & other) const86 bool operator!=(const dynarray &other) const {
87 return !(*this == other);
88 }
89
90 public:
91 T* Start, *Last, *End;
92 };
93
94 template<typename T>
push_back(const T & value)95 void dynarray<T>::push_back(const T& value) {
96 if (Last == End) {
97 unsigned NewCapacity = capacity() * 2;
98 if (NewCapacity == 0)
99 NewCapacity = 4;
100
101 T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
102
103 unsigned Size = size();
104 for (unsigned I = 0; I != Size; ++I)
105 new (NewStart + I) T(Start[I]);
106
107 for (unsigned I = 0, N = size(); I != N; ++I)
108 Start[I].~T();
109 free(Start);
110
111 Start = NewStart;
112 Last = Start + Size;
113 End = Start + NewCapacity;
114 }
115
116 new (Last) T(value);
117 ++Last;
118 }
119
120 struct Point {
PointPoint121 Point() { x = y = z = 0.0; }
PointPoint122 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
123
124 float x, y, z;
125 };
126
main()127 int main() {
128 dynarray<int> di;
129 di.push_back(0);
130 di.push_back(1);
131 di.push_back(2);
132 di.push_back(3);
133 di.push_back(4);
134 assert(di.size() == 5);
135 for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
136 assert(*I == I - di.begin());
137
138 for (int I = 0, N = di.size(); I != N; ++I)
139 assert(di[I] == I);
140
141 di.pop_back();
142 assert(di.size() == 4);
143 di.push_back(4);
144
145 dynarray<int> di2 = di;
146 assert(di2.size() == 5);
147 assert(di.begin() != di2.begin());
148 for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
149 I != IEnd; ++I)
150 assert(*I == I - di2.begin());
151
152 dynarray<int> di3(di);
153 assert(di3.size() == 5);
154 assert(di.begin() != di3.begin());
155 for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
156 I != IEnd; ++I)
157 assert(*I == I - di3.begin());
158
159 dynarray<int> di4;
160 assert(di4.size() == 0);
161 di4 = di;
162 assert(di4.size() == 5);
163 assert(di.begin() != di4.begin());
164 for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
165 I != IEnd; ++I)
166 assert(*I == I - di4.begin());
167
168 assert(di4 == di);
169 di4[3] = 17;
170 assert(di4 != di);
171
172 dynarray<Point> dp;
173 dp.push_back(Point());
174 assert(dp.size() == 1);
175
176 return 0;
177 }
178