Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OwnedPtr.hh

Go to the documentation of this file.
00001 
00020 #ifndef MANGO_OWNED_PTR_H
00021 #define MANGO_OWNED_PTR_H
00022 
00023 #include <memory>          // auto_ptr
00024 #include <stdexcept>       // throws
00025 
00026 #include "nullness.hh"     // use
00027 #include "ObjSharing.hh"   // use
00028 #include "ValidityChecker.hh" // use
00029 #include "CheckedPtr.hh"   // use
00030 #include "Ownership.hh"    // use
00031 #include "BLinkableFWD.hh" // use
00032 #include "BLinkFWD.hh"     // use
00033 #include "OwnedFWD.hh"     // use
00034 
00035 namespace MangoPtr
00036 {
00037     // Overload of isNull(T*) for Owned pointers
00038     template <typename T, OwnershipType oshiptype>
00039     inline bool 
00040     isNull(const Owned<T,oshiptype>& p) {return p.isNull();}
00041     
00042     // Overload of isNotNull(T*) for Owned pointers
00043     template <typename T, OwnershipType oshiptype>
00044     inline bool 
00045     isNotNull(const Owned<T,oshiptype>& p) {return p.isNotNull();}
00046 
00047     template <typename OType, OwnershipType oshiptype>
00048     class Owned<OType*, oshiptype>
00049         : protected BLinkable<ForOwnedBy::Wrapper>
00050     {
00051         protected:
00053             typedef OType* PType;
00055             template <typename O2Type, OwnershipType oshiptype2> 
00056                     friend class Owned;
00057 
00058         public:
00060             typedef OType ObjectType;
00061 
00063 
00064 
00065             Owned(): optr(NullPtr), deleteObj(&Owned::callDelete) {}      
00066             // When the whole template is instantiated, owner 
00067             // copy is only possible with oshiptype=OShared.
00068             #ifndef MANGO_ALL_TEMPLATE_INSTANTIATE
00069             inline Owned(const Owned&);
00070             template <typename O2Type> inline 
00071             Owned(const Owned<O2Type, oshiptype>&);
00072             #endif
00073             explicit Owned(OType*);
00074             template <typename O2Type> explicit inline 
00075             Owned(std::auto_ptr<O2Type>&);
00076             template <typename O2Type> explicit inline 
00077             Owned(Ownership<O2Type, oshiptype>);
00079             inline ~Owned();
00080 
00081         public: 
00083 
00084             inline void swap(Owned& rhs);
00085             inline PType release();
00087             inline void reset() {resetToDefault(); nullify(optr);}
00088             inline Ownership<PType, oshiptype> giveOwnership();
00089             // When the whole template is instantiated, owner 
00090             // assignment is only possible with oshiptype=OShared.
00091             #ifndef MANGO_ALL_TEMPLATE_INSTANTIATE
00094             inline Owned& operator=(const Owned& rhs) {return assignFrom(rhs);}
00097             template <typename O2Type> 
00098             inline Owned& 
00099             operator=(const Owned<O2Type, oshiptype>& rhs) {return assignFrom(rhs);}
00100             #endif 
00101 
00102             inline void takeOwnership(OType* p);
00103             template <typename O2Type> inline void 
00104             takeOwnership(std::auto_ptr<O2Type>&);
00105             template <typename O2Type> inline void 
00106             takeOwnership(Ownership<O2Type, oshiptype>);
00108 
00109         public: 
00111 
00112             inline PType cloneObjNew() const;
00113             inline PType shareUsage(ValidityChecker&) const;
00114             #include "opConstWarningOff.pp"
00115             inline operator const Owned<const OType*, oshiptype>&() const;
00116             #include "opConstWarningOn.pp"
00118 
00119         public: 
00120             // /\name Accessors
00121             // @{
00123             inline bool isNotNull() const { return sharing.isValid((void*)optr); }
00126             inline bool isNull() const { return ! isNotNull(); }
00128             size_t getCountUser() const {return sharing.getCountUser();}
00130             size_t getCountOwned() const {return sharing.getCountOwned();}
00132             bool owns(PType rhs) const {return MangoPtr::isNotNull(rhs) && rhs==optr;}
00135             template <typename O2Type>
00136             bool owns(const BLink<O2Type>& rhs) const {return owns(rhs());}
00142             CheckedPtr<OType> operator()() const {return isNotNull() ? optr : NullPtr;}
00144             OType* ptr() const {return isNotNull() ? optr : NullPtr;}
00147             bool operator==(const Owned& rhs) const {return optr == rhs.optr;}
00149             bool operator!=(const Owned& rhs) const {return optr != rhs.optr;}
00151             bool operator<(const Owned& rhs)  const {return optr <  rhs.optr;}
00152             // @}
00153 
00154         private: // methods
00155             inline void resetToDefault();
00156             template <typename O2Type> 
00157             inline Owned& assignFrom(const Owned<O2Type, oshiptype>&);
00159             inline void callDelete() {delete optr;}
00160             
00161             
00162         private: // data
00163             PType optr; 
00164             
00171             mutable ObjSharing<oshiptype> sharing; 
00172         
00173             typedef void (Owned::*DeleteFn)();
00174             const DeleteFn deleteObj; 
00175     };
00176 
00177     #ifndef MANGO_ALL_TEMPLATE_INSTANTIATE
00178 
00179     template <typename OType, OwnershipType oshiptype>
00180     inline 
00181     Owned<OType*, oshiptype>::Owned(const Owned& owner)
00182         : optr(owner()), sharing(owner.sharing((void*)optr)), 
00183           deleteObj(&Owned::callDelete)
00184     {
00185         assert(MangoPtr::isNull(optr) == isNull());
00186     }
00187 
00189     template <typename OType, OwnershipType oshiptype>
00190     template <typename O2Type>
00191     inline 
00192     Owned<OType*, oshiptype>::Owned(const Owned<O2Type,oshiptype>& owner)
00193         : optr(owner()), sharing(owner.sharing((void*)optr)), 
00194           deleteObj(&Owned::callDelete)
00195     {
00196         assert(MangoPtr::isNull(optr) == isNull());
00197     }
00198     #endif // MANGO_ALL_TEMPLATE_INSTANTIATE
00199     
00201     template <typename OType, OwnershipType oshiptype>
00202     inline 
00203     Owned<OType*, oshiptype>::Owned(OType* p)
00204         : optr(p), deleteObj(&Owned::callDelete)
00205         // sharing.pointer set only if optr used
00206     {
00207     }
00208 
00212     template <typename OType, OwnershipType oshiptype>
00213     template <typename O2Type>
00214     inline 
00215     Owned<OType*, oshiptype>::Owned(std::auto_ptr<O2Type>& ap)
00216         : optr(ap.release()), deleteObj(&Owned::callDelete)
00217         // sharing.pointer set only if optr used
00218     {
00219     }
00220 
00225     template <typename OType, OwnershipType oshiptype>
00226     template <typename O2Type>
00227     inline 
00228     Owned<OType*, oshiptype>::Owned(Ownership<O2Type, oshiptype> os)
00229         : optr(NullPtr), deleteObj(&Owned::callDelete)
00230     {
00231         sharing.swap(os.owner.sharing);
00232         optr = os.owner();
00233         os.owner.optr = NullPtr;
00234         assert(MangoPtr::isNull(optr) == isNull());
00235         assert(os.owner.isNull());
00236     }
00237 
00239     template <typename OType, OwnershipType oshiptype>
00240     inline 
00241     Owned<OType*, oshiptype>::~Owned() 
00242     {
00243         if (sharing.destructNeedsDelete((void*)optr))
00244         {
00245             (this->*deleteObj)();
00247             sharing.invalidateUsage();
00248         }
00249     }
00250         
00259     template <typename OType, OwnershipType oshiptype>
00260     inline void 
00261     Owned<OType*, oshiptype>::resetToDefault()
00262     {
00263         if (sharing.destructNeedsDelete((void*)optr) )
00264         {
00265             (this->*deleteObj)();
00267             sharing.invalidateUsage();
00268         }
00269         // unlink from remaining sharers
00270         sharing.unlinkNew();
00271     }
00272 
00277     template <typename OType, OwnershipType oshiptype>
00278     inline void 
00279     Owned<OType*, oshiptype>::takeOwnership(OType* p)
00280     {
00281         resetToDefault();
00282         optr = p;
00283     }
00284 
00289     template <typename OType, OwnershipType oshiptype>
00290     template <typename O2Type>
00291     inline void 
00292     Owned<OType*, oshiptype>::takeOwnership(std::auto_ptr<O2Type>& ap)
00293     {
00294         resetToDefault();
00295         optr = ap.release();
00296     }
00297 
00305     template <typename OType, OwnershipType oshiptype>
00306     template <typename O2Type>
00307     inline void 
00308     Owned<OType*, oshiptype>::takeOwnership(Ownership<O2Type, oshiptype> os)
00309     {
00310         resetToDefault();
00311         sharing.swap(os.owner.sharing);
00312         optr = os.owner();
00313         nullify(os.owner.optr);
00314         assert(MangoPtr::isNull(optr) == isNull());
00315     }
00316 
00317     /*
00318         Make this owner equal to the one on the \a rhs.
00319         Since two owners can't refer to the same pointee,
00320         this owner will contain a clone of the pointee 
00321         owned by \a rhs.
00322     */
00323     template <typename OType, OwnershipType oshiptype>
00324     template <typename O2Type>
00325     inline Owned<OType*, oshiptype>&
00326     Owned<OType*, oshiptype>::assignFrom(const Owned<O2Type, oshiptype>& rhs)
00327     {
00328         resetToDefault();
00329         optr = rhs();
00330         sharing = rhs.sharing((void*)optr);
00331         return *this;
00332     }
00333 
00340     template <typename OType, OwnershipType oshiptype>
00341     inline Ownership<OType*, oshiptype> 
00342     Owned<OType*, oshiptype>::giveOwnership() 
00343     {
00344         return Ownership<OType*, oshiptype>(*this);
00345     }
00346 
00348     template <typename OType, OwnershipType oshiptype>
00349     inline void 
00350     Owned<OType*, oshiptype>::swap(Owned& rhs) 
00351     {
00352         std::swap(optr, rhs.optr);
00353         sharing.swap(rhs.sharing);
00354     }
00355 
00364     template <typename OType, OwnershipType oshiptype>
00365     inline OType* 
00366     Owned<OType*, oshiptype>::cloneObjNew() 
00367     const
00368     { 
00369         return isNotNull() ? new OType(*optr) : NullPtr;
00370     }
00371 
00389     template <typename OType, OwnershipType oshiptype>
00390     inline OType* 
00391     Owned<OType*, oshiptype>::release() 
00392     {
00393         // make sure all users know they can't use it anymore
00394         sharing.invalidateUsage();
00395         // and unlink us from other owners and users
00396         sharing.unlinkNew();
00397         PType tmp = optr;
00398         nullify(optr);
00399         return tmp;
00400     }
00401 
00414     template <typename OType, OwnershipType oshiptype>
00415     inline 
00416     Owned<OType*, oshiptype>::operator const Owned<const OType*, oshiptype>&() 
00417     const 
00418     {
00419         return * static_cast<const Owned<const OType*, oshiptype>*>(
00420                      static_cast<const void*>(this)
00421                  );
00422     }
00423     
00431     template <typename OType, OwnershipType oshiptype>
00432     inline OType* 
00433     Owned<OType*, oshiptype>::shareUsage(ValidityChecker& val) 
00434     const
00435     {
00436         val = sharing((void*)optr).usage(); 
00437         assert(val.isShared());
00438         assert(val.isValid() == MangoPtr::isNotNull(*this));
00439         return (*this)();
00440     }
00441               
00442 } // namespace
00443 
00535 #endif // MANGO_OWNED_PTR_H

Generated on Tue Nov 12 20:43:53 2002 for Mango-ptr Library by doxygen1.2.18