00001 #ifndef MANGO_BLINK_H
00002 #define MANGO_BLINK_H
00003
00023 #include "nullness.hh"
00024 #include "ValidityChecker.hh"
00025 #include "CheckedPtr.hh"
00026 #include "BLinkable.hh"
00027 #include "OwnedFWD.hh"
00028 #include "BLinkFWD.hh"
00029
00030 namespace MangoPtr
00031 {
00032
00033 template <typename T>
00034 inline bool
00035 isNull(const BLink<T>& p) {return p.isNull();}
00036
00037
00038 template <typename T>
00039 inline bool
00040 isNotNull(const BLink<T>& p) {return p.isNotNull();}
00041
00042
00043 template <typename OType>
00044 class BLink
00045 {
00046 private:
00048 typedef OType* PType;
00049
00050 public:
00052 template <typename OType2> friend class BLink;
00054 typedef OType ObjectType;
00055
00056 public:
00058
00059
00060 BLink() throw(): optr(NullPtr) {}
00061
00062 inline BLink(const BLink&);
00063 template <typename OType2> inline
00064 BLink(const BLink<OType2>&);
00065
00066 inline BLink(OType&);
00067 template <typename OType2, OwnershipType oshiptype> explicit inline
00068 BLink(const Owned<OType2, oshiptype>&);
00070
00071 public:
00073
00074 template <typename OType2, OwnershipType oshiptype>
00075 inline void tieTo(const Owned<OType2, oshiptype>&);
00076 inline void tieTo(OType&);
00077 inline BLink& operator=(const BLink&);
00078 template <typename OType2>
00079 inline BLink& operator=(const BLink<OType2>&);
00080 inline void swap(BLink&) throw();
00082 inline void reset() {validator.reset(); nullify(optr);}
00084
00086
00087
00088 inline bool isNotNull() const throw();
00090 inline bool isNull() const throw() {return ! isNotNull();}
00091 inline PType cloneObjNew() const;
00093
00094 public:
00095
00097
00098 #include "opConstWarningOff.pp"
00099 inline operator const BLink<const OType>&() const;
00100 #include "opConstWarningOn.pp"
00101 template <typename OType2>
00102 inline bool operator<(const BLink<OType2>&) const throw();
00103 template <typename OType2>
00104 inline bool operator==(const BLink<OType2>&) const throw();
00105 template <typename OType2>
00106 inline bool operator!=(const BLink<OType2>&) const throw();
00112 CheckedPtr<OType> operator()() const {return isNotNull() ? optr : NullPtr;}
00114 OType* ptr() const {return isNotNull() ? optr : NullPtr;}
00116
00117 private:
00118 PType optr;
00119 ValidityChecker validator;
00120 };
00121
00122 template <typename OType> inline
00123 BLink<OType>::BLink(const BLink& rhs)
00124 : optr(rhs.optr), validator(rhs.validator)
00125 {
00126 assert(validator.isShared());
00127
00128 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00129 }
00130
00132 template <typename OType>
00133 template <typename OType2> inline
00134 BLink<OType>::BLink(const BLink<OType2>& rhs)
00135 : optr(rhs.optr), validator(rhs.validator)
00136 {
00137 assert(validator.isShared());
00138
00139 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00140 }
00141
00143 template <typename OType>
00144 template <typename OType2, OwnershipType oshiptype> inline
00145 BLink<OType>::BLink(const Owned<OType2, oshiptype>& owner)
00146 : optr(NullPtr)
00147 {
00148 tieTo(owner);
00149 assert(validator.isShared());
00150
00151 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00152 }
00153
00159 template <typename OType> inline
00160 BLink<OType>::BLink(OType& oobj)
00161 : optr(&oobj), validator(oobj.getValidityOwner())
00162 {
00163 assert(validator.isShared());
00164
00165 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00166 }
00167
00168
00170 template <typename OType>
00171 inline bool
00172 BLink<OType>::isNotNull()
00173 const throw()
00174 {
00175
00176 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00177 return validator.isValid();
00178 }
00179
00186 template <typename OType>
00187 inline BLink<OType>&
00188 BLink<OType>::operator=(const BLink& rhs)
00189 {
00190 validator = rhs.validator;
00191 assert(validator.isShared());
00192 optr = rhs.optr;
00193
00194 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00195 return *this;
00196 }
00197
00202 template <typename OType>
00203 template <typename OType2>
00204 inline BLink<OType>&
00205 BLink<OType>::operator=(const BLink<OType2>& rhs)
00206 {
00207 validator = rhs.validator;
00208 assert(validator.isShared());
00209 optr = rhs.optr;
00210
00211 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00212 return *this;
00213 }
00214
00220 template <typename OType>
00221 template <typename OType2, OwnershipType oshiptype>
00222 inline void
00223 BLink<OType>::tieTo(const Owned<OType2, oshiptype>& owner)
00224 {
00225 optr = owner.shareUsage(validator);
00226 assert(validator.isShared());
00227
00228 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00229 }
00230
00235 template <typename OType>
00236 inline void
00237 BLink<OType>::tieTo(OType& blinkable)
00238 {
00239 optr = &blinkable;
00240 validator = blinkable.getValidityOwner();
00241 assert(validator.isShared());
00242
00243 assert(MangoPtr::isNotNull(optr) || ! validator.isValid());
00244 }
00245
00247 template <typename OType>
00248 inline void
00249 BLink<OType>::swap(BLink& rhs)
00250 throw()
00251 {
00252 std::swap(optr, rhs.optr);
00253 validator.swap(rhs.validator);
00254 }
00255
00268 template <typename OType>
00269 inline
00270 BLink<OType>::operator const BLink<const OType>&()
00271 const
00272 {
00273 return * static_cast<const BLink<const OType>*>(
00274 static_cast<const void*>(this)
00275 );
00276 }
00277
00279 template <typename OType>
00280 template <typename OType2>
00281 inline bool
00282 BLink<OType>::operator<(const BLink<OType2>& rhs)
00283 const throw()
00284 {
00285 return optr < rhs.optr;
00286 }
00287
00292 template <typename OType>
00293 template <typename OType2>
00294 inline bool
00295 BLink<OType>::operator==(const BLink<OType2>& rhs)
00296 const throw()
00297 {
00298 return rhs == optr;
00299 }
00300
00305 template <typename OType>
00306 template <typename OType2>
00307 inline bool
00308 BLink<OType>::operator!=(const BLink<OType2>& rhs)
00309 const throw()
00310 {
00311 return ! (rhs == optr);
00312 }
00313
00325 template <typename OType> inline
00326 OType*
00327 BLink<OType>::cloneObjNew()
00328 const
00329 {
00330 return isNotNull() ? new OType(*optr) : NullPtr;
00331 }
00332
00333 }
00334
00437 #endif // MANGO_BLINK_H