00001 #ifndef _REFCLASS_H_
00002 #define _REFCLASS_H_
00003 static int _refclass_global_int_yo;
00004 #define REFASSERT(X) if (!(X)){_refclass_global_int_yo=*(int*)0;}else{;}
00005 #ifdef _WIN32
00006 #pragma warning (4:4786)
00007 #endif
00008
00015 template <class T, class Arg> class TRef: public T {
00016 public:
00018 mutable int refcount;
00020 TRef (const Arg & a):T(a){refcount=0;}
00022 T* operator -> () {return this;}
00024 const T* operator -> ()const {return this;}
00026 const T* operator *()const {return this;}
00028 T* operator *(){return this;}
00030 void Deallocate() {}
00031
00032 };
00033
00035 #define INSTANTIATE_REFCLASS(T,Arg,TStar) RefClass<T,Arg,TStar>::TMap RefClass <T,Arg,TStar>::hmap;RefClass<T,Arg,TStar>::TMap RefClass <T,Arg,TStar>::NiL;
00036
00037 #define INSTANTIATE_DEFAULT_REFCLASS(T,Arg) RefClass<T,Arg>::TMap RefClass <T,Arg>::hmap; RefClass<T,Arg>::TMap RefClass <T,Arg>::NiL;
00038
00039 #define INSTANTIATE_TSUB(T,Arg) T * (*TSub<T,Arg>::construct_T) (const Arg & a) = TSub<T,Arg>::construct_T= &TSub<T,Arg>::Default_T_Construct;
00040
00042 template <class T, class Arg> class TSub {
00043 public:
00045 T * t;
00047 mutable int refcount;
00049 static T* Default_T_Construct (const Arg &a) {return new T (a);}
00051 static T *(*construct_T)(const Arg &a);
00053 TSub (const Arg & a) {
00054 t = (*construct_T)(a);
00055 refcount=0;
00056 }
00058 void Deallocate() {
00059 if (t){
00060 delete t;
00061 t=0;
00062 }
00063 }
00065 T* operator -> () {return t;}
00067 const T* operator -> ()const {return t;}
00069 const T* operator *()const {return t;}
00071 T* operator *(){return t;}
00072 bool operator == (const TSub <T,Arg> & a) const{
00073 return t==*a;
00074 }
00075 bool operator <(const TSub <T,Arg> & a) const{
00076 return t<*a;
00077 }
00078 };
00079
00083 template <class T, class Arg, class TStar = TRef<T,Arg> > class RefClass {
00084 typedef TStar Tstar;
00086 typedef std::map<Arg,TStar> TMap;
00088 void TConstruct (const Arg & a) {
00089 t = hmap.find (a);
00090 if (t==hmap.end()) {
00091 t=hmap.insert(TMap::value_type(a,TStar (a))).first;
00092 }
00093 IncRef();
00094 }
00095 protected:
00097 typename TMap::iterator t;
00099 static TMap NiL;
00100
00103 static TMap hmap;
00107 void DestroyObject (){
00108 DecRef();
00109 if ((*t).second.refcount==0) {
00110 (*t).second.Deallocate();
00111 hmap.erase(t);
00112 setNull();
00113 }
00114 }
00116 void IncRef()const {(*t).second.refcount++;}
00118 void DecRef()const{
00119 (*t).second.refcount--;
00120 REFASSERT((*t).second.refcount>=0);
00121 }
00123 enum SPECIALARG {NOTATHANG};
00127 RefClass (SPECIALARG dummy,SPECIALARG d){t=NiL.begin();}
00129 bool isNull() const{return t==NiL.begin();}
00131 void setNull() {t = NiL.begin();}
00132 public:
00134 Arg GetKey()const {return (*t).first;}
00136 int getRefCount() const {return (*t).second.refcount;}
00138 RefClass (const Arg& a) {
00139 TConstruct(a);
00140 }
00142 RefClass () {
00143 TConstruct (Arg());
00144 }
00146 RefClass (const RefClass<T,Arg,TStar> & r) {r.IncRef(); t = r.t;}
00148 RefClass<T,Arg,TStar> & operator = (const RefClass<T,Arg,TStar> & r) {r.IncRef();DestroyObject();t=r.t;return *this;}
00150 ~RefClass () {DestroyObject();}
00152 T * Get () {REFASSERT (!isNull());return *((*t).second);}
00154 const T* Get () const {REFASSERT (!isNull());return *((*t).second);}
00156 T * operator *() {return Get();}
00158 const T* operator * () const {return Get();}
00160 T * operator -> () {return Get();}
00162 const T* operator -> () const {return Get();}
00164 bool operator < (const RefClass<T,Arg,TStar> & r) const {return (*t).second<(*r.t).second;}
00166 bool operator == (const RefClass<T,Arg,TStar> & r) const{return (*t).second==(*r.t).second;}
00168 void Debug () const{printf ("0x%x refcount %d content: %s\n",&((*t).second),(*t).second.refcount,(*t).second->print().c_str());}
00169 };
00170 #endif