casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ptr.h
Go to the documentation of this file.
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