Home C-Bits Package Documentation Project Page

Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members  

ref_ptr.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  *              The CBITS Software License, Version 1.0
00003  *
00004  *               Copyright (c) 2002-2003 Bruce Lowery
00005  *                       All rights reserved
00006  *
00007  * Redistribution and use of this software, in source and binary forms, 
00008  * with or without modification, are permitted provided that the above 
00009  * copyright notice, this paragraph, and the following paragraph are 
00010  * retained in each source code file.
00011  *
00012  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00013  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00014  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00015  * DISCLAIMED.  IN NO EVENT SHALL BRUCE LOWERY OR OTHER CONTRIBUTORS 
00016  * TO THE CBITS LIBRARY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00017  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00018  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00019  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00020  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00021  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00022  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00023  * SUCH DAMAGE.
00024  * ====================================================================
00025  */
00026 #ifndef __REF_PTR_H__
00027 #define __REF_PTR_H__
00028 
00029 #include <stdlib.h>
00030 
00031 #ifdef USE_PTHREADS
00032 #include <pthread.h>
00033 #elif defined WIN32
00034 #include <winnt.h>
00035 #endif
00036 
00064 namespace cbits
00065 {
00066 
00085 template< typename T >
00086 class ref_ptr
00087 {
00088 public:
00089 
00095     ref_ptr<T>( T* t ) : _t(t),_refs(new long)
00096     {
00097         *(_refs) = 1;
00098 #ifdef USE_PTHREADS
00099         _lock = new pthread_mutex_t;
00100         pthread_mutex_init( _lock, 0 );
00101 #elif defined WIN32
00102         _lock = CreateMutex( 0, FALSE, 0 );
00103 #endif
00104     }
00105 
00106 
00112     ref_ptr<T>( const ref_ptr<T>& r )
00113     {
00114         r.lock();
00115         _t = r._t;
00116         _refs = r._refs;
00117         _lock = r._lock;
00118         (*_refs)++;
00119         r.unlock();
00120     }
00121 
00122 
00128     ref_ptr<T>& operator=( const ref_ptr<T>& r )
00129     {
00130         if( _t == r._t )
00131         {
00132             return *this;
00133         }
00134 
00135         r.lock();
00136         (*r._refs)++;
00137 
00138         lock();
00139         (*_refs)--;
00140         int n = *_refs;
00141         unlock();
00142 
00143         if( 0 == n )
00144         {
00145             freeObject();
00146         }
00147 
00148         _t = r._t;
00149         _refs = r._refs;
00150         _lock = r._lock;
00151         r.unlock();
00152         return *this;
00153     }
00154 
00155 
00164     const long getRefCount() const
00165     {
00166         lock();
00167         long n = *_refs;
00168         unlock();
00169         return n;
00170     }
00171 
00172 
00178     bool operator==( const ref_ptr<T>& r )
00179     {
00180         return _t == r._t;
00181     }
00182 
00183 
00189     T* operator->()
00190     {
00191         return _t;
00192     }
00193 
00194 
00200     T& operator*()
00201     {
00202         return *_t;
00203     }
00204 
00205 
00213     virtual ~ref_ptr<T>()
00214     {
00215         lock();
00216         (*_refs)--;
00217         int n = *_refs;
00218         unlock();
00219 
00220         if( 0 == n )
00221         {
00222             freeObject();
00223         }
00224     }
00225 
00226 
00227 protected:
00228 
00229     T* _t;       
00230     long* _refs; 
00232 private:
00233 
00238     void freeObject()
00239     {
00240         delete _t;
00241         delete _refs;
00242 #if defined USE_PTHREADS 
00243         delete _lock;
00244 #elif defined WIN32
00245         CloseHandle( _lock );
00246 #endif
00247     }
00248 
00252     void lock() const
00253     {
00254 #ifdef USE_PTHREADS
00255         pthread_mutex_lock( _lock );
00256 #elif defined(WIN32)
00257         WaitForSingleObject( _lock, INFINITE );
00258 #endif
00259 
00260     }
00261 
00265     void unlock() const
00266     {
00267 #ifdef USE_PTHREADS
00268         pthread_mutex_unlock( _lock );
00269 #elif defined(WIN32)
00270         ReleaseMutex( _lock );
00271 #endif
00272     }
00273 
00274 #ifdef USE_PTHREADS
00275     mutable pthread_mutex_t * _lock;  
00276 #elif defined(WIN32)
00277     HANDLE _lock;                     
00278 #endif
00279 };
00280 
00281 };
00282 
00283 #endif
00284 
00285 /*
00286  * $Id: ref_ptr.h,v 1.5 2002/10/15 03:13:54 brulow Exp $
00287  *
00288  * History: (Add nothing manually below)
00289  * -----------------------------------------------------------------------
00290  *
00291  * $Log: ref_ptr.h,v $
00292  * Revision 1.5  2002/10/15 03:13:54  brulow
00293  * Fix unit tests
00294  *
00295  * Revision 1.4  2002/10/14 01:36:54  brulow
00296  * Add pointer pkg documentation
00297  *
00298  * Revision 1.3  2002/10/14 01:21:04  brulow
00299  * Add unit tests for pointer pkg
00300  *
00301  * Revision 1.2  2002/10/13 20:12:59  brulow
00302  * *** empty log message ***
00303  *
00304  * Revision 1.1  2002/10/13 15:19:58  brulow
00305  * Add 'smart, ref counting' pointer.
00306  *
00307  *
00308  */

Generated by
doxygen
Hosted by
SourceForge