- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/include/frost_utils_refptr.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     /// Reference counting pointer
    00005     /** This is a pointer that automatically deletes
    00006     *   its content when not used anymore.<br>
    00007     *   Can be used in conjunction with s_wptr.
    00008     *   Uses reference counting.
    00009     */
    00010     template<class T>
    00011     class s_refptr
    00012     {
    00013     public :
    00014
    00015         template<class> friend class s_refptr;
    00016         template<class> friend class s_wptr;
    00017
    00018         /// Default constructor.
    00019         /** \note Initializes the pointer to NULL.
    00020         */
    00021         s_refptr()
    00022         {
    00023             pValue_    = nullptr;
    00024             pCounter_  = nullptr;
    00025             pWCounter_ = nullptr;
    00026         }
    00027
    00028         /// Copy constructor.
    00029         /** \param mValue the s_refptr to copy
    00030         */
    00031         s_refptr(const s_refptr& mValue)
    00032         {
    00033             pValue_    = mValue.pValue_;
    00034             pCounter_  = mValue.pCounter_;
    00035             pWCounter_ = mValue.pWCounter_;
    00036
    00037             Increment_();
    00038         }
    00039
    00040         /// Conversion from nullptr.
    00041         s_refptr(const s_nullptr& pNull)
    00042         {
    00043             pValue_    = nullptr;
    00044             pCounter_  = nullptr;
    00045             pWCounter_ = nullptr;
    00046         }
    00047
    00048         /// Constructor.
    00049         /** \param pValue The pointer to assign
    00050         *   \note This is the only way to assign a classic
    00051         *         pointer to a s_refptr.
    00052         */
    00053         explicit s_refptr(T* pValue)
    00054         {
    00055             pValue_    = pValue;
    00056             pCounter_  = new default_uint(0);
    00057             pWCounter_ = new default_uint(0);
    00058
    00059             Increment_();
    00060         }
    00061
    00062         template<class N>
    00063         /// Conversion constructor.
    00064         /** \param mValue the s_refptr to copy
    00065         */
    00066         explicit s_refptr(const s_refptr<N>& mValue)
    00067         {
    00068             pValue_    = mValue.pValue_;
    00069             pCounter_  = mValue.pCounter_;
    00070             pWCounter_ = mValue.pWCounter_;
    00071
    00072             Increment_();
    00073         }
    00074
    00075         /// Destructor.
    00076         /** \note Can cause deletion of the contained
    00077         *         pointer.
    00078         */
    00079         ~s_refptr()
    00080         {
    00081             Decrement_();
    00082         }
    00083
    00084         /// Returns the contained pointer.
    00085         /** \return The contained pointer
    00086         */
    00087         const T* Get() const
    00088         {
    00089             return pValue_;
    00090         }
    00091
    00092         /// Returns the contained pointer.
    00093         /** \return The contained pointer
    00094         */
    00095         T* Get()
    00096         {
    00097             return pValue_;
    00098         }
    00099
    00100         /// Checks if this pointer is usable.
    00101         /** \return 'true' is this pointer is usable
    00102         */
    00103         s_bool IsValid() const
    00104         {
    00105             return (pValue_ != 0);
    00106         }
    00107
    00108         /// Returns the number of s_refptr pointing to the object.
    00109         /** \return The number of s_refptr pointing to the object
    00110         *   \note This function returns 0 if the pointer is NULL.
    00111         */
    00112         s_uint_t<default_uint> GetCount() const
    00113         {
    00114             if (pCounter_)
    00115                 return *pCounter_;
    00116             else
    00117                 return 0u;
    00118         }
    00119
    00120         /// Returns the number of s_wptr pointing to the object.
    00121         /** \return The number of s_wptr pointing to the object
    00122         *   \note This function returns 0 if the pointer is NULL.
    00123         */
    00124         s_uint_t<default_uint> GetWeakCount() const
    00125         {
    00126             if (pWCounter_)
    00127                 return *pWCounter_;
    00128             else
    00129                 return 0u;
    00130         }
    00131
    00132         /// Sets this pointer to NULL.
    00133         /** \note Can cause deletion of the contained
    00134         *         pointer.
    00135         */
    00136         void SetNull()
    00137         {
    00138             Decrement_();
    00139
    00140             pValue_    = nullptr;
    00141             pCounter_  = nullptr;
    00142             pWCounter_ = nullptr;
    00143         }
    00144
    00145         /// Creates a s_wptr pointing at the same object.
    00146         s_wptr<T> CreateWeak() const
    00147         {
    00148             return s_wptr<T>(*this);
    00149         }
    00150
    00151         /// Returns a reference to the contained value.
    00152         /** \return A reference to the contained value
    00153         */
    00154         typename PtrTraits<T>::CRef operator * () const
    00155         {
    00156             return *pValue_;
    00157         }
    00158
    00159         /// Returns a reference to the contained value.
    00160         /** \return A reference to the contained value
    00161         */
    00162         typename PtrTraits<T>::Ref operator * ()
    00163         {
    00164             return *pValue_;
    00165         }
    00166
    00167         /// Dereferences the pointer.
    00168         /** \return The contained pointer
    00169         */
    00170         const T* operator -> () const
    00171         {
    00172             return pValue_;
    00173         }
    00174
    00175         /// Dereferences the pointer.
    00176         /** \return The contained pointer
    00177         */
    00178         T* operator -> ()
    00179         {
    00180             return pValue_;
    00181         }
    00182
    00183         /// Copy operator.
    00184         /** \param mValue The value to copy
    00185         *   \note Can cause deletion of the contained
    00186         *         pointer.
    00187         */
    00188         s_refptr& operator = (const s_refptr& mValue)
    00189         {
    00190             if (&mValue != this)
    00191             {
    00192                 Decrement_();
    00193
    00194                 pValue_    = mValue.pValue_;
    00195                 pCounter_  = mValue.pCounter_;
    00196                 pWCounter_ = mValue.pWCounter_;
    00197
    00198                 Increment_();
    00199             }
    00200
    00201             return *this;
    00202         }
    00203
    00204         template<class N>
    00205         /// Copy operator.
    00206         /** \param mValue The value to copy
    00207         *   \note Can cause deletion of the contained
    00208         *         pointer.
    00209         */
    00210         s_refptr& operator = (const s_refptr<N>& mValue)
    00211         {
    00212             if (mValue.pValue_ != pValue_)
    00213             {
    00214                 Decrement_();
    00215
    00216                 pValue_    = mValue.pValue_;
    00217                 pCounter_  = mValue.pCounter_;
    00218                 pWCounter_ = mValue.pWCounter_;
    00219
    00220                 Increment_();
    00221             }
    00222
    00223             return *this;
    00224         }
    00225
    00226         template<class N>
    00227         /// Checks if this pointer equals another
    00228         /** \param mValue The pointer to test
    00229         */
    00230         s_bool operator == (const s_refptr<N>& mValue)
    00231         {
    00232             return (pValue_ == mValue.pValue_);
    00233         }
    00234
    00235         /// Checks if this pointer equals another
    00236         /** \param pValue The pointer to test
    00237         */
    00238         s_bool operator == (T* pValue) const
    00239         {
    00240             return (pValue_ == pValue);
    00241         }
    00242
    00243         /// Checks if this pointer is null
    00244         /** \param pValue The null pointer
    00245         *   \return 'true' if this pointer is null
    00246         */
    00247         s_bool operator == (s_nullptr pValue) const
    00248         {
    00249             return (pValue_ == 0);
    00250         }
    00251
    00252         template<class N>
    00253         /// Checks if this pointer is different from another
    00254         /** \param mValue The pointer to test
    00255         */
    00256         s_bool operator != (const s_refptr<N>& mValue)
    00257         {
    00258             return (pValue_ != mValue.pValue_);
    00259         }
    00260
    00261         /// Checks if this pointer is different from another
    00262         /** \param pValue The pointer to test
    00263         */
    00264         s_bool operator != (T* pValue) const
    00265         {
    00266             return (pValue_ != pValue);
    00267         }
    00268
    00269         /// Checks if this pointer is not null
    00270         /** \param pValue The null pointer
    00271         *   \return 'true' if this pointer is not null
    00272         */
    00273         s_bool operator != (s_nullptr pValue) const
    00274         {
    00275             return (pValue_ != 0);
    00276         }
    00277
    00278         /// Allows : "if (!pPointer)".
    00279         bool operator ! () const
    00280         {
    00281             return (pValue_ == 0);
    00282         }
    00283
    00284         typedef void (s_refptr::*MemberFn)();
    00285         /// Allows : "if (pPointer)".
    00286         operator MemberFn() const
    00287         {
    00288             if (pValue_ != 0)
    00289                 return &s_refptr::SetNull;
    00290             else
    00291                 return 0;
    00292         }
    00293
    00294         /// Allows limited implicit inheritance conversion.
    00295         template<class N>
    00296         operator s_refptr<const N>() const
    00297         {
    00298             return s_refptr<N>(pValue_, pCounter_, pWCounter_);
    00299         }
    00300
    00301         /// Allows limited implicit inheritance conversion.
    00302         template<class N>
    00303         operator s_refptr<N>()
    00304         {
    00305             return s_refptr<N>(pValue_, pCounter_, pWCounter_);
    00306         }
    00307
    00308         s_ctnr< s_refptr<T> > operator , (const s_refptr<T>& pValue) const
    00309         {
    00310             s_ctnr< s_refptr<T> > mContainer;
    00311             mContainer.PushBack(*this);
    00312             mContainer.PushBack(pValue);
    00313             return mContainer;
    00314         }
    00315
    00316         /// Casts the provided pointer to this one's type.
    00317         /** \param pValue The pointer to cast
    00318         *   \return The new casted pointer
    00319         */
    00320         template<class N>
    00321         static s_refptr<T> StaticCast(const s_refptr<N>& pValue)
    00322         {
    00323             return s_refptr<T>(static_cast<T*>(pValue.pValue_), pValue.pCounter_, pValue.pWCounter_);
    00324         }
    00325
    00326         /// Tries to dynamic cast the provided pointer to this one's type.
    00327         /** \param pValue The pointer to cast
    00328         *   \return The new casted pointer
    00329         *   \note Dynamic cast can fail, and in this case, will result in
    00330         *         a NULL pointer.
    00331         */
    00332         template<class N>
    00333         static s_refptr<T> DynamicCast(const s_refptr<N>& pValue)
    00334         {
    00335             T* pTemp = dynamic_cast<T*>(pValue.pValue_);
    00336             if (pTemp)
    00337                 return s_refptr<T>(pTemp, pValue.pCounter_, pValue.pWCounter_);
    00338             else
    00339                 return s_refptr<T>();
    00340         }
    00341
    00342     protected :
    00343
    00344         /// Constructor.
    00345         /** \param pValue   The pointer to assign
    00346         *   \param pCounter The counter to use
    00347         *   \param pWCounter The weak ptr counter to use
    00348         *   \note This function should not be called
    00349         *         by anyone else than itself (and other
    00350         *         template specializations).
    00351         */
    00352         explicit s_refptr(T* pValue, default_uint* pCounter, default_uint* pWCounter)
    00353         {
    00354             pValue_    = pValue;
    00355             pCounter_  = pCounter;
    00356             pWCounter_ = pWCounter;
    00357
    00358             Increment_();
    00359         }
    00360
    00361     private :
    00362
    00363         void Increment_()
    00364         {
    00365             if (pCounter_)
    00366                 ++(*pCounter_);
    00367         }
    00368
    00369         void Decrement_()
    00370         {
    00371             if (pCounter_)
    00372             {
    00373                 --(*pCounter_);
    00374                 if (*pCounter_ == 0u)
    00375                 {
    00376                     if (*pWCounter_ == 0u)
    00377                     {
    00378                         delete pCounter_;
    00379                         pCounter_ = nullptr;
    00380                         delete pWCounter_;
    00381                         pWCounter_ = nullptr;
    00382                     }
    00383
    00384                     delete pValue_;
    00385                     pValue_ = nullptr;
    00386                 }
    00387             }
    00388         }
    00389
    00390         T*    pValue_;
    00391         default_uint* pCounter_;
    00392         default_uint* pWCounter_;
    00393     };
    00394 }