00001 #ifndef NO_PTR_DYNOBJ_H
00002 #define NO_PTR_DYNOBJ_H
00003
00023 #include "nullness.hh"
00024 #include "DynObjKey.hh"
00025 #include "RRefUsage.hh"
00026 #include "Deleter.hh"
00027 #include "Contexts.hh"
00028 #include "NoPtrFwd.hh"
00029
00030
00031
00032
00033
00034
00035 namespace std
00036 {
00037
00038
00039 template<typename TT> class auto_ptr;
00040
00041
00042 template <typename ObjType>
00043 inline void
00044 swap(NoPtr::DynObj<ObjType>& lhs,
00045 NoPtr::DynObj<ObjType>& rhs)
00046 {
00047 lhs.swap(rhs);
00048 }
00049
00050
00051 template <typename ObjType>
00052 inline void
00053 swap(NoPtr::DynObj<ObjType, NoPtr::InValueContainer>& lhs,
00054 NoPtr::DynObj<ObjType, NoPtr::InValueContainer>& rhs)
00055 {
00056 lhs.swap(rhs);
00057 }
00058
00059
00060 template <typename ObjType>
00061 inline void
00062 swap(NoPtr::DynObj<ObjType, NoPtr::InValueContainerOpt1>& lhs,
00063 NoPtr::DynObj<ObjType, NoPtr::InValueContainerOpt1>& rhs)
00064 {
00065 lhs.swap(rhs);
00066 }
00067
00068
00069 template <typename ObjType>
00070 inline void
00071 swap(NoPtr::DynObj<ObjType, NoPtr::InValueContainerOpt2>& lhs,
00072 NoPtr::DynObj<ObjType, NoPtr::InValueContainerOpt2>& rhs)
00073 {
00074 lhs.swap(rhs);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 }
00086
00087 namespace NoPtr
00088 {
00090 template <typename TT, class Context>
00091 inline bool
00092 isNull(const DynObj<TT,Context>& p) {return p.isNull();}
00093
00096 template <typename TT, class Context>
00097 inline bool
00098 isNotNull(const DynObj<TT,Context>& p) {return p.isNotNull();}
00099
00100 template <typename ObjType, class Context>
00101 class DynObj
00102
00103 : private NoPtrImpl::Deleter<ObjType>,
00104 private Context
00105 {
00106 private:
00108 template <typename, class> friend class DynObj;
00110 template <typename> friend class DynTmp;
00111
00112 public:
00114 typedef ObjType ObjectType;
00116 typedef DynObj<ObjType,NoPtr::InValueContainer>
00117 InValueContainer;
00119 typedef DynObj<ObjType,NoPtr::InValueContainerOpt1>
00120 InValueContainerOpt1;
00122 typedef DynObj<ObjType,NoPtr::InValueContainerOpt2>
00123 InValueContainerOpt2;
00124
00125 public:
00127
00128 DynObj() throw(): _obj(NullPtr) {}
00130 explicit DynObj(ObjType* ptr) throw(): _obj(ptr) {}
00131
00133 template <typename ObjType2>
00134 explicit DynObj(std::auto_ptr<ObjType2>& aptr) throw()
00135 : _obj( aptr.release() ) {}
00137 template <typename ObjType2>
00138 DynObj(const DynTmp<ObjType2>& mobj) throw()
00139 {
00140 mobj.deliver( _obj, _rrefUsage,
00141 NoPtrImpl::DynObjKey<ObjType>() );
00142 }
00143
00145 ~DynObj()
00146 {
00147 if (soleOwner())
00148 {
00149 destroy(_obj);
00150 _rrefUsage.destroy();
00151 }
00152 }
00154
00155
00156
00157 #ifndef TEST_ALL_INSTANTIATE
00158
00159
00160
00161
00162
00163 DynObj(const DynObj& rhs)
00164 : NoPtrImpl::Deleter<ObjType>(), Context(rhs), _obj(rhs._obj),
00165 _rrefUsage(rhs._rrefUsage)
00166 {
00167 Context::checkCopyable();
00168
00169
00170 }
00171 #endif
00172
00174
00176 void acquire(ObjType* ptr)
00177 {
00178 assert(ptr != _obj);
00179 assert(soleOwner());
00180 destroy(_obj);
00181 _rrefUsage.reset();
00182 _obj = ptr;
00183 }
00185 template <typename ObjType2>
00186 void acquire(std::auto_ptr<ObjType2>& aptr)
00187 {
00188 acquire(aptr.release());
00189 }
00190
00196 template <typename ObjType2, class Context2>
00197 void acquire(DynObj<ObjType2,Context2>& rhs)
00198 {
00199 assert(rhs._obj != _obj);
00200 assert(soleOwner());
00201 destroy(_obj);
00202 _rrefUsage.reset();
00203
00204 assert(rhs.soleOwner());
00205 _obj = rhs._obj;
00206 rhs._obj = NullPtr;
00207 rhs._rrefUsage.moveTo(_rrefUsage);
00208
00209 }
00213 template <typename ObjType2>
00214 void acquire(const DynTmp<ObjType2>& mobj)
00215 {
00216 assert(soleOwner());
00217 reset();
00218 mobj.deliver( _obj, _rrefUsage,
00219 NoPtrImpl::DynObjKey<ObjType>() );
00220 }
00222
00224
00227 void reset()
00228 {
00229 assert(soleOwner());
00230 destroy(_obj);
00231 _rrefUsage.reset();
00232 _obj = NullPtr;
00233 }
00234
00236 void swap(DynObj& rhs) throw()
00237 {
00238 std::swap(_obj, rhs._obj);
00239 _rrefUsage.swap(rhs._rrefUsage);
00240 Context::swap(rhs);
00241 }
00242
00247 ObjType* release() throw()
00248 {
00249 assert(soleOwner());
00250 _rrefUsage.reset();
00251 ObjType* const tmp = _obj;
00252 _obj = NullPtr;
00253 return tmp;
00254 }
00255
00260 DynTmp<ObjType> moveToTmp() throw()
00261 {
00262 assert(soleOwner());
00263 ObjType* const tmp = _obj;
00264 _obj = NullPtr;
00265 return DynTmp<ObjType>( tmp, _rrefUsage,
00266 NoPtrImpl::DynObjKey<ObjType>() );
00267 }
00275 DynTmp<ObjType> giveAway() throw() {return moveToTmp();}
00276
00277
00279
00281
00283 bool isNull() const throw()
00284 {
00285 assert(soleOwner());
00286 return _obj == NullPtr;
00287 }
00289 bool isNotNull() const throw()
00290 {
00291 assert(soleOwner());
00292 return _obj != NullPtr;
00293 }
00294
00299 ObjType* getPtr() const throw()
00300 {
00301 assert(soleOwner());
00302 return _obj;
00303 }
00304
00306
00308
00317 ObjType& operator()() const
00318 {
00319 return *(operator->());
00320 }
00321
00334 ObjType& operator*() const
00335 {
00336 return *(operator->());
00337 }
00338
00340 template <typename ObjType2>
00341 void operator=(const DynTmp<ObjType2>& mobj)
00342 {
00343 acquire(mobj);
00344 }
00361 template <typename ObjType2, class Context2>
00362 bool operator<(const DynObj<ObjType2,Context2>& rhs) const throw()
00363 {
00364 if (_obj && rhs._obj)
00365 return (*_obj) < *(rhs._obj);
00366
00367
00368 if (_obj == NullPtr) return true;
00369
00370 assert(rhs._obj == NullPtr);
00371 return false;
00372 }
00376 template <typename ObjType2, class Context2>
00377 bool operator==(const DynObj<ObjType2,Context2>& rhs) const throw()
00378 {
00379 if (_obj && rhs._obj)
00380 return (_obj == rhs._obj) || ((*_obj) == *(rhs._obj));
00381
00382
00383 return _obj == rhs._obj;
00384 }
00386 template <typename ObjType2, class Context2>
00387 bool operator!=(const DynObj<ObjType2,Context2>& rhs) const throw()
00388 {
00389 return !(*this == rhs);
00390 }
00391
00392 #include "opConstWarningOff.hpp"
00401 operator const DynObj<const ObjType,Context>&() const throw()
00402 {
00403 typedef DynObj<const ObjType,Context> DynConstObj;
00404 return * static_cast<const DynConstObj*>(
00405 static_cast<const void*>(this)
00406 );
00407 }
00408 #include "opConstWarningOn.hpp"
00410
00411
00412
00413 #ifndef TEST_ALL_INSTANTIATE
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 DynObj& operator=(const DynObj& rhs)
00425 {
00426
00427
00428 if (_obj == rhs._obj) return *this;
00429
00430
00431
00432 Context::checkCopyable();
00433 if (soleOwner())
00434
00435
00436 {
00437 destroy(_obj);
00438 _rrefUsage.reset();
00439 }
00440
00441 _obj = rhs._obj;
00442
00443
00444 _rrefUsage = rhs._rrefUsage;
00445 Context::operator=(rhs);
00446 return *this;
00447 }
00448 #endif // TEST_ALL_INSTANTIATE
00449
00450 public:
00451
00452
00453
00454
00455
00456
00457 void getRRefUsage(NoPtrImpl::RRefUsageForUser& rrefUsage) const
00458 {
00459 _rrefUsage.create();
00460 rrefUsage.shareFrom(_rrefUsage);
00461 }
00462
00463 private:
00464
00465
00466
00467
00468
00469 ObjType* operator->() const
00470 {
00471 assert(soleOwner());
00472 assert(NoPtr::isNotNull(_obj));
00473 return _obj;
00474 }
00475
00476 private:
00477 ObjType* _obj;
00478 mutable NoPtrImpl::RRefUsageForOwner _rrefUsage;
00479 };
00480
00481 }
00482
00603 #endif // NO_PTR_DYNOBJ_H