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/IllegalStateException.hpp"
00023 #include "coherence/lang/MemberHolder.hpp"
00024 #include "coherence/lang/SmartMember.hpp"
00025 #include "coherence/lang/SynchronizedMemberReadBlock.hpp"
00026 #include "coherence/lang/SynchronizedMemberWriteBlock.hpp"
00027 #include "coherence/lang/TypedHandle.hpp"
00028
00029 #include <ostream>
00030 #include <sstream>
00031
00032 COH_OPEN_NAMESPACE2(coherence,lang)
00033
00034 template<class> class MemberView;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 template<class T>
00058 class MemberHandle
00059 : public SmartMember
00060 {
00061
00062
00063 public:
00064
00065
00066
00067 typedef T ValueType;
00068
00069
00070
00071
00072 typedef typename T::Handle ValueHandle;
00073
00074
00075
00076
00077 typedef typename T::View ValueView;
00078
00079
00080
00081
00082 typedef ValueHandle GetType;
00083
00084
00085
00086
00087 typedef ValueView ConstGetType;
00088
00089
00090
00091
00092 typedef enum
00093 {
00094 UNFLIPPED = 0,
00095 FLIPPED = 1,
00096 MUTABLE = 2
00097 };
00098
00099
00100
00101
00102 public:
00103
00104
00105
00106
00107 MemberHandle(Object& oParent)
00108 : SmartMember(oParent), m_po(NULL), m_nFlipped(UNFLIPPED)
00109 {
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 template<class DH>
00121 MemberHandle(Object& oParent, const DH& h, bool fMutable = false)
00122 : SmartMember(oParent), m_po(NULL), m_nFlipped(fMutable ? MUTABLE : UNFLIPPED)
00123 {
00124 set(h);
00125 }
00126
00127
00128
00129
00130 ~MemberHandle()
00131 {
00132 T* po;
00133 int8_t nFlipped;
00134
00135 {
00136 SynchronizedMemberWriteBlock syncWrite(getParent());
00137 po = m_po;
00138 nFlipped = m_nFlipped;
00139 m_po = NULL;
00140 }
00141
00142 if (NULL != po)
00143 {
00144 try
00145 {
00146 if (nFlipped == FLIPPED)
00147 {
00148 ((const T*) po)->_detach();
00149 }
00150 else
00151 {
00152 po->_detach();
00153 }
00154 }
00155 catch (const std::exception& e)
00156 {
00157
00158 std::cerr << "Error during ~MemberHandle: " << e.what() << std::endl;
00159 return;
00160 }
00161 }
00162 }
00163
00164 private:
00165
00166
00167
00168 MemberHandle(const MemberHandle&);
00169
00170
00171
00172
00173 public:
00174
00175
00176
00177
00178
00179
00180
00181
00182 MemberHandle& operator=(MemberHandle& that)
00183 {
00184 operator=((ValueHandle) that);
00185 return *this;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 template<class DT> MemberHandle& operator=(const MemberHandle<DT>& mv)
00197 {
00198 operator=((TypedHandle<DT>) mv);
00199 return *this;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 template<class DT> MemberHandle& operator=(const TypedHolder<DT>& th)
00211 {
00212 set(cast<typename DT::Handle>(th));
00213 return *this;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 template<class DT> MemberHandle& operator=(const MemberHolder<DT>& mh)
00225 {
00226 set(cast<typename DT::Handle>(mh));
00227 return *this;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 template<class DT> MemberHandle& operator=(const TypedHandle<DT>& h)
00239 {
00240 set(h);
00241 return *this;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 MemberHandle& operator=(T* p)
00253 {
00254 return operator=((ValueHandle) p);
00255 }
00256
00257
00258
00259
00260
00261
00262 operator ValueView() const
00263 {
00264 return get();
00265 }
00266
00267
00268
00269
00270
00271
00272 operator ValueHandle()
00273 {
00274 return get();
00275 }
00276
00277
00278
00279
00280
00281
00282 template<class PT>
00283 operator TypedHandle<const PT>() const
00284 {
00285 return (ValueView) *this;
00286 }
00287
00288
00289
00290
00291
00292
00293 template<class PT>
00294 operator TypedHandle<PT>()
00295 {
00296 return (ValueHandle) *this;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 template<class PT>
00323 operator TypedHolder<PT>()
00324 {
00325 return (ValueHandle) *this;
00326 }
00327
00328
00329
00330
00331
00332
00333 ValueView operator->() const
00334 {
00335 return (ValueView) *this;
00336 }
00337
00338
00339
00340
00341
00342
00343 ValueHandle operator->()
00344 {
00345 return (ValueHandle) *this;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355 template<class AT>
00356 bool operator==(const MemberHandle<AT>& mv) const
00357 {
00358 typename MemberHandle<AT>::ValueView v = mv;
00359 return operator==(v);
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369 template<class AT>
00370 bool operator!=(const MemberHandle<AT>& mv) const
00371 {
00372 return !operator==(mv);
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382 template<class AT>
00383 bool operator==(const MemberHolder<AT>& mh) const
00384 {
00385 typename TypedHolder<AT>::ValueView v = mh;
00386 return operator==(v);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396 template<class AT>
00397 bool operator!=(const MemberHolder<AT>& mh) const
00398 {
00399 return !operator==(mh);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409 template<class AT>
00410 bool operator==(const MemberView<AT>& mv) const
00411 {
00412 typename MemberView<AT>::ValueView v = mv;
00413 return operator==(v);
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423 template<class AT>
00424 bool operator!=(const MemberView<AT>& mv) const
00425 {
00426 return !operator==(mv);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436 template<class AT>
00437 bool operator==(const TypedHolder<AT>& th) const
00438 {
00439 return operator==(get_pointer((typename TypedHolder<AT>::ValueView) th));
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 template<class AT>
00450 bool operator!=(const TypedHolder<AT>& th) const
00451 {
00452 return !operator==(th);
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 template<class AT>
00463 bool operator==(const TypedHandle<AT>& h) const
00464 {
00465 return operator==(get_pointer(h));
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475 template<class AT>
00476 bool operator!=(const TypedHandle<AT>& h) const
00477 {
00478 return !operator==(h);
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488 bool operator==(const Object* cpThat) const
00489 {
00490 SynchronizedMemberReadBlock syncRead(getParent());
00491 return ((const Object*) m_po) == cpThat;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501 bool operator!=(const Object* cpThat) const
00502 {
00503 return !operator==(cpThat);
00504 }
00505
00506 private:
00507
00508
00509
00510 MemberHandle<T>& operator=(const MemberHandle<T>&);
00511
00512
00513
00514
00515 protected:
00516
00517
00518
00519
00520
00521
00522
00523
00524 void set(const ValueHandle& h, SynchronizedMemberWriteBlock* pSync = NULL)
00525 {
00526 T* po = get_pointer(h);
00527 Object* pAttach = po == NULL ? NULL : po->_attach();
00528 T* pDetach = NULL;
00529
00530
00531 {
00532 SynchronizedMemberWriteBlock syncWrite(getParent(), pSync);
00533 COH_ENSURE(m_nFlipped != FLIPPED);
00534 pDetach = m_po;
00535 m_po = NULL == pAttach ? NULL : po;
00536 }
00537
00538 if (pDetach)
00539 {
00540 pDetach->_detach();
00541 }
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00553 {
00554 SynchronizedMemberReadBlock syncRead(getParent(), pSync);
00555 return (const T*) m_po;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 ValueHandle get(SynchronizedMemberReadBlock* pSync = NULL)
00567 {
00568 SynchronizedMemberReadBlock syncRead(getParent(), pSync);
00569 if (m_nFlipped != FLIPPED)
00570 {
00571 return m_po;
00572 }
00573
00574 COH_THROW (IllegalStateException::
00575 create("attempt to access handle from flipped MemberHandle"));
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 void flipHandle()
00585 {
00586 T* po = NULL;
00587 int8_t nFlipped;
00588
00589 {
00590 SynchronizedMemberWriteBlock syncWrite(getParent());
00591 nFlipped = m_nFlipped;
00592
00593 switch (nFlipped)
00594 {
00595 case UNFLIPPED:
00596 po = m_po;
00597 m_nFlipped = FLIPPED;
00598 break;
00599
00600 case FLIPPED:
00601
00602 break;
00603
00604 case MUTABLE:
00605 default:
00606 COH_THROW (IllegalStateException::create("unflippable MemberHandle"));
00607 }
00608 }
00609
00610
00611 if (NULL != po)
00612 {
00613 ((const T*) po)->_attach();
00614 po->_detach();
00615 }
00616 }
00617
00618
00619
00620
00621 protected:
00622
00623
00624
00625
00626
00627
00628
00629 virtual void onConst()
00630 {
00631 if (m_nFlipped == UNFLIPPED)
00632 {
00633 flipHandle();
00634 }
00635 SmartMember::onConst();
00636 }
00637
00638
00639
00640
00641 private:
00642
00643
00644
00645 T* m_po;
00646
00647
00648
00649
00650 int8_t m_nFlipped;
00651
00652
00653
00654
00655
00656
00657
00658 template<class D, class H> friend D cast(MemberHandle<T>& mh, bool fTest);
00659
00660
00661
00662
00663 friend class SynchronizedMemberReadBlock;
00664
00665
00666
00667
00668 friend class SynchronizedMemberWriteBlock;
00669 };
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 template<class T> std::ostream& operator<<(std::ostream& out, const MemberHandle<T>& th)
00684 {
00685 out << (typename T::View) th;
00686 return out;
00687 }
00688
00689
00690
00691
00692
00693
00694 template<class T> void clear_handle(MemberHandle<T>& mh)
00695 {
00696 mh = typename MemberHandle<T>::ValueHandle(NULL);
00697 }
00698
00699
00700
00701
00702
00703
00704
00705
00706 template<class T>
00707 bool is_null(const MemberHandle<T>& mh)
00708 {
00709 static TypedHandle<const T> vNull;
00710 return mh == vNull;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 template<class D, class T>
00725 D cast(MemberHandle<T>& mh, bool fThrow = true)
00726 {
00727 return cast<D>((typename MemberHandle<T>::ValueHandle) mh, fThrow);
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741 template<class D, class T>
00742 D cast(const MemberHandle<T>& mh, bool fThrow = true)
00743 {
00744 return cast<D>((typename MemberHandle<T>::ValueView) mh, fThrow);
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754 template<class D, class T>
00755 bool instanceof(MemberHandle<T>& mh)
00756 {
00757 return NULL != cast<D>(mh, false);
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767 template<class D, class T>
00768 bool instanceof(const MemberHandle<T>& mh)
00769 {
00770 return NULL != cast<D>(mh, false);
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 template<class AT, class T>
00782 bool operator==(const TypedHandle<AT>& h, const MemberHandle<T>& mh)
00783 {
00784 return mh == h;
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 template<class T>
00796 bool operator==(const Object* cpo, const MemberHandle<T>& mh)
00797 {
00798 return mh == cpo;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 template<class AT, class T>
00810 bool operator!=(const TypedHandle<AT>& h, const MemberHandle<T>& mh)
00811 {
00812 return mh != h;
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 template<class T>
00824 bool operator!=(const Object* cpo, const MemberHandle<T>& mh)
00825 {
00826 return mh != cpo;
00827 }
00828
00829 COH_CLOSE_NAMESPACE2
00830
00831 #endif // COH_MEMBER_HANDLE_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.