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