Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clangxx -emit-llvm -c -o - %s
      2 #include <stddef.h>
      3 #include <stdlib.h>
      4 #include <assert.h>
      5 
      6 // Placement new requires <new> to be included, but we don't support that yet.
      7 void* operator new(size_t, void* ptr) throw() {
      8   return ptr;
      9 }
     10 void operator delete(void*, void*) throw() {
     11 }
     12 
     13 template<typename T>
     14 class dynarray {
     15 public:
     16   dynarray() { Start = Last = End = 0; }
     17 
     18   dynarray(const dynarray &other) {
     19     Start = (T*)malloc(sizeof(T) * other.size());
     20     Last = End = Start + other.size();
     21 
     22     for (unsigned I = 0, N = other.size(); I != N; ++I)
     23       new (Start + I) T(other[I]);
     24   }
     25 
     26   ~dynarray() {
     27     for (unsigned I = 0, N = size(); I != N; ++I)
     28       Start[I].~T();
     29 
     30     free(Start);
     31   }
     32 
     33   dynarray &operator=(const dynarray &other) {
     34     T* NewStart = (T*)malloc(sizeof(T) * other.size());
     35 
     36     for (unsigned I = 0, N = other.size(); I != N; ++I)
     37       new (NewStart + I) T(other[I]);
     38 
     39     for (unsigned I = 0, N = size(); I != N; ++I)
     40       Start[I].~T();
     41 
     42     free(Start);
     43     Start = NewStart;
     44     Last = End = NewStart + other.size();
     45     return *this;
     46   }
     47 
     48   unsigned size() const { return Last - Start; }
     49   unsigned capacity() const { return End - Start; }
     50 
     51   void push_back(const T& value);
     52 
     53   void pop_back() {
     54     --Last;
     55     Last->~T();
     56   }
     57 
     58   T& operator[](unsigned Idx) {
     59     return Start[Idx];
     60   }
     61 
     62   const T& operator[](unsigned Idx) const {
     63     return Start[Idx];
     64   }
     65 
     66   typedef T* iterator;
     67   typedef const T* const_iterator;
     68 
     69   iterator begin() { return Start; }
     70   const_iterator begin() const { return Start; }
     71 
     72   iterator end() { return Last; }
     73   const_iterator end() const { return Last; }
     74 
     75   bool operator==(const dynarray &other) const {
     76     if (size() != other.size())
     77       return false;
     78 
     79     for (unsigned I = 0, N = size(); I != N; ++I)
     80       if ((*this)[I] != other[I])
     81         return false;
     82 
     83     return true;
     84   }
     85 
     86   bool operator!=(const dynarray &other) const {
     87     return !(*this == other);
     88   }
     89 
     90 public:
     91   T* Start, *Last, *End;
     92 };
     93 
     94 template<typename T>
     95 void dynarray<T>::push_back(const T& value) {
     96   if (Last == End) {
     97     unsigned NewCapacity = capacity() * 2;
     98     if (NewCapacity == 0)
     99       NewCapacity = 4;
    100 
    101     T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
    102 
    103     unsigned Size = size();
    104     for (unsigned I = 0; I != Size; ++I)
    105       new (NewStart + I) T(Start[I]);
    106 
    107     for (unsigned I = 0, N = size(); I != N; ++I)
    108       Start[I].~T();
    109     free(Start);
    110 
    111     Start = NewStart;
    112     Last = Start + Size;
    113     End = Start + NewCapacity;
    114   }
    115 
    116   new (Last) T(value);
    117   ++Last;
    118 }
    119 
    120 struct Point {
    121   Point() { x = y = z = 0.0; }
    122   Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
    123 
    124   float x, y, z;
    125 };
    126 
    127 int main() {
    128   dynarray<int> di;
    129   di.push_back(0);
    130   di.push_back(1);
    131   di.push_back(2);
    132   di.push_back(3);
    133   di.push_back(4);
    134   assert(di.size() == 5);
    135   for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
    136     assert(*I == I - di.begin());
    137 
    138   for (int I = 0, N = di.size(); I != N; ++I)
    139     assert(di[I] == I);
    140 
    141   di.pop_back();
    142   assert(di.size() == 4);
    143   di.push_back(4);
    144 
    145   dynarray<int> di2 = di;
    146   assert(di2.size() == 5);
    147   assert(di.begin() != di2.begin());
    148   for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
    149        I != IEnd; ++I)
    150     assert(*I == I - di2.begin());
    151 
    152   dynarray<int> di3(di);
    153   assert(di3.size() == 5);
    154   assert(di.begin() != di3.begin());
    155   for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
    156        I != IEnd; ++I)
    157     assert(*I == I - di3.begin());
    158 
    159   dynarray<int> di4;
    160   assert(di4.size() == 0);
    161   di4 = di;
    162   assert(di4.size() == 5);
    163   assert(di.begin() != di4.begin());
    164   for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
    165        I != IEnd; ++I)
    166     assert(*I == I - di4.begin());
    167 
    168   assert(di4 == di);
    169   di4[3] = 17;
    170   assert(di4 != di);
    171 
    172   dynarray<Point> dp;
    173   dp.push_back(Point());
    174   assert(dp.size() == 1);
    175 
    176   return 0;
    177 }
    178