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
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), m_cpo(NULL)
00078 {
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 MemberView(const Object& oGuardian, const ValueView& that)
00088 : SmartMember(oGuardian), m_cpo(NULL)
00089 {
00090 const T* cpo = get_pointer(that);
00091 if (cpo != NULL)
00092 {
00093 cpo->_attach(oGuardian._isEscaped());
00094 m_cpo = cpo;
00095 }
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105 MemberView(const Object& oGuardian, const ValueView& that, bool fMutable)
00106 : SmartMember(oGuardian, fMutable ? MUTABLE : SAFE_CONST),
00107 m_cpo(NULL)
00108 {
00109 const T* cpo = get_pointer(that);
00110 if (cpo != NULL)
00111 {
00112 cpo->_attach(oGuardian._isEscaped());
00113 m_cpo = cpo;
00114 }
00115 }
00116
00117
00118
00119
00120 ~MemberView()
00121 {
00122 const T* cpo = m_cpo;
00123 if (cpo != NULL)
00124 {
00125 m_cpo = NULL;
00126 try
00127 {
00128 cpo->_detach(getGuardian()._isEscaped());
00129 }
00130 catch (const std::exception& e)
00131 {
00132
00133 std::cerr << "Error during ~MemberView: " << e.what()
00134 << std::endl;
00135 return;
00136 }
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 != NULL)
00240 {
00241 cpo->_attach(fEscaped);
00242 cpo->_detach(!fEscaped);
00243 }
00244
00245 SmartMember::onEscape(fEscaped);
00246 }
00247
00248
00249
00250
00251 protected:
00252
00253
00254
00255
00256
00257
00258
00259 void set(const TypedHolder<T>& that,
00260 SynchronizedMemberWriteBlock* pSync = NULL)
00261 {
00262 const Object& oGuardian = getGuardian();
00263 const T* cpDetach = NULL;
00264 const T* cpo = get_pointer(that);
00265 bool fEscaped = oGuardian._isEscaped();
00266 const Object* cpAttach = NULL == cpo ? NULL : cpo->_attach(fEscaped);
00267
00268 if (pSync != NULL)
00269 {
00270
00271 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00272 if (m_nMutability >= CONST)
00273 {
00274 coh_throw_illegal_state("attempt to set const MemberView");
00275 }
00276
00277 cpDetach = m_cpo;
00278 m_cpo = NULL == cpAttach ? NULL : cpo;
00279 }
00280 else if (fEscaped)
00281 {
00282
00283 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00284 if (m_nMutability >= CONST)
00285 {
00286 coh_throw_illegal_state("attempt to set const MemberView");
00287 }
00288
00289 cpDetach = m_cpo;
00290 m_cpo = NULL == cpAttach ? NULL : cpo;
00291 }
00292 else
00293 {
00294 if (m_nMutability >= CONST)
00295 {
00296 coh_throw_illegal_state("attempt to set const MemberView");
00297 }
00298
00299 cpDetach = m_cpo;
00300 m_cpo = NULL == cpAttach ? NULL : cpo;
00301 }
00302
00303 if (cpDetach)
00304 {
00305 cpDetach->_detach(fEscaped);
00306 }
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00318 {
00319 const Object& oGuardian = getGuardian();
00320
00321 if (pSync != NULL)
00322 {
00323
00324 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00325 return ValueView(m_cpo);
00326 }
00327 else if (m_nMutability == SAFE_CONST || !oGuardian._isEscaped())
00328 {
00329
00330 return ValueView(m_cpo);
00331 }
00332 else
00333 {
00334
00335 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00336 return ValueView(m_cpo);
00337 }
00338 }
00339
00340
00341
00342
00343 protected:
00344
00345
00346
00347 const T* m_cpo;
00348
00349
00350
00351
00352
00353
00354
00355 friend class SynchronizedMemberReadBlock;
00356
00357
00358
00359
00360 friend class SynchronizedMemberWriteBlock;
00361 };
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 template<class T> std::ostream& operator<<(std::ostream& out, const MemberView<T>& mv)
00376 {
00377 out << (typename T::View) mv;
00378 return out;
00379 }
00380
00381
00382
00383
00384
00385
00386 template<class T> void clear_handle(MemberView<T>& mv)
00387 {
00388 mv = NULL;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 template<class D, class T>
00403 D cast(const MemberView<T>& mv, bool fThrow = true)
00404 {
00405 return cast<D>((typename MemberView<T>::ValueView) mv, fThrow);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415 template<class D, class T>
00416 bool instanceof(const MemberView<T>& mv)
00417 {
00418 return NULL != cast<D>(mv, false);
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428 template<class T>
00429 bool is_null(const MemberView<T>& mv)
00430 {
00431 return mv == NULL;
00432 }
00433
00434 COH_CLOSE_NAMESPACE2
00435
00436 #endif // COH_MEMBER_VIEW_HPP