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