blob: e464c0e2e4ba0f7c6b0e3dcc5b4946fae2f25451 [file] [log] [blame]
// Build don't link:
// 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>;