00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef COH_MEMBER_HANDLE_HPP
00017 #define COH_MEMBER_HANDLE_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
00027 #include <ostream>
00028
00029 COH_OPEN_NAMESPACE2(coherence,lang)
00030
00031 template<class> class MemberView;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 template<class T>
00055 class MemberHandle
00056 : public SmartMember, public ChainedHandleElement
00057 {
00058
00059
00060 public:
00061
00062
00063
00064 typedef T ValueType;
00065
00066
00067
00068
00069 typedef typename T::Handle ValueHandle;
00070
00071
00072
00073
00074 typedef typename T::View ValueView;
00075
00076
00077
00078
00079 typedef ValueHandle GetType;
00080
00081
00082
00083
00084 typedef ValueView ConstGetType;
00085
00086
00087
00088
00089 public:
00090
00091
00092
00093
00094
00095 MemberHandle(const Object& oGuardian)
00096 : SmartMember(oGuardian), ChainedHandleElement( false),
00097 m_po(NULL)
00098 {
00099 if (oGuardian._isEscaped())
00100 {
00101 m_prev = m_next = NULL;
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 MemberHandle(const Object& oGuardian, const ValueHandle& that)
00113 : SmartMember(oGuardian), ChainedHandleElement( false),
00114 m_po(NULL)
00115 {
00116 if (oGuardian._isEscaped())
00117 {
00118 m_prev = m_next = NULL;
00119 }
00120 set(that);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 MemberHandle(const Object& oGuardian, const ValueHandle& that,
00133 bool fMutable)
00134 : SmartMember(oGuardian), ChainedHandleElement( false),
00135 m_po(NULL)
00136 {
00137 if (oGuardian._isEscaped())
00138 {
00139 m_prev = m_next = NULL;
00140 }
00141 set(that);
00142 m_nMutability = fMutable ? forever_mutable : safe_immutable;
00143 }
00144
00145
00146
00147
00148 ~MemberHandle()
00149 {
00150 try
00151 {
00152 const T* cpo = m_po;
00153 if (cpo && m_fView && m_prev == NULL)
00154 {
00155
00156
00157 cpo->_detach( true);
00158 }
00159 else
00160 {
00161
00162 m_nMutability = inherited;
00163 set(NULL);
00164 }
00165 }
00166 catch (const std::exception& e)
00167 {
00168
00169 std::cerr << "Error during ~MemberHandle: " << e.what() << std::endl;
00170 return;
00171 }
00172 }
00173
00174 private:
00175
00176
00177
00178 MemberHandle(const MemberHandle&);
00179
00180
00181
00182
00183 public:
00184
00185
00186
00187
00188
00189
00190
00191 MemberHandle& operator=(const ValueHandle& that)
00192 {
00193 set(that);
00194 return *this;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 MemberHandle& operator=(MemberHandle& that)
00206 {
00207 operator=((ValueHandle) that);
00208 return *this;
00209 }
00210
00211
00212
00213
00214
00215
00216 operator ValueView() const
00217 {
00218 return get();
00219 }
00220
00221
00222
00223
00224
00225
00226 operator ValueHandle()
00227 {
00228 return get();
00229 }
00230
00231
00232
00233
00234
00235
00236 template<class PT>
00237 operator TypedHandle<const PT>() const
00238 {
00239 return get();
00240 }
00241
00242
00243
00244
00245
00246
00247 template<class PT>
00248 operator TypedHandle<PT>()
00249 {
00250 return get();
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 template<class PT>
00260 operator TypedHolder<PT>() const
00261 {
00262 return get();
00263 }
00264
00265
00266
00267
00268
00269
00270 template<class PT>
00271 operator TypedHolder<PT>()
00272 {
00273 return get();
00274 }
00275
00276
00277
00278
00279
00280
00281 ValueView operator->() const
00282 {
00283 return get();
00284 }
00285
00286
00287
00288
00289
00290
00291 ValueHandle operator->()
00292 {
00293 return get();
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 const T& operator*() const
00304 {
00305 return *get();
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315 T& operator*()
00316 {
00317 return *get();
00318 }
00319
00320 private:
00321
00322
00323
00324 MemberHandle<T>& operator=(const MemberHandle<T>&);
00325
00326
00327
00328
00329 protected:
00330
00331
00332
00333
00334
00335
00336
00337
00338 void set(const TypedHandle<T>& that,
00339 SynchronizedMemberWriteBlock* pSync = NULL)
00340 {
00341 if (m_prev == NULL)
00342 {
00343 setEscaped(that, pSync);
00344 }
00345 else if (m_nMutability >= forever_immutable)
00346 {
00347 coh_throw_illegal_state("attempt to set const MemberHandle");
00348 }
00349 else
00350 {
00351 performAction(link(that));
00352 m_po = get_pointer(that);
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 void setEscaped(const TypedHandle<T>& that,
00365 SynchronizedMemberWriteBlock* pSync = NULL)
00366 {
00367 const Object& oGuardian = getGuardian();
00368 T* po = get_pointer(that);
00369 T* pDetach = NULL;
00370 Object* pAttach = po == NULL ? NULL : po->_attach( true);
00371
00372 if (pSync == NULL)
00373 {
00374
00375 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00376 if (m_nMutability >= forever_immutable)
00377 {
00378 coh_throw_illegal_state("attempt to set const MemberHandle");
00379 }
00380 pDetach = m_po;
00381 m_po = NULL == pAttach ? NULL : po;
00382 }
00383 else
00384 {
00385
00386 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00387 if (m_nMutability >= forever_immutable)
00388 {
00389 coh_throw_illegal_state("attempt to set const MemberHandle");
00390 }
00391 pDetach = m_po;
00392 m_po = NULL == pAttach ? NULL : po;
00393 }
00394
00395 if (pDetach)
00396 {
00397 pDetach->_detach( true);
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00410 {
00411 if (m_prev == NULL)
00412 {
00413 return getEscaped(pSync);
00414 }
00415 else
00416 {
00417 return TypedHandle<const T>(m_po, *this);
00418 }
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 ValueView getEscaped(SynchronizedMemberReadBlock* pSync = NULL) const
00430 {
00431 if (pSync != NULL)
00432 {
00433 SynchronizedMemberReadBlock syncRead(getGuardian(), pSync);
00434
00435 return ValueView((const T*) m_po);
00436 }
00437 else if (m_nMutability == safe_immutable)
00438 {
00439
00440 return ValueView((const T*) m_po);
00441 }
00442 else
00443 {
00444 SynchronizedMemberReadBlock::Guard guard(getGuardian());
00445
00446 return ValueView((const T*) m_po);
00447 }
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 ValueHandle get(SynchronizedMemberReadBlock* pSync = NULL)
00459 {
00460 if (m_prev == NULL)
00461 {
00462 return getEscaped(pSync);
00463 }
00464 else
00465 {
00466 return TypedHandle<T>(m_po, *this);
00467 }
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 ValueHandle getEscaped(SynchronizedMemberReadBlock* pSync = NULL)
00479 {
00480 const Object& oGuardian = getGuardian();
00481 if (pSync == NULL)
00482 {
00483 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00484 if (m_fView)
00485 {
00486 coh_throw_illegal_state(
00487 "attempt to access handle from const MemberHandle");
00488 }
00489 return ValueHandle(m_po);
00490 }
00491 else
00492 {
00493 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00494 if (m_fView)
00495 {
00496 coh_throw_illegal_state(
00497 "attempt to access handle from const MemberHandle");
00498 }
00499 return ValueHandle(m_po);
00500 }
00501 }
00502
00503
00504
00505
00506
00507
00508 void performAction(Action nAction) const
00509 {
00510 T* po = m_po;
00511 switch (nAction)
00512 {
00513 case action_error:
00514 coh_throw_illegal_state("corrupted ChainedHandleElement");
00515 case action_flip:
00516 if (NULL != po) ((const T*) po)->_attach( false);
00517
00518 case action_detach:
00519 if (NULL != po)
00520 {
00521 if (m_fView)
00522 {
00523 ((const T*) po)->_detach( false);
00524 }
00525 else
00526 {
00527 po->_detach( false);
00528 }
00529 }
00530
00531 case action_none:
00532 default:
00533 break;
00534 }
00535 }
00536
00537
00538
00539 protected:
00540
00541
00542
00543
00544
00545
00546 virtual void onConst()
00547 {
00548 bool fEscaped = m_prev == NULL;
00549 T* po = NULL;
00550
00551 if (fEscaped)
00552 {
00553 SynchronizedMemberWriteBlock::Guard guard(getGuardian());
00554 po = m_po;
00555 }
00556 else
00557 {
00558 po = m_po;
00559 }
00560
00561 if (NULL != po)
00562 {
00563
00564 if (fEscaped)
00565 {
00566 ((const T*) po)->_attach( true);
00567 po->_detach( true);
00568 }
00569 else if (scan())
00570 {
00571 performAction(action_flip);
00572 }
00573 }
00574
00575 m_fView = true;
00576 SmartMember::onConst();
00577 }
00578
00579
00580
00581
00582 virtual void onEscape(bool fEscaped) const
00583 {
00584 T* po = m_po;
00585 if (po != NULL)
00586 {
00587 if (m_fView)
00588 {
00589 const T* cpo = po;
00590 cpo->_attach(fEscaped);
00591 }
00592 else
00593 {
00594 po->_attach(fEscaped);
00595 }
00596 }
00597
00598 if (fEscaped)
00599 {
00600 performAction(unlink());
00601 m_prev = m_next = NULL;
00602 }
00603 else
00604 {
00605 if (po)
00606 {
00607 if (m_fView)
00608 {
00609 const T* cpo = po;
00610 cpo->_detach( true);
00611 }
00612 else
00613 {
00614 po->_detach( true);
00615 }
00616 }
00617 m_prev = m_next = this;
00618 }
00619
00620 SmartMember::onEscape(fEscaped);
00621 }
00622
00623
00624
00625
00626 virtual size64_t retained() const
00627 {
00628 ValueView v = get();
00629 return v == NULL
00630 ? 0
00631 : v->sizeOf( true);
00632 }
00633
00634
00635
00636 protected:
00637
00638
00639
00640 T* m_po;
00641
00642
00643
00644
00645
00646
00647
00648 template<class D, class H> friend D cast(MemberHandle<T>& mh, bool fThrow);
00649
00650
00651
00652
00653 friend class SynchronizedMemberReadBlock;
00654
00655
00656
00657
00658 friend class SynchronizedMemberWriteBlock;
00659 };
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 template <typename Char, typename Traits, class T>
00674 COH_INLINE std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, const MemberHandle<T>& mh)
00675 {
00676 out << (typename T::View) mh;
00677 return out;
00678 }
00679
00680
00681
00682
00683
00684
00685 template<class T> void clear_handle(MemberHandle<T>& mh)
00686 {
00687 mh = NULL;
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697 template<class T>
00698 bool is_null(const MemberHandle<T>& mh)
00699 {
00700 return mh == NULL;
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 template<class D, class T>
00715 D cast(MemberHandle<T>& mh, bool fThrow = true)
00716 {
00717 return cast<D>((typename MemberHandle<T>::ValueHandle) mh, fThrow);
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 template<class D, class T>
00732 D cast(const MemberHandle<T>& mh, bool fThrow = true)
00733 {
00734 return cast<D>((typename MemberHandle<T>::ValueView) mh, fThrow);
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744 template<class D, class T>
00745 bool instanceof(MemberHandle<T>& mh)
00746 {
00747 return NULL != cast<D>(mh, false);
00748 }
00749
00750
00751
00752
00753
00754
00755
00756
00757 template<class D, class T>
00758 bool instanceof(const MemberHandle<T>& mh)
00759 {
00760 return NULL != cast<D>(mh, false);
00761 }
00762
00763 COH_CLOSE_NAMESPACE2
00764
00765 #endif // COH_MEMBER_HANDLE_HPP