blob: dd2488fc382a6b474ca76d48143ef34909c09af0 [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)
Sebastian Redle47590e2009-05-29 16:43:59 +000034 new (Start + I) T(other[I]);
35
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
92public:
93 T* Start, *Last, *End;
94};
95
96struct Point {
97 Point() { x = y = z = 0.0; }
98 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
99
100 float x, y, z;
101};
102
103// FIXME: remove these when we have implicit instantiation for member
104// functions of class templates.
Sebastian Redle47590e2009-05-29 16:43:59 +0000105template class dynarray<int>;
106template class dynarray<Point>;
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000107
108int main() {
109 dynarray<int> di;
110 di.push_back(0);
111 di.push_back(1);
112 di.push_back(2);
113 di.push_back(3);
114 di.push_back(4);
115 assert(di.size() == 5);
116 for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
117 assert(*I == I - di.begin());
118
Douglas Gregor815215d2009-05-27 05:35:12 +0000119 for (int I = 0, N = di.size(); I != N; ++I)
120 assert(di[I] == I);
121
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000122 di.pop_back();
123 assert(di.size() == 4);
124 di.push_back(4);
125
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000126 dynarray<int> di2 = di;
127 assert(di2.size() == 5);
128 assert(di.begin() != di2.begin());
129 for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
130 I != IEnd; ++I)
131 assert(*I == I - di2.begin());
132
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000133 dynarray<int> di3(di);
134 assert(di3.size() == 5);
135 assert(di.begin() != di3.begin());
136 for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
137 I != IEnd; ++I)
138 assert(*I == I - di3.begin());
139
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000140 dynarray<int> di4;
141 assert(di4.size() == 0);
142 di4 = di;
143 assert(di4.size() == 5);
144 assert(di.begin() != di4.begin());
145 for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
146 I != IEnd; ++I)
147 assert(*I == I - di4.begin());
Douglas Gregor2f1735c2009-05-26 21:27:04 +0000148
149 return 0;
150}