From: Douglas Gregor Date: Tue, 26 May 2009 21:27:04 +0000 (+0000) Subject: A simple dynamic array class template, to be used as a test-bed for template instanti... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2f1735c643abfc7c18bf7d0ad95b716099d43ccf;p=clang A simple dynamic array class template, to be used as a test-bed for template instantiation git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72437 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp new file mode 100644 index 0000000000..990c799ee1 --- /dev/null +++ b/test/SemaTemplate/example-dynarray.cpp @@ -0,0 +1,151 @@ +// RUN: clang-cc -fsyntax-only -verify %s +#include +#include + +template +class dynarray { + dynarray() { Start = Last = End = 0; } + + dynarray(const dynarray &other) { + Start = (T*)malloc(sizeof(T) * other.size()); + Last = End = Start + other.size(); + + // FIXME: Use placement new, below + for (unsigned I = 0, N = other.size(); I != N; ++I) + Start[I] = other[I]; + // new (Start + I) T(other[I]); + } + + ~dynarray() { + free(Start); + } + + dynarray &operator=(const dynarray &other) { + T* NewStart = (T*)malloc(sizeof(T) * other.size()); + + // FIXME: Use placement new, below + for (unsigned I = 0, N = other.size(); I != N; ++I) + NewStart[I] = other[I]; + // new (Start + 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) + // FIXME: new (NewStart + I) T(Start[I]) + NewStart[I] = Start[I]; + + // FIXME: destruct old values + free(Start); + + Start = NewStart; + Last = Start + Size; + End = Start + NewCapacity; + } + + // FIXME: new (Last) T(value); + *Last = 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]; + } + + // FIXME: use these for begin/end when we can instantiate + // TypedefType nodes. + typedef T* iterator; + typedef const T* const_iterator; + + T* begin() { return Start; } + const T* begin() const { return Start; } + + T* end() { return Last; } + const T* 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 struct dynarray; +template struct dynarray; + +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()); + + di.pop_back(); + assert(di.size() == 4); + di.push_back(4); + +#if 0 + // FIXME: Copy construction via copy initialization + 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()); + + // FIXME: Copy construction via direct initialization + 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()); + + // FIXME: assignment operator + 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()); +#endif + + return 0; +}