From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/test/SemaTemplate/example-dynarray.cpp | 177 +++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 clang/test/SemaTemplate/example-dynarray.cpp (limited to 'clang/test/SemaTemplate/example-dynarray.cpp') diff --git a/clang/test/SemaTemplate/example-dynarray.cpp b/clang/test/SemaTemplate/example-dynarray.cpp new file mode 100644 index 0000000..999521e --- /dev/null +++ b/clang/test/SemaTemplate/example-dynarray.cpp @@ -0,0 +1,177 @@ +// RUN: %clangxx -emit-llvm -c -o - %s +#include +#include +#include + +// Placement new requires 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 +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 +void dynarray::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 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::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 di2 = di; + assert(di2.size() == 5); + assert(di.begin() != di2.begin()); + for (dynarray::iterator I = di2.begin(), IEnd = di2.end(); + I != IEnd; ++I) + assert(*I == I - di2.begin()); + + dynarray di3(di); + assert(di3.size() == 5); + assert(di.begin() != di3.begin()); + for (dynarray::iterator I = di3.begin(), IEnd = di3.end(); + I != IEnd; ++I) + assert(*I == I - di3.begin()); + + dynarray di4; + assert(di4.size() == 0); + di4 = di; + assert(di4.size() == 5); + assert(di.begin() != di4.begin()); + for (dynarray::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 dp; + dp.push_back(Point()); + assert(dp.size() == 1); + + return 0; +} -- cgit v1.2.3