summaryrefslogtreecommitdiff
path: root/clang/test/SemaTemplate/example-dynarray.cpp
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/SemaTemplate/example-dynarray.cpp
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/SemaTemplate/example-dynarray.cpp')
-rw-r--r--clang/test/SemaTemplate/example-dynarray.cpp177
1 files changed, 177 insertions, 0 deletions
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 <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;
+}