1 // { dg-do assemble  }
2 // prms-id: 13911
3 
4 template<unsigned int N>
5 class ref_counter {
6 public:
ref_counter()7   ref_counter() : p_refcnt(new unsigned int(N)) {}
ref_counter(const ref_counter<N> & x)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   }
~ref_counter()17   ~ref_counter() {decrement();}
18 
unique()19   bool unique() const {return *p_refcnt == N;}
20 
21 private:
22   unsigned int* p_refcnt;
decrement()23   void decrement() {
24     if (unique()) delete p_refcnt;
25     else --*p_refcnt;
26   }
27 };
28 
29 template<class T, unsigned int N>
30 class ref_pointer {
31 public:
32 
ref_pointer()33   ref_pointer() : the_p(0) {}
ref_pointer(T * just_newed)34   ref_pointer(T* just_newed) : the_p(just_newed) {}
~ref_pointer()35   virtual ~ref_pointer() {if (unique()) delete the_p;}
36 protected:
ref_pointer(T * the_p_arg,ref_counter<N> & ref_count_arg)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 
40 public:
41 
42   ref_pointer& operator=(const ref_pointer&);
43   ref_pointer& operator=(T*);
44   operator const T*() const {return the_p;}
operator()45   T* operator()() {return the_p;}
operator()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 
unique()58   bool unique() const {return ref_count.unique();}
isNull()59   bool isNull() const {return the_p==0;}
60 
61 protected:
refCount()62   ref_counter<N>& refCount() {return ref_count;}
63 
64 private:
65 
66   ref_counter<N> ref_count;
67   T* the_p;
68 };
69 
70 template<class T, unsigned int N>
71 ref_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 
81 template<class T, unsigned int N>
82 ref_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 
91 template<class T>
92 class CountedObjPtr : public ref_pointer<T, 1> {
93 public:
CountedObjPtr()94   CountedObjPtr() {}
CountedObjPtr(T * just_newed)95   CountedObjPtr(T* just_newed) : ref_pointer<T, 1>(just_newed) {}
CountedObjPtr(T * the_p_arg,ref_counter<1> & ref_count_arg)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 
116 class TSObservable;
117 
118 class TSObserver {
119 public:
120 
121   enum TSType { NormalTS, UpYldCrvTS, DownYldCrvTS, ZeroVolTS };
122 
~TSObserver()123   virtual ~TSObserver() {}
124 
125   virtual void update(TSObservable* theChangedObservable) = 0;
key()126   virtual TSType key() const { return myKey; }
key()127   virtual TSType& key() { return myKey; }
128 protected:
TSObserver(TSType myKeyArg)129   TSObserver(TSType myKeyArg) : myKey(myKeyArg) {}
130   TSType myKey;
131 };
132 
133 
134 
135 //now try to instantiate
136 template class CountedObjPtr<TSObserver>;
137