1// { dg-do assemble  }
2// GROUPS passed old-abort
3const int TRUE = 1;
4const int FALSE = 0;
5
6class Rep {
7protected:
8    Rep(): count(0)
9	{ }
10    Rep(const Rep& other): count(0)
11	{ }
12
13    Rep& operator=(const Rep& other)
14	{ /* DO NOT copy over other.count */
15	  return *this; }
16
17public:		// TODO - for now
18    // Because it is to hard to restrict these operations to the descendants
19    // of Rep<REP> that we haven't named yet.  So we just make them public.
20    void inc()
21	{ count++; }
22    void dec()
23	{ if (0 == --count) delete this; }
24private:
25    unsigned count;
26};
27
28template<class REP>
29class Ref {
30public:
31    Ref(): rep(0)
32	{ }
33    Ref(const Ref<REP>& other): rep(other.rep)
34	{ if (rep) rep->inc(); }
35    ~Ref()
36	{ if (rep) rep->dec();
37	  rep = 0; }
38
39    Ref<REP>& operator=(const Ref<REP>& other)
40	{ if (rep != other.rep) {
41	    if (rep) rep->dec();
42	    rep = other.rep;
43	    if (rep) rep->inc(); }
44	  return *this; }
45
46    bool null() const
47	{ return 0 == rep ? TRUE: FALSE; }
48    bool valid() const
49	{ return 0 != rep ? TRUE: FALSE; }
50
51    REP* operator->() const		// should be a valid() reference
52	{ return rep; }
53    operator REP*() const;		// should be a valid() reference
54
55protected:
56    REP *rep;
57
58    Ref(REP *r): rep(r)
59	{ if (rep) rep->inc(); }
60
61    Ref<REP>& operator=(REP *r)
62	{ if (rep != r) {
63	    if (rep) rep->dec();
64	    rep = r;
65	    if (rep) rep->inc(); }
66	  return *this; }
67};
68
69template<class REP>
70Ref<REP>::operator REP*() const		// should be a valid() reference
71{ return rep; }
72
73template<class REP>
74inline int
75operator==(const Ref<REP>& a, const Ref<REP>& b)
76{ return (REP *) a == (REP *) b; }
77
78template<class REP>
79inline int
80operator!=(const Ref<REP>& a, const Ref<REP>& b)
81{ return (REP *) a != (REP *) b; }
82
83class XRep: public Rep {
84public:
85    int i;
86};
87
88int
89main()
90{
91    Ref<XRep> y;
92
93    return y != y;
94}
95