summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.old-deja/g++.mike/p8018.C
blob: f085b6e82575f6f011794430b7e93c7b38c462e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// { dg-do run  }
// prms-id: 8018

class RefCount {
private:
  int nref;

public:
  RefCount() : nref(0) {}
  ~RefCount() {}

  int nrefs() const { return nref; }
  int reference() {
    nref++;
    return nref;
  }
  int unreference() {
    nref--;
    return nref;
  }
};

class A : public RefCount {
public:
  A() {}
  ~A() {}
};

class RefA {
private:
  A *p;

  void clear() {
    if (p) {
      p->unreference();
      if (!p->nrefs())
	delete p;
    }
  }

public:
  RefA(A* a) : p(a) { if (p) p->reference(); }
  RefA(const RefA& a) : p(a.p) { if (p) p->reference(); }
  ~RefA() { clear(); }

  A* operator->() { return p; }

  RefA& operator=(const RefA& a) {
    clear();
    p=a.p;
    if (p)
      p->reference();
    return *this;
  }

  RefA& operator=(A* a) {
    clear();
    p=a;
    if (p)
      p->reference();
    return *this;
  }
};

class AccRefA {
private:
  RefA a;

public:
  AccRefA(A* ap) : a(ap) {}
  AccRefA(const RefA& ar) : a(ar) {}
  ~AccRefA() {}

  operator RefA&() { return a; }
  RefA& result() { return a; }
};

int
main() {
  RefA a1 = new A;
  AccRefA aa1(a1);
  RefA a3 = aa1;

  if (a1->nrefs() != 3)
    return 1;
}