00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef SOME_OBJ_HEADER
00029 #define SOME_OBJ_HEADER
00030
00031 #include <algorithm>
00032
00033 namespace SOME
00034 {
00035
00048 template < typename BaseClass >
00049 class ObjectBase
00050 {
00051 public:
00053
00057 ObjectBase(const SOME::ClassCatalog& cat): catalog(cat)
00058 {}
00059
00061
00062
00063
00064 virtual ~ObjectBase()
00065 { }
00066
00068
00071 bool construct()
00072 {
00073 reset(0);
00074 BaseClass* (*ctor0)() = (BaseClass* (*)())catalog.getCtor0();
00075 if (ctor0 == 0)
00076 return false;
00077
00078 reset((*ctor0)());
00079
00080 return !isNull();
00081 }
00082
00084
00087 template < typename ParamType1 >
00088 bool construct(ParamType1& a)
00089 {
00090 reset(0);
00091 BaseClass* (*ctor1)(ParamType1&) = (BaseClass * (*)(ParamType1&))catalog.getCtor1();
00092 if (ctor1 == 0)
00093 return false;
00094
00095 reset((*ctor1)(a));
00096
00097 return !isNull();
00098 }
00099
00101
00104 template < typename ParamType1, typename ParamType2 >
00105 bool construct(ParamType1& a, ParamType2& b)
00106 {
00107 reset(0);
00108 BaseClass* (*ctor2)(ParamType1&, ParamType2&) = (BaseClass * (*)(ParamType1&, ParamType2&))catalog.getCtor2();
00109 if (ctor2 == 0)
00110 return false;
00111
00112 reset((*ctor2)(a, b));
00113
00114 return !isNull();
00115 }
00116
00118 bool isNull()
00119 {
00120 return get() == NULL;
00121 }
00122
00124 const SOME::ClassCatalog& getClassCatalog() const
00125 {
00126 return catalog;
00127 }
00128
00129
00130 BaseClass& operator*() const
00131 {
00132 return *get();
00133 }
00134 BaseClass* operator->() const
00135 {
00136 return get();
00137 }
00138 virtual BaseClass* get() const = 0;
00139
00140 private:
00141 virtual void reset(BaseClass*) = 0;
00142
00143 private:
00144 SOME::ClassCatalog catalog;
00145 }
00146 ;
00147
00158 template < typename BaseClass >
00159 class Object: public ObjectBase < BaseClass >
00160 {
00161 public:
00163
00167 Object(const SOME::ClassCatalog& cat): ObjectBase < BaseClass > (cat)
00168 {}
00169
00173 virtual BaseClass* get() const
00174 {
00175 return p;
00176 }
00177
00181 void destroy() const
00182 {
00183 delete p;
00184 reset(0);
00185 }
00186
00187 private:
00188 virtual void reset(BaseClass* new_p)
00189 {
00190 p = new_p;
00191 }
00192
00193 private:
00194 BaseClass* p;
00195 }
00196 ;
00197
00210 template < typename BaseClass >
00211 class SmartObject: public ObjectBase < BaseClass >
00212 {
00213 public:
00215
00219 SmartObject(const SOME::ClassCatalog& cat):
00220 ObjectBase < BaseClass > (cat),
00221 p(0)
00222 {
00223 pn = new long(1);
00224 }
00225
00227 SmartObject(const SmartObject& r): ObjectBase < BaseClass > (r), p(r.p)
00228 {
00229 ++*(pn = r.pn);
00230 }
00231
00233 ~SmartObject()
00234 {
00235 dispose();
00236 }
00237
00239 SmartObject& operator=(const SmartObject& r)
00240 {
00241 share(r.px, r.pn);
00242 return *this;
00243 }
00244
00248 virtual BaseClass* get() const
00249 {
00250 return p;
00251 }
00252
00253 private:
00254 virtual void reset(BaseClass* new_p)
00255 {
00256 if ( p == new_p ) return ;
00257 if (--*pn == 0)
00258 {
00259 delete p;
00260 }
00261 else
00262 {
00263 try
00264 {
00265 pn = new long;
00266 }
00267 catch (...)
00268 {
00269 ++*pn;
00270 delete new_p;
00271 throw;
00272 }
00273 }
00274
00275
00276
00277 *pn = 1;
00278 p = new_p;
00279 }
00280
00281 void dispose()
00282 {
00283 if (--*pn == 0)
00284 {
00285 delete p;
00286 delete pn;
00287 }
00288 }
00289
00290 void share(BaseClass* rp, long* rpn)
00291 {
00292 if (pn != rpn)
00293 {
00294 dispose();
00295 p = rp;
00296 ++*(pn = rpn);
00297 }
00298 }
00299
00300 private:
00301 BaseClass* p;
00302 long* pn;
00303 }
00304 ;
00305
00306 }
00307
00308
00309
00310
00311 #endif //SOME_OBJ_HEADER