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