blob: 999521e91e5f20b718742ca0693f1aaffc8848d7 [file] [log] [blame]
Daniel Dunbar9fde9c42010-06-29 16:52:24 +00001// RUN: %clangxx -emit-llvm -c -o - %s
Sebastian Redle47590e2009-05-29 16:43:59 +00002#include <stddef.h>
Douglas Gregor2f1735c2009-05-26 21:27:04 +00003#include <stdlib.h>
4#include <assert.h>
5
Sebastian Redle47590e2009-05-29 16:43:59 +00006// Placement new requires <new> to be included, but we don't support that yet.
7void* operator new(size_t, void* ptr) throw() {
8 return ptr;
9}
10void operator delete(void*, void*) throw() {
11}
12
Douglas Gregor2f1735c2009-05-26 21:27:04 +000013template<typename T>
14class dynarray {
Douglas Gregorc177aa22009-05-28 16:41:44 +000015public:
Douglas Gregor2f1735c2009-05-26 21:27:04 +000016 dynarray() { Start = Last = End = 0; }
17
18 dynarray(const dynarray &other) {
19 Start = (T*)malloc(sizeof(T) * other.size());
20 Last = End = Start + other.size();
21
Douglas Gregor2f1735c2009-05-26 21:27:04 +000022 for (unsigned I = 0, N = other.size(); I != N; ++I)
Sebastian Redle47590e2009-05-29 16:43:59 +000023 new (Start + I) T(other[I]);
Douglas Gregor2f1735c2009-05-26 21:27:04 +000024 }
25
26 ~dynarray() {
Douglas Gregor4fe95f92009-09-04 19:04:08 +000027 for (unsigned I = 0, N = size(); I != N; ++I)
28 Start[I].~T();
29
Douglas Gregor2f1735c2009-05-26 21:27:04 +000030 free(Start);
31 }
32
33 dynarray &operator=(const dynarray &other) {
34 T* NewStart = (T*)malloc(sizeof(T) * other.size());
35
Douglas Gregor2f1735c2009-05-26 21:27:04 +000036 for (unsigned I = 0, N = other.size(); I != N; ++I)
Anders Carlssona53f93b2009-06-01 00:40:08 +000037 new (NewStart + I) T(other[I]);
Sebastian Redle47590e2009-05-29 16:43:59 +000038
Douglas Gregor4fe95f92009-09-04 19:04:08 +000039 for (unsigned I = 0, N = size(); I != N; ++I)
40 Start[I].~T();
41
Douglas Gregor2f1735c2009-05-26 21:27:04 +000042 free(Start);
43 Start = NewStart;
44 Last = End = NewStart + other.size();
45 return *this;
46 }
47
48 unsigned size() const { return Last - Start; }
49 unsigned capacity() const { return End - Start; }
50
Douglas Gregor5c7e2812009-07-22 15:45:39 +000051 void push_back(const T& value);
52
Douglas Gregor2f1735c2009-05-26 21:27:04 +000053 void pop_back() {
Douglas Gregor2f1735c2009-05-26 21:27:04 +000054 --Last;
Douglas Gregor4fe95f92009-09-04 19:04:08 +000055 Last->~T();
Douglas Gregor2f1735c2009-05-26 21:27:04 +000056 }
57
58 T& operator[](unsigned Idx) {
59 return Start[Idx];
60 }
61
62 const T& operator[](unsigned Idx) const {
63 return Start[Idx];
64 }
65
Douglas Gregor2f1735c2009-05-26 21:27:04 +000066 typedef T* iterator;
67 typedef const T* const_iterator;
68
Douglas Gregor815215d2009-05-27 05:35:12 +000069 iterator begin() { return Start; }
70 const_iterator begin() const { return Start; }
Douglas Gregor2f1735c2009-05-26 21:27:04 +000071
Douglas Gregor815215d2009-05-27 05:35:12 +000072 iterator end() { return Last; }
73 const_iterator end() const { return Last; }
Douglas Gregor2f1735c2009-05-26 21:27:04 +000074
Douglas Gregord7f37bf2009-06-22 23:06:13 +000075 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
86 bool operator!=(const dynarray &other) const {
87 return !(*this == other);
88 }
89
Douglas Gregor2f1735c2009-05-26 21:27:04 +000090public:
91 T* Start, *Last, *End;
92};
93
Douglas Gregor5c7e2812009-07-22 15:45:39 +000094template<typename T>
95void 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
Douglas Gregor4fe95f92009-09-04 19:04:08 +0000107 for (unsigned I = 0, N = size(); I != N; ++I)
108 Start[I].~T();
Douglas Gregor5c7e2812009-07-22 15:45:39 +0000109 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
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000120struct Point {
121 Point() { x = y = z = 0.0; }
122 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
123
124 float x, y, z;
125};
126
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000127int 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
Douglas Gregor815215d2009-05-27 05:35:12 +0000138 for (int I = 0, N = di.size(); I != N; ++I)
139 assert(di[I] == I);
140
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000141 di.pop_back();
142 assert(di.size() == 4);
143 di.push_back(4);
144
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000145 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
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000152 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
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000159 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());
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000167
Douglas Gregord7f37bf2009-06-22 23:06:13 +0000168 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
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000176 return 0;
177}