Main Page   Class Hierarchy   Compound List   File List   Compound Members  

SOMEObject.h

00001 /********************************************************************
00002 ** Copyright (C) 2000 SOMELib Project
00003 **
00004 ** This library is free software; you can redistribute it and/or
00005 ** modify it under the terms of the GNU Library General Public
00006 ** License as published by the Free Software Foundation; either
00007 ** version 2 of the License, or (at your option) any later version.
00008 **
00009 ** This library is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 ** Library General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU Library General Public
00015 ** License along with this library; if not, write to the
00016 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017 ** Boston, MA  02111-1307, USA. 
00018 **
00019 *******************************************************************/
00020 
00021 //  SOME::SmartObject based off of boost::shared_ptr from www.boost.org
00022 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. Permission to copy,
00023 //  use, modify, sell and distribute this software is granted provided this
00024 //  copyright notice appears in all copies. This software is provided "as is"
00025 //  without express or implied warranty, and with no claim as to its
00026 //  suitability for any purpose.
00027 
00028 #ifndef SOME_OBJ_HEADER
00029 #define SOME_OBJ_HEADER
00030 
00031 #include <algorithm>
00032 
00033 namespace SOME
00034 {
00035 
00048 template < typename BaseClass >
00049 class ObjectBase
00050 {
00051 public:
00053 
00057 ObjectBase(const SOME::ClassCatalog& cat): catalog(cat)
00058     {}
00059 
00061 
00062 
00063 
00064     virtual ~ObjectBase()
00065     { }
00066 
00068 
00071     bool construct()
00072     {
00073         reset(0);
00074         BaseClass* (*ctor0)() = (BaseClass* (*)())catalog.getCtor0();
00075         if (ctor0 == 0)
00076             return false;
00077 
00078         reset((*ctor0)());
00079 
00080         return !isNull();
00081     }
00082 
00084 
00087     template < typename ParamType1 >
00088     bool construct(ParamType1& a)
00089     {
00090         reset(0);
00091         BaseClass* (*ctor1)(ParamType1&) = (BaseClass * (*)(ParamType1&))catalog.getCtor1();
00092         if (ctor1 == 0)
00093             return false;
00094 
00095         reset((*ctor1)(a));
00096 
00097         return !isNull();
00098     }
00099 
00101 
00104     template < typename ParamType1, typename ParamType2 >
00105     bool construct(ParamType1& a, ParamType2& b)
00106     {
00107         reset(0);
00108         BaseClass* (*ctor2)(ParamType1&, ParamType2&) = (BaseClass * (*)(ParamType1&, ParamType2&))catalog.getCtor2();
00109         if (ctor2 == 0)
00110             return false;
00111 
00112         reset((*ctor2)(a, b));
00113 
00114         return !isNull();
00115     }
00116 
00118     bool isNull()
00119     {
00120         return get() == NULL;
00121     }
00122 
00124     const SOME::ClassCatalog& getClassCatalog() const
00125     {
00126         return catalog;
00127     }
00128 
00129     //Pointer overloads
00130     BaseClass& operator*() const
00131     {
00132         return *get();
00133     }  // never throws
00134     BaseClass* operator->() const
00135     {
00136         return get();
00137     }  // never throws
00138     virtual BaseClass* get() const = 0;
00139 
00140 private:
00141     virtual void reset(BaseClass*) = 0;
00142 
00143 private:
00144     SOME::ClassCatalog catalog;
00145 }
00146 ;  //ObjectBase
00147 
00158 template < typename BaseClass >
00159 class Object: public ObjectBase < BaseClass >
00160 {
00161 public:
00163 
00167 Object(const SOME::ClassCatalog& cat): ObjectBase < BaseClass > (cat)
00168     {}
00169 
00173     virtual BaseClass* get() const
00174     {
00175         return p;
00176     }
00177 
00181     void destroy() const
00182     {
00183         delete p;
00184         reset(0);
00185     }
00186 
00187 private:
00188     virtual void reset(BaseClass* new_p)
00189     {
00190         p = new_p;
00191     }
00192 
00193 private:
00194     BaseClass* p;
00195 }
00196 ;  //Object
00197 
00210 template < typename BaseClass >
00211 class SmartObject: public ObjectBase < BaseClass >
00212 {
00213 public:
00215 
00219 SmartObject(const SOME::ClassCatalog& cat):
00220     ObjectBase < BaseClass > (cat),
00221     p(0)
00222     {
00223         pn = new long(1);
00224     }
00225 
00227 SmartObject(const SmartObject& r): ObjectBase < BaseClass > (r), p(r.p)
00228     {
00229         ++*(pn = r.pn);
00230     }
00231 
00233     ~SmartObject()
00234     {
00235         dispose();
00236     }
00237 
00239     SmartObject& operator=(const SmartObject& r)
00240     {
00241         share(r.px, r.pn);
00242         return *this;
00243     }
00244 
00248     virtual BaseClass* get() const
00249     {
00250         return p;
00251     }
00252 
00253 private:
00254     virtual void reset(BaseClass* new_p)
00255     {
00256         if ( p == new_p ) return ;
00257         if (--*pn == 0)
00258         {
00259             delete p;
00260         }
00261         else
00262         { // allocate new reference counter
00263             try
00264             {
00265                 pn = new long;
00266             }  // fix: prevent leak if new throws
00267             catch (...)
00268             {
00269                 ++*pn;   // undo effect of --*pn above to meet effects guarantee
00270                 delete new_p;
00271                 throw;
00272             } // catch
00273         } // allocate new reference counter
00274 
00275 
00276 
00277         *pn = 1;
00278         p = new_p;
00279     }
00280 
00281     void dispose()
00282     {
00283         if (--*pn == 0)
00284         {
00285             delete p;
00286             delete pn;
00287         }
00288     }
00289 
00290     void share(BaseClass* rp, long* rpn)
00291     {
00292         if (pn != rpn)
00293         {
00294             dispose();
00295             p = rp;
00296             ++*(pn = rpn);
00297         }
00298     }
00299 
00300 private:
00301     BaseClass* p;
00302     long* pn;
00303 }
00304 ;  //SmartObject
00305 
00306 } //namespace SOME
00307 
00308 
00309 
00310 
00311 #endif //SOME_OBJ_HEADER

Generated at Fri Dec 8 14:24:48 2000 for SOMELib by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000