00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef COH_MEMBER_HOLDER_HPP
00017 #define COH_MEMBER_HOLDER_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Object.hpp"
00022 #include "coherence/lang/SmartMember.hpp"
00023 #include "coherence/lang/SynchronizedMemberReadBlock.hpp"
00024 #include "coherence/lang/SynchronizedMemberWriteBlock.hpp"
00025 #include "coherence/lang/TypedHandle.hpp"
00026 #include "coherence/lang/TypedHolder.hpp"
00027 
00028 #include <ostream>
00029 
00030 COH_OPEN_NAMESPACE2(coherence,lang)
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 template<class T>
00053 class MemberHolder
00054     : public SmartMember
00055     {
00056     
00057 
00058     public:
00059 
00060 
00061 
00062         typedef const T ValueType;
00063 
00064 
00065 
00066 
00067         typedef typename T::Handle ValueHandle;
00068 
00069 
00070 
00071 
00072         typedef typename T::View ValueView;
00073 
00074 
00075 
00076 
00077         typedef typename T::Holder ValueHolder;
00078 
00079 
00080 
00081 
00082         typedef TypedHolder<T> GetType;
00083 
00084 
00085     
00086 
00087     public:
00088 
00089 
00090 
00091 
00092 
00093         MemberHolder(const Object& oGuardian)
00094             : SmartMember(oGuardian), m_fView(false), m_po(NULL)
00095             {
00096             }
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104         MemberHolder(const Object& oGuardian, const TypedHolder<T>& that)
00105             : SmartMember(oGuardian), m_fView(that.m_fView), m_po(NULL)
00106             {
00107             T* po = const_cast<T*>(that.m_cpo);
00108             if (po != NULL)
00109                 {
00110                 bool fEscaped = oGuardian._isEscaped();
00111                 if (m_fView)
00112                     {
00113                     ((const T*) po)->_attach(fEscaped);
00114                     }
00115                 else
00116                     {
00117                     po->_attach(fEscaped);
00118                     }
00119                 m_po = po;
00120                 }
00121             }
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131         MemberHolder(const Object& oGuardian, const TypedHolder<T>& that,
00132                 bool fMutable)
00133             : SmartMember(oGuardian, fMutable ? MUTABLE : SAFE_CONST),
00134               m_fView(that.m_fView), m_po(NULL)
00135             {
00136             T* po = const_cast<T*>(that.m_cpo);
00137             if (po != NULL)
00138                 {
00139                 bool fEscaped = oGuardian._isEscaped();
00140                 if (m_fView)
00141                     {
00142                     ((const T*) po)->_attach(fEscaped);
00143                     }
00144                 else
00145                     {
00146                     po->_attach(fEscaped);
00147                     }
00148                 m_po = po;
00149                 }
00150             }
00151 
00152 
00153 
00154 
00155         ~MemberHolder()
00156             {
00157             T*   po    = m_po;
00158             bool fView = m_fView;
00159 
00160             if (po != NULL)
00161                 {
00162                 m_po = NULL;
00163                 try
00164                     {
00165                     bool fEscaped = getGuardian()._isEscaped();
00166                     if (fView)
00167                         {
00168                         ((const T*) po)->_detach(fEscaped);
00169                         }
00170                     else
00171                         {
00172                         po->_detach(fEscaped);
00173                         }
00174                     }
00175                 catch (const std::exception& e)
00176                     {
00177                     
00178                     std::cerr << "Error during ~MemberHolder: " << e.what()
00179                         << std::endl;
00180                     return; 
00181                     }
00182                 }
00183             }
00184 
00185     protected:
00186 
00187 
00188 
00189 
00190 
00191         MemberHolder()
00192             : SmartMember(), m_fView(false), m_po(NULL)
00193             {
00194             }
00195 
00196     private:
00197 
00198 
00199 
00200         MemberHolder(const MemberHolder&);
00201 
00202 
00203     
00204 
00205     public:
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214         MemberHolder& operator=(const MemberHolder& that)
00215             {
00216             set(that); 
00217             return *this;
00218             }
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228         MemberHolder& operator=(const TypedHolder<T>& that)
00229             {
00230             set(that);
00231             return *this;
00232             }
00233 
00234 
00235 
00236 
00237 
00238 
00239         operator ValueView() const
00240             {
00241             const Object& oGuardian = getGuardian();
00242 
00243             if (m_nMutability == SAFE_CONST || !oGuardian._isEscaped())
00244                 {
00245                 
00246                 return ValueView(m_po);
00247                 }
00248             else
00249                 {
00250                 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00251                 return ValueView(m_po); 
00252                 }
00253             }
00254 
00255 
00256 
00257 
00258 
00259 
00260         template<class PT>
00261         operator TypedHandle<const PT>() const
00262             {
00263             return (ValueView) *this;
00264             }
00265 
00266 
00267 
00268 
00269 
00270 
00271         template<class PT>
00272         operator TypedHolder<PT>() const
00273             {
00274             return get();
00275             }
00276 
00277 
00278 
00279 
00280 
00281 
00282         ValueView operator->() const
00283             {
00284             return (ValueView) *this;
00285             }
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294         const T& operator*() const
00295             {
00296             return *get();
00297             }
00298 
00299     
00300 
00301     protected:
00302 
00303 
00304 
00305         virtual void onEscape(bool fEscaped) const
00306             {
00307             T* po = m_po;
00308             if (po != NULL)
00309                 {
00310                 if (m_fView)
00311                     {
00312                     const T* cpo = po;
00313                     cpo->_attach(fEscaped);  
00314                     cpo->_detach(!fEscaped); 
00315                     }
00316                 else
00317                     {
00318                     po->_attach(fEscaped);  
00319                     po->_detach(!fEscaped); 
00320                     }
00321                 }
00322 
00323             SmartMember::onEscape(fEscaped);
00324             }
00325 
00326     
00327 
00328     protected:
00329 
00330 
00331 
00332 
00333 
00334 
00335         void set(const TypedHolder<T>& that,
00336                 SynchronizedMemberWriteBlock *pSync = NULL)
00337             {
00338             const Object& oGuardian = getGuardian();
00339             bool          fEscaped  = oGuardian._isEscaped();
00340             T*            pNew      = const_cast<T*>(that.m_cpo);
00341             bool          fNewView  = that.m_fView;
00342             T*            pOld;
00343             bool          fOldView;
00344 
00345             if (pNew != NULL)
00346                 {
00347                 if (fNewView)
00348                     {
00349                     ((const T*) pNew)->_attach(fEscaped);
00350                     }
00351                 else
00352                     {
00353                     pNew->_attach(fEscaped);
00354                     }
00355                 }
00356 
00357             if (pSync != NULL)
00358                 {
00359                 
00360                 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00361                 if (m_nMutability >= CONST)
00362                     {
00363                     coh_throw_illegal_state("attempt to set const MemberHolder");
00364                     }
00365 
00366                 pOld     = m_po;
00367                 fOldView = m_fView;
00368 
00369                 m_po    = pNew;
00370                 m_fView = fNewView;
00371                 }
00372             else if (fEscaped)
00373                 {
00374                 
00375                 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00376                 if (m_nMutability >= CONST)
00377                     {
00378                     coh_throw_illegal_state("attempt to set const MemberHolder");
00379                     }
00380                 pOld     = m_po;
00381                 fOldView = m_fView;
00382 
00383                 m_po    = pNew;
00384                 m_fView = fNewView;
00385                 }
00386             else
00387                 {
00388                 if (m_nMutability >= CONST)
00389                     {
00390                     coh_throw_illegal_state("attempt to set const MemberHolder");
00391                     }
00392                 pOld     = m_po;
00393                 fOldView = m_fView;
00394 
00395                 m_po    = pNew;
00396                 m_fView = fNewView;
00397                 }
00398 
00399             if (pOld != NULL)
00400                 {
00401                 if (fOldView)
00402                     {
00403                     ((const T*) pOld)->_detach(fEscaped);
00404                     }
00405                 else
00406                     {
00407                     pOld->_detach(fEscaped);
00408                     }
00409                 }
00410             }
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421         TypedHolder<T> get(SynchronizedMemberReadBlock* pSync = NULL) const
00422             {
00423             const Object& oGuardian = getGuardian();
00424 
00425             if (pSync != NULL)
00426                 {
00427                 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00428                 if (m_fView)
00429                     {
00430                     return ValueView(m_po); 
00431                     }
00432                 return ValueHandle(m_po); 
00433                 }
00434             else if (m_nMutability == SAFE_CONST || !oGuardian._isEscaped())
00435                 {
00436                 
00437                 if (m_fView)
00438                     {
00439                     return ValueView(m_po);
00440                     }
00441                 return ValueHandle(m_po);
00442                 }
00443             else
00444                 {
00445                 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00446                 if (m_fView)
00447                     {
00448                     return ValueView(m_po); 
00449                     }
00450                 return ValueHandle(m_po); 
00451                 }
00452             }
00453 
00454 
00455     
00456 
00457     protected:
00458 
00459 
00460 
00461 
00462         bool m_fView;
00463 
00464 
00465 
00466 
00467         T* m_po;
00468 
00469 
00470     
00471 
00472 
00473 
00474 
00475     template<class> friend class Array;
00476 
00477 
00478 
00479 
00480     friend class SynchronizedMemberReadBlock;
00481 
00482 
00483 
00484 
00485     friend class SynchronizedMemberWriteBlock;
00486     };
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 template<class T> std::ostream& operator<<(std::ostream& out, const MemberHolder<T>& th)
00501     {
00502     out << (typename T::View) th;
00503     return out;
00504     }
00505 
00506 
00507 
00508 
00509 
00510 
00511 template<class T> void clear_handle(MemberHolder<T>& mh)
00512     {
00513     mh = NULL;
00514     }
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 template<class T>
00524 bool is_null(const MemberHolder<T>& mh)
00525     {
00526     return mh == NULL;
00527     }
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 template<class D, class T>
00541 D cast(const MemberHolder<T>& mh, bool fThrow = true)
00542     {
00543     return cast<D>((TypedHolder<T>) mh, fThrow);
00544     }
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 template<class D, class T>
00554 bool instanceof(const MemberHolder<T>& mh)
00555     {
00556     return instanceof<D>((TypedHolder<T>) mh);
00557     }
00558 
00559 COH_CLOSE_NAMESPACE2
00560 
00561 #endif // COH_MEMBER_HOLDER_HPP