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