casa
$Rev:20696$
|
00001 //# ptr.h: pointer classes (currently only counted pointer) used within casadbus 00002 //# 00003 //# Copyright (C) 2011 00004 //# Associated Universities, Inc. Washington DC, USA. 00005 //# 00006 //# This library is free software; you can redistribute it and/or modify it 00007 //# under the terms of the GNU Library General Public License as published by 00008 //# the Free Software Foundation; either version 2 of the License, or (at your 00009 //# option) any later version. 00010 //# 00011 //# This library is distributed in the hope that it will be useful, but WITHOUT 00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 //# License for more details. 00015 //# 00016 //# You should have received a copy of the GNU Library General Public License 00017 //# along with this library; if not, write to the Free Software Foundation, 00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00019 //# 00020 //# Correspondence concerning AIPS++ should be addressed as follows: 00021 //# Internet email: aips2-request@nrao.edu. 00022 //# Postal address: AIPS++ Project Office 00023 //# National Radio Astronomy Observatory 00024 //# 520 Edgemont Road 00025 //# Charlottesville, VA 22903-2475 USA 00026 //# 00027 //# $Id$ 00028 00029 #ifndef __casadbus_ptr_h__ 00030 #define __casadbus_ptr_h__ 00031 #include <string> 00032 #include <stdio.h> 00033 00034 namespace casa { 00035 00036 namespace memory { 00037 template <class T> class cptr { 00038 public: 00039 cptr( ) : ptr((T*)0) { } 00040 cptr(T *p) : ptr(p) { } 00041 cptr<T>(const cptr<T> &other) : ptr(other.ptr) { } 00042 cptr<T>(cptr<T> *other) : ptr(other->ptr) { } 00043 T *operator->( ) { return ptr.val; } 00044 T &operator*( ) { return *ptr.val; } 00045 00046 const T *operator->( ) const { return ptr.val; } 00047 const T &operator*( ) const { return *ptr.val; } 00048 00049 bool isNull( ) const { return ptr.isNull( ); } 00050 const cptr<T> &operator=( const cptr<T> &other ) { ptr = other.ptr; return *this; } 00051 const cptr<T> &operator=( T *&optr ) { ptr = optr; optr = 0; return *this; } 00052 std::string state( ) const { 00053 char buf[128]; 00054 sprintf( buf, "0x%lx (%d)", (unsigned long) ptr.val, *ptr.count ); 00055 return std::string(buf); 00056 } 00057 void clear( ) { ptr.clear( ); } 00058 unsigned int count( ) const { return *ptr.count; } 00059 00060 private: 00061 template <class X> friend bool operator==(const cptr<X>&, X*); 00062 template <class X> friend bool operator==(X*, const cptr<X>&); 00063 00064 struct kernel { 00065 T *val; 00066 unsigned int *count; 00067 kernel(T *v) : val(v), count(new unsigned int) { *count = 1u; } 00068 kernel( const kernel &other ) : val(other.val), count(other.count) { *count += 1u; } 00069 ~kernel( ) { release( ); } 00070 void operator=( const kernel &other ) { release( ); val = other.val; count = other.count; *count += 1u; } 00071 void operator=( T *oval ) { release( ); val = oval; count = new unsigned int; *count = 1u; } 00072 void release( ) { if ( --*count == 0u ) { delete val; delete count; } } 00073 bool isNull( ) const { return val == 0 ? true : false; } 00074 void clear( ) { release( ); val = 0; count = new unsigned int; *count = 1u; } 00075 bool eq( T *x ) const { return val == x; } 00076 }; 00077 kernel ptr; 00078 }; 00079 00080 template<class T> bool operator==( const cptr<T> &l, T *r ) { return l.ptr.eq(r); } 00081 template<class T> bool operator==( T *l, const cptr<T> &r ) { return r.ptr.eq(l); } 00082 00083 // considered introducing something like: 00084 // 00085 // template <class D, class B> class cptr_ref { 00086 // public: 00087 // cptr_ref(cptr<D> &); 00088 // cptr_ref( const cptr_ref<D,B> &other); 00089 // B *operator->( ) { return ref.operator->( ); } 00090 // B &operator*( ) { return ref.operator*( ); } 00091 // }; 00092 // 00093 // to represent a base class (B) reference to a counted pointer based on 00094 // a derived class (D). However, the derived class is still intertwined 00095 // with the type so it falls short for a number of derived classes. 00096 } 00097 00098 using memory::operator==; 00099 00100 } 00101 00102 #endif 00103 00104