1// { dg-do assemble  }
2// prms-id: 13911
3
4template<unsigned int N>
5class ref_counter {
6public:
7  ref_counter() : p_refcnt(new unsigned int(N)) {}
8  ref_counter(const ref_counter<N>& x) : p_refcnt(x.p_refcnt) {
9    ++*p_refcnt;
10  }
11  ref_counter& operator=(const ref_counter<N>& rhs) {
12    ++*rhs.p_refcnt;
13    decrement();
14    p_refcnt = rhs.p_refcnt;
15    return *this;
16  }
17  ~ref_counter() {decrement();}
18
19  bool unique() const {return *p_refcnt == N;}
20
21private:
22  unsigned int* p_refcnt;
23  void decrement() {
24    if (unique()) delete p_refcnt;
25    else --*p_refcnt;
26  }
27};
28
29template<class T, unsigned int N>
30class ref_pointer {
31public:
32
33  ref_pointer() : the_p(0) {}
34  ref_pointer(T* just_newed) : the_p(just_newed) {}
35  virtual ~ref_pointer() {if (unique()) delete the_p;}
36protected:
37  ref_pointer(T* the_p_arg, ref_counter<N>& ref_count_arg)
38    : the_p(the_p_arg), ref_count(ref_count_arg) {}
39
40public:
41
42  ref_pointer& operator=(const ref_pointer&);
43  ref_pointer& operator=(T*);
44  operator const T*() const {return the_p;}
45  T* operator()() {return the_p;}
46  T* operator()() const {return the_p;}
47  T& operator*() const {return *the_p;}
48  friend bool operator==(const ref_pointer<T, N>& lhs,
49			 const ref_pointer<T, N>& rhs) {
50    return lhs.the_p == rhs.the_p;
51  }
52  friend bool operator!=(const ref_pointer<T, N>& lhs,
53			 const ref_pointer<T, N>& rhs) {
54    return lhs.the_p != rhs.the_p;
55  }
56
57
58  bool unique() const {return ref_count.unique();}
59  bool isNull() const {return the_p==0;}
60
61protected:
62  ref_counter<N>& refCount() {return ref_count;}
63
64private:
65
66  ref_counter<N> ref_count;
67  T* the_p;
68};
69
70template<class T, unsigned int N>
71ref_pointer<T, N>& ref_pointer<T, N>::operator=(const ref_pointer<T, N>& rhs) {
72  if (the_p != rhs.the_p) {
73    if (unique()) delete the_p;
74    the_p = rhs.the_p;
75    ref_count = rhs.ref_count;
76  }
77  return *this;
78}
79
80
81template<class T, unsigned int N>
82ref_pointer<T, N>& ref_pointer<T, N>::operator=(T* just_newed) {
83  if (unique()) delete the_p;
84  the_p = just_newed;
85  ref_count = ref_counter<N>();
86  return *this;
87}
88
89
90
91template<class T>
92class CountedObjPtr : public ref_pointer<T, 1> {
93public:
94  CountedObjPtr() {}
95  CountedObjPtr(T* just_newed) : ref_pointer<T, 1>(just_newed) {}
96  CountedObjPtr(T* the_p_arg, ref_counter<1>& ref_count_arg)
97    : ref_pointer<T, 1>(the_p_arg, ref_count_arg) {}
98  CountedObjPtr<T>& operator=(T* rhs) {
99    ref_pointer<T, 1>::operator=(rhs);
100    return *this;
101  }
102  CountedObjPtr<T>& operator=(const CountedObjPtr<T>& rhs) {
103    ref_pointer<T, 1>::operator=(rhs);
104    return *this;
105  }
106  T* operator->() const {return (*this)();}
107
108};
109
110
111
112
113
114//instantiating type
115
116class TSObservable;
117
118class TSObserver {
119public:
120
121  enum TSType { NormalTS, UpYldCrvTS, DownYldCrvTS, ZeroVolTS };
122
123  virtual ~TSObserver() {}
124
125  virtual void update(TSObservable* theChangedObservable) = 0;
126  virtual TSType key() const { return myKey; }
127  virtual TSType& key() { return myKey; }
128protected:
129  TSObserver(TSType myKeyArg) : myKey(myKeyArg) {}
130  TSType myKey;
131};
132
133
134
135//now try to instantiate
136template class CountedObjPtr<TSObserver>;
137