# BasicSmartPointer.h

Go to the documentation of this file.

    00001 /*******************************************************************\
    00002
    00003               Copyright (C) 2003 Joseph Coffland
    00004
    00005     This program is free software; you can redistribute it and/or
    00006      modify it under the terms of the GNU General Public License
    00007     as published by the Free Software Foundation; either version 2
    00008         of the License, or (at your option) any later version.
    00009
    00010    This program is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00013              GNU General Public License for more details.
    00014
    00015   You should have received a copy of the GNU General Public License
    00016      along with this program; if not, write to the Free Software
    00017       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    00018                            02111-1307, USA.
    00019
    00020             For information regarding this software email
    00021                    jcofflan@users.sourceforge.net
    00022
    00023 \*******************************************************************/
    00024
    00025 #include "BasicException.h"
    00026
    00027 #ifndef BASICSMARTPOINTER_H
    00028 #define BASICSMARTPOINTER_H
    00029
    00030 #include "BasicCounter.h"
    00031
    00032 #include <stdlib.h>
    00033
    00034 // Forward Delcarations
    00035 class BasicException;
    00036
    00037 typedef enum {SP_NEW, SP_ARRAY, SP_MALLOC} sp_alloc_t;
    00038
    00066 template <class T, sp_alloc_t alloc_t = SP_NEW>
    00067 class BasicSmartPointer {
    00069   BasicCounter *refCounter;
    00070
    00072   T *ptr;
    00073
    00074 public:
    00079   BasicSmartPointer() : refCounter(0), ptr(0) {}
    00080
    00087   BasicSmartPointer(const BasicSmartPointer<T, alloc_t> &smartPtr) :
    00088     refCounter(0), ptr(0) {
    00089     *this = smartPtr;
    00090   }
    00091
    00104   BasicSmartPointer(T *ptr) : refCounter(0), ptr(0) {
    00105     if (ptr) {
    00106       refCounter = new BasicCounter(1);
    00107       this->ptr = ptr;
    00108     }
    00109   }
    00110
    00116   ~BasicSmartPointer() {release();}
    00117
    00126   const bool operator==(const BasicSmartPointer<T, alloc_t> &smartPtr) {
    00127     return ptr == smartPtr.ptr;
    00128   }
    00129
    00138   const bool operator==(const T *ptr) {
    00139     return this->ptr == ptr;
    00140   }
    00141
    00150   BasicSmartPointer<T, alloc_t> &
    00151   operator=(const BasicSmartPointer<T, alloc_t> &smartPtr) {
    00152     if (*this == smartPtr) return *this;
    00153
    00154     release();
    00155
    00156     refCounter = smartPtr.refCounter;
    00157     if (refCounter) refCounter->inc();
    00158     ptr = smartPtr.ptr;
    00159
    00160     return *this;
    00161   }
    00162
    00169   T *operator->() const {checkPtr(); return get();}
    00170
    00177   T &operator*() const {checkPtr(); return *get();}
    00178
    00186   T &operator[](const long x) const {checkPtr(); return get()[x];}
    00187
    00193   T *get() const {return ptr;}
    00194
    00196   bool operator!() const {return ptr == 0;}
    00197
    00203   void release() {
    00204     if (refCounter && !refCounter->dec()) {
    00205       delete refCounter;
    00206       switch (alloc_t) {
    00207       case SP_NEW: delete ptr; break;
    00208       case SP_ARRAY: delete [] ptr; break;
    00209       case SP_MALLOC: free(ptr); break;
    00210       }
    00211     }
    00212
    00213     refCounter = 0;
    00214     ptr = 0;
    00215   }
    00216
    00227   T *adopt() {
    00228     if (refCounter && refCounter->getCount() > 1)
    00229       throw BasicException(std::string("BasicSmartPointer: Cannot adopt a") +
    00230                            "pointer with multiple references!");
    00231
    00232     if (refCounter) {
    00233       delete refCounter;
    00234       refCounter = 0;
    00235     }
    00236     T *tmp = ptr;
    00237     ptr = 0;
    00238
    00239     return tmp;
    00240   }
    00241
    00250   long getRefCount() const {return refCounter ? refCounter->getCount() : 0;}
    00251
    00257   bool isNull() const {return get() == 0;}
    00258
    00259 protected:
    00260   void checkPtr() const {
    00261     if (!ptr)
    00262       throw
    00263         BasicException("BasicSmartPointer: Can't dereference a NULL pointer!");
    00264   }
    00265 };
    00266 #endif