00001 #ifndef REFSTORAGE_TMPL_HEADER
00002 #define REFSTORAGE_TMPL_HEADER
00003
00004
00005
00013
00014
00015
00016
00017 #include "Utilsexc.hh"
00018
00019
00020
00021 namespace RazorBack {
00022
00031 template <class T_>
00032 class Refstorage_
00033 {
00034
00035 private:
00036
00041 struct Storage_
00042 {
00043
00044 T_* Dataptr;
00045 int Refcount;
00046
00048 Storage_(): Dataptr(NULL), Refcount(0) {}
00049
00057 explicit Storage_(const T_* Dptr): Dataptr((T_*)Dptr), Refcount(0) {}
00058
00060 Storage_(const Storage_& S)
00061 : Dataptr(S.Dataptr==NULL? NULL: new T_(*(S.Dataptr))),
00062 Refcount(0) {}
00063
00065 ~Storage_() { delete Dataptr; }
00066
00067 };
00068
00069
00070 private:
00071
00072 Storage_ *Storptr;
00073
00074
00075 protected:
00076
00078 Refstorage_(): Storptr(NULL) {}
00079
00087 explicit Refstorage_(const T_* Dp):
00088 Storptr(new Storage_(Dp))
00089 {
00090 Storptr->Refcount=1;
00091 }
00092
00094 Refstorage_(const Refstorage_<T_>& Rf):
00095 Storptr(Rf.Storptr)
00096 {
00097 if (Storptr!=NULL) Storptr->Refcount++;
00098 }
00099
00101 virtual ~Refstorage_()
00102 {
00103 unlink_old();
00104 }
00105
00107 Refstorage_<T_>& operator=(const Refstorage_<T_>& Rhs)
00108 {
00109 if (this==&Rhs || Storptr==Rhs.Storptr)
00110 return(*this);
00111 unlink_old();
00112 Storptr=Rhs.Storptr;
00113 if (Storptr!=NULL) Storptr->Refcount++;
00114 return(*this);
00115 }
00116
00121 void unlink_old()
00122 {
00123 if (Storptr!=NULL && --Storptr->Refcount==0)
00124 delete Storptr;
00125 }
00126
00128 void clone()
00129 {
00130 if (Storptr!=NULL && Storptr->Refcount>1)
00131 {
00132 Storage_* Newsptr=new Storage_(*Storptr);
00133 unlink_old();
00134 Storptr=Newsptr; Storptr->Refcount=1;
00135 }
00136 }
00137
00145 void replace_storage(const T_* Dp)
00146 {
00147 unlink_old();
00148 Storptr=new Storage_(Dp);
00149 Storptr->Refcount=1;
00150 }
00151
00153 bool empty() const { return (Storptr==NULL || Storptr->Dataptr==NULL); }
00154
00159 const T_& data() const
00160 {
00161 if (empty())
00162 throw Emptyexc_("Refstorage_::data() (const)");
00163 return *(Storptr->Dataptr);
00164 }
00165 T_& data()
00166 {
00167 if (empty())
00168 throw Emptyexc_("Refstorage_::data()");
00169 return *(Storptr->Dataptr);
00170 }
00171
00176 const T_* ptr() const { return (empty()? NULL: Storptr->Dataptr); }
00177 T_* ptr() { return (empty()? NULL: Storptr->Dataptr); }
00178 };
00179
00180
00181
00182
00183 }
00184
00185
00186
00187 #endif // REFSTORAGE_TMPL_HEADER