1eefb6abc7699722024d757d7be96498ed4df16edDaniel Dunbar// RUN: %clangxx -emit-llvm -c -o - %s 296a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl#include <stddef.h> 38ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor#include <stdlib.h> 48ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor#include <assert.h> 58ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 696a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl// Placement new requires <new> to be included, but we don't support that yet. 796a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redlvoid* operator new(size_t, void* ptr) throw() { 896a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl return ptr; 996a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl} 1096a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redlvoid operator delete(void*, void*) throw() { 1196a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl} 1296a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl 138ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregortemplate<typename T> 148ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregorclass dynarray { 15f390f634e50720c0b3324c4629212cdc744ba1feDouglas Gregorpublic: 168ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray() { Start = Last = End = 0; } 178ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 188ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray(const dynarray &other) { 198ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor Start = (T*)malloc(sizeof(T) * other.size()); 208ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor Last = End = Start + other.size(); 218ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 228ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor for (unsigned I = 0, N = other.size(); I != N; ++I) 2396a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl new (Start + I) T(other[I]); 248ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor } 258ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 268ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor ~dynarray() { 276ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor for (unsigned I = 0, N = size(); I != N; ++I) 286ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor Start[I].~T(); 296ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor 308ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor free(Start); 318ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor } 328ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 338ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray &operator=(const dynarray &other) { 348ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor T* NewStart = (T*)malloc(sizeof(T) * other.size()); 358ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 368ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor for (unsigned I = 0, N = other.size(); I != N; ++I) 37962ed0695d1083e26f79d99d6fc7aebc0ba4e70eAnders Carlsson new (NewStart + I) T(other[I]); 3896a2aaa2853850c2520614b6196b61daaf506ae2Sebastian Redl 396ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor for (unsigned I = 0, N = size(); I != N; ++I) 406ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor Start[I].~T(); 416ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor 428ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor free(Start); 438ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor Start = NewStart; 448ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor Last = End = NewStart + other.size(); 458ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor return *this; 468ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor } 478ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 488ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor unsigned size() const { return Last - Start; } 498ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor unsigned capacity() const { return End - Start; } 508ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 510ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor void push_back(const T& value); 520ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 538ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor void pop_back() { 548ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor --Last; 556ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor Last->~T(); 568ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor } 578ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 588ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor T& operator[](unsigned Idx) { 598ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor return Start[Idx]; 608ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor } 618ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 628ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor const T& operator[](unsigned Idx) const { 638ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor return Start[Idx]; 648ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor } 658ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 668ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor typedef T* iterator; 678ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor typedef const T* const_iterator; 688ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 69f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor iterator begin() { return Start; } 70f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor const_iterator begin() const { return Start; } 718ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 72f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor iterator end() { return Last; } 73f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor const_iterator end() const { return Last; } 748ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 75cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor bool operator==(const dynarray &other) const { 76cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor if (size() != other.size()) 77cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor return false; 78cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor 79cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor for (unsigned I = 0, N = size(); I != N; ++I) 80cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor if ((*this)[I] != other[I]) 81cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor return false; 82cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor 83cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor return true; 84cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor } 85cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor 86cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor bool operator!=(const dynarray &other) const { 87cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor return !(*this == other); 88cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor } 89cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor 908ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregorpublic: 918ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor T* Start, *Last, *End; 928ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor}; 938ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 940ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregortemplate<typename T> 950ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregorvoid dynarray<T>::push_back(const T& value) { 960ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor if (Last == End) { 970ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor unsigned NewCapacity = capacity() * 2; 980ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor if (NewCapacity == 0) 990ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor NewCapacity = 4; 1000ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 1010ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor T* NewStart = (T*)malloc(sizeof(T) * NewCapacity); 1020ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 1030ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor unsigned Size = size(); 1040ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor for (unsigned I = 0; I != Size; ++I) 1050ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor new (NewStart + I) T(Start[I]); 1060ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 1076ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor for (unsigned I = 0, N = size(); I != N; ++I) 1086ccc6f3f2044286d82ad46e726d4696c6673cfa8Douglas Gregor Start[I].~T(); 1090ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor free(Start); 1100ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 1110ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor Start = NewStart; 1120ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor Last = Start + Size; 1130ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor End = Start + NewCapacity; 1140ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor } 1150ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 1160ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor new (Last) T(value); 1170ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor ++Last; 1180ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor} 1190ce8515575703c71af6b9efe0a43bc518e1fe803Douglas Gregor 1208ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregorstruct Point { 1218ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor Point() { x = y = z = 0.0; } 1228ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor Point(const Point& other) : x(other.x), y(other.y), z(other.z) { } 1238ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 1248ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor float x, y, z; 1258ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor}; 1268ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 1278ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregorint main() { 1288ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray<int> di; 1298ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.push_back(0); 1308ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.push_back(1); 1318ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.push_back(2); 1328ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.push_back(3); 1338ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.push_back(4); 1348ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di.size() == 5); 1358ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I) 1368ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(*I == I - di.begin()); 1378ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 138f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor for (int I = 0, N = di.size(); I != N; ++I) 139f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor assert(di[I] == I); 140f97986dce99ea113744872de1d2a6d2da274061bDouglas Gregor 1418ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.pop_back(); 1428ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di.size() == 4); 1438ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di.push_back(4); 1448ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 1458ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray<int> di2 = di; 1468ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di2.size() == 5); 1478ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di.begin() != di2.begin()); 1488ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end(); 1498ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor I != IEnd; ++I) 1508ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(*I == I - di2.begin()); 1518ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 1528ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray<int> di3(di); 1538ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di3.size() == 5); 1548ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di.begin() != di3.begin()); 1558ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end(); 1568ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor I != IEnd; ++I) 1578ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(*I == I - di3.begin()); 1588ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 1598ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor dynarray<int> di4; 1608ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di4.size() == 0); 1618ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor di4 = di; 1628ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di4.size() == 5); 1638ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(di.begin() != di4.begin()); 1648ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end(); 1658ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor I != IEnd; ++I) 1668ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor assert(*I == I - di4.begin()); 1678ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor 168cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor assert(di4 == di); 169cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor di4[3] = 17; 170cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor assert(di4 != di); 171cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor 172cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor dynarray<Point> dp; 173cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor dp.push_back(Point()); 174cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor assert(dp.size() == 1); 175cad27f643ec41875c51d5ac860abf766f0a33675Douglas Gregor 1768ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor return 0; 1778ab892a09e1955353db19620b1a6dbadb74877fbDouglas Gregor} 178