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