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