sprint 1-alpha
|
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