forked from OSchip/llvm-project
178 lines
3.9 KiB
C++
178 lines
3.9 KiB
C++
// RUN: %clang -emit-llvm -S -o %t %s
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
// Placement new requires <new> to be included, but we don't support that yet.
|
|
void* operator new(size_t, void* ptr) throw() {
|
|
return ptr;
|
|
}
|
|
void operator delete(void*, void*) throw() {
|
|
}
|
|
|
|
template<typename T>
|
|
class dynarray {
|
|
public:
|
|
dynarray() { Start = Last = End = 0; }
|
|
|
|
dynarray(const dynarray &other) {
|
|
Start = (T*)malloc(sizeof(T) * other.size());
|
|
Last = End = Start + other.size();
|
|
|
|
for (unsigned I = 0, N = other.size(); I != N; ++I)
|
|
new (Start + I) T(other[I]);
|
|
}
|
|
|
|
~dynarray() {
|
|
for (unsigned I = 0, N = size(); I != N; ++I)
|
|
Start[I].~T();
|
|
|
|
free(Start);
|
|
}
|
|
|
|
dynarray &operator=(const dynarray &other) {
|
|
T* NewStart = (T*)malloc(sizeof(T) * other.size());
|
|
|
|
for (unsigned I = 0, N = other.size(); I != N; ++I)
|
|
new (NewStart + I) T(other[I]);
|
|
|
|
for (unsigned I = 0, N = size(); I != N; ++I)
|
|
Start[I].~T();
|
|
|
|
free(Start);
|
|
Start = NewStart;
|
|
Last = End = NewStart + other.size();
|
|
return *this;
|
|
}
|
|
|
|
unsigned size() const { return Last - Start; }
|
|
unsigned capacity() const { return End - Start; }
|
|
|
|
void push_back(const T& value);
|
|
|
|
void pop_back() {
|
|
--Last;
|
|
Last->~T();
|
|
}
|
|
|
|
T& operator[](unsigned Idx) {
|
|
return Start[Idx];
|
|
}
|
|
|
|
const T& operator[](unsigned Idx) const {
|
|
return Start[Idx];
|
|
}
|
|
|
|
typedef T* iterator;
|
|
typedef const T* const_iterator;
|
|
|
|
iterator begin() { return Start; }
|
|
const_iterator begin() const { return Start; }
|
|
|
|
iterator end() { return Last; }
|
|
const_iterator end() const { return Last; }
|
|
|
|
bool operator==(const dynarray &other) const {
|
|
if (size() != other.size())
|
|
return false;
|
|
|
|
for (unsigned I = 0, N = size(); I != N; ++I)
|
|
if ((*this)[I] != other[I])
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool operator!=(const dynarray &other) const {
|
|
return !(*this == other);
|
|
}
|
|
|
|
public:
|
|
T* Start, *Last, *End;
|
|
};
|
|
|
|
template<typename T>
|
|
void dynarray<T>::push_back(const T& value) {
|
|
if (Last == End) {
|
|
unsigned NewCapacity = capacity() * 2;
|
|
if (NewCapacity == 0)
|
|
NewCapacity = 4;
|
|
|
|
T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
|
|
|
|
unsigned Size = size();
|
|
for (unsigned I = 0; I != Size; ++I)
|
|
new (NewStart + I) T(Start[I]);
|
|
|
|
for (unsigned I = 0, N = size(); I != N; ++I)
|
|
Start[I].~T();
|
|
free(Start);
|
|
|
|
Start = NewStart;
|
|
Last = Start + Size;
|
|
End = Start + NewCapacity;
|
|
}
|
|
|
|
new (Last) T(value);
|
|
++Last;
|
|
}
|
|
|
|
struct Point {
|
|
Point() { x = y = z = 0.0; }
|
|
Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
|
|
|
|
float x, y, z;
|
|
};
|
|
|
|
int main() {
|
|
dynarray<int> di;
|
|
di.push_back(0);
|
|
di.push_back(1);
|
|
di.push_back(2);
|
|
di.push_back(3);
|
|
di.push_back(4);
|
|
assert(di.size() == 5);
|
|
for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
|
|
assert(*I == I - di.begin());
|
|
|
|
for (int I = 0, N = di.size(); I != N; ++I)
|
|
assert(di[I] == I);
|
|
|
|
di.pop_back();
|
|
assert(di.size() == 4);
|
|
di.push_back(4);
|
|
|
|
dynarray<int> di2 = di;
|
|
assert(di2.size() == 5);
|
|
assert(di.begin() != di2.begin());
|
|
for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
|
|
I != IEnd; ++I)
|
|
assert(*I == I - di2.begin());
|
|
|
|
dynarray<int> di3(di);
|
|
assert(di3.size() == 5);
|
|
assert(di.begin() != di3.begin());
|
|
for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
|
|
I != IEnd; ++I)
|
|
assert(*I == I - di3.begin());
|
|
|
|
dynarray<int> di4;
|
|
assert(di4.size() == 0);
|
|
di4 = di;
|
|
assert(di4.size() == 5);
|
|
assert(di.begin() != di4.begin());
|
|
for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
|
|
I != IEnd; ++I)
|
|
assert(*I == I - di4.begin());
|
|
|
|
assert(di4 == di);
|
|
di4[3] = 17;
|
|
assert(di4 != di);
|
|
|
|
dynarray<Point> dp;
|
|
dp.push_back(Point());
|
|
assert(dp.size() == 1);
|
|
|
|
return 0;
|
|
}
|