blob: 990c799ee1195cc340a907cdee7a1bb27ec547fe [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 {
7 dynarray() { Start = Last = End = 0; }
8
9 dynarray(const dynarray &other) {
10 Start = (T*)malloc(sizeof(T) * other.size());
11 Last = End = Start + other.size();
12
13 // FIXME: Use placement new, below
14 for (unsigned I = 0, N = other.size(); I != N; ++I)
15 Start[I] = other[I];
16 // new (Start + I) T(other[I]);
17 }
18
19 ~dynarray() {
20 free(Start);
21 }
22
23 dynarray &operator=(const dynarray &other) {
24 T* NewStart = (T*)malloc(sizeof(T) * other.size());
25
26 // FIXME: Use placement new, below
27 for (unsigned I = 0, N = other.size(); I != N; ++I)
28 NewStart[I] = other[I];
29 // new (Start + I) T(other[I]);
30
31 // FIXME: destroy everything in Start
32 free(Start);
33 Start = NewStart;
34 Last = End = NewStart + other.size();
35 return *this;
36 }
37
38 unsigned size() const { return Last - Start; }
39 unsigned capacity() const { return End - Start; }
40
41 void push_back(const T& value) {
42 if (Last == End) {
43 unsigned NewCapacity = capacity() * 2;
44 if (NewCapacity == 0)
45 NewCapacity = 4;
46
47 T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
48
49 unsigned Size = size();
50 for (unsigned I = 0; I != Size; ++I)
51 // FIXME: new (NewStart + I) T(Start[I])
52 NewStart[I] = Start[I];
53
54 // FIXME: destruct old values
55 free(Start);
56
57 Start = NewStart;
58 Last = Start + Size;
59 End = Start + NewCapacity;
60 }
61
62 // FIXME: new (Last) T(value);
63 *Last = value;
64 ++Last;
65 }
66
67 void pop_back() {
68 // FIXME: destruct old value
69 --Last;
70 }
71
72 T& operator[](unsigned Idx) {
73 return Start[Idx];
74 }
75
76 const T& operator[](unsigned Idx) const {
77 return Start[Idx];
78 }
79
80 // FIXME: use these for begin/end when we can instantiate
81 // TypedefType nodes.
82 typedef T* iterator;
83 typedef const T* const_iterator;
84
85 T* begin() { return Start; }
86 const T* begin() const { return Start; }
87
88 T* end() { return Last; }
89 const T* end() const { return Last; }
90
91public:
92 T* Start, *Last, *End;
93};
94
95struct Point {
96 Point() { x = y = z = 0.0; }
97 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
98
99 float x, y, z;
100};
101
102// FIXME: remove these when we have implicit instantiation for member
103// functions of class templates.
104template struct dynarray<int>;
105template struct dynarray<Point>;
106
107int main() {
108 dynarray<int> di;
109 di.push_back(0);
110 di.push_back(1);
111 di.push_back(2);
112 di.push_back(3);
113 di.push_back(4);
114 assert(di.size() == 5);
115 for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
116 assert(*I == I - di.begin());
117
118 di.pop_back();
119 assert(di.size() == 4);
120 di.push_back(4);
121
122#if 0
123 // FIXME: Copy construction via copy initialization
124 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
131 // FIXME: Copy construction via direct initialization
132 dynarray<int> di3(di);
133 assert(di3.size() == 5);
134 assert(di.begin() != di3.begin());
135 for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
136 I != IEnd; ++I)
137 assert(*I == I - di3.begin());
138
139 // FIXME: assignment operator
140 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());
148#endif
149
150 return 0;
151}