00001
00025
00026
00027
00028
00029 #ifndef __ETL__HANDLE_H
00030 #define __ETL__HANDLE_H
00031
00032
00033
00034 #include <cassert>
00035
00036
00037
00038
00039
00040 #define ETL_SELF_DELETING_SHARED_OBJECT
00041
00042
00043
00044 #ifdef NDEBUG
00045 #define assert_cast static_cast
00046 #else
00047 #define assert_cast dynamic_cast
00048 #endif
00049
00050
00051 _ETL_BEGIN_NAMESPACE
00052
00053
00054 template <class T> class handle;
00055 template <class T> class loose_handle;
00056 template <class T> class rhandle;
00057
00058
00059
00065 class shared_object
00066 {
00067 private:
00068 mutable int refcount;
00069
00070 protected:
00071 shared_object():refcount(0) { }
00072
00073 #ifdef ETL_SELF_DELETING_SHARED_OBJECT
00074 virtual ~shared_object() { }
00075 #else
00076 ~shared_object() { }
00077 #endif
00078
00079 public:
00080 void ref()const
00081 { assert(refcount>=0); refcount++; }
00082
00084 bool unref()const
00085 {
00086 assert(refcount>0);
00087
00088 refcount--;
00089
00090 if(refcount==0) {
00091 #ifdef ETL_SELF_DELETING_SHARED_OBJECT
00092 refcount=-666;
00093 delete this;
00094 #endif
00095 return false;
00096 }
00097
00098 return true;
00099 }
00100
00101 int count()const
00102 { return refcount; }
00103 };
00104
00105
00111 class virtual_shared_object
00112 {
00113 protected:
00114 virtual_shared_object() { }
00115 public:
00116 virtual ~virtual_shared_object()=0;
00117 virtual void ref()const=0;
00118 virtual bool unref()const=0;
00119 virtual int count()const=0;
00120 virtual virtual_shared_object *clone()=0;
00121 };
00122
00123
00129 template <class T>
00130 class handle
00131 {
00132 public:
00133
00134 typedef T value_type;
00135 typedef T& reference;
00136 typedef const T& const_reference;
00137 typedef T* pointer;
00138 typedef const T* const_pointer;
00139 typedef int count_type;
00140 typedef int size_type;
00141
00142 protected:
00143 value_type *obj;
00144
00145 public:
00146
00148 handle():obj(NULL) {}
00149
00151 handle(pointer x):obj(x)
00152 {
00153 if(obj)
00154 obj->ref();
00155 }
00156
00158 handle(const handle<value_type> &x):obj(x.get())
00159 {
00160 if(obj)
00161 obj->ref();
00162 }
00163
00165 ~handle() { detach(); }
00166
00168
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00187 handle<value_type> &
00188 operator=(const handle<value_type> &x)
00189 {
00190 if(x.get()==obj)
00191 return *this;
00192
00193 detach();
00194
00195 obj=x.get();
00196 if(obj)obj->ref();
00197 return *this;
00198 }
00199
00201 handle<value_type> &
00202 swap(handle<value_type> &x)
00203 {
00204 pointer ptr=x.obj;
00205 x.obj=x.get();
00206 obj=ptr;
00207 return *this;
00208 }
00209
00211
00212 void
00213 detach()
00214 {
00215 pointer xobj(obj);
00216 obj=0;
00217 #ifdef ETL_SELF_DELETING_SHARED_OBJECT
00218 if(xobj)
00219 xobj->unref();
00220 #else
00221 if(xobj && !xobj->unref())
00222 delete xobj;
00223 #endif
00224 }
00225
00226
00227
00228
00229 void reset() { detach(); }
00230
00231 bool empty()const { return obj==0; }
00232
00234
00235 void spawn() { operator=(handle(new T())); }
00236
00237 handle<value_type> clone()const { assert(obj); return static_cast<value_type*>(obj->clone()); }
00238
00240 handle<const value_type> constant()const { assert(obj); return *this; }
00241
00243 count_type
00244 count()const
00245 { return obj?obj->count():0; }
00246
00248 bool
00249 unique()const
00250 { assert(obj); return count()==1; }
00251
00252 reference
00253 operator*()const
00254 { assert(obj); return *obj; }
00255
00256 pointer
00257 operator->()const
00258 { assert(obj); return obj; }
00259
00261 operator bool()const
00262 { return obj!=NULL; }
00263
00264 operator handle<const value_type>()const
00265 { return handle<const value_type>(static_cast<const_pointer>(obj)); }
00266
00267
00269 template <class U> static
00270 handle<T> cast_static(const handle<U> &x)
00271 { return handle<T>(static_cast<T*>(x.get())); }
00272
00274 template <class U> static
00275 handle<T> cast_dynamic(const handle<U> &x)
00276 { return handle<T>(dynamic_cast<T*>(x.get())); }
00277
00279 template <class U> static
00280 handle<T> cast_const(const handle<U> &x)
00281 { return handle<T>(const_cast<T*>(x.get())); }
00282
00284 template <class U> static
00285 handle<T> cast_reinterpret(const handle<U> &x)
00286 { return handle<T>(reinterpret_cast<T*>(x.get())); }
00287
00288 template<class U> static handle<T> cast_static(const loose_handle<U> &x);
00289 template<class U> static handle<T> cast_dynamic(const loose_handle<U> &x);
00290 template<class U> static handle<T> cast_const(const loose_handle<U> &x);
00291 template<class U> static handle<T> cast_reinterpret(const loose_handle<U> &x);
00292
00293 template<class U> static handle<T> cast_static(const rhandle<U> &x);
00294 template<class U> static handle<T> cast_dynamic(const rhandle<U> &x);
00295 template<class U> static handle<T> cast_const(const rhandle<U> &x);
00296 template<class U> static handle<T> cast_reinterpret(const rhandle<U> &x);
00297
00298 template<class U> static handle<T> cast_static(U* x);
00299 template<class U> static handle<T> cast_dynamic(U* x);
00300 template<class U> static handle<T> cast_const(U* x);
00301 template<class U> static handle<T> cast_reinterpret(U* x);
00302
00304 pointer get()const { return obj; }
00305
00306 bool
00307 operator!()const
00308 { return !obj; }
00309
00311 template <class U>
00312 operator handle<U>()const
00313 { return handle<U>(static_cast<U*>(obj)); }
00314 };
00315
00316
00322 class rshared_object : public shared_object
00323 {
00324 private:
00325 mutable int rrefcount;
00326
00327 public:
00328 void *front_;
00329 void *back_;
00330
00331 protected:
00332 rshared_object():rrefcount(0),front_(0),back_(0) { }
00333
00334 public:
00335 void rref()const
00336 { rrefcount++; }
00337
00338 void runref()const
00339 {
00340 assert(rrefcount>0);
00341 rrefcount--;
00342 }
00343
00344 int rcount()const
00345 { return rrefcount; }
00346 };
00347
00348
00354 template <class T>
00355 class rhandle : public handle<T>
00356 {
00357 friend class rshared_object;
00358 public:
00359
00360 typedef T value_type;
00361 typedef T& reference;
00362 typedef const T& const_reference;
00363 typedef T* pointer;
00364 typedef const T* const_pointer;
00365 typedef int count_type;
00366 typedef int size_type;
00367
00368
00369 using handle<value_type>::count;
00370 using handle<value_type>::unique;
00371 using handle<value_type>::operator bool;
00372 using handle<value_type>::get;
00373 using handle<value_type>::operator *;
00374 using handle<value_type>::operator ->;
00375
00376
00377
00378
00379
00380
00381 private:
00382 using handle<value_type>::obj;
00383
00384 rhandle<value_type> *prev_;
00385 rhandle<value_type> *next_;
00386
00387 void add_to_rlist()
00388 {
00389
00390
00391 assert(obj);
00392 obj->rref();
00393
00394
00395 if(!obj->front_)
00396 {
00397 obj->front_=obj->back_=this;
00398 prev_=next_=0;
00399 return;
00400 }
00401
00402 prev_=reinterpret_cast<rhandle<value_type>*>(obj->back_);
00403 next_=0;
00404 prev_->next_=this;
00405 obj->back_=this;
00406 }
00407
00408 void del_from_rlist()
00409 {
00410
00411 assert(obj);
00412 obj->runref();
00413
00414
00415 if(obj->front_==obj->back_)
00416 {
00417 obj->front_=obj->back_=0;
00418 prev_=next_=0;
00419 return;
00420 }
00421
00422 if(!prev_)
00423 obj->front_=(void*)next_;
00424 else
00425 prev_->next_=next_;
00426
00427 if(!next_)
00428 obj->back_=(void*)prev_;
00429 else
00430 next_->prev_=prev_;
00431 }
00432
00433 public:
00434
00436 rhandle() {}
00437
00439 rhandle(pointer x):handle<T>(x)
00440 {
00441
00442 if(obj)add_to_rlist();
00443 }
00444
00445 rhandle(const handle<value_type> &x):handle<T>(x)
00446 {
00447
00448 if(obj)add_to_rlist();
00449 }
00450
00452 rhandle(const rhandle<value_type> &x):handle<T>(x)
00453 {
00454
00455 if(obj)add_to_rlist();
00456 }
00457
00459 ~rhandle() { detach(); }
00460
00462
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00485 rhandle<value_type> &
00486 operator=(const rhandle<value_type> &x)
00487 {
00488
00489 if(x.get()==obj)
00490 return *this;
00491
00492 detach();
00493
00494 obj=x.get();
00495 if(obj)
00496 {
00497 obj->ref();
00498 add_to_rlist();
00499 }
00500 return *this;
00501 }
00502
00503 rhandle<value_type>&
00504 operator=(const handle<value_type> &x)
00505 {
00506
00507 if(x.get()==obj)
00508 return *this;
00509
00510 detach();
00511
00512 obj=x.get();
00513 if(obj)
00514 {
00515 obj->ref();
00516 add_to_rlist();
00517 }
00518 return *this;
00519 }
00520
00521 rhandle<value_type>&
00522 operator=(value_type* x)
00523 {
00524
00525 if(x==obj)
00526 return *this;
00527
00528 detach();
00529
00530 obj=x;
00531 if(obj)
00532 {
00533 obj->ref();
00534 add_to_rlist();
00535 }
00536 return *this;
00537 }
00538
00540
00541 void
00542 detach()
00543 {
00544
00545 if(obj)del_from_rlist();
00546 handle<value_type>::detach();
00547 obj=0;
00548 }
00549
00550
00551
00552
00553 void reset() { detach(); }
00554
00556
00557 void spawn() { operator=(handle<value_type>(new T())); }
00558
00560 count_type
00561 rcount()const
00562 {
00563
00564 return obj?obj->rcount():0;
00565 }
00566
00568 bool
00569 runique()const
00570 {
00571
00572 assert(obj); return obj->front_==obj->back_;
00573 }
00574
00576 int replace(const handle<value_type> &x)
00577 {
00578
00579 assert(obj);
00580 assert(x.get()!=obj);
00581
00582 if(x.get()==obj)
00583 return 0;
00584
00585 rhandle<value_type> *iter;
00586 rhandle<value_type> *next;
00587
00588 iter=reinterpret_cast<rhandle<value_type>*>(obj->front_);
00589
00590 assert(iter);
00591
00592 next=iter->next_;
00593
00594 int i=0;
00595 #ifndef NDEBUG
00596 pointer obj_=obj;
00597 #endif
00598
00599 for(;iter;iter=next,next=iter?iter->next_:0,i++)
00600 {
00601 assert(iter->get()==obj_);
00602 (*iter)=x;
00603 }
00604
00605 assert(obj==x.get());
00606
00607 return i;
00608 }
00609
00611
00612 handle<value_type> &
00613 swap(handle<value_type> &x);
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 };
00624
00625
00626
00627
00628
00629
00630
00631
00637 template <class T>
00638 class loose_handle
00639 {
00640 public:
00641
00642 typedef T value_type;
00643 typedef T& reference;
00644 typedef const T& const_reference;
00645 typedef T* pointer;
00646 typedef const T* const_pointer;
00647 typedef int count_type;
00648 typedef int size_type;
00649
00650 protected:
00651 value_type *obj;
00652
00653 public:
00654
00656 loose_handle():obj(0) {}
00657
00659 loose_handle(pointer x):obj(x) { }
00660
00662 loose_handle(const loose_handle<value_type> &x):obj(x.get()) { }
00663
00664 loose_handle(const handle<value_type> &x):obj(x.get()) { }
00665
00666 template <class U> const loose_handle<value_type> &
00667 operator=(const handle<U> &x)
00668 {
00669 if(x.get()==obj)
00670 return *this;
00671
00672 obj=static_cast<value_type*>(x.get());
00673 return *this;
00674 }
00675
00676 template <class U> const loose_handle<value_type> &
00677 operator=(const loose_handle<U> &x)
00678 {
00679 if(x.get()==obj)
00680 return *this;
00681
00682 obj=static_cast<value_type*>(x.get());
00683 return *this;
00684 }
00685
00687 const loose_handle<value_type> &
00688 operator=(const loose_handle<value_type> &x)
00689 {
00690 if(x.get()==obj)
00691 return *this;
00692
00693 obj=x.get();
00694 return *this;
00695 }
00696
00698 loose_handle<value_type> &
00699 swap(loose_handle<value_type> &x)
00700 {
00701 pointer ptr=x.obj;
00702 x.obj=x.get();
00703 obj=ptr;
00704 return *this;
00705 }
00706
00708 void detach() { obj=0; }
00709
00710
00711
00712
00713 void reset() { detach(); }
00714
00715 bool empty()const { return obj==0; }
00716
00717 handle<value_type> clone()const { assert(obj); return obj->clone(); }
00718
00720 loose_handle<const value_type> constant()const { return *this; }
00721
00723 count_type
00724 count()const
00725 { return obj?obj->count():0; }
00726
00727 reference
00728 operator*()const
00729 { assert(obj); return *obj; }
00730
00731 pointer
00732 operator->()const
00733 { assert(obj); return obj; }
00734
00736
00737
00738
00739
00741 operator loose_handle<const value_type>()const
00742 { return loose_handle<const value_type>(static_cast<const_pointer>(obj)); }
00743
00744 operator handle<value_type>()const
00745 { return handle<value_type>(obj); }
00746
00747 operator rhandle<value_type>()const
00748 { return rhandle<value_type>(obj); }
00749
00751 pointer get()const { return obj; }
00752
00754 operator bool()const
00755 { return obj!=0; }
00756
00757 bool
00758 operator!()const
00759 { return !obj; }
00760
00761 void ref() { if(obj)obj->ref(); }
00762
00763 bool unref() { if(obj && !obj->unref()){ obj=0; return false; } return true; }
00764 };
00765
00766
00767
00768
00769 template<class T> template<class U> handle<T>
00770 handle<T>::cast_static(const loose_handle<U> &x)
00771 { return handle<T>(static_cast<T*>(x.get())); }
00772
00773 template <class T> template <class U> handle<T>
00774 handle<T>::cast_dynamic(const loose_handle<U> &x)
00775 { return handle<T>(dynamic_cast<T*>(x.get())); }
00776
00777 template <class T> template <class U> handle<T>
00778 handle<T>::cast_const(const loose_handle<U> &x)
00779 { return handle<T>(const_cast<T*>(x.get())); }
00780
00781 template <class T> template <class U> handle<T>
00782 handle<T>::cast_reinterpret(const loose_handle<U> &x)
00783 { return handle<T>(reinterpret_cast<T*>(x.get())); }
00784
00785
00786
00787 template <class T> template <class U> handle<T>
00788 handle<T>::cast_static(const rhandle<U> &x)
00789 { return handle<T>(static_cast<T*>(x.get())); }
00790
00791 template <class T> template <class U> handle<T>
00792 handle<T>::cast_dynamic(const rhandle<U> &x)
00793 { return handle<T>(dynamic_cast<T*>(x.get())); }
00794
00795 template <class T> template <class U> handle<T>
00796 handle<T>::cast_const(const rhandle<U> &x)
00797 { return handle<T>(const_cast<T*>(x.get())); }
00798
00799 template <class T> template <class U> handle<T>
00800 handle<T>::cast_reinterpret(const rhandle<U> &x)
00801 { return handle<T>(reinterpret_cast<T*>(x.get())); }
00802
00803
00804
00805 template <class T> template <class U> handle<T>
00806 handle<T>::cast_static(U* x)
00807 { return handle<T>(static_cast<T*>(x)); }
00808
00809 template <class T> template <class U> handle<T>
00810 handle<T>::cast_dynamic(U* x)
00811 { return handle<T>(dynamic_cast<T*>(x)); }
00812
00813 template <class T> template <class U> handle<T>
00814 handle<T>::cast_const(U* x)
00815 { return handle<T>(const_cast<T*>(x)); }
00816
00817 template <class T> template <class U> handle<T>
00818 handle<T>::cast_reinterpret(U* x)
00819 { return handle<T>(reinterpret_cast<T*>(x)); }
00820
00821
00822
00823
00824
00825 template <class T,class U> bool
00826 operator==(const handle<T> &lhs,const handle<U> &rhs)
00827 { return (lhs.get()==rhs.get()); }
00828 template <class T,class U> bool
00829 operator==(const loose_handle<T> &lhs,const loose_handle<U> &rhs)
00830 { return (lhs.get()==rhs.get()); }
00831 template <class T,class U> bool
00832 operator==(const handle<T> &lhs,const loose_handle<U> &rhs)
00833 { return (lhs.get()==rhs.get()); }
00834 template <class T,class U> bool
00835 operator==(const loose_handle<T> &lhs,const handle<U> &rhs)
00836 { return (lhs.get()==rhs.get()); }
00837 template <class T> bool
00838 operator==(const handle<T> &lhs,const T *rhs)
00839 { return (lhs.get()==rhs); }
00840 template <class T> bool
00841 operator==(const loose_handle<T> &lhs,const T *rhs)
00842 { return (lhs.get()==rhs); }
00843 template <class T> bool
00844 operator==(const T *lhs,const handle<T> &rhs)
00845 { return (lhs==rhs.get()); }
00846 template <class T> bool
00847 operator==(const T *lhs,const loose_handle<T> &rhs)
00848 { return (lhs==rhs.get()); }
00849
00850
00851 template <class T,class U> bool
00852 operator!=(const handle<T> &lhs,const handle<U> &rhs)
00853 { return (lhs.get()!=rhs.get()); }
00854 template <class T,class U> bool
00855 operator!=(const loose_handle<T> &lhs,const loose_handle<U> &rhs)
00856 { return (lhs.get()!=rhs.get()); }
00857 template <class T,class U> bool
00858 operator!=(const handle<T> &lhs,const loose_handle<U> &rhs)
00859 { return (lhs.get()!=rhs.get()); }
00860 template <class T,class U> bool
00861 operator!=(const loose_handle<T> &lhs,const handle<U> &rhs)
00862 { return (lhs.get()!=rhs.get()); }
00863 template <class T> bool
00864 operator!=(const handle<T> &lhs,const T *rhs)
00865 { return (lhs.get()!=rhs); }
00866 template <class T> bool
00867 operator!=(const loose_handle<T> &lhs,const T *rhs)
00868 { return (lhs.get()!=rhs); }
00869 template <class T> bool
00870 operator!=(const T *lhs,const handle<T> &rhs)
00871 { return (lhs!=rhs.get()); }
00872 template <class T> bool
00873 operator!=(const T *lhs,const loose_handle<T> &rhs)
00874 { return (lhs!=rhs.get()); }
00875
00876
00877 template <class T,class U> bool
00878 operator<(const handle<T> &lhs,const handle<U> &rhs)
00879 { return (lhs.get()<rhs.get()); }
00880 template <class T,class U> bool
00881 operator<(const loose_handle<T> &lhs,const loose_handle<U> &rhs)
00882 { return (lhs.get()<rhs.get()); }
00883 template <class T,class U> bool
00884 operator<(const handle<T> &lhs,const loose_handle<U> &rhs)
00885 { return (lhs.get()<rhs.get()); }
00886 template <class T,class U> bool
00887 operator<(const loose_handle<T> &lhs,const handle<U> &rhs)
00888 { return (lhs.get()<rhs.get()); }
00889 template <class T> bool
00890 operator<(const handle<T> &lhs,const T *rhs)
00891 { return (lhs.get()<rhs); }
00892 template <class T> bool
00893 operator<(const loose_handle<T> &lhs,const T *rhs)
00894 { return (lhs.get()<rhs); }
00895 template <class T> bool
00896 operator<(const T *lhs,const handle<T> &rhs)
00897 { return (lhs<rhs.get()); }
00898 template <class T> bool
00899 operator<(const T *lhs,const loose_handle<T> &rhs)
00900 { return (lhs<rhs.get()); }
00901
00902 _ETL_END_NAMESPACE
00903
00904
00905
00906 #endif