00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef COH_MEMBER_VIEW_HPP
00017 #define COH_MEMBER_VIEW_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 template<class T>
00046 class MemberView
00047 : public SmartMember, public ChainedHandleElement
00048 {
00049
00050
00051 public:
00052
00053
00054
00055 typedef T ValueType;
00056
00057
00058
00059
00060 typedef typename T::View ValueView;
00061
00062
00063
00064
00065 typedef ValueView GetType;
00066
00067
00068
00069
00070 public:
00071
00072
00073
00074
00075
00076 MemberView(const Object& oGuardian)
00077 : SmartMember(oGuardian), ChainedHandleElement( true),
00078 m_cpo(NULL)
00079 {
00080 if (oGuardian._isEscaped())
00081 {
00082 m_prev = m_next = NULL;
00083 }
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 MemberView(const Object& oGuardian, const ValueView& that)
00093 : SmartMember(oGuardian), ChainedHandleElement( true),
00094 m_cpo(NULL)
00095 {
00096 if (oGuardian._isEscaped())
00097 {
00098 m_prev = m_next = NULL;
00099 }
00100 set(that);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 MemberView(const Object& oGuardian, const ValueView& that, bool fMutable)
00111 : SmartMember(oGuardian), ChainedHandleElement( true),
00112 m_cpo(NULL)
00113 {
00114 if (oGuardian._isEscaped())
00115 {
00116 m_prev = m_next = NULL;
00117 }
00118 set(that);
00119 m_nMutability = fMutable ? forever_mutable : safe_immutable;
00120 }
00121
00122
00123
00124
00125 ~MemberView()
00126 {
00127 try
00128 {
00129 m_nMutability = inherited;
00130 set(NULL);
00131 }
00132 catch (const std::exception& e)
00133 {
00134
00135 std::cerr << "Error during ~MemberView: " << e.what() << std::endl;
00136 return;
00137 }
00138 }
00139
00140 private:
00141
00142
00143
00144 MemberView(const MemberView&);
00145
00146
00147
00148
00149 public:
00150
00151
00152
00153
00154
00155
00156
00157 MemberView& operator=(const ValueView& that)
00158 {
00159 set(that);
00160 return *this;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 MemberView& operator=(const MemberView& that)
00171 {
00172 set(that);
00173 return *this;
00174 }
00175
00176
00177
00178
00179
00180
00181 operator ValueView() const
00182 {
00183 return get();
00184 }
00185
00186
00187
00188
00189
00190
00191 template<class PT>
00192 operator TypedHandle<const PT>() const
00193 {
00194 return get();
00195 }
00196
00197
00198
00199
00200
00201
00202 template<class PT>
00203 operator TypedHolder<PT>() const
00204 {
00205 return get();
00206 }
00207
00208
00209
00210
00211
00212
00213 ValueView operator->() const
00214 {
00215 return get();
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225 const T& operator*() const
00226 {
00227 return *get();
00228 }
00229
00230
00231
00232 protected:
00233
00234
00235
00236 virtual void onEscape(bool fEscaped) const
00237 {
00238 const T* cpo = m_cpo;
00239 if (cpo)
00240 {
00241 cpo->_attach(fEscaped);
00242 }
00243
00244 if (fEscaped)
00245 {
00246 performAction(unlink());
00247 m_prev = m_next = NULL;
00248 }
00249 else
00250 {
00251 if (cpo)
00252 {
00253 cpo->_detach( true);
00254 }
00255 m_prev = m_next = this;
00256 }
00257
00258 SmartMember::onEscape(fEscaped);
00259 }
00260
00261
00262
00263
00264 virtual size64_t retained() const
00265 {
00266 ValueView v = get();
00267 return v == NULL
00268 ? 0
00269 : v->sizeOf( true);
00270 }
00271
00272
00273
00274
00275 protected:
00276
00277
00278
00279
00280
00281
00282
00283 void set(const TypedHolder<T>& that,
00284 SynchronizedMemberWriteBlock* pSync = NULL)
00285 {
00286 if (m_prev == NULL)
00287 {
00288 setEscaped(that, pSync);
00289 }
00290 else if (m_nMutability >= forever_immutable)
00291 {
00292 coh_throw_illegal_state("attempt to set const MemberView");
00293 }
00294 else
00295 {
00296 performAction(link(that));
00297 m_cpo = get_pointer(that);
00298 }
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308 void setEscaped(const TypedHolder<T>& that,
00309 SynchronizedMemberWriteBlock* pSync = NULL)
00310 {
00311 const Object& oGuardian = getGuardian();
00312 const T* cpo = get_pointer(that);
00313 const T* cpDetach = NULL;
00314 const Object* cpAttach = NULL == cpo ? NULL : cpo->_attach( true);
00315
00316 if (pSync == NULL)
00317 {
00318
00319 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00320 if (m_nMutability >= forever_immutable)
00321 {
00322 coh_throw_illegal_state("attempt to set const MemberView");
00323 }
00324
00325 cpDetach = m_cpo;
00326 m_cpo = NULL == cpAttach ? NULL : cpo;
00327 }
00328 else
00329 {
00330
00331 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00332 if (m_nMutability >= forever_immutable)
00333 {
00334 coh_throw_illegal_state("attempt to set const MemberView");
00335 }
00336
00337 cpDetach = m_cpo;
00338 m_cpo = NULL == cpAttach ? NULL : cpo;
00339 }
00340
00341 if (cpDetach)
00342 {
00343 cpDetach->_detach( true);
00344 }
00345
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00357 {
00358 if (m_prev == NULL)
00359 {
00360 return getEscaped(pSync);
00361 }
00362 else
00363 {
00364 return TypedHandle<const T>(m_cpo, *this);
00365 }
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 ValueView getEscaped(SynchronizedMemberReadBlock* pSync = NULL) const
00377 {
00378 const Object& oGuardian = getGuardian();
00379 if (pSync != NULL)
00380 {
00381
00382 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00383 return ValueView(m_cpo);
00384 }
00385 else if (m_nMutability == safe_immutable)
00386 {
00387
00388 return ValueView(m_cpo);
00389 }
00390 else
00391 {
00392
00393 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00394 return ValueView(m_cpo);
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 void performAction(Action nAction) const
00406 {
00407 const T* cpo = m_cpo;
00408 switch (nAction)
00409 {
00410 case action_error:
00411 case action_flip:
00412 coh_throw_illegal_state("corrupted ChainedHandleElement");
00413 case action_detach:
00414 if (cpo) cpo->_detach( false);
00415
00416 case action_none:
00417 default:
00418 break;
00419 }
00420 }
00421
00422
00423
00424
00425 protected:
00426
00427
00428
00429 const T* m_cpo;
00430
00431
00432
00433
00434
00435
00436 friend class SynchronizedMemberReadBlock;
00437
00438
00439
00440
00441 friend class SynchronizedMemberWriteBlock;
00442 };
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 template<class T> std::ostream& operator<<(std::ostream& out, const MemberView<T>& mv)
00457 {
00458 out << (typename T::View) mv;
00459 return out;
00460 }
00461
00462
00463
00464
00465
00466
00467 template<class T> void clear_handle(MemberView<T>& mv)
00468 {
00469 mv = NULL;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 template<class D, class T>
00484 D cast(const MemberView<T>& mv, bool fThrow = true)
00485 {
00486 return cast<D>((typename MemberView<T>::ValueView) mv, fThrow);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496 template<class D, class T>
00497 bool instanceof(const MemberView<T>& mv)
00498 {
00499 return NULL != cast<D>(mv, false);
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 template<class T>
00510 bool is_null(const MemberView<T>& mv)
00511 {
00512 return mv == NULL;
00513 }
00514
00515 COH_CLOSE_NAMESPACE2
00516
00517 #endif // COH_MEMBER_VIEW_HPP