| // { dg-do assemble } |
| // prms-id: 13911 |
| |
| template<unsigned int N> |
| class ref_counter { |
| public: |
| ref_counter() : p_refcnt(new unsigned int(N)) {} |
| ref_counter(const ref_counter<N>& x) : p_refcnt(x.p_refcnt) { |
| ++*p_refcnt; |
| } |
| ref_counter& operator=(const ref_counter<N>& rhs) { |
| ++*rhs.p_refcnt; |
| decrement(); |
| p_refcnt = rhs.p_refcnt; |
| return *this; |
| } |
| ~ref_counter() {decrement();} |
| |
| bool unique() const {return *p_refcnt == N;} |
| |
| private: |
| unsigned int* p_refcnt; |
| void decrement() { |
| if (unique()) delete p_refcnt; |
| else --*p_refcnt; |
| } |
| }; |
| |
| template<class T, unsigned int N> |
| class ref_pointer { |
| public: |
| |
| ref_pointer() : the_p(0) {} |
| ref_pointer(T* just_newed) : the_p(just_newed) {} |
| virtual ~ref_pointer() {if (unique()) delete the_p;} |
| protected: |
| ref_pointer(T* the_p_arg, ref_counter<N>& ref_count_arg) |
| : the_p(the_p_arg), ref_count(ref_count_arg) {} |
| |
| public: |
| |
| ref_pointer& operator=(const ref_pointer&); |
| ref_pointer& operator=(T*); |
| operator const T*() const {return the_p;} |
| T* operator()() {return the_p;} |
| T* operator()() const {return the_p;} |
| T& operator*() const {return *the_p;} |
| friend bool operator==(const ref_pointer<T, N>& lhs, |
| const ref_pointer<T, N>& rhs) { |
| return lhs.the_p == rhs.the_p; |
| } |
| friend bool operator!=(const ref_pointer<T, N>& lhs, |
| const ref_pointer<T, N>& rhs) { |
| return lhs.the_p != rhs.the_p; |
| } |
| |
| |
| bool unique() const {return ref_count.unique();} |
| bool isNull() const {return the_p==0;} |
| |
| protected: |
| ref_counter<N>& refCount() {return ref_count;} |
| |
| private: |
| |
| ref_counter<N> ref_count; |
| T* the_p; |
| }; |
| |
| template<class T, unsigned int N> |
| ref_pointer<T, N>& ref_pointer<T, N>::operator=(const ref_pointer<T, N>& rhs) { |
| if (the_p != rhs.the_p) { |
| if (unique()) delete the_p; |
| the_p = rhs.the_p; |
| ref_count = rhs.ref_count; |
| } |
| return *this; |
| } |
| |
| |
| template<class T, unsigned int N> |
| ref_pointer<T, N>& ref_pointer<T, N>::operator=(T* just_newed) { |
| if (unique()) delete the_p; |
| the_p = just_newed; |
| ref_count = ref_counter<N>(); |
| return *this; |
| } |
| |
| |
| |
| template<class T> |
| class CountedObjPtr : public ref_pointer<T, 1> { |
| public: |
| CountedObjPtr() {} |
| CountedObjPtr(T* just_newed) : ref_pointer<T, 1>(just_newed) {} |
| CountedObjPtr(T* the_p_arg, ref_counter<1>& ref_count_arg) |
| : ref_pointer<T, 1>(the_p_arg, ref_count_arg) {} |
| CountedObjPtr<T>& operator=(T* rhs) { |
| ref_pointer<T, 1>::operator=(rhs); |
| return *this; |
| } |
| CountedObjPtr<T>& operator=(const CountedObjPtr<T>& rhs) { |
| ref_pointer<T, 1>::operator=(rhs); |
| return *this; |
| } |
| T* operator->() const {return (*this)();} |
| |
| }; |
| |
| |
| |
| |
| |
| //instantiating type |
| |
| class TSObservable; |
| |
| class TSObserver { |
| public: |
| |
| enum TSType { NormalTS, UpYldCrvTS, DownYldCrvTS, ZeroVolTS }; |
| |
| virtual ~TSObserver() {} |
| |
| virtual void update(TSObservable* theChangedObservable) = 0; |
| virtual TSType key() const { return myKey; } |
| virtual TSType& key() { return myKey; } |
| protected: |
| TSObserver(TSType myKeyArg) : myKey(myKeyArg) {} |
| TSType myKey; |
| }; |
| |
| |
| |
| //now try to instantiate |
| template class CountedObjPtr<TSObserver>; |