TCSharedPtrImpl.h

Go to the documentation of this file.
00001 //*******************************************************************************
00002 //
00003 // *******   ***   ***               *
00004 //    *     *     *                  *
00005 //    *    *      *                *****
00006 //    *    *       ***  *   *   **   *    **    ***
00007 //    *    *          *  * *   *     *   ****  * * *
00008 //    *     *         *   *      *   * * *     * * *
00009 //    *      ***   ***    *     **   **   **   *   *
00010 //                        *
00011 //*******************************************************************************
00012 // see http://sourceforge.net/projects/tcsystem/ for details.
00013 // Copyright (C) 2003 - 2008 Thomas Goessler. All Rights Reserved. 
00014 //*******************************************************************************
00015 //
00016 // TCSystem is the legal property of its developers.
00017 // Please refer to the COPYRIGHT file distributed with this source distribution.
00018 // 
00019 // This library is free software; you can redistribute it and/or             
00020 // modify it under the terms of the GNU Lesser General Public                
00021 // License as published by the Free Software Foundation; either              
00022 // version 2.1 of the License, or (at your option) any later version.        
00023 //                                                                           
00024 // This library is distributed in the hope that it will be useful,           
00025 // but WITHOUT ANY WARRANTY; without even the implied warranty of            
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         
00027 // Lesser General Public License for more details.                           
00028 //                                                                           
00029 // You should have received a copy of the GNU Lesser General Public          
00030 // License along with this library; if not, write to the Free Software       
00031 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
00032 //*******************************************************************************
00033 //  $Id: TCSharedPtrImpl.h 836 2008-04-08 21:24:19Z the_____tiger $
00034 //*******************************************************************************
00035 #ifndef _TC_SHARED_PTR_IMP_H_
00036 #define _TC_SHARED_PTR_IMP_H_
00037 
00038 #include "TCInterlocked.h"
00039 
00040 #include <memory>    // for std::auto_ptr
00041 #include <algorithm> // for std::swap
00042 
00043 #include "TCNewEnable.h"
00044 
00045 namespace TC
00046 {
00047    class WeakPtrCount;
00048    class SharedPtrCount;
00049 
00067    namespace Impl
00068    {
00070       class SharedPtrCountBase
00071       {
00072       protected:
00073          virtual ~SharedPtrCountBase() {}
00074          virtual void DeletePtr() = 0;
00075 
00077          SharedPtrCountBase()
00078              :m_count(1),
00079             m_weak_count(1)
00080          {
00081          }
00082 
00083       private:
00085          inline void AddReference()
00086          {
00087             Interlocked::Increment(m_count);
00088          }
00093          inline void ReleaseReference()
00094          {
00095             if (Interlocked::Decrement(m_count) == 0)
00096             {
00097                DeletePtr();
00098                ReleaseWeakReference();
00099             }
00100          }
00102          inline uint32 GetUseCount() const { return m_count;}
00103 
00105          inline void AddWeakReference()
00106          {
00107             Interlocked::Increment(m_weak_count);
00108          }
00113          inline void ReleaseWeakReference()
00114          {
00115             if (Interlocked::Decrement(m_weak_count) == 0)
00116             {
00117                Destroy();
00118             }
00119          }
00120 
00125          inline void Destroy() { delete this;}
00126 
00127       private:
00129          Interlocked::Type m_count;
00131          Interlocked::Type m_weak_count;
00132 
00133          friend class TC::SharedPtrCount;
00134          friend class TC::WeakPtrCount;
00135       };
00136 
00141       template <class T, class DELETER>
00142       class SharedPtrCountType: protected SharedPtrCountBase
00143       {
00144       protected:
00146          SharedPtrCountType(T* ptr, DELETER deleter)
00147             :m_ptr(ptr),
00148             m_deleter(deleter)
00149          {
00150          }
00151          
00152          virtual void DeletePtr()
00153          {
00154             m_deleter(m_ptr);
00155          }
00156       private:
00158          T* m_ptr;
00160          DELETER m_deleter;
00161 
00162          friend class TC::SharedPtrCount;
00163       };
00164 
00165    } // namspace Impl
00166 
00168    class SharedPtrCount
00169    {
00170    public:
00172       SharedPtrCount():m_count(0) {}
00173 
00175       template <class PTR_TYPE, class DELETER>
00176       SharedPtrCount(PTR_TYPE* ptr, DELETER deleter)
00177       {
00178          m_count = new Impl::SharedPtrCountType<PTR_TYPE, DELETER>(ptr, deleter);
00179       }
00180 
00182       template <class PTR_TYPE, class DELETER>
00183       SharedPtrCount(std::auto_ptr<PTR_TYPE>& ptr, DELETER deleter)
00184       {
00185          m_count = new Impl::SharedPtrCountType<PTR_TYPE, DELETER>(ptr.get(), deleter);
00186          ptr.release();
00187       }
00188 
00190       explicit SharedPtrCount(const SharedPtrCount& count)
00191          :m_count(count.m_count)
00192       {
00193          if (m_count) m_count->AddReference();
00194       }
00195 
00197       explicit SharedPtrCount(const WeakPtrCount& count);
00198 
00200       ~SharedPtrCount()
00201       {
00202          if (m_count)
00203          {
00204             m_count->ReleaseReference();
00205             m_count = 0;
00206          }
00207       }
00208 
00213       SharedPtrCount& operator=(const SharedPtrCount& count)
00214       {
00215          if (count.m_count != m_count)
00216          {
00217             if (count.m_count) count.m_count->AddReference();
00218             if (m_count) m_count->ReleaseReference();
00219             m_count = count.m_count;
00220          }
00221 
00222          return *this;
00223       }
00224 
00226       uint32 GetUseCount() const
00227       {
00228          return m_count ? m_count->GetUseCount() : 0;
00229       }
00230 
00232       void Swap(SharedPtrCount& a)
00233       {
00234          std::swap(m_count, a.m_count);
00235       }
00236 
00238       friend inline bool operator==(const SharedPtrCount& a, const SharedPtrCount& b)
00239       {
00240          return a.m_count == b.m_count;
00241       }
00242 
00244       friend inline bool operator<(const SharedPtrCount& a, const SharedPtrCount& b)
00245       {
00246          return a.m_count < b.m_count;;
00247       }
00248 
00249    private:
00251       Impl::SharedPtrCountBase* m_count;
00252       friend class TC::WeakPtrCount;
00253    };
00254 
00256    class WeakPtrCount
00257    {
00258    public:
00259       WeakPtrCount() :m_count(0) {}
00260 
00262       explicit WeakPtrCount(const WeakPtrCount& r) :m_count(r.m_count)
00263       {
00264          if (m_count != 0) m_count->AddWeakReference();
00265       }
00266 
00268       explicit WeakPtrCount(const SharedPtrCount& r) :m_count(r.m_count)
00269       {
00270          if (m_count != 0) m_count->AddWeakReference();
00271       }
00272 
00274       ~WeakPtrCount()
00275       {
00276          if (m_count != 0)
00277          {
00278             m_count->ReleaseWeakReference();
00279             m_count = 0;
00280          }
00281       }
00282 
00284       WeakPtrCount& operator=(const SharedPtrCount& r)
00285       {
00286          if (r.m_count != 0) r.m_count->AddWeakReference();
00287          if (m_count   != 0) m_count->ReleaseWeakReference();
00288          m_count = r.m_count;
00289 
00290          return *this;
00291       }
00292 
00294       WeakPtrCount& operator=(const WeakPtrCount& r)
00295       {
00296          if (r.m_count != 0) r.m_count->AddWeakReference();
00297          if (m_count   != 0) m_count->ReleaseWeakReference();
00298          m_count = r.m_count;
00299 
00300          return *this;
00301       }
00302 
00304       uint32 GetUseCount() const
00305       {
00306          return m_count != 0 ? m_count->GetUseCount(): 0;
00307       }
00308 
00310       void Swap(WeakPtrCount& a)
00311       {
00312          std::swap(m_count, a.m_count);
00313       }
00314 
00316       friend inline bool operator==(const WeakPtrCount& a, const WeakPtrCount& b)
00317       {
00318          return a.m_count == b.m_count;
00319       }
00320 
00322       friend inline bool operator<(const WeakPtrCount& a, const WeakPtrCount& b)
00323       {
00324          return a.m_count < b.m_count;
00325       }
00326 
00327    private:
00329       Impl::SharedPtrCountBase* m_count;
00330       friend class TC::SharedPtrCount;
00331    };
00332 
00333 
00338    inline SharedPtrCount::SharedPtrCount(const WeakPtrCount& count)
00339       :m_count(count.m_count)
00340    {
00341       if (m_count) m_count->AddReference();
00342    }
00343 
00344 } // namespace TC
00345 
00346 #include "TCNewDisable.h"
00347 
00348 #endif // _TC_SHARED_PTR_IMP_H_
00349 

Copyright (c) Thomas Goessler 2003 - 2008