sprint 1-alpha
sprint/container/shared_ptr.h
Go to the documentation of this file.
00001 /******************************************************************************
00002 *   sprint::shared_ptr
00003 *
00004 *   Copyright (C) 2005-2011  Paolo Medici <www.pmx.it>
00005 *
00006 *  This library is free software; you can redistribute it and/or
00007 *  modify it under the terms of the GNU Lesser General Public
00008 *  License as published by the Free Software Foundation; either
00009 *  version 2.1 of the License, or (at your option) any later version.
00010 *
00011 *  This library is distributed in the hope that it will be useful,
00012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 *  Lesser General Public License for more details.
00015 *
00016 *  You should have received a copy of the GNU Lesser General Public
00017 *  License along with this library; if not, write to the Free Software
00018 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 *
00020 *******************************************************************************/
00021 #ifndef _SPRINT_SHARED_PTR_H
00022 #define _SPRINT_SHARED_PTR_H
00023 
00029 namespace sprint {
00030 
00040 struct sharable {
00041       mutable long m_refCount;
00043       sharable() : m_refCount(0) { }
00045       long use_count() const { return m_refCount; }
00046       };
00047       
00049 template<class T>
00050 void add_ref(T * obj) { obj->m_refCount ++; }      
00051 
00053 template<class T>
00054 void release(T * obj) 
00055      { 
00056        if(obj)
00057            {
00058            obj->m_refCount --; 
00059            if(obj->m_refCount == 0)
00060              delete obj;
00061            }
00062      }      
00063           
00079 template<class T>
00080 class shared_ptr {
00081  T *m_ptr;
00082  public:
00083   
00085   shared_ptr(T * obj) : m_ptr(obj) 
00086   { 
00087     sprint::add_ref(m_ptr);
00088   }
00090   shared_ptr(const shared_ptr<T> & obj) : m_ptr(obj.get())  // non explicit (avoid bogus copy costructor)
00091   { 
00092     sprint::add_ref(m_ptr);
00093   }
00095   template<class R>
00096   explicit shared_ptr(const shared_ptr<R> & obj) : m_ptr(obj.get()) 
00097   { 
00098     sprint::add_ref(m_ptr);
00099   }
00100   
00102   ~shared_ptr() 
00103   { 
00104     sprint::release(m_ptr);
00105   }
00106    
00107   inline shared_ptr & operator = ( const shared_ptr<T> & a)
00108   {
00109     sprint::release(m_ptr);
00110     m_ptr = a.m_ptr;
00111     sprint::add_ref(m_ptr);
00112     return *this;
00113   }
00114   
00115   inline T & operator *() const
00116   {
00117     return *m_ptr;
00118   }
00119   
00120   inline T * operator->() const
00121   {
00122     return m_ptr;
00123   }
00124   inline T * get() const
00125   {
00126       return m_ptr;
00127   }
00128 
00130   int use_count() const {
00131         return m_ptr->m_refCount;
00132   }
00133       
00134   void swap(shared_ptr & b) 
00135     {
00136       T * tmp;
00137       tmp = b.m_ptr;
00138       b.m_ptr = m_ptr;
00139       m_ptr = tmp;
00140     }
00141 };
00142 
00143 }
00144 
00145 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines