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