Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

ref_ptr.hpp

Go to the documentation of this file.
00001 /*==========================================================================
00002  * Copyright (c) 2004 University of Massachusetts.  All Rights Reserved.
00003  *
00004  * Use of the Lemur Toolkit for Language Modeling and Information Retrieval
00005  * is subject to the terms of the software license set forth in the LICENSE
00006  * file included with this software, and also available at
00007  * http://www.lemurproject.org/license.html
00008  *
00009  *==========================================================================
00010  */
00011 
00012 //
00013 // ref_ptr
00014 //
00015 // 15 December 2004 -- tds
00016 //
00017 
00018 #ifndef INDRI_REFPTR_HPP
00019 #define INDRI_REFPTR_HPP
00020 
00021 #include "indri/atomic.hpp"
00022 
00023 namespace indri {
00024   namespace atomic
00025   {
00026     
00027     template<class T>
00028     class ref_ptr {
00029     private:
00030       template<class TT>
00031       struct object_ref {
00032         TT* object;
00033         value_type counter;
00034       };
00035 
00036       typedef ref_ptr<T> my_type;
00037       mutable object_ref<T>* _ref;
00038 
00039       void _removeRef() {
00040         if( _ref ) {
00041           decrement( _ref->counter );
00042           if( _ref->counter == 0 ) {
00043             delete _ref->object;
00044             delete _ref;
00045           }
00046         }
00047       }
00048 
00049       void _addRef() {
00050         if( _ref )
00051           increment( _ref->counter );
00052       }
00053 
00054       my_type& _refAssign( const my_type& other ) {
00055         _removeRef();
00056         _ref = other._ref;
00057         _addRef();
00058         return *this;
00059       }
00060 
00061     public:
00062       ref_ptr() :
00063         _ref(0)
00064       {
00065       }
00066 
00067       ~ref_ptr() {
00068         _removeRef();
00069       }
00070 
00071       ref_ptr( const my_type& other ) :
00072         _ref(0)
00073       {
00074         _refAssign( other );
00075       }
00076 
00077       ref_ptr( T* object ) {
00078         _ref = new object_ref<T>;
00079         _ref->object = object;
00080         _ref->counter = 1;
00081       }
00082 
00083       my_type& operator= ( T* object ) {
00084         _removeRef();
00085 
00086         if( object != 0 ) {
00087           _ref = new object_ref<T>;
00088           _ref->object = object;
00089           _ref->counter = 1;
00090         } else {
00091           _ref = 0;
00092         }
00093 
00094         return *this;
00095       }
00096 
00097       my_type& operator= ( const ref_ptr& other ) {
00098         _refAssign( other );
00099         return *this;
00100       }
00101 
00102       bool operator== ( T* other ) {
00103         if( _ref == 0 )
00104           return other == 0;
00105       
00106         return _ref->object == other;
00107       }
00108 
00109       bool operator== ( ref_ptr& other ) {
00110         return _ref == other._ref;
00111       }
00112 
00113       atomic::value_type references() {
00114         if( _ref )
00115           return _ref->counter;
00116         return 0;
00117       }
00118 
00119       T& operator* () {
00120         return *_ref->object;
00121       }
00122 
00123       T* operator-> () {
00124         return _ref->object;
00125       }
00126 
00127       T* get() {
00128         if( _ref )
00129           return _ref->object;
00130         return 0;
00131       }
00132     };
00133   }
00134 }
00135 
00136 #endif // INDRI_REFPTR_HPP

Generated on Tue Jun 15 11:02:55 2010 for Lemur by doxygen 1.3.4