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