00001 //# DlHandle.h: smart pointer for display library. 00002 //# Copyright (C) 2010 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id$ 00027 00028 #ifndef DLHANDLE_H_ 00029 #define DLHANDLE_H_ 00030 #include <cstddef> 00031 00032 namespace casa { //# NAMESPACE CASA - BEGIN 00033 00034 class DlTarget; 00035 00036 class DlHandleBase { 00037 00038 protected: 00039 DlHandleBase( ) { } 00040 DlHandleBase( const DlHandleBase & ) { } 00041 virtual void target_gone( ) const = 0; 00042 virtual bool null( ) const = 0; 00043 00044 void throw_exception( const char * ) const; 00045 00046 virtual ~DlHandleBase( ) { } 00047 private: 00048 friend class DlTarget; 00049 00050 // Prevent heap allocation 00051 void * operator new (size_t); 00052 void * operator new[] (size_t); 00053 }; 00054 00055 00056 template <class T> class DlHandle : public DlHandleBase { 00057 public: 00058 DlHandle( ) : target_(0) { } 00059 DlHandle( T *tgt ) : target_(tgt) { 00060 if ( target_ ) target_->reg(this); 00061 } 00062 DlHandle( const DlHandle<T> &other ) : DlHandleBase(other), target_(other.target_) { 00063 if ( target_ ) target_->reg(this); 00064 } 00065 T *operator->( ) { 00066 if ( ! target_ ) throw_exception( "null pointer in DlHandle" ); 00067 return target_; 00068 } 00069 const T *operator->( ) const { 00070 if ( ! target_ ) throw_exception( "null pointer in DlHandle" ); 00071 return target_; 00072 } 00073 operator T*( ) { 00074 if ( ! target_ ) throw_exception( "null pointer in DlHandle" ); 00075 return target_; 00076 } 00077 T &operator*( ) { 00078 if ( ! target_ ) throw_exception( "null pointer in DlHandle" ); 00079 return *target_; 00080 } 00081 operator const T*( ) const { 00082 if ( ! target_ ) throw_exception( "null pointer in DlHandle" ); 00083 return target_; 00084 } 00085 const T &operator*( ) const { 00086 if ( ! target_ ) throw_exception( "null pointer in DlHandle" ); 00087 return *target_; 00088 } 00089 DlHandle<T> &operator=( const DlHandle<T> &other ) { 00090 if ( target_ ) target_->unreg(this); 00091 target_ = other.target_; 00092 if ( target_ ) target_->reg(this); 00093 return *this; 00094 } 00095 T *operator=( T *tgt ) { 00096 if ( target_ ) target_->unreg(this); 00097 target_ = tgt; 00098 if ( target_ ) target_->reg(this); 00099 return target_; 00100 } 00101 00102 ~DlHandle( ) { 00103 if ( target_ ) target_->unreg(this); 00104 } 00105 00106 bool null( ) const { 00107 return target_ == 0; 00108 } 00109 const T *ptr( ) const { 00110 return target_; 00111 } 00112 00113 protected: 00114 void target_gone( ) const { 00115 ((DlHandle<T>*)this)->target_ = 0; 00116 } 00117 T *target_; 00118 }; 00119 } 00120 #endif