e7b0774d96f17f4acb22e6dc237f617c530e6c1c
[gcc.git] / gcc / testsuite / g++.dg / torture / pr39362.C
1 /* { dg-do compile } */
2
3 void *fastMalloc (int n);
4 void fastFree (void *p);
5 template <class T> struct C
6 {
7 void deref () { delete static_cast <T *>(this); }
8 };
9 template <typename T>
10 struct 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 };
19 template <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 };
27 template <typename T> class F;
28 template <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 };
39 template <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 };
54 template <typename T, int cap> class I;
55 template <typename T> struct I <T, 0> : H <T>
56 {
57 I (int capacity) { allocateBuffer (capacity); }
58 ~I () { this->deallocateBuffer (buffer ()); }
59 using H <T>::allocateBuffer;
60 H <T>::buffer;
61 };
62 template <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 };
76 template <typename T, int cap>
77 J <T, cap>::J (const J & other) : m_buffer (other.capacity ())
78 {
79 }
80 template <typename T, int cap>
81 void J <T, cap>::shrink (int size)
82 {
83 G <T>::destruct (begin () + size, end ());
84 m_size = size;
85 }
86 struct 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 };
95 const A::B &
96 A::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