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. 7 void* operator new(size_t, void* ptr) throw() { 8 return ptr; 9 } 10 void operator delete(void*, void*) throw() { 11 } 12 13 template<typename T> 14 class dynarray { 15 public: 16 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 22 for (unsigned I = 0, N = other.size(); I != N; ++I) 23 new (Start + I) T(other[I]); 24 } 25 26 ~dynarray() { 27 for (unsigned I = 0, N = size(); I != N; ++I) 28 Start[I].~T(); 29 30 free(Start); 31 } 32 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 48 unsigned size() const { return Last - Start; } 49 unsigned capacity() const { return End - Start; } 50 51 void push_back(const T& value); 52 53 void pop_back() { 54 --Last; 55 Last->~T(); 56 } 57 58 T& operator[](unsigned Idx) { 59 return Start[Idx]; 60 } 61 62 const T& operator[](unsigned Idx) const { 63 return Start[Idx]; 64 } 65 66 typedef T* iterator; 67 typedef const T* const_iterator; 68 69 iterator begin() { return Start; } 70 const_iterator begin() const { return Start; } 71 72 iterator end() { return Last; } 73 const_iterator end() const { return Last; } 74 75 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 86 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> 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 { 121 Point() { x = y = z = 0.0; } 122 Point(const Point& other) : x(other.x), y(other.y), z(other.z) { } 123 124 float x, y, z; 125 }; 126 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