OSDN Git Service

2009-07-17 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.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 () { 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