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