00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _TemplateLibrary_RefNode_H_
00019 #define _TemplateLibrary_RefNode_H_ 1
00020
00168 #include <lib/sconfig.h>
00169
00170 #include <lib/threads/atomic.h>
00171
00172
00173
00174 template<typename T,typename NSPC>class RefNode;
00175
00177
00178
00186 class _packed_ InternalRefNodeBase
00187 {
00188 template<typename T,typename NSPC>friend class RefNode;
00189 private:
00190 int refcnt;
00191
00192 protected:
00198 inline void _InternalRefNodeBase_aqref()
00199 { ++refcnt; }
00200 inline void _InternalRefNodeBase_deref()
00201 { if(--refcnt<=0) delete this; }
00202
00203 private:
00205 void _failCritAssert();
00206
00208 InternalRefNodeBase(const InternalRefNodeBase &);
00209 InternalRefNodeBase &operator=(const InternalRefNodeBase &);
00210 public:
00212 inline InternalRefNodeBase() : refcnt(0) { }
00215 inline virtual ~InternalRefNodeBase() { if(refcnt) _failCritAssert(); }
00216 };
00217
00218
00228 class _packed_ InternalRefNodeBase_ThreadSave
00229 {
00230 template<typename T,typename NSPC>friend class RefNode;
00231 private:
00232 AtomicInt refcnt;
00233
00234 protected:
00240 inline void _InternalRefNodeBase_aqref()
00241 { refcnt.inc(); }
00242 inline void _InternalRefNodeBase_deref()
00243 { if(refcnt.DecAndTest()) delete this; }
00244
00245 private:
00247 void _failCritAssert();
00248
00250 InternalRefNodeBase_ThreadSave(const InternalRefNodeBase_ThreadSave &);
00251 InternalRefNodeBase_ThreadSave &operator=(const InternalRefNodeBase_ThreadSave &);
00252 public:
00254 inline InternalRefNodeBase_ThreadSave() : refcnt(0) { }
00257 inline virtual ~InternalRefNodeBase_ThreadSave()
00258 { if(refcnt.val()) _failCritAssert(); }
00259 };
00260
00261
00263 struct _packed_ _RefNode_VoidNSPC
00264 {
00265 inline _RefNode_VoidNSPC(){}
00266 inline ~_RefNode_VoidNSPC(){}
00267 };
00268
00269
00281 template<typename T,typename NSPC=_RefNode_VoidNSPC>
00282 class _packed_ RefNode : public NSPC
00283 {
00284 private:
00285 T *in;
00286
00287 inline void _aqref() { if(in) in->_InternalRefNodeBase_aqref(); }
00288 inline void _deref() { if(in) in->_InternalRefNodeBase_deref(); }
00289 public:
00291 inline RefNode() : NSPC() { in=NULL; }
00292 inline RefNode(const RefNode &r) : NSPC() { in=r.in; _aqref(); }
00293 inline ~RefNode() { _deref(); }
00294
00296 inline RefNode &operator=(const RefNode &r)
00297 { _deref(); in=r.in; _aqref(); return(*this); }
00298
00300 inline void deref() { _deref(); }
00301
00303 inline bool operator!() const { return(!in); }
00304 inline operator bool() const { return((bool)in); }
00305
00307 inline RefNode(T *_in) { in=_in; _aqref(); }
00308 inline RefNode &operator=(T *_in)
00309 { _deref(); in=_in; _aqref(); return(*this); }
00310
00312 inline T *operator->() { return(in); }
00313 inline const T*operator->() const { return(in); }
00314
00316 inline T &operator*() { return(*in); }
00317 inline const T &operator*() const { return(*in); }
00318 };
00319
00320 #endif