blob: 51eece9e6f66c2daed1deb08dfcc1f8381b775ea [file] [log] [blame]
Douglas Gregor8ab892a2009-05-26 21:27:04 +00001// RUN: clang-cc -fsyntax-only -verify %s
2#include <stdlib.h>
3#include <assert.h>
4
5template<typename T>
6class dynarray {
Douglas Gregorf390f632009-05-28 16:41:44 +00007public:
Douglas Gregor8ab892a2009-05-26 21:27:04 +00008 dynarray() { Start = Last = End = 0; }
9
10 dynarray(const dynarray &other) {
11 Start = (T*)malloc(sizeof(T) * other.size());
12 Last = End = Start + other.size();
13
14 // FIXME: Use placement new, below
15 for (unsigned I = 0, N = other.size(); I != N; ++I)
16 Start[I] = other[I];
17 // new (Start + I) T(other[I]);
18 }
19
20 ~dynarray() {
21 free(Start);
22 }
23
24 dynarray &operator=(const dynarray &other) {
25 T* NewStart = (T*)malloc(sizeof(T) * other.size());
26
27 // FIXME: Use placement new, below
28 for (unsigned I = 0, N = other.size(); I != N; ++I)
29 NewStart[I] = other[I];
30 // new (Start + I) T(other[I]);
31
32 // FIXME: destroy everything in Start
33 free(Start);
34 Start = NewStart;
35 Last = End = NewStart + other.size();
36 return *this;
37 }
38
39 unsigned size() const { return Last - Start; }
40 unsigned capacity() const { return End - Start; }
41
42 void push_back(const T& value) {
43 if (Last == End) {
44 unsigned NewCapacity = capacity() * 2;
45 if (NewCapacity == 0)
46 NewCapacity = 4;
47
48 T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
49
50 unsigned Size = size();
51 for (unsigned I = 0; I != Size; ++I)
52 // FIXME: new (NewStart + I) T(Start[I])
53 NewStart[I] = Start[I];
54
55 // FIXME: destruct old values
56 free(Start);
57
58 Start = NewStart;
59 Last = Start + Size;
60 End = Start + NewCapacity;
61 }
62
63 // FIXME: new (Last) T(value);
64 *Last = value;
65 ++Last;
66 }
67
68 void pop_back() {
69 // FIXME: destruct old value
70 --Last;
71 }
72
73 T& operator[](unsigned Idx) {
74 return Start[Idx];
75 }
76
77 const T& operator[](unsigned Idx) const {
78 return Start[Idx];
79 }
80
Douglas Gregor8ab892a2009-05-26 21:27:04 +000081 typedef T* iterator;
82 typedef const T* const_iterator;
83
Douglas Gregorf97986d2009-05-27 05:35:12 +000084 iterator begin() { return Start; }
85 const_iterator begin() const { return Start; }
Douglas Gregor8ab892a2009-05-26 21:27:04 +000086
Douglas Gregorf97986d2009-05-27 05:35:12 +000087 iterator end() { return Last; }
88 const_iterator end() const { return Last; }
Douglas Gregor8ab892a2009-05-26 21:27:04 +000089
90public:
91 T* Start, *Last, *End;
92};
93
94struct Point {
95 Point() { x = y = z = 0.0; }
96 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
97
98 float x, y, z;
99};
100
101// FIXME: remove these when we have implicit instantiation for member
102// functions of class templates.
103template struct dynarray<int>;
104template struct dynarray<Point>;
105
106int main() {
107 dynarray<int> di;
108 di.push_back(0);
109 di.push_back(1);
110 di.push_back(2);
111 di.push_back(3);
112 di.push_back(4);
113 assert(di.size() == 5);
114 for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
115 assert(*I == I - di.begin());
116
Douglas Gregorf97986d2009-05-27 05:35:12 +0000117 for (int I = 0, N = di.size(); I != N; ++I)
118 assert(di[I] == I);
119
Douglas Gregor8ab892a2009-05-26 21:27:04 +0000120 di.pop_back();
121 assert(di.size() == 4);
122 di.push_back(4);
123
Douglas Gregor8ab892a2009-05-26 21:27:04 +0000124 dynarray<int> di2 = di;
125 assert(di2.size() == 5);
126 assert(di.begin() != di2.begin());
127 for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
128 I != IEnd; ++I)
129 assert(*I == I - di2.begin());
130
Douglas Gregor8ab892a2009-05-26 21:27:04 +0000131 dynarray<int> di3(di);
132 assert(di3.size() == 5);
133 assert(di.begin() != di3.begin());
134 for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
135 I != IEnd; ++I)
136 assert(*I == I - di3.begin());
137
Douglas Gregor8ab892a2009-05-26 21:27:04 +0000138 dynarray<int> di4;
139 assert(di4.size() == 0);
140 di4 = di;
141 assert(di4.size() == 5);
142 assert(di.begin() != di4.begin());
143 for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
144 I != IEnd; ++I)
145 assert(*I == I - di4.begin());
Douglas Gregor8ab892a2009-05-26 21:27:04 +0000146
147 return 0;
148}