• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clangxx -emit-llvm -c -o - %s
2 #include <stddef.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 
6 // Placement new requires <new> to be included, but we don't support that yet.
operator new(size_t,void * ptr)7 void* operator new(size_t, void* ptr) throw() {
8   return ptr;
9 }
operator delete(void *,void *)10 void operator delete(void*, void*) throw() {
11 }
12 
13 template<typename T>
14 class dynarray {
15 public:
dynarray()16   dynarray() { Start = Last = End = 0; }
17 
dynarray(const dynarray & other)18   dynarray(const dynarray &other) {
19     Start = (T*)malloc(sizeof(T) * other.size());
20     Last = End = Start + other.size();
21 
22     for (unsigned I = 0, N = other.size(); I != N; ++I)
23       new (Start + I) T(other[I]);
24   }
25 
~dynarray()26   ~dynarray() {
27     for (unsigned I = 0, N = size(); I != N; ++I)
28       Start[I].~T();
29 
30     free(Start);
31   }
32 
operator =(const dynarray & other)33   dynarray &operator=(const dynarray &other) {
34     T* NewStart = (T*)malloc(sizeof(T) * other.size());
35 
36     for (unsigned I = 0, N = other.size(); I != N; ++I)
37       new (NewStart + I) T(other[I]);
38 
39     for (unsigned I = 0, N = size(); I != N; ++I)
40       Start[I].~T();
41 
42     free(Start);
43     Start = NewStart;
44     Last = End = NewStart + other.size();
45     return *this;
46   }
47 
size() const48   unsigned size() const { return Last - Start; }
capacity() const49   unsigned capacity() const { return End - Start; }
50 
51   void push_back(const T& value);
52 
pop_back()53   void pop_back() {
54     --Last;
55     Last->~T();
56   }
57 
operator [](unsigned Idx)58   T& operator[](unsigned Idx) {
59     return Start[Idx];
60   }
61 
operator [](unsigned Idx) const62   const T& operator[](unsigned Idx) const {
63     return Start[Idx];
64   }
65 
66   typedef T* iterator;
67   typedef const T* const_iterator;
68 
begin()69   iterator begin() { return Start; }
begin() const70   const_iterator begin() const { return Start; }
71 
end()72   iterator end() { return Last; }
end() const73   const_iterator end() const { return Last; }
74 
operator ==(const dynarray & other) const75   bool operator==(const dynarray &other) const {
76     if (size() != other.size())
77       return false;
78 
79     for (unsigned I = 0, N = size(); I != N; ++I)
80       if ((*this)[I] != other[I])
81         return false;
82 
83     return true;
84   }
85 
operator !=(const dynarray & other) const86   bool operator!=(const dynarray &other) const {
87     return !(*this == other);
88   }
89 
90 public:
91   T* Start, *Last, *End;
92 };
93 
94 template<typename T>
push_back(const T & value)95 void dynarray<T>::push_back(const T& value) {
96   if (Last == End) {
97     unsigned NewCapacity = capacity() * 2;
98     if (NewCapacity == 0)
99       NewCapacity = 4;
100 
101     T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
102 
103     unsigned Size = size();
104     for (unsigned I = 0; I != Size; ++I)
105       new (NewStart + I) T(Start[I]);
106 
107     for (unsigned I = 0, N = size(); I != N; ++I)
108       Start[I].~T();
109     free(Start);
110 
111     Start = NewStart;
112     Last = Start + Size;
113     End = Start + NewCapacity;
114   }
115 
116   new (Last) T(value);
117   ++Last;
118 }
119 
120 struct Point {
PointPoint121   Point() { x = y = z = 0.0; }
PointPoint122   Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
123 
124   float x, y, z;
125 };
126 
main()127 int main() {
128   dynarray<int> di;
129   di.push_back(0);
130   di.push_back(1);
131   di.push_back(2);
132   di.push_back(3);
133   di.push_back(4);
134   assert(di.size() == 5);
135   for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
136     assert(*I == I - di.begin());
137 
138   for (int I = 0, N = di.size(); I != N; ++I)
139     assert(di[I] == I);
140 
141   di.pop_back();
142   assert(di.size() == 4);
143   di.push_back(4);
144 
145   dynarray<int> di2 = di;
146   assert(di2.size() == 5);
147   assert(di.begin() != di2.begin());
148   for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
149        I != IEnd; ++I)
150     assert(*I == I - di2.begin());
151 
152   dynarray<int> di3(di);
153   assert(di3.size() == 5);
154   assert(di.begin() != di3.begin());
155   for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
156        I != IEnd; ++I)
157     assert(*I == I - di3.begin());
158 
159   dynarray<int> di4;
160   assert(di4.size() == 0);
161   di4 = di;
162   assert(di4.size() == 5);
163   assert(di.begin() != di4.begin());
164   for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
165        I != IEnd; ++I)
166     assert(*I == I - di4.begin());
167 
168   assert(di4 == di);
169   di4[3] = 17;
170   assert(di4 != di);
171 
172   dynarray<Point> dp;
173   dp.push_back(Point());
174   assert(dp.size() == 1);
175 
176   return 0;
177 }
178