1 /* { dg-do compile } */ 2 /* { dg-additional-options "-Wno-return-type" } */ 3 4 void *fastMalloc (int n); 5 void fastFree (void *p); 6 template <class T> struct C 7 { derefC8 void deref () { delete static_cast <T *>(this); } 9 }; 10 template <typename T> 11 struct D 12 { DD13 D (T *ptr) : m_ptr (ptr) { } ~DD14 ~D () { if (T * ptr = m_ptr) ptr->deref (); } 15 T *operator-> () const; 16 T *m_ptr; 17 typedef T *UnspecifiedBoolType; 18 operator UnspecifiedBoolType () const; 19 }; 20 template <typename T> struct E 21 { destructE22 static void destruct (T * begin, T * end) 23 { 24 for (T * cur = begin; cur != end; ++cur) 25 cur->~T (); 26 } 27 }; 28 template <typename T> class F; 29 template <typename T> struct G 30 { destructG31 static void destruct (T * begin, T * end) 32 { 33 E <T>::destruct (begin, end); 34 } uninitializedFillG35 static void uninitializedFill (T * dst, T * dstEnd, const T & val) 36 { 37 F<T>::uninitializedFill (dst, dstEnd, val); 38 } 39 }; 40 template <typename T> struct H 41 { allocateBufferH42 void allocateBuffer (int newCapacity) 43 { 44 m_buffer = static_cast <T *>(fastMalloc (newCapacity * sizeof (T))); 45 } deallocateBufferH46 void deallocateBuffer (T * bufferToDeallocate) 47 { 48 if (m_buffer == bufferToDeallocate) 49 fastFree (bufferToDeallocate); 50 } bufferH51 T *buffer () { } capacityH52 int capacity () const { } 53 T *m_buffer; 54 }; 55 template <typename T, int cap> class I; 56 template <typename T> struct I <T, 0> : H <T> 57 { 58 I (int capacity) { allocateBuffer (capacity); } 59 ~I () { this->deallocateBuffer (buffer ()); } 60 using H <T>::allocateBuffer; 61 H <T>::buffer; // { dg-warning "deprecated" } 62 }; 63 template <typename T, int cap = 0> struct J 64 { 65 typedef T *iterator; 66 ~J () { if (m_size) shrink (0); } 67 J (const J &); 68 int capacity () const { m_buffer.capacity (); } 69 T & operator[](int i) { } 70 iterator begin () { } 71 iterator end () { return begin () + m_size; } 72 void shrink (int size); 73 template <typename U> void append (const U &); 74 int m_size; 75 I <T, cap> m_buffer; 76 }; 77 template <typename T, int cap> 78 J <T, cap>::J (const J & other) : m_buffer (other.capacity ()) 79 { 80 } 81 template <typename T, int cap> 82 void J <T, cap>::shrink (int size) 83 { 84 G <T>::destruct (begin () + size, end ()); 85 m_size = size; 86 } 87 struct A : public C <A> 88 { 89 virtual ~A (); 90 typedef J <D <A> > B; 91 virtual A *firstChild () const; 92 virtual A *nextSibling () const; 93 virtual const B & children (int length); 94 B m_children; 95 }; 96 const A::B & 97 A::children (int length) 98 { 99 for (D <A> obj = firstChild (); obj; obj = obj->nextSibling ()) 100 { 101 B children = obj->children (2); 102 for (unsigned i = 0; i <length; ++i) 103 m_children.append (children[i]); 104 } 105 } 106 107