00001 #ifndef MANGO_OWNED_CONTAINER_H
00002 #define MANGO_OWNED_CONTAINER_H
00003
00023 #include "nullness.hh"
00024 #include "ValidityOwner.hh"
00025 #include "ValidityChecker.hh"
00026 #include "CntrCleaner.hh"
00027 #include "CntrClonerFWD.hh"
00028 #include "BLinkableFWD.hh"
00029 #include "Ownership.hh"
00030 #include "OwnedFWD.hh"
00031
00032 namespace MangoPtr
00033 {
00087 template <typename CntrType, OwnershipType oshiptype>
00088 class Owned: protected BLinkable<ForOwnedBy::Wrapper>
00089 {
00090 public:
00092 typedef CntrType OwnedType;
00093
00095
00096
00097 Owned(): cleanerUpper(&Owned::doCleanUp) {}
00098 inline explicit Owned(CntrType&);
00099 template <typename O2Type> explicit inline
00100 Owned(Ownership<O2Type, oshiptype>);
00101 inline ~Owned();
00103
00104 public:
00106
00107 inline void swap(Owned&);
00108 inline void swap(CntrType&);
00109 inline void clear();
00110 inline void unlink() const;
00111 inline void reset();
00112
00113 inline Ownership<CntrType, oshiptype> transfer();
00114 inline void takeOwnership(CntrType&);
00115 template <typename O2Type>
00116 inline void takeOwnership(Ownership<O2Type, oshiptype>);
00118
00119 public:
00121
00122 inline void cloneObjNew(CntrType&) const;
00123 inline CntrType* shareUsage(ValidityChecker&) const;
00125 CntrType& cntr() {return ocntr;}
00127 const CntrType& cntr() const {return ocntr;}
00133 CntrType* operator()() {return &ocntr;}
00135 const CntrType* operator()() const {return &ocntr;}
00137
00138 private:
00139 mutable CntrType ocntr;
00140 mutable ValidityOwner usage;
00141
00142
00143 typedef void (Owned::*DeleteFn)();
00145 const DeleteFn cleanerUpper;
00146
00147 private:
00152 void doCleanUp() { CntrCleaner<CntrType>::execute(ocntr); }
00153
00154 private:
00155 #ifndef MANGO_ALL_TEMPLATE_INSTANTIATE
00156
00157
00158 inline Owned(const Owned&);
00159 template <typename O2Type> inline
00160 Owned(const Owned<O2Type, oshiptype>&);
00161 inline Owned& operator=(const Owned& rhs);
00162 template <typename O2Type>
00163 inline Owned& operator=(const Owned<O2Type, oshiptype>& rhs);
00164 #endif
00165 };
00166
00172 template <typename CntrType, OwnershipType oshiptype>
00173 inline
00174 Owned<CntrType, oshiptype>::Owned(CntrType& cntr)
00175 : cleanerUpper(&Owned::doCleanUp)
00176 {
00177 std::swap(ocntr,cntr);
00178 }
00179
00185 template <typename CntrType, OwnershipType oshiptype>
00186 template <typename O2Type>
00187 inline
00188 Owned<CntrType, oshiptype>::Owned(Ownership<O2Type, oshiptype> os)
00189 : cleanerUpper(&Owned::doCleanUp)
00190 {
00191 std::swap(ocntr, os.owner.ocntr);
00192 assert(os.owner()->empty());
00193 }
00194
00201 template <typename CntrType, OwnershipType oshiptype>
00202 inline
00203 Owned<CntrType, oshiptype>::~Owned()
00204 {
00205 usage.setValid(false);
00206 usage.reset(false);
00207 (this->*cleanerUpper)();
00208 }
00209
00223 template <typename CntrType, OwnershipType oshiptype>
00224 inline void
00225 Owned<CntrType, oshiptype>::swap(Owned& that)
00226 {
00227 std::swap(ocntr, that.ocntr);
00228
00229
00230 }
00231
00236 template <typename CntrType, OwnershipType oshiptype>
00237 inline void
00238 Owned<CntrType, oshiptype>::swap(CntrType& that)
00239 {
00240 std::swap(that, ocntr);
00241 }
00242
00245 template <typename CntrType, OwnershipType oshiptype>
00246 inline void
00247 Owned<CntrType, oshiptype>::clear()
00248 {
00249 (this->*cleanerUpper)();
00250 CntrType empty;
00251 std::swap(empty, ocntr);
00252 assert(ocntr.empty());
00253 }
00254
00261 template <typename CntrType, OwnershipType oshiptype>
00262 inline void
00263 Owned<CntrType, oshiptype>::unlink()
00264 const
00265 {
00266 usage.setValid(false);
00267 usage.reset(false);
00268 }
00269
00277 template <typename CntrType, OwnershipType oshiptype>
00278 inline void
00279 Owned<CntrType, oshiptype>::reset()
00280 {
00281 clear();
00282 unlink();
00283 }
00284
00288 template <typename CntrType, OwnershipType oshiptype>
00289 inline Ownership<CntrType, oshiptype>
00290 Owned<CntrType, oshiptype>::transfer()
00291 {
00292 return Ownership<CntrType, oshiptype>(*this);
00293
00294 }
00295
00299 template <typename CntrType, OwnershipType oshiptype>
00300 inline void
00301 Owned<CntrType, oshiptype>::takeOwnership(CntrType& p)
00302 {
00303 reset();
00304 std::swap(p, ocntr);
00305 assert(p.empty());
00306 }
00307
00310 template <typename CntrType, OwnershipType oshiptype>
00311 template <typename O2Type>
00312 inline void
00313 Owned<CntrType, oshiptype>::takeOwnership(Ownership<O2Type, oshiptype> os)
00314 {
00315 clear();
00316 std::swap(ocntr, os.owner.ocntr);
00317 assert(os.owner()->empty());
00318 }
00319
00329 template <typename CntrType, OwnershipType oshiptype>
00330 inline void
00331 Owned<CntrType, oshiptype>::cloneObjNew(CntrType& dest)
00332 const
00333 {
00334 assert(dest.empty());
00335 dest = ocntr;
00336 CntrCloner<CntrType>::execute(dest);
00337 }
00338
00345 template <typename CntrType, OwnershipType oshiptype>
00346 inline CntrType*
00347 Owned<CntrType, oshiptype>::shareUsage(ValidityChecker& val)
00348 const
00349 {
00350 if (! usage.isValid()) usage.setValid(true);
00351 val = usage;
00352 assert(val.isShared());
00353 assert(val.isValid());
00354 return &ocntr;
00355 }
00356
00375
00376
00377 template <typename CntrType>
00378 class Owned<CntrType&, OStrict>;
00379
00380 }
00381
00382
00383 #endif // MANGO_OWNED_CONTAINER_H