nux-0.9.46
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #ifndef WIDGETSMARTPOINTER_H 00024 #define WIDGETSMARTPOINTER_H 00025 00026 namespace nux 00027 { 00028 00029 struct RefCounts 00030 { 00031 RefCounts () : totalRefs_ (1), strongRefs_ (1) 00032 { 00033 } 00034 00035 NThreadSafeCounter totalRefs_; 00036 NThreadSafeCounter strongRefs_; 00037 }; 00038 00039 enum Null 00040 { 00041 null = 0 00042 }; 00043 00045 // forward definitions 00046 00047 template <typename T> 00048 class GenericWeakSP; 00049 00050 template <typename T> 00051 class GenericSP; 00052 00054 template <typename T> 00055 class GenericSP 00056 { 00057 public: 00059 GenericSP() 00060 : ptr_ (0) 00061 , refCounts_ (0) 00062 , deletewhenrefcounthitzero_ (true) 00063 { 00064 } 00065 00067 GenericSP (const GenericSP<T>& other) 00068 : ptr_ (0) 00069 , refCounts_ (0) 00070 , deletewhenrefcounthitzero_ (true) 00071 { 00072 ptr_ = other.ptr_; 00073 refCounts_ = other.refCounts_; 00074 deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_; 00075 00076 if (ptr_ != 0) 00077 { 00078 refCounts_->strongRefs_.Increment(); 00079 refCounts_->totalRefs_.Increment(); 00080 } 00081 } 00082 00084 00087 template <typename O> 00088 GenericSP (const GenericSP<O>& other) 00089 : ptr_ (0) 00090 , refCounts_ (0) 00091 , deletewhenrefcounthitzero_ (true) 00092 { 00093 if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) 00094 { 00095 ptr_ = (T *) other.ptr_; 00096 refCounts_ = other.refCounts_; 00097 deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_; 00098 } 00099 00100 if (ptr_ != 0) 00101 { 00102 refCounts_->strongRefs_.Increment(); 00103 refCounts_->totalRefs_.Increment(); 00104 } 00105 } 00106 00108 00112 explicit GenericSP (T *ptr, bool deletewhenrefcounthitzero = true) 00113 : ptr_ (0) 00114 , refCounts_ (0) 00115 , deletewhenrefcounthitzero_ (true) 00116 { 00117 if (ptr != 0) 00118 { 00119 ptr_ = ptr; 00120 refCounts_ = new RefCounts; 00121 deletewhenrefcounthitzero_ = deletewhenrefcounthitzero;; 00122 } 00123 } 00124 00126 00130 template <typename O> 00131 explicit GenericSP (O *ptr, bool deletewhenrefcounthitzero = true) 00132 : ptr_ (0) 00133 , refCounts_ (0) 00134 , deletewhenrefcounthitzero_ (true) 00135 { 00136 if (ptr != 0) 00137 { 00138 if (ptr->Type().IsDerivedFromType (T::StaticObjectType) ) 00139 { 00140 ptr_ = (T *) ptr; 00141 refCounts_ = new RefCounts; 00142 deletewhenrefcounthitzero_ = deletewhenrefcounthitzero; 00143 } 00144 else 00145 { 00146 // This is possible but check why! 00147 // It can happen when doing something like this: 00148 // Layout* layout = this; 00149 // where this is a Baseobject. 00150 nuxAssert (0); 00151 } 00152 } 00153 } 00154 00156 00159 GenericSP &operator = (const GenericSP<T>& other) 00160 { 00161 if (ptr_ != other.ptr_) 00162 { 00163 ReleaseReference (); 00164 00165 ptr_ = other.ptr_; 00166 refCounts_ = other.refCounts_; 00167 deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_; 00168 00169 if (ptr_ != 0) 00170 { 00171 refCounts_->strongRefs_.Increment(); 00172 refCounts_->totalRefs_.Increment(); 00173 } 00174 } 00175 00176 return *this; 00177 } 00178 00180 00183 template <typename O> 00184 GenericSP &operator = (const GenericSP<O>& other) 00185 { 00186 if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) 00187 { 00188 if (ptr_ != other.ptr_) 00189 { 00190 ReleaseReference (); 00191 00192 ptr_ = other.ptr_; 00193 refCounts_ = other.refCounts_; 00194 deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_; 00195 00196 if (ptr_ != 0) 00197 { 00198 refCounts_->strongRefs_.Increment(); 00199 refCounts_->totalRefs_.Increment(); 00200 } 00201 } 00202 } 00203 else 00204 { 00205 ReleaseReference (); 00206 } 00207 00208 return *this; 00209 } 00210 00211 ~GenericSP () 00212 { 00213 ReleaseReference (); 00214 } 00215 00216 T &operator * () const 00217 { 00218 nuxAssert (ptr_ != 0); 00219 return *ptr_; 00220 } 00221 00222 T *operator -> () const 00223 { 00224 nuxAssert (ptr_ != 0); 00225 return ptr_; 00226 } 00227 00229 00232 void Swap (GenericSP<T>& other) 00233 { 00234 std::swap (ptr_, other.ptr_); 00235 std::swap (refCounts_, other.refCounts_); 00236 } 00237 00239 00242 bool operator () () const 00243 { 00244 return ptr_ != 0; 00245 } 00246 00248 00251 bool IsNull() const 00252 { 00253 if (ptr_ == 0) 00254 return true; 00255 00256 return false; 00257 } 00258 00260 00263 bool IsValid() const 00264 { 00265 if (ptr_ != 0) 00266 return true; 00267 00268 return false; 00269 } 00270 00271 bool operator < (T *ptr) const 00272 { 00273 return (ptr_ < ptr); 00274 } 00275 00276 bool operator > (T *ptr) const 00277 { 00278 return (ptr_ > ptr); 00279 } 00280 00281 bool operator < (GenericSP<T> other) const 00282 { 00283 return (ptr_ < other.ptr_); 00284 } 00285 00286 bool operator > (GenericSP<T> other) const 00287 { 00288 return (ptr_ > other.ptr_); 00289 } 00290 00291 bool operator != (T *ptr) const 00292 { 00293 return (ptr_ != ptr); 00294 } 00295 00296 bool operator == (T *ptr) const 00297 { 00298 return (ptr_ == ptr); 00299 } 00300 00301 template<typename U> 00302 bool operator != (U *ptr) const 00303 { 00304 if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00305 return false; 00306 00307 return (ptr_ != ptr); 00308 } 00309 00310 template<typename U> 00311 bool operator == (U *ptr) const 00312 { 00313 if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00314 return false; 00315 00316 return (ptr_ == ptr); 00317 } 00318 00319 template<typename U> 00320 bool operator != (const GenericSP<U>& other) const 00321 { 00322 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00323 return false; 00324 00325 return ptr_ != other.ptr_; 00326 } 00327 00328 template<typename U> 00329 bool operator == (const GenericSP<U>& other) const 00330 { 00331 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00332 return false; 00333 00334 return ptr_ == other.ptr_; 00335 } 00336 00337 template<typename U> 00338 bool operator != (const GenericWeakSP<U>& other) const 00339 { 00340 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00341 return false; 00342 00343 return ptr_ != other.ptr_; 00344 } 00345 00346 template<typename U> 00347 bool operator == (const GenericWeakSP<U>& other) const 00348 { 00349 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00350 return false; 00351 00352 return ptr_ == other.ptr_; 00353 } 00354 00355 void Release() 00356 { 00357 ReleaseReference(); 00358 } 00359 00360 private: 00361 GenericSP (T *ptr, RefCounts *refCounts) : ptr_ (ptr), refCounts_ (refCounts) 00362 { 00363 } 00364 00365 void ReleaseReference() 00366 { 00367 if (ptr_ == 0) 00368 { 00369 return; 00370 } 00371 00372 { 00373 refCounts_->strongRefs_.Decrement(); 00374 bool release = refCounts_->strongRefs_ == 0; 00375 00376 if (release && deletewhenrefcounthitzero_) 00377 { 00378 delete ptr_; 00379 } 00380 00381 ptr_ = 0; 00382 } 00383 00384 { 00385 refCounts_->totalRefs_.Decrement(); 00386 bool release = refCounts_->totalRefs_ == 0; 00387 00388 if (release) 00389 { 00390 delete refCounts_; 00391 } 00392 00393 refCounts_ = 0; 00394 } 00395 } 00396 00397 T *ptr_; 00398 RefCounts *refCounts_; 00399 bool deletewhenrefcounthitzero_; 00400 00401 template <typename U> 00402 friend GenericSP<U> Create (); 00403 00404 template <typename U, typename P1> 00405 friend GenericSP<U> Create (P1 p1); 00406 00407 template <typename U, typename P1, typename P2> 00408 friend GenericSP<U> Create (P1 p1, P2 p2); 00409 00410 template <typename U, typename P1, typename P2, typename P3> 00411 friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3); 00412 00413 template <typename U, typename P1, typename P2, typename P3, typename P4> 00414 friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4); 00415 00416 template <typename U, typename P1, typename P2, typename P3, typename P4, typename P5> 00417 friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5); 00418 00419 template <typename U, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> 00420 friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6); 00421 00422 template <typename U, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> 00423 friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7); 00424 00425 template <typename U> 00426 friend GenericSP<U> WrapWSPtr (U *u); 00427 00428 template <typename O> 00429 friend class GenericSP; 00430 00431 template <typename O> 00432 friend class GenericWeakSP; 00433 00434 // template<typename T, typename U> 00435 // friend bool operator == (const GenericSP<T>& a, const GenericSP<U>& b); 00436 00437 // template<typename T, typename U> 00438 // friend bool operator != (const GenericSP<T>& a, const GenericSP<U>& b); 00439 00440 // template<typename T> 00441 // friend bool operator == (const GenericSP<T>& a, T*); 00442 00443 template<typename U> 00444 friend bool operator == (U *, const GenericSP<U>& a); 00445 00446 // template<typename T> 00447 // friend bool operator != (const GenericSP<T>& a, T*); 00448 00449 template<typename U> 00450 friend bool operator != (U *, const GenericSP<U>& a); 00451 00452 // template<typename T, typename U> 00453 // friend bool operator == (const GenericSP<T>& a, const GenericWeakSP<U>& b); 00454 00455 // template<typename T, typename U> 00456 // friend bool operator == (const GenericWeakSP<T>& a, const GenericSP<U>& b); 00457 // 00458 // template<typename T, typename U> 00459 // friend bool operator != (const GenericSP<T>& a, const GenericWeakSP<U>& b); 00460 // 00461 // template<typename T, typename U> 00462 // friend bool operator != (const GenericWeakSP<T>& a, const GenericSP<U>& b); 00463 00464 template <typename U, typename F> 00465 friend GenericSP<U> staticCast (const GenericSP<F>& from); 00466 00467 template <typename U, typename F> 00468 friend GenericSP<U> constCast (const GenericSP<F>& from); 00469 00470 template <typename U, typename F> 00471 friend GenericSP<U> dynamicCast (const GenericSP<F>& from); 00472 00473 template <typename U, typename F> 00474 friend GenericSP<U> checkedCast (const GenericSP<F>& from); 00475 00476 template <typename U, typename F> 00477 friend GenericSP<U> queryCast (const GenericSP<F>& from); 00478 }; 00479 00480 00482 00487 template <typename T> 00488 class GenericWeakSP 00489 { 00490 public: 00492 GenericWeakSP () : ptr_ (0), refCounts_ (0) 00493 { 00494 } 00495 00497 00500 GenericWeakSP (const GenericWeakSP<T>& other) 00501 { 00502 ptr_ = other.ptr_; 00503 refCounts_ = other.refCounts_; 00504 00505 if (ptr_ != 0) 00506 { 00507 refCounts_->totalRefs_.Increment(); 00508 } 00509 } 00510 00512 00515 template <typename O> 00516 GenericWeakSP (const GenericWeakSP<O>& other) 00517 : ptr_ (0) 00518 , refCounts_ (0) 00519 { 00520 if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) 00521 { 00522 ptr_ = other.ptr_; 00523 refCounts_ = other.refCounts_; 00524 00525 if (ptr_ != 0) 00526 { 00527 refCounts_->totalRefs_.Increment(); 00528 } 00529 } 00530 } 00531 00532 // //! Construction from a smart pointer of type T. 00533 // /*! 00534 // @param other Maintains a weak smart pointer reference to this parameter. 00535 // */ 00536 // GenericWeakSP (const GenericSP<T>& other) 00537 // : ptr_(0) 00538 // , refCounts_(0) 00539 // { 00540 // if(other.ptr_) 00541 // { 00542 // ptr_ = other.ptr_; 00543 // refCounts_ = other.refCounts_; 00544 // 00545 // if (ptr_ != 0) 00546 // { 00547 // refCounts_->totalRefs_.Increment(); 00548 // } 00549 // } 00550 // } 00551 00553 00556 template <typename O> 00557 GenericWeakSP (const GenericSP<O>& other) 00558 : ptr_ (0) 00559 , refCounts_ (0) 00560 { 00561 if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) 00562 { 00563 ptr_ = other.ptr_; 00564 refCounts_ = other.refCounts_; 00565 00566 if (ptr_ != 0) 00567 { 00568 refCounts_->totalRefs_.Increment(); 00569 } 00570 } 00571 } 00572 00574 00577 GenericWeakSP &operator = (const GenericWeakSP<T>& other) 00578 { 00579 if (get () != other.get () ) 00580 { 00581 ReleaseReference (); 00582 00583 ptr_ = other.ptr_; 00584 refCounts_ = other.refCounts_; 00585 00586 if (ptr_ != 0) 00587 { 00588 refCounts_->totalRefs_.Increment(); 00589 } 00590 } 00591 00592 return *this; 00593 } 00594 00596 00599 template <typename O> 00600 GenericWeakSP &operator = (const GenericWeakSP<O>& other) 00601 { 00602 if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) 00603 { 00604 if (get () != other.get () ) 00605 { 00606 ReleaseReference (); 00607 00608 ptr_ = other.ptr_; 00609 refCounts_ = other.refCounts_; 00610 00611 if (ptr_ != 0) 00612 { 00613 refCounts_->totalRefs_.Increment(); 00614 } 00615 } 00616 } 00617 else 00618 { 00619 ReleaseReference(); 00620 } 00621 00622 return *this; 00623 } 00624 00626 00629 template <typename O> 00630 GenericWeakSP &operator = (const GenericSP<O>& other) 00631 { 00632 if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) 00633 { 00634 if (get () != other.ptr_) 00635 { 00636 ReleaseReference (); 00637 00638 ptr_ = other.ptr_; 00639 refCounts_ = other.refCounts_; 00640 00641 if (ptr_ != 0) 00642 { 00643 refCounts_->totalRefs_.Increment(); 00644 } 00645 } 00646 } 00647 else 00648 { 00649 ReleaseReference(); 00650 } 00651 00652 return *this; 00653 } 00654 00655 ~GenericWeakSP () 00656 { 00657 ReleaseReference (); 00658 } 00659 00660 T &operator * () const 00661 { 00662 nuxAssert ( (refCounts_->strongRefs_.GetValue() != 0) && (ptr_ != 0) ); 00663 00664 return *get (); 00665 } 00666 00667 T *operator -> () const 00668 { 00669 nuxAssert ( (refCounts_->strongRefs_.GetValue() != 0) && (ptr_ != 0) ); 00670 00671 return get (); 00672 } 00673 00674 void Swap (GenericWeakSP<T>& other) 00675 { 00676 std::swap (ptr_, other.ptr_); 00677 std::swap (refCounts_, other.refCounts_); 00678 } 00679 00680 bool operator < (T *ptr) const 00681 { 00682 return (ptr_ < ptr); 00683 } 00684 00685 bool operator > (T *ptr) const 00686 { 00687 return (ptr_ > ptr); 00688 } 00689 00690 bool operator < (GenericWeakSP<T> other) const 00691 { 00692 return (ptr_ < other.ptr_); 00693 } 00694 00695 bool operator > (GenericWeakSP<T> other) const 00696 { 00697 return (ptr_ > other.ptr_); 00698 } 00699 00700 bool operator != (T *ptr) const 00701 { 00702 return (ptr_ != ptr); 00703 } 00704 00705 bool operator == (T *ptr) const 00706 { 00707 return (ptr_ == ptr); 00708 } 00709 00710 template<typename U> 00711 bool operator != (U *ptr) const 00712 { 00713 if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00714 return false; 00715 00716 return (ptr_ != ptr); 00717 } 00718 00719 template<typename U> 00720 bool operator == (U *ptr) const 00721 { 00722 if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00723 return false; 00724 00725 return (ptr_ == ptr); 00726 } 00727 00728 template<typename U> 00729 bool operator != (const GenericWeakSP<U>& other) const 00730 { 00731 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00732 return false; 00733 00734 return ptr_ != other.ptr_; 00735 } 00736 00737 template<typename U> 00738 bool operator == (const GenericWeakSP<U>& other) const 00739 { 00740 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00741 return false; 00742 00743 return ptr_ == other.ptr_; 00744 } 00745 00746 template<typename U> 00747 bool operator != (const GenericSP<U>& other) const 00748 { 00749 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00750 return false; 00751 00752 return ptr_ != other.ptr_; 00753 } 00754 00755 template<typename U> 00756 bool operator == (const GenericSP<U>& other) const 00757 { 00758 if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) ) 00759 return false; 00760 00761 return ptr_ == other.ptr_; 00762 } 00763 00764 bool IsNull () const 00765 { 00766 return get () == 0; 00767 } 00768 00769 bool IsValid () const 00770 { 00771 return get () != 0; 00772 } 00773 00774 void Release() 00775 { 00776 ReleaseReference(); 00777 } 00778 00779 private: 00780 GenericWeakSP (T *ptr, RefCounts *refCounts) : ptr_ (ptr), refCounts_ (refCounts) 00781 { 00782 } 00783 00784 T *get () const 00785 { 00786 if (refCounts_ == 0 || (refCounts_->strongRefs_ == 0) ) 00787 { 00788 return 0; 00789 } 00790 00791 return ptr_; 00792 } 00793 00794 // bool isNull () const 00795 // { 00796 // return get () == 0; 00797 // } 00798 00799 void ReleaseReference () 00800 { 00801 if (ptr_ == 0) 00802 { 00803 return; 00804 } 00805 00806 refCounts_->totalRefs_.Decrement(); 00807 bool release = refCounts_->totalRefs_ == 0; 00808 00809 if (release) 00810 { 00811 delete refCounts_; 00812 } 00813 00814 refCounts_ = 0; 00815 ptr_ = 0; 00816 } 00817 00818 T *ptr_; 00819 RefCounts *refCounts_; 00820 00821 template <typename O> 00822 friend class GenericWeakSP; 00823 00824 template <typename O> 00825 friend class SmartPtr; 00826 00827 // template<typename T, typename U> 00828 // friend bool operator == (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b); 00829 00830 // template<typename T, typename U> 00831 // friend bool operator != (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b); 00832 00833 // template<typename T> 00834 // friend bool operator == (const GenericWeakSP<T>& a, T*); 00835 00836 template<typename U> 00837 friend bool operator == (U *, const GenericWeakSP<U>& a); 00838 00839 // template<typename T> 00840 // friend bool operator != (const GenericWeakSP<T>& a, T*); 00841 00842 template<typename U> 00843 friend bool operator != (U *, const GenericWeakSP<U>& a); 00844 00845 // template<typename T, typename U> 00846 // friend bool operator == (const GenericSP<T>& a, const GenericWeakSP<U>& b); 00847 // 00848 // template<typename T, typename U> 00849 // friend bool operator == (const GenericWeakSP<T>& a, const GenericSP<U>& b); 00850 // 00851 // template<typename T, typename U> 00852 // friend bool operator != (const GenericSP<T>& a, const GenericWeakSP<U>& b); 00853 // 00854 // template<typename T, typename U> 00855 // friend bool operator != (const GenericWeakSP<T>& a, const GenericSP<U>& b); 00856 00857 template <typename U, typename F> 00858 friend GenericWeakSP<U> staticCast (const GenericWeakSP<F>& from); 00859 00860 template <typename U, typename F> 00861 friend GenericWeakSP<U> constCast (const GenericWeakSP<F>& from); 00862 00863 template <typename U, typename F> 00864 friend GenericWeakSP<U> dynamicCast (const GenericWeakSP<F>& from); 00865 00866 template <typename U, typename F> 00867 friend GenericWeakSP<U> checkedCast (const GenericWeakSP<F>& from); 00868 00869 template <typename U, typename F> 00870 friend GenericWeakSP<U> queryCast (const GenericWeakSP<F>& from); 00871 }; 00872 00874 // globals 00875 00876 // template<typename T, typename U> 00877 // inline bool operator == (const GenericSP<T>& a, const GenericSP<U>& b) 00878 // { 00879 // return a.ptr_ == b.ptr_; 00880 // } 00881 // 00882 // template<typename T, typename U> 00883 // inline bool operator == (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b) 00884 // { 00885 // return a.get () == b.get (); 00886 // } 00887 // 00888 // template<typename T, typename U> 00889 // inline bool operator == (const GenericSP<T>& a, const GenericWeakSP<U>& b) 00890 // { 00891 // return a.ptr_ == b.get (); 00892 // } 00893 // 00894 // template<typename T, typename U> 00895 // inline bool operator == (const GenericWeakSP<T>& a, const GenericSP<U>& b) 00896 // { 00897 // return a.get () == b.ptr_; 00898 // } 00899 // 00900 // template<typename T, typename U> 00901 // inline bool operator != (const GenericSP<T>& a, const GenericSP<U>& b) 00902 // { 00903 // return a.ptr_ != b.ptr_; 00904 // } 00905 // 00906 // template<typename T, typename U> 00907 // inline bool operator != (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b) 00908 // { 00909 // return a.get () != b.get (); 00910 // } 00911 // 00912 // template<typename T, typename U> 00913 // inline bool operator != (const GenericSP<T>& a, const GenericWeakSP<U>& b) 00914 // { 00915 // return a.ptr_ != b.get (); 00916 // } 00917 // 00918 // template<typename T, typename U> 00919 // inline bool operator != (const GenericWeakSP<T>& a, const GenericSP<U>& b) 00920 // { 00921 // return a.get () != b.ptr_; 00922 // } 00923 00924 // template<typename T> 00925 // inline bool operator == (const GenericSP<T>& a, T* ptr) 00926 // { 00927 // return a.ptr_ == ptr; 00928 // } 00929 00930 template<typename T> 00931 inline bool operator == (T *ptr, const GenericSP<T>& a) 00932 { 00933 return a.ptr_ == ptr; 00934 } 00935 00936 // template<typename T> 00937 // inline bool operator != (const GenericSP<T>& a, T* ptr) 00938 // { 00939 // return a.ptr_ != ptr; 00940 // } 00941 00942 template<typename T> 00943 inline bool operator != (T *ptr, const GenericSP<T>& a) 00944 { 00945 return a.ptr_ != ptr; 00946 } 00947 00948 // template<typename T> 00949 // inline bool operator == (const GenericWeakSP<T>& a, T* ptr) 00950 // { 00951 // return a.ptr_ == ptr; 00952 // } 00953 00954 template<typename T> 00955 inline bool operator == (T *ptr, const GenericWeakSP<T>& a) 00956 { 00957 return a.ptr_ == ptr; 00958 } 00959 00960 // template<typename T> 00961 // inline bool operator != (const GenericWeakSP<T>& a, T* ptr) 00962 // { 00963 // return a.ptr_ != ptr; 00964 // } 00965 00966 template<typename T> 00967 inline bool operator != (T *ptr, const GenericWeakSP<T>& a) 00968 { 00969 return a.ptr_ != ptr; 00970 } 00971 00973 // creation functions 00974 00975 template <typename T> 00976 GenericSP<T> Create () 00977 { 00978 RefCounts *rc = new RefCounts; 00979 00980 try 00981 { 00982 T *t = new T; 00983 return GenericSP<T> (t, rc); 00984 } 00985 catch (...) 00986 { 00987 delete rc; 00988 throw; 00989 } 00990 } 00991 00992 template <typename T, typename P1> 00993 GenericSP<T> Create (P1 p1) 00994 { 00995 RefCounts *rc = new RefCounts; 00996 00997 try 00998 { 00999 T *t = new T (p1); 01000 return GenericSP<T> (t, rc); 01001 } 01002 catch (...) 01003 { 01004 delete rc; 01005 throw; 01006 } 01007 } 01008 01009 template <typename T, typename P1, typename P2> 01010 GenericSP<T> Create (P1 p1, P2 p2) 01011 { 01012 RefCounts *rc = new RefCounts; 01013 01014 try 01015 { 01016 T *t = new T (p1, p2); 01017 return GenericSP<T> (t, rc); 01018 } 01019 catch (...) 01020 { 01021 delete rc; 01022 throw; 01023 } 01024 } 01025 01026 template <typename T, typename P1, typename P2, typename P3> 01027 GenericSP<T> Create (P1 p1, P2 p2, P3 p3) 01028 { 01029 RefCounts *rc = new RefCounts; 01030 01031 try 01032 { 01033 T *t = new T (p1, p2, p3); 01034 return GenericSP<T> (t, rc); 01035 } 01036 catch (...) 01037 { 01038 delete rc; 01039 throw; 01040 } 01041 } 01042 01043 template <typename T, typename P1, typename P2, typename P3, typename P4> 01044 GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4) 01045 { 01046 RefCounts *rc = new RefCounts; 01047 01048 try 01049 { 01050 T *t = new T (p1, p2, p3, p4); 01051 return GenericSP<T> (t, rc); 01052 } 01053 catch (...) 01054 { 01055 delete rc; 01056 throw; 01057 } 01058 } 01059 01060 template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5> 01061 GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 01062 { 01063 RefCounts *rc = new RefCounts; 01064 01065 try 01066 { 01067 T *t = new T (p1, p2, p3, p4, p5); 01068 return GenericSP<T> (t, rc); 01069 } 01070 catch (...) 01071 { 01072 delete rc; 01073 throw; 01074 } 01075 } 01076 01077 template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> 01078 GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 01079 { 01080 RefCounts *rc = new RefCounts; 01081 01082 try 01083 { 01084 T *t = new T (p1, p2, p3, p4, p5, p6); 01085 return GenericSP<T> (t, rc); 01086 } 01087 catch (...) 01088 { 01089 delete rc; 01090 throw; 01091 } 01092 } 01093 01094 template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> 01095 GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) 01096 { 01097 RefCounts *rc = new RefCounts; 01098 01099 try 01100 { 01101 T *t = new T (p1, p2, p3, p4, p5, p6, p7); 01102 return GenericSP<T> (t, rc); 01103 } 01104 catch (...) 01105 { 01106 delete rc; 01107 throw; 01108 } 01109 } 01110 01111 template <typename T> 01112 GenericSP<T> WrapWSPtr (T *t) 01113 { 01114 if (t == 0) 01115 { 01116 return GenericSP<T> (); 01117 } 01118 01119 try 01120 { 01121 RefCounts *rc = new RefCounts; 01122 01123 return GenericSP<T> (t, rc); 01124 } 01125 catch (...) 01126 { 01127 delete t; 01128 throw; 01129 } 01130 } 01131 01133 // casts 01134 01135 template <typename U, typename F> 01136 GenericSP<U> staticCast (const GenericSP<F>& from) 01137 { 01138 if (from.ptr_ == 0) 01139 { 01140 return GenericSP<U>(); 01141 } 01142 01143 U *ptr = static_cast <U *> (from.ptr_); 01144 RefCounts *refCounts = from.refCounts_; 01145 01146 if (ptr != 0) 01147 { 01148 refCounts->strongRefs_.Increment(); 01149 refCounts->totalRefs_.Increment(); 01150 } 01151 01152 return GenericSP<U> (ptr, refCounts); 01153 } 01154 01155 template <typename T, typename F> 01156 GenericSP<T> constCast (const GenericSP<F>& from) 01157 { 01158 if (from.ptr_ == 0) 01159 { 01160 return GenericSP<T>(); 01161 } 01162 01163 T *ptr = const_cast <T *> (from.ptr_); 01164 RefCounts *refCounts = from.refCounts_; 01165 01166 if (ptr != 0) 01167 { 01168 refCounts->strongRefs_.Increment(); 01169 refCounts->totalRefs_.Increment(); 01170 } 01171 01172 return GenericSP<T> (ptr, refCounts); 01173 } 01174 01175 template <typename T, typename F> 01176 GenericSP<T> dynamicCast (const GenericSP<F>& from) 01177 { 01178 if (from.ptr_ == 0) 01179 { 01180 return GenericSP<T>(); 01181 } 01182 01183 T *ptr = &dynamic_cast <T &> (*from.ptr_); 01184 RefCounts *refCounts = from.refCounts_; 01185 01186 if (ptr != 0) 01187 { 01188 refCounts->strongRefs_.Increment(); 01189 refCounts->totalRefs_.Increment(); 01190 } 01191 01192 return GenericSP<T> (ptr, refCounts); 01193 } 01194 01195 template <typename T, typename F> 01196 GenericSP<T> queryCast (const GenericSP<F>& from) 01197 { 01198 T *ptr = dynamic_cast <T *> (from.ptr_); 01199 01200 if (ptr == 0) 01201 { 01202 return GenericSP<T>(); 01203 } 01204 01205 RefCounts *refCounts = from.refCounts_; 01206 01207 if (ptr != 0) 01208 { 01209 refCounts->strongRefs_.Increment(); 01210 refCounts->totalRefs_.Increment(); 01211 } 01212 01213 return GenericSP<T> (ptr, refCounts); 01214 } 01215 01216 template <typename T, typename F> 01217 GenericSP<T> checkedCast (const GenericSP<F>& from) 01218 { 01219 if (from.ptr_ == 0) 01220 { 01221 return GenericSP<T>(); 01222 } 01223 01224 nuxAssert (dynamic_cast<T *> (from.ptr_) != 0); 01225 01226 T *ptr = static_cast <T *> (from.ptr_); 01227 RefCounts *refCounts = from.refCounts_; 01228 01229 if (ptr != 0) 01230 { 01231 refCounts->strongRefs_.Increment(); 01232 refCounts->totalRefs_.Increment(); 01233 } 01234 01235 return GenericSP<T> (ptr, refCounts); 01236 } 01237 01238 template <typename U, typename F> 01239 GenericWeakSP<U> staticCast (const GenericWeakSP<F>& from) 01240 { 01241 if (from.get () == 0) 01242 { 01243 return GenericWeakSP<U>(); 01244 } 01245 01246 U *ptr = static_cast <U *> (from.ptr_); 01247 RefCounts *refCounts = from.refCounts_; 01248 01249 if (ptr != 0) 01250 { 01251 refCounts->totalRefs_.Increment(); 01252 } 01253 01254 return GenericWeakSP<U> (ptr, refCounts); 01255 } 01256 01257 template <typename T, typename F> 01258 GenericWeakSP<T> constCast (const GenericWeakSP<F>& from) 01259 { 01260 if (from.get () == 0) 01261 { 01262 return GenericWeakSP<T>(); 01263 } 01264 01265 T *ptr = const_cast <T *> (from.ptr_); 01266 RefCounts *refCounts = from.refCounts_; 01267 01268 if (ptr != 0) 01269 { 01270 refCounts->totalRefs_.Increment(); 01271 } 01272 01273 return GenericWeakSP<T> (ptr, refCounts); 01274 } 01275 01276 template <typename T, typename F> 01277 GenericWeakSP<T> dynamicCast (const GenericWeakSP<F>& from) 01278 { 01279 if (from.get () == 0) 01280 { 01281 return GenericWeakSP<T>(); 01282 } 01283 01284 T *ptr = &dynamic_cast <T &> (*from.ptr_); 01285 RefCounts *refCounts = from.refCounts_; 01286 01287 if (ptr != 0) 01288 { 01289 refCounts->totalRefs_.Increment(); 01290 } 01291 01292 return GenericWeakSP<T> (ptr, refCounts); 01293 } 01294 01295 template <typename T, typename F> 01296 GenericWeakSP<T> queryCast (const GenericWeakSP<F>& from) 01297 { 01298 T *ptr = dynamic_cast <T *> (from.get () ); 01299 01300 if (ptr == 0) 01301 { 01302 return GenericWeakSP<T>(); 01303 } 01304 01305 RefCounts *refCounts = from.refCounts_; 01306 01307 if (ptr != 0) 01308 { 01309 refCounts->totalRefs_.Increment(); 01310 } 01311 01312 return GenericWeakSP<T> (ptr, refCounts); 01313 } 01314 01315 template <typename T, typename F> 01316 GenericWeakSP<T> checkedCast (const GenericWeakSP<F>& from) 01317 { 01318 if (from.get () == 0) 01319 { 01320 return GenericWeakSP<T>(); 01321 } 01322 01323 nuxAssert (dynamic_cast<T *> (from.ptr_) != 0); 01324 01325 T *ptr = static_cast <T *> (from.ptr_); 01326 RefCounts *refCounts = from.refCounts_; 01327 01328 if (ptr != 0) 01329 { 01330 refCounts->totalRefs_.Increment(); 01331 } 01332 01333 return GenericWeakSP<T> (ptr, refCounts); 01334 } 01335 01337 // std specializations 01338 01339 template <typename T> 01340 inline void swap (GenericSP<T>& t1, GenericSP<T>& t2) 01341 { 01342 t1.swap (t2); 01343 } 01344 01345 template <typename T> 01346 inline void swap (GenericWeakSP<T>& t1, GenericWeakSP<T>& t2) 01347 { 01348 t1.swap (t2); 01349 } 01350 01351 } 01352 01353 #endif // WIDGETSMARTPOINTER_H