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