summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/example-dynarray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate/example-dynarray.cpp')
-rw-r--r--test/SemaTemplate/example-dynarray.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp
new file mode 100644
index 0000000..cca3709
--- /dev/null
+++ b/test/SemaTemplate/example-dynarray.cpp
@@ -0,0 +1,150 @@
+// RUN: clang-cc -fsyntax-only -verify %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() {
+ 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]);
+
+ // FIXME: destroy everything in Start
+ 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) {
+ 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]);
+
+ // FIXME: destruct old values
+ free(Start);
+
+ Start = NewStart;
+ Last = Start + Size;
+ End = Start + NewCapacity;
+ }
+
+ new (Last) T(value);
+ ++Last;
+ }
+
+ void pop_back() {
+ // FIXME: destruct old value
+ --Last;
+ }
+
+ 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; }
+
+public:
+ T* Start, *Last, *End;
+};
+
+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;
+};
+
+// FIXME: remove these when we have implicit instantiation for member
+// functions of class templates.
+template class dynarray<int>;
+template class dynarray<Point>;
+
+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());
+
+ return 0;
+}
OpenPOWER on IntegriCloud