blob: 680ee04ba18e17b872b5e7eac9bf308570b9612c [file] [log] [blame]
Douglas Gregor2f1735c2009-05-26 21:27:04 +00001// RUN: clang-cc -fsyntax-only -verify %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() {
27 free(Start);
28 }
29
30 dynarray &operator=(const dynarray &other) {
31 T* NewStart = (T*)malloc(sizeof(T) * other.size());
32
Douglas Gregor2f1735c2009-05-26 21:27:04 +000033 for (unsigned I = 0, N = other.size(); I != N; ++I)
Anders Carlssona53f93b2009-06-01 00:40:08 +000034 new (NewStart + I) T(other[I]);
Sebastian Redle47590e2009-05-29 16:43:59 +000035
Douglas Gregor2f1735c2009-05-26 21:27:04 +000036 // FIXME: destroy everything in Start
37 free(Start);
38 Start = NewStart;
39 Last = End = NewStart + other.size();
40 return *this;
41 }
42
43 unsigned size() const { return Last - Start; }
44 unsigned capacity() const { return End - Start; }
45
46 void push_back(const T& value) {
47 if (Last == End) {
48 unsigned NewCapacity = capacity() * 2;
49 if (NewCapacity == 0)
50 NewCapacity = 4;
51
52 T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
53
54 unsigned Size = size();
55 for (unsigned I = 0; I != Size; ++I)
Sebastian Redle47590e2009-05-29 16:43:59 +000056 new (NewStart + I) T(Start[I]);
Douglas Gregor2f1735c2009-05-26 21:27:04 +000057
58 // FIXME: destruct old values
59 free(Start);
60
61 Start = NewStart;
62 Last = Start + Size;
63 End = Start + NewCapacity;
64 }
65
Sebastian Redle47590e2009-05-29 16:43:59 +000066 new (Last) T(value);
Douglas Gregor2f1735c2009-05-26 21:27:04 +000067 ++Last;
68 }
69
70 void pop_back() {
71 // FIXME: destruct old value
72 --Last;
73 }
74
75 T& operator[](unsigned Idx) {
76 return Start[Idx];
77 }
78
79 const T& operator[](unsigned Idx) const {
80 return Start[Idx];
81 }
82
Douglas Gregor2f1735c2009-05-26 21:27:04 +000083 typedef T* iterator;
84 typedef const T* const_iterator;
85
Douglas Gregor815215d2009-05-27 05:35:12 +000086 iterator begin() { return Start; }
87 const_iterator begin() const { return Start; }
Douglas Gregor2f1735c2009-05-26 21:27:04 +000088
Douglas Gregor815215d2009-05-27 05:35:12 +000089 iterator end() { return Last; }
90 const_iterator end() const { return Last; }
Douglas Gregor2f1735c2009-05-26 21:27:04 +000091
Douglas Gregord7f37bf2009-06-22 23:06:13 +000092 bool operator==(const dynarray &other) const {
93 if (size() != other.size())
94 return false;
95
96 for (unsigned I = 0, N = size(); I != N; ++I)
97 if ((*this)[I] != other[I])
98 return false;
99
100 return true;
101 }
102
103 bool operator!=(const dynarray &other) const {
104 return !(*this == other);
105 }
106
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000107public:
108 T* Start, *Last, *End;
109};
110
111struct Point {
112 Point() { x = y = z = 0.0; }
113 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
114
115 float x, y, z;
116};
117
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000118int main() {
119 dynarray<int> di;
120 di.push_back(0);
121 di.push_back(1);
122 di.push_back(2);
123 di.push_back(3);
124 di.push_back(4);
125 assert(di.size() == 5);
126 for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
127 assert(*I == I - di.begin());
128
Douglas Gregor815215d2009-05-27 05:35:12 +0000129 for (int I = 0, N = di.size(); I != N; ++I)
130 assert(di[I] == I);
131
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000132 di.pop_back();
133 assert(di.size() == 4);
134 di.push_back(4);
135
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000136 dynarray<int> di2 = di;
137 assert(di2.size() == 5);
138 assert(di.begin() != di2.begin());
139 for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
140 I != IEnd; ++I)
141 assert(*I == I - di2.begin());
142
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000143 dynarray<int> di3(di);
144 assert(di3.size() == 5);
145 assert(di.begin() != di3.begin());
146 for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
147 I != IEnd; ++I)
148 assert(*I == I - di3.begin());
149
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000150 dynarray<int> di4;
151 assert(di4.size() == 0);
152 di4 = di;
153 assert(di4.size() == 5);
154 assert(di.begin() != di4.begin());
155 for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
156 I != IEnd; ++I)
157 assert(*I == I - di4.begin());
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000158
Douglas Gregord7f37bf2009-06-22 23:06:13 +0000159 assert(di4 == di);
160 di4[3] = 17;
161 assert(di4 != di);
162
163 dynarray<Point> dp;
164 dp.push_back(Point());
165 assert(dp.size() == 1);
166
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000167 return 0;
168}