- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/include/frost_utils_wptr.h

Go to the documentation of this file.

    00001 // Warning : If you need to use this file, include frost_utils_types.h
    00002 namespace Frost
    00003 {
    00004     /// Weak pointer
    00005     /** This is a companion of the reference counter pointer.<br>
    00006     *   Use the Lock() function to get a valid pointer, or a NULL
    00007     *   one if it has been deleted.
    00008     */
    00009     template<class T>
    00010     class s_wptr
    00011     {
    00012     public :
    00013
    00014         template<class N> friend class s_wptr;
    00015
    00016         /// Default constructor.
    00017         /** \note Initializes the pointer to NULL.
    00018         */
    00019         s_wptr()
    00020         {
    00021             pValue_    = nullptr;
    00022             pCounter_  = nullptr;
    00023             pWCounter_ = nullptr;
    00024         }
    00025
    00026         /// Copy constructor.
    00027         s_wptr(const s_wptr& pPtr)
    00028         {
    00029             pValue_    = pPtr.pValue_;
    00030             pCounter_  = pPtr.pCounter_;
    00031             pWCounter_ = pPtr.pWCounter_;
    00032
    00033             Increment_();
    00034         }
    00035
    00036         /// Conversion from nullptr.
    00037         s_wptr(const s_nullptr& pNull)
    00038         {
    00039             pValue_    = nullptr;
    00040             pCounter_  = nullptr;
    00041             pWCounter_ = nullptr;
    00042         }
    00043
    00044         /// Destructor.
    00045         /** \note This function will <b>never</b> delete the pointed object (if any).
    00046         */
    00047         ~s_wptr()
    00048         {
    00049             Decrement_();
    00050         }
    00051
    00052         template<class N>
    00053         /// s_refptr conversion.
    00054         s_wptr(const s_refptr<N>& pRefPtr)
    00055         {
    00056             pValue_    = pRefPtr.pValue_;
    00057             pCounter_  = pRefPtr.pCounter_;
    00058             pWCounter_ = pRefPtr.pWCounter_;
    00059
    00060             Increment_();
    00061         }
    00062
    00063         template<class N>
    00064         /// s_wptr conversion.
    00065         s_wptr(const s_wptr<N>& pPtr)
    00066         {
    00067             pValue_    = pPtr.pValue_;
    00068             pCounter_  = pPtr.pCounter_;
    00069             pWCounter_ = pPtr.pWCounter_;
    00070
    00071             Increment_();
    00072         }
    00073
    00074         /// Checks if this pointer points to a valid object.
    00075         /** \note The pointer can be invalid if the object has
    00076         *         been deleted somewhere else.
    00077         */
    00078         s_bool IsValid() const
    00079         {
    00080             return (pCounter_ && *pCounter_ != 0u);
    00081         }
    00082
    00083         /// Returns the number of s_refptr pointing to the object.
    00084         /** \return The number of s_refptr pointing to the object
    00085         *   \note If this function returns 0, then the object has
    00086         *         been deleted and this pointer is invalid, or it
    00087         *         is simply NULL.
    00088         */
    00089         s_uint_t<default_uint> GetCount() const
    00090         {
    00091             if (pCounter_)
    00092                 return *pCounter_;
    00093             else
    00094                 return 0u;
    00095         }
    00096
    00097         /// Returns the number of s_wptr pointing to the object.
    00098         /** \return The number of s_wptr pointing to the object
    00099         *   \note This function returns 0 if the pointer is NULL.
    00100         */
    00101         s_uint_t<default_uint> GetWeakCount() const
    00102         {
    00103             if (pWCounter_)
    00104                 return *pWCounter_;
    00105             else
    00106                 return 0u;
    00107         }
    00108
    00109         /// Sets this pointer to NULL.
    00110         /** \note This function will <b>never</b> delete the pointed object (if any).
    00111         */
    00112         void SetNull()
    00113         {
    00114             Decrement_();
    00115
    00116             pValue_    = nullptr;
    00117             pCounter_  = nullptr;
    00118             pWCounter_ = nullptr;
    00119         }
    00120
    00121         /// Creates a s_refptr pointing to the object (if any).
    00122         /** \returns A s_refptr pointing to the object (if any)
    00123         *   \note If this pointer is invalid, this function returns an empty
    00124         *         s_refptr.
    00125         */
    00126         s_refptr<const T> Lock() const
    00127         {
    00128             if (IsValid())
    00129                 return s_refptr<const T>(pValue_, pCounter_, pWCounter_);
    00130             else
    00131                 return s_refptr<const T>();
    00132         }
    00133
    00134         /// Creates a s_refptr pointing to the object (if any).
    00135         /** \returns A s_refptr pointing to the object (if any)
    00136         *   \note If this pointer is invalid, this function returns an empty
    00137         *         s_refptr.
    00138         */
    00139         s_refptr<T> Lock()
    00140         {
    00141             if (IsValid())
    00142                 return s_refptr<T>(pValue_, pCounter_, pWCounter_);
    00143             else
    00144                 return s_refptr<T>();
    00145         }
    00146
    00147         /// Dereferences the pointer.
    00148         /** \return The contained pointer
    00149         *   \note You should test for the pointer's validity before using
    00150         *         this operator, unless you're sure the object is still
    00151         *         alive.
    00152         */
    00153         const T* operator -> () const
    00154         {
    00155             return pValue_;
    00156         }
    00157
    00158         /// Dereferences the pointer.
    00159         /** \return The contained pointer
    00160         *   \note You should test for the pointer's validity before using
    00161         *         this operator, unless you're sure the object is still
    00162         *         alive.
    00163         */
    00164         T* operator -> ()
    00165         {
    00166             return pValue_;
    00167         }
    00168
    00169         /// Returns a reference to the contained value.
    00170         /** \return A reference to the contained value
    00171         */
    00172         typename PtrTraits<T>::CRef operator * () const
    00173         {
    00174             return *pValue_;
    00175         }
    00176
    00177         /// Returns a reference to the contained value.
    00178         /** \return A reference to the contained value
    00179         */
    00180         typename PtrTraits<T>::Ref operator * ()
    00181         {
    00182             return *pValue_;
    00183         }
    00184
    00185         /// nullptr assignation operator.
    00186         /** \param pPtr The value to copy
    00187         */
    00188         s_wptr& operator = (const s_nullptr& pPtr)
    00189         {
    00190             pValue_    = nullptr;
    00191             pCounter_  = nullptr;
    00192             pWCounter_ = nullptr;
    00193
    00194             return *this;
    00195         }
    00196
    00197         /// Copy operator.
    00198         /** \param pPtr The value to copy
    00199         */
    00200         s_wptr& operator = (const s_wptr& pPtr)
    00201         {
    00202             pValue_ = pPtr.pValue_;
    00203             pCounter_ = pPtr.pCounter_;
    00204             pWCounter_ = pPtr.pWCounter_;
    00205
    00206             Increment_();
    00207
    00208             return *this;
    00209         }
    00210
    00211         template<class N>
    00212         /// Copy operator.
    00213         /** \param pPtr The value to copy
    00214         */
    00215         s_wptr& operator = (const s_wptr<N>& pPtr)
    00216         {
    00217             pValue_ = pPtr.pValue_;
    00218             pCounter_ = pPtr.pCounter_;
    00219             pWCounter_ = pPtr.pWCounter_;
    00220
    00221             Increment_();
    00222
    00223             return *this;
    00224         }
    00225
    00226         /// Checks if this pointer equals another
    00227         /** \param pValue The pointer to test
    00228         */
    00229         template<class N>
    00230         s_bool operator == (const s_wptr<N>& pValue) const
    00231         {
    00232             return (pValue_ == pValue.pValue_);
    00233         }
    00234
    00235         /// Checks if this pointer equals another
    00236         /** \param pValue The pointer to test
    00237         */
    00238         template<class N>
    00239         s_bool operator == (const s_refptr<N>& pValue) const
    00240         {
    00241             return (pValue_ == pValue.pValue_);
    00242         }
    00243
    00244         /// Checks if this pointer equals another
    00245         /** \param pValue The pointer to test
    00246         */
    00247         template<class N>
    00248         s_bool operator == (N* pValue) const
    00249         {
    00250             return (pValue_ == pValue);
    00251         }
    00252
    00253         /// Checks if this pointer is null
    00254         /** \param pValue The null pointer
    00255         *   \return 'true' if this pointer is null
    00256         */
    00257         s_bool operator == (s_nullptr pValue) const
    00258         {
    00259             return (pValue_ == 0);
    00260         }
    00261
    00262         /// Checks if this pointer is different from another
    00263         /** \param pValue The pointer to test
    00264         *   \return 'true' if this pointer is different from another
    00265         */
    00266         template<class N>
    00267         s_bool operator != (const s_wptr<N>& pValue) const
    00268         {
    00269             return (pValue_ != pValue.pValue_);
    00270         }
    00271
    00272         /// Checks if this pointer is different from another
    00273         /** \param pValue The pointer to test
    00274         *   \return 'true' if this pointer is different from another
    00275         */
    00276         template<class N>
    00277         s_bool operator != (const s_refptr<N>& pValue) const
    00278         {
    00279             return (pValue_ != pValue.pValue_);
    00280         }
    00281
    00282         /// Checks if this pointer is different from another
    00283         /** \param pValue The pointer to test
    00284         *   \return 'true' if this pointer is different from another
    00285         */
    00286         template<class N>
    00287         s_bool operator != (N* pValue) const
    00288         {
    00289             return (pValue_ != pValue);
    00290         }
    00291
    00292         /// Checks if this pointer is not null
    00293         /** \param pValue The null pointer
    00294         *   \return 'true' if this pointer is not null
    00295         */
    00296         s_bool operator != (s_nullptr pValue) const
    00297         {
    00298             return (pValue_ != 0);
    00299         }
    00300
    00301         /// Checks if this pointer's value is lower than the other
    00302         /** \param pValue The pointer to test
    00303         *   \return 'true' if this pointer's value is lower than the other
    00304         */
    00305         template<class N>
    00306         s_bool operator < (const s_wptr<N>& pValue) const
    00307         {
    00308             return (pValue_ < pValue.pValue_);
    00309         }
    00310
    00311         /// Checks if this pointer's value is lower than the other
    00312         /** \param pValue The pointer to test
    00313         *   \return 'true' if this pointer's value is lower than the other
    00314         */
    00315         template<class N>
    00316         s_bool operator < (const s_refptr<N>& pValue) const
    00317         {
    00318             return (pValue_ < pValue.pValue_);
    00319         }
    00320
    00321         /// Checks if this pointer's value is lower than the other
    00322         /** \param pValue The pointer to test
    00323         *   \return 'true' if this pointer's value is lower than the other
    00324         */
    00325         template<class N>
    00326         s_bool operator < (N* pValue) const
    00327         {
    00328             return (pValue_ < pValue);
    00329         }
    00330
    00331         /// Checks if this pointer's value is lower or equal than the other
    00332         /** \param pValue The pointer to test
    00333         *   \return 'true' if this pointer's value is lower or equal than the other
    00334         */
    00335         template<class N>
    00336         s_bool operator <= (const s_wptr<N>& pValue) const
    00337         {
    00338             return (pValue_ <= pValue.pValue_);
    00339         }
    00340
    00341         /// Checks if this pointer's value is lower or equal than the other
    00342         /** \param pValue The pointer to test
    00343         *   \return 'true' if this pointer's value is lower or equal than the other
    00344         */
    00345         template<class N>
    00346         s_bool operator <= (const s_refptr<N>& pValue) const
    00347         {
    00348             return (pValue_ <= pValue.pValue_);
    00349         }
    00350
    00351         /// Checks if this pointer's value is lower or equal than the other
    00352         /** \param pValue The pointer to test
    00353         *   \return 'true' if this pointer's value is lower or equal than the other
    00354         */
    00355         template<class N>
    00356         s_bool operator <= (N* pValue) const
    00357         {
    00358             return (pValue_ <= pValue);
    00359         }
    00360
    00361         /// Checks if this pointer's value is greater than the other
    00362         /** \param pValue The pointer to test
    00363         *   \return 'true' if this pointer's value is greater than the other
    00364         */
    00365         template<class N>
    00366         s_bool operator > (const s_wptr<N>& pValue) const
    00367         {
    00368             return (pValue_ > pValue.pValue_);
    00369         }
    00370
    00371         /// Checks if this pointer's value is greater than the other
    00372         /** \param pValue The pointer to test
    00373         *   \return 'true' if this pointer's value is greater than the other
    00374         */
    00375         template<class N>
    00376         s_bool operator > (const s_refptr<N>& pValue) const
    00377         {
    00378             return (pValue_ > pValue.pValue_);
    00379         }
    00380
    00381         /// Checks if this pointer's value is greater than the other
    00382         /** \param pValue The pointer to test
    00383         *   \return 'true' if this pointer's value is greater than the other
    00384         */
    00385         template<class N>
    00386         s_bool operator > (N* pValue) const
    00387         {
    00388             return (pValue_ > pValue);
    00389         }
    00390
    00391         /// Checks if this pointer's value is greater or equal than the other
    00392         /** \param pValue The pointer to test
    00393         *   \return 'true' if this pointer's value is greater or equal than the other
    00394         */
    00395         template<class N>
    00396         s_bool operator >= (const s_wptr<N>& pValue) const
    00397         {
    00398             return (pValue_ >= pValue.pValue_);
    00399         }
    00400
    00401         /// Checks if this pointer's value is greater or equal than the other
    00402         /** \param pValue The pointer to test
    00403         *   \return 'true' if this pointer's value is greater or equal than the other
    00404         */
    00405         template<class N>
    00406         s_bool operator >= (const s_refptr<N>& pValue) const
    00407         {
    00408             return (pValue_ >= pValue.pValue_);
    00409         }
    00410
    00411         /// Checks if this pointer's value is greater or equal than the other
    00412         /** \param pValue The pointer to test
    00413         *   \return 'true' if this pointer's value is greater or equal than the other
    00414         */
    00415         template<class N>
    00416         s_bool operator >= (N* pValue) const
    00417         {
    00418             return (pValue_ >= pValue);
    00419         }
    00420
    00421         /// Allows : "if (!pPointer)".
    00422         bool operator ! () const
    00423         {
    00424             return (pCounter_ == 0 ? true : *pCounter_ == 0u);
    00425         }
    00426
    00427         typedef void (s_wptr::*MemberFn)();
    00428         /// Allows : "if (pPointer)".
    00429         operator MemberFn() const
    00430         {
    00431             if (pCounter_ && *pCounter_ != 0u)
    00432                 return &s_wptr::SetNull;
    00433             else
    00434                 return 0;
    00435         }
    00436
    00437         s_ctnr< s_wptr<T> > operator , (const s_wptr<T>& pValue) const
    00438         {
    00439             s_ctnr< s_wptr<T> > mContainer;
    00440             mContainer.PushBack(*this);
    00441             mContainer.PushBack(pValue);
    00442             return mContainer;
    00443         }
    00444
    00445         /// Casts the provided pointer to this one's type.
    00446         /** \param pValue The pointer to cast
    00447         *   \return The new casted pointer
    00448         */
    00449         template<class N>
    00450         static s_wptr<T> StaticCast(const s_wptr<N>& pValue)
    00451         {
    00452             return s_wptr<T>(static_cast<T*>(pValue.pValue_), pValue.pCounter_, pValue.pWCounter_);
    00453         }
    00454
    00455         /// Tries to dynamic cast the provided pointer to this one's type.
    00456         /** \param pValue The pointer to cast
    00457         *   \return The new casted pointer
    00458         *   \note Dynamic cast can fail, and in this case, will result in
    00459         *         a NULL pointer.
    00460         */
    00461         template<class N>
    00462         static s_wptr<T> DynamicCast(const s_wptr<N>& pValue)
    00463         {
    00464             T* pTemp = dynamic_cast<T*>(pValue.pValue_);
    00465             if (pTemp)
    00466                 return s_wptr<T>(pTemp, pValue.pCounter_, pValue.pWCounter_);
    00467             else
    00468                 return s_wptr<T>();
    00469         }
    00470
    00471     private :
    00472
    00473         s_wptr(T* pValue, default_uint* pCounter, default_uint* pWCounter) :
    00474             pValue_(pValue), pCounter_(pCounter), pWCounter_(pWCounter)
    00475         {
    00476         }
    00477
    00478         void Increment_()
    00479         {
    00480             if (pWCounter_)
    00481             {
    00482                 ++(*pWCounter_);
    00483             }
    00484         }
    00485
    00486         void Decrement_()
    00487         {
    00488             if (pWCounter_)
    00489             {
    00490                 --(*pWCounter_);
    00491                 if (*pWCounter_ == 0u && *pCounter_ == 0u)
    00492                 {
    00493                     delete pCounter_;
    00494                     pCounter_ = nullptr;
    00495                     delete pWCounter_;
    00496                     pWCounter_ = nullptr;
    00497                 }
    00498             }
    00499         }
    00500
    00501         T*    pValue_;
    00502         default_uint* pCounter_;
    00503         default_uint* pWCounter_;
    00504     };
    00505 }