1 // { dg-do assemble  }
2 // GROUPS passed scope pt
3 class Link {
4 public:
5   Link();
6   Link(Link *);
7 private:
8   Link *next_;
9 
10 friend class IListBase;
11 friend class IListIterBase;
12 };
13 
14 inline
Link()15 Link::Link() : next_(0)
16 {
17 }
18 
19 inline
Link(Link * next)20 Link::Link(Link *next) : next_(next)
21 {
22 }
23 
24 class IListBase {
25 public:
26   IListBase();
27   IListBase(Link *);
28   void  append(Link *);
29   void insert(Link *);
30   Link *head();
31   int empty();
32   Link *get();
33   void remove(Link *);
34 private:
35   Link *head_;
36 friend class IListIterBase;
37 };
38 
39 inline
IListBase()40 IListBase::IListBase() : head_(0)
41 {
42 }
43 
44 inline
IListBase(Link * head)45 IListBase::IListBase(Link *head) : head_(head)
46 {
47 }
48 
49 inline
insert(Link * p)50 void IListBase::insert(Link *p)
51 {
52   p->next_ = head_;
53   head_ = p;
54 }
55 
56 inline
head()57 Link *IListBase::head()
58 {
59   return head_;
60 }
61 
62 inline
empty()63 int IListBase::empty()
64 {
65   return head_ == 0;
66 }
67 
68 inline
get()69 Link *IListBase::get()
70 {
71   Link *tem = head_;
72   head_ = head_->next_;
73   return tem;
74 }
75 
76 template<class T> class IListIter;
77 
78 template<class T>
79 class IList : private IListBase {
80 public:
IList()81   IList() { }
IList(T * p)82   IList(T *p) : IListBase(p) { }
83   ~IList();
append(T * p)84   void append(T *p) { IListBase::append(p); }
insert(T * p)85   void insert(T *p) { IListBase::insert(p); }
remove(T * p)86   void remove(T *p) { IListBase::remove(p); }
head()87   T *head() { return (T *)IListBase::head(); }
get()88   T *get() { return (T *)IListBase::get(); }
89   IListBase::empty; // { dg-warning "deprecated" }
90 friend class IListIter<T>;
91 };
92 
93 template<class T>
~IList()94 IList<T>::~IList()
95 {
96   while (!empty())
97     delete get();
98 }
99 
100 class IListIterBase {
101 public:
102   IListIterBase(const IListBase &);
103   int done();
104   Link *cur();
105   void next();
106 private:
107   Link *p_;
108 };
109 
110 inline
IListIterBase(const IListBase & list)111 IListIterBase::IListIterBase(const IListBase &list) : p_(list.head_)
112 {
113 }
114 
115 inline
done()116 int IListIterBase::done()
117 {
118   return p_ == 0;
119 }
120 
121 inline
cur()122 Link *IListIterBase::cur()
123 {
124   return p_;
125 }
126 
127 inline
next()128 void IListIterBase::next()
129 {
130   p_ = p_->next_;
131 }
132 
133 
134 template<class T>
135 class IListIter : private IListIterBase {
136 public:
IListIter(const IList<T> & list)137   IListIter(const IList<T> &list) : IListIterBase(list) { }
cur()138   T *cur() { return (T *)IListIterBase::cur(); }
139   IListIterBase::next; // { dg-warning "deprecated" }
140   IListIterBase::done; // { dg-warning "deprecated" }
141 };
142 
143 
144 struct A {
145   IList<Link> list;
146   int x;
147   void foo();
148 };
149 
150 
foo()151 void A::foo()
152 {
153   for (IListIter<Link> iter(list); !iter.done(); iter.next())
154     ;
155   x = 0;
156 }
157