00001 #ifndef NO_PTR_RREF_H
00002 #define NO_PTR_RREF_H
00003
00023 #include "nullness.hh"
00024 #include "RRefUsage.hh"
00025 #include "NoPtrFwd.hh"
00026
00027 namespace NoPtr
00028 {
00030 template <typename TT>
00031 inline bool
00032 isNull(const RRef<TT>& p) {return p.isNull();}
00033
00035 template <typename TT>
00036 inline bool
00037 isNotNull(const RRef<TT>& p) {return p.isNotNull();}
00038
00039 template <typename ObjType>
00040 class RRef
00041 {
00042 public:
00044 typedef ObjType ObjectType;
00045
00046 public:
00048
00051 RRef() throw(): _obj(NullPtr) {}
00052
00054 RRef(const RRef& rhs): _obj(rhs.getPtr())
00055 {
00056 if (_obj) _rrefUsage.shareFrom(rhs._rrefUsage);
00057 }
00058
00063 template <typename ObjType2>
00064 RRef(const RRef<ObjType2>& rhs): _obj(rhs.getPtr())
00065 {
00066 if (_obj) _rrefUsage.shareFrom(rhs._rrefUsage);
00067 }
00068
00076 template <typename ObjType2, class Context>
00077 RRef(const DynObj<ObjType2,Context>& rhs)
00078 : _obj(rhs.getPtr())
00079 {
00080 if (_obj)
00081 {
00082 rhs.getRRefUsage(_rrefUsage);
00083 assert(_rrefUsage.isValid());
00084 }
00085 }
00086
00092 RRef(ObjType& rrefable): _obj(&rrefable)
00093 {
00094 rrefable.getRRefUsage(_rrefUsage);
00095 assert(_rrefUsage.isValid());
00096 }
00097
00099
00100
00101 ~RRef() { _rrefUsage.destroy(); }
00102
00103 public:
00105
00109 void reset()
00110 {
00111 _obj = NullPtr;
00112 _rrefUsage.reset();
00113 }
00114
00121 template <typename ObjType2>
00122 void reset(const RRef<ObjType2>& rhs)
00123 {
00124 ObjType2* const obj = rhs.getPtr();
00125 if (obj == _obj) return;
00126
00127 _rrefUsage.reset();
00128 _obj = obj;
00129 if (_obj) _rrefUsage.shareFrom(rhs._rrefUsage);
00130 }
00131
00136 template <typename ObjType2, class Context>
00137 void reset(const DynObj<ObjType2,Context>& rhs)
00138 {
00139 ObjType2* const obj = rhs.getPtr();
00140 if (obj == _obj) return;
00141
00142 _rrefUsage.reset();
00143 _obj = obj;
00144 if (_obj)
00145 {
00146 rhs.getRRefUsage(_rrefUsage);
00147 assert(_rrefUsage.isValid());
00148 }
00149 }
00158 void reset(ObjType& rrefable)
00159 {
00160 if (_obj == &rrefable) return;
00161
00162 _rrefUsage.reset();
00163 _obj = &rrefable;
00164 rrefable.getRRefUsage(_rrefUsage);
00165 assert(_rrefUsage.isValid());
00166 }
00167
00169
00171
00173 void swap(RRef& rhs) throw()
00174 {
00175 std::swap(_obj, rhs._obj);
00176 _rrefUsage.swap(rhs._rrefUsage);
00177 }
00178
00180 bool isNotNull() const throw() {return getPtr() != NullPtr;}
00182 bool isNull() const throw() {return getPtr() == NullPtr;}
00183
00186 ObjType* getPtr() const throw()
00187 {
00188 return _rrefUsage.isValid() ? _obj : NullPtr;
00189 }
00191
00192 public:
00193
00195
00203 ObjType& operator()() const
00204 {
00205 return *(operator->());
00206 }
00207
00212 ObjType& operator*() const
00213 {
00214 return *(operator->());
00215 }
00216
00218 RRef& operator=(const RRef& rhs)
00219 {
00220 reset(rhs);
00221 return *this;
00222 }
00224 template <typename ObjType2>
00225 RRef& operator=(const RRef<ObjType2>& rhs)
00226 {
00227 reset(rhs);
00228 return *this;
00229 }
00231 template <typename ObjType2, class Context>
00232 RRef& operator=(const DynObj<ObjType2,Context>& rhs)
00233 {
00234 reset(rhs);
00235 return *this;
00236 }
00238 RRef& operator=(ObjType& rrefable)
00239 {
00240 reset(rrefable);
00241 return *this;
00242 }
00243
00249 #include "opConstWarningOff.hpp"
00250 inline operator const RRef<const ObjType>&() const throw()
00251 {
00252 return * static_cast<const RRef<const ObjType>*>(
00253 static_cast<const void*>(this)
00254 );
00255 }
00256 #include "opConstWarningOn.hpp"
00261 template <typename ObjType2>
00262 inline bool operator<(const RRef<ObjType2>& rhs) const throw()
00263 {
00264 ObjType* const lhsp = getPtr();
00265 ObjType2* const rhsp = rhs.getPtr();
00266 if (lhsp && rhsp)
00267 return (*lhsp) < *(rhsp);
00268
00269
00270 if (lhsp == NullPtr) return true;
00271
00272 assert(rhsp == NullPtr);
00273 return false;
00274 }
00280 template <typename ObjType2>
00281 bool operator==(const RRef<ObjType2>& rhs) const throw()
00282 {
00283 ObjType* const lhsp = getPtr();
00284 ObjType2* const rhsp = rhs.getPtr();
00285 if (lhsp && rhsp) return (lhsp == rhsp) || (*lhsp == *rhsp);
00286 return lhsp == rhsp;
00287 }
00289 template <typename ObjType2>
00290 bool operator!=(const RRef<ObjType2>& rhs) const throw()
00291 {
00292 return ! (*this == rhs);
00293 }
00295
00296 private:
00298 template <typename> friend class RRef;
00299
00305 ObjType* operator->() const
00306 {
00307 assert( _rrefUsage.isValid() );
00308 return getPtr();
00309 }
00310
00311 private:
00313 ObjType* _obj;
00315 NoPtrImpl::RRefUsageForUser _rrefUsage;
00316 };
00317
00318
00319 }
00320
00401 #endif // NO_PTR_RREF_H