nux-0.9.48

NuxCore/SmartPtr/GenericSmartPointer.h

Go to the documentation of this file.
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