blob: 7dcc508d2c8441a65a978a2ed70bbb7f8a769541 [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
Douglas Gregor5c7e2812009-07-22 15:45:39 +000046 void push_back(const T& value);
47
Douglas Gregor2f1735c2009-05-26 21:27:04 +000048 void pop_back() {
49 // FIXME: destruct old value
50 --Last;
51 }
52
53 T& operator[](unsigned Idx) {
54 return Start[Idx];
55 }
56
57 const T& operator[](unsigned Idx) const {
58 return Start[Idx];
59 }
60
Douglas Gregor2f1735c2009-05-26 21:27:04 +000061 typedef T* iterator;
62 typedef const T* const_iterator;
63
Douglas Gregor815215d2009-05-27 05:35:12 +000064 iterator begin() { return Start; }
65 const_iterator begin() const { return Start; }
Douglas Gregor2f1735c2009-05-26 21:27:04 +000066
Douglas Gregor815215d2009-05-27 05:35:12 +000067 iterator end() { return Last; }
68 const_iterator end() const { return Last; }
Douglas Gregor2f1735c2009-05-26 21:27:04 +000069
Douglas Gregord7f37bf2009-06-22 23:06:13 +000070 bool operator==(const dynarray &other) const {
71 if (size() != other.size())
72 return false;
73
74 for (unsigned I = 0, N = size(); I != N; ++I)
75 if ((*this)[I] != other[I])
76 return false;
77
78 return true;
79 }
80
81 bool operator!=(const dynarray &other) const {
82 return !(*this == other);
83 }
84
Douglas Gregor2f1735c2009-05-26 21:27:04 +000085public:
86 T* Start, *Last, *End;
87};
88
Douglas Gregor5c7e2812009-07-22 15:45:39 +000089template<typename T>
90void dynarray<T>::push_back(const T& value) {
91 if (Last == End) {
92 unsigned NewCapacity = capacity() * 2;
93 if (NewCapacity == 0)
94 NewCapacity = 4;
95
96 T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
97
98 unsigned Size = size();
99 for (unsigned I = 0; I != Size; ++I)
100 new (NewStart + I) T(Start[I]);
101
102 // FIXME: destruct old values
103 free(Start);
104
105 Start = NewStart;
106 Last = Start + Size;
107 End = Start + NewCapacity;
108 }
109
110 new (Last) T(value);
111 ++Last;
112}
113
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000114struct Point {
115 Point() { x = y = z = 0.0; }
116 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
117
118 float x, y, z;
119};
120
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000121int main() {
122 dynarray<int> di;
123 di.push_back(0);
124 di.push_back(1);
125 di.push_back(2);
126 di.push_back(3);
127 di.push_back(4);
128 assert(di.size() == 5);
129 for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
130 assert(*I == I - di.begin());
131
Douglas Gregor815215d2009-05-27 05:35:12 +0000132 for (int I = 0, N = di.size(); I != N; ++I)
133 assert(di[I] == I);
134
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000135 di.pop_back();
136 assert(di.size() == 4);
137 di.push_back(4);
138
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000139 dynarray<int> di2 = di;
140 assert(di2.size() == 5);
141 assert(di.begin() != di2.begin());
142 for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
143 I != IEnd; ++I)
144 assert(*I == I - di2.begin());
145
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000146 dynarray<int> di3(di);
147 assert(di3.size() == 5);
148 assert(di.begin() != di3.begin());
149 for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
150 I != IEnd; ++I)
151 assert(*I == I - di3.begin());
152
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000153 dynarray<int> di4;
154 assert(di4.size() == 0);
155 di4 = di;
156 assert(di4.size() == 5);
157 assert(di.begin() != di4.begin());
158 for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
159 I != IEnd; ++I)
160 assert(*I == I - di4.begin());
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000161
Douglas Gregord7f37bf2009-06-22 23:06:13 +0000162 assert(di4 == di);
163 di4[3] = 17;
164 assert(di4 != di);
165
166 dynarray<Point> dp;
167 dp.push_back(Point());
168 assert(dp.size() == 1);
169
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000170 return 0;
171}