TeSharedPtr.h

Go to the documentation of this file.
00001 /************************************************************************************
00002 TerraLib - a library for developing GIS applications.
00003 Copyright � 2001-2007 INPE and Tecgraf/PUC-Rio.
00004 
00005 This code is part of the TerraLib library.
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 You should have received a copy of the GNU Lesser General Public
00012 License along with this library.
00013 
00014 The authors reassure the license terms regarding the warranties.
00015 They specifically disclaim any warranties, including, but not limited to,
00016 the implied warranties of merchantability and fitness for a particular purpose.
00017 The library provided hereunder is on an "as is" basis, and the authors have no
00018 obligation to provide maintenance, support, updates, enhancements, or modifications.
00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
00020 indirect, special, incidental, or consequential damages arising out of the use
00021 of this library and its documentation.
00022 *************************************************************************************/
00023 
00024 #ifndef TESHAREDPTR_H
00025   #define TESHAREDPTR_H
00026 
00027   #include "TeMutex.h"
00028   #include "TeAgnostic.h"
00029 
00030   /**
00031    * @class This class deals with automatic object deletion when no 
00032    * reference to that object no longer exists.
00033    * @note This is a thread-safe class.
00034    * @author Emiliano F. Castejon <castejon@dpi.inpe.br>
00035    * @ingroup Utils
00036    * @example TeSharedPtr_test.cpp Shows how to use this class.
00037    * @note Shared-mode - The object will be automaticaly deleted 
00038    * when apropriate.
00039    * @note Not-Shared-mode - The object will NOT be deleted.
00040    */
00041   template< class T >
00042   class TeSharedPtr {
00043     public :
00044       /**
00045        * @brief Default Constructor( Shared mode ).
00046        */
00047       explicit TeSharedPtr();
00048       
00049       /**
00050        * @brief Alternative Constructor( Shared mode ).
00051        *
00052        * @param pointer A pointer the the active object.
00053        */
00054       explicit TeSharedPtr( T* pointer );      
00055         
00056       /**
00057        * @brief Alternative Constructor.
00058        *
00059        * @param external External shared pointer reference.
00060        */
00061       TeSharedPtr( const TeSharedPtr< T >& external );        
00062       
00063       /**
00064        * @brief Alternative Constructor( Not-shared mode ).
00065        * @param objectReference A reference to an existing
00066        * object.
00067        * @note By using this constructor this pointer instance
00068        * will be constructed in not-shared mode and will not delete 
00069        * the object instance.
00070        */
00071       explicit TeSharedPtr( T& objectReference );           
00072         
00073       /**
00074        * @deprecated DEPRECATED - Will be removed in the future (Use the 
00075        * method TeSharedPtr( T& objectReference ) to construct pointers
00076        * in not-shared mode ).
00077        * @brief Alternative Constructor.
00078        * @param pointer A pointer the the active object.
00079        * @param not_shared_flag A flag indication for a static
00080        * assignment ( the pointed object will not be deleted at the
00081        * this object destruction ).
00082        */
00083       explicit TeSharedPtr( T* pointer,  bool not_shared_flag );        
00084 
00085       /**
00086        * @brief Default Destructor
00087        */
00088       ~TeSharedPtr();
00089 
00090       /**
00091        * @brief Verifies if the current pointer points to an active object.
00092        *
00093        * @return true if active, false if not.
00094        */
00095       inline bool isActive() const
00096       {
00097         return ( reference_ != 0 );
00098       };
00099       
00100       /**
00101        * @brief Verifies if the current pointer is shared.
00102        *
00103        * @return true if shared, false if not.
00104        */
00105       inline bool isShared() const
00106       {
00107         return ( ! not_shared_flag_ );
00108       };      
00109       
00110       /**
00111        * @brief Reset the active instance deleting any pointed object
00112        * if the current instance is in shared mode and no more references 
00113        * to the pointed object exists.
00114        */
00115       inline void reset()
00116       {
00117         reset( 0, 0 );
00118       };
00119       
00120       /**
00121        * @brief Reset the active instance the the new pointer (shared mode).
00122        *
00123        * @param pointer A pointer the the active object.
00124        */
00125       inline void reset( T* pointer )
00126       {
00127         reset( pointer, false );
00128       };
00129 
00130       /**
00131        * @brief Reset the active instance the the new pointer.
00132        *
00133        * @param pointer A pointer the the active object.
00134        * @param not_shared_flag A flag indication for a static
00135        * assignment ( the pointed object will not be deleted at the
00136        * this object destruction ).
00137        */
00138       void reset( T* pointer, bool not_shared_flag );
00139 
00140       // Operator = overload.
00141       const TeSharedPtr< T >& operator=( const TeSharedPtr< T >& external );
00142 
00143       /**
00144        * @brief Operator * overload.
00145        *
00146        * @return The pointed object reference.
00147        */
00148       inline T& operator*() const
00149       {
00150         TEAGN_DEBUG_CONDITION( isActive(), 
00151           "Trying to use an inactive shared pointer instance" );
00152     
00153         return *reference_;
00154       };
00155 
00156       /**
00157        * @brief Operator -> overload.
00158        *
00159        * @return The pointed object pointer.
00160        */
00161       inline T* operator->() const
00162       {
00163         TEAGN_DEBUG_CONDITION( isActive(), 
00164           "Trying to use an inactive shared pointer instance" );
00165         
00166         return reference_;
00167       };
00168 
00169       // Operator == overload.
00170       inline bool operator==( const TeSharedPtr< T >& external ) const
00171       {
00172         return ( ( reference_ == external.reference_ ) && 
00173           ( counter_ == external.counter_ ) &&
00174           ( not_shared_flag_ == external.not_shared_flag_ ) );
00175       };
00176       
00177       /**
00178        * @brief Operator< overload.
00179        *
00180        * @param external The external instance reference.
00181        * @return true if the current pointer pointed address has a lower value 
00182        * then the external shared pointer pointed address.
00183        */
00184       inline bool operator<( const TeSharedPtr< T >& external ) const
00185       {
00186         return ( reference_ < external.reference_ );
00187       };      
00188       
00189       /**
00190        * @brief Operator> overload.
00191        *
00192        * @param external The external instance reference.
00193        * @return true if the current pointer pointed address has a lower value 
00194        * then the external shared pointer pointed address.
00195        */
00196       inline bool operator>( const TeSharedPtr< T >& external ) const
00197       {
00198         return ( reference_ > external.reference_ );
00199       };      
00200             
00201       // Operator != overload.
00202       inline bool operator!=( const TeSharedPtr< T >& external ) const
00203       {
00204         return ( ! operator==( external ) );
00205       };
00206 
00207       /**
00208        * @brief A Naked Pointer to the encapsulated object.
00209        *
00210        * @return The internal instance pointer.
00211        */
00212       inline T* nakedPointer() const
00213       {
00214         return reference_;
00215       };
00216       
00217       /**
00218        * @brief The number of current references to the pointed object.
00219        *
00220        * @return The number of current references to the pointed object.
00221        */
00222       unsigned long int getRefCount() const;            
00223 
00224     protected :
00225     
00226       /**
00227        * @brief This instance locking mutex.
00228        */    
00229       mutable TeMutex this_lock_instance_;
00230       
00231       /**
00232        * @brief A pointer to the shared counter locking mutex (default:0).
00233        */    
00234       mutable TeMutex* counter_lock_instance_ptr_;      
00235 
00236       /**
00237        * @brief A pointer to the current number of active users of this 
00238        * pointer (default:0).
00239        */
00240       mutable unsigned long int volatile* counter_;
00241 
00242       /**
00243        * @brief A pointer to the current object encapsulated by this
00244        * shared pointer (default:0).
00245        */
00246       mutable T* reference_;
00247 
00248       /**
00249        * @brief A flag indicating if this shared pointer was created by a
00250        * dynamic assignment ( false value ) or by a static
00251        * assignment(if true, the encapsulated object will not
00252        * be deleted when apropriate) (default:false).
00253        */
00254       mutable bool not_shared_flag_;
00255       
00256       /**
00257        * @brief Set all internal variables to default values.
00258        *
00259        */
00260       void init();
00261   };
00262 
00263   
00264   template< class T >
00265   TeSharedPtr< T >::TeSharedPtr()
00266   {
00267     init();
00268   }
00269   
00270   
00271   template< class T >
00272   TeSharedPtr< T >::TeSharedPtr( T* pointer )
00273   {
00274     init();
00275     reset( pointer, false );
00276   } 
00277  
00278    
00279   template< class T >
00280   TeSharedPtr< T >::TeSharedPtr( const TeSharedPtr< T >& external )
00281   {
00282     init();
00283     operator=( external );
00284   } 
00285   
00286   template< class T >
00287   TeSharedPtr< T >::TeSharedPtr( T& objectReference )
00288   {
00289     init();
00290     reset( &objectReference, true );
00291   } 
00292     
00293   template< class T >
00294   TeSharedPtr< T >::TeSharedPtr( T* pointer, bool not_shared_flag )
00295   {
00296     init();
00297     reset( pointer, not_shared_flag );
00298   }  
00299 
00300 
00301   template< class T >
00302     TeSharedPtr< T >::~TeSharedPtr()
00303   {
00304     reset( 0, 0 );
00305   }
00306 
00307   template< class T >
00308   void TeSharedPtr< T >::reset( T* pointer, bool not_shared_flag )
00309   {
00310     this_lock_instance_.lock();
00311     
00312     /* updating the shared objects */
00313     
00314     if( ( reference_ != 0 ) && ( ! not_shared_flag_ ) ) {
00315       counter_lock_instance_ptr_->lock();
00316     
00317       --(*counter_);
00318       
00319       /* Cleanning the shared pointed objects if necessary */
00320 
00321       if( (*counter_) == 0 ) {
00322         delete counter_;
00323         delete reference_;
00324         delete counter_lock_instance_ptr_;
00325       } else {
00326         counter_lock_instance_ptr_->unLock();
00327       }
00328     }
00329      
00330     init();
00331     
00332     /* Acquiring the pointed object */
00333 
00334     if( pointer != 0 ) {
00335       if( ! not_shared_flag ) {
00336         counter_ = new unsigned long int;
00337         (*counter_) = 1;
00338         counter_lock_instance_ptr_ = new TeMutex;
00339       }
00340 
00341       reference_ = pointer;
00342       not_shared_flag_ = not_shared_flag;
00343     }
00344     
00345     this_lock_instance_.unLock();
00346   }
00347 
00348 
00349   template< class T >
00350   const TeSharedPtr< T >& TeSharedPtr< T >::operator=(
00351     const TeSharedPtr< T >& external )
00352   {
00353     if( ( &external ) != this ) 
00354     {
00355       reset( 0, 0 );
00356   
00357       this_lock_instance_.lock();
00358       
00359       if( (&external) != 0 ) 
00360       {
00361         external.this_lock_instance_.lock();
00362       
00363         if( external.reference_ ) 
00364         {
00365           reference_ = external.reference_;
00366           counter_lock_instance_ptr_ = external.counter_lock_instance_ptr_;
00367           counter_ = external.counter_;
00368           reference_ = external.reference_;
00369           not_shared_flag_ = external.not_shared_flag_;
00370         
00371           if( ! not_shared_flag_ ) 
00372           {
00373             (*counter_) = (*counter_) + 1;
00374           }
00375         }
00376         
00377         external.this_lock_instance_.unLock();
00378       }
00379       
00380       this_lock_instance_.unLock();
00381     }
00382 
00383     return *this;
00384   }
00385   
00386   template< class T >
00387   unsigned long int TeSharedPtr< T >::getRefCount() const
00388   {
00389     if( reference_ ) {
00390       if( counter_) {
00391         return (*counter_);
00392       } else {
00393         return 1;
00394       }
00395     } else {
00396       return 0;
00397     }
00398   }  
00399   
00400   template< class T >
00401   void TeSharedPtr< T >::init()
00402   {
00403     counter_ = 0;
00404     reference_ = 0;
00405     counter_lock_instance_ptr_ = 0;
00406     not_shared_flag_ = false;  
00407   }  
00408   
00409 #endif
00410 

Generated on Sun Jul 29 04:01:28 2012 for TerraLib - Development Source by  doxygen 1.5.3