Main Page   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

SmartPtrImpl.h

00001 /*****************************************************************************
00002  * Author:   Valient Gough <vgough@pobox.com>
00003  *
00004  *****************************************************************************
00005  * Copyright (c) 2001, Valient Gough
00006  *
00007  * This library is free software; you can distribute it and/or modify it under
00008  * the terms of the GNU Lesser General Public License (LGPL), as published by
00009  * the Free Software Foundation; either version 2.1 of the License, or (at your
00010  * option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE.  See the LGPL in the file COPYING for more
00015  * details.
00016  *
00017  */
00018 
00019 #ifndef _SmartPtrImpl_incl_
00020 #define _SmartPtrImpl_incl_
00021 
00022 // smart pointer implementation details - things that are not normally
00023 // necessary to view when looking at how to use a SmartPtr
00024 
00025 #include <typeinfo>
00026 #include <assert.h>
00027 
00028 namespace rel
00029 {
00030 
00031     class OpaqueValue;
00032 
00033     /*
00034         Base class for underlying implementation in smart pointer
00035      */
00036     class OpaqueValueData
00037     {
00038     public:
00039         virtual ~OpaqueValueData();
00040 
00041         // get pointer to data
00042         virtual void *getValue() const =0;
00043         // get type of data
00044         virtual const std::type_info &type() const =0;
00045 
00046         // clone existing opaque value data.  Returns "this" by default.
00047         virtual OpaqueValueData *clone();
00048 
00049         // retain opaque value data.  Should be called by anyone wanting to
00050         // keep this value around.
00051         virtual void retain() =0;
00052         // release opaque value data.  Returns true if this OpaqueValueData can
00053         // now be freed.
00054         virtual bool release() =0;
00055 
00056         // special support for interpretable results (can act as a function -
00057         // taking a set of arguments and returning another type).
00058         virtual bool interpret(const std::type_info &attemptedResultType,
00059                 const OpaqueValue *args, OpaqueValue *output) =0;
00060     };
00061 
00062 
00063     template<class Type>
00064     bool smartPtrInterpret(Type * /*value*/, 
00065             const std::type_info & /*attemptedResultType*/,
00066             const OpaqueValue * /*args*/ , 
00067             OpaqueValue * /*output*/)
00068     {
00069         return false;
00070     }
00071 
00072     class OVDPtrImplBase : public OpaqueValueData
00073     {
00074     public:
00075         OVDPtrImplBase(void *src, void (*destructor)(void*));
00076         ~OVDPtrImplBase();
00077 
00078         void *getValue() const;
00079         void retain();
00080         bool release();
00081 
00082     protected:
00083         int refCnt;
00084         // raw data pointer.  This is opaque to the map.
00085         void *value;
00086         // destructor helper
00087         void (*destroyOp)(void *);
00088     };
00089 
00090     /*
00091         Default implementation of OpaqueValueData, for storing a pointer to
00092         data.
00093      */
00094     template<class Type>
00095     class OVDPtrImpl : public OVDPtrImplBase
00096     {
00097     public:
00098         OVDPtrImpl(Type *src, void (*destructor)(Type*))
00099             : OVDPtrImplBase(src, (void(*)(void*))destructor) {}
00100 
00101         ~OVDPtrImpl() {}
00102 
00103         const std::type_info &type() const {return typeid(Type);}
00104 
00105         bool interpret(const std::type_info &resultType,
00106                 const OpaqueValue *args, OpaqueValue *output)
00107         { return smartPtrInterpret<Type>((Type*)value, resultType, 
00108                 args, output); }
00109     };
00110 
00111     /*
00112         implementation of OpaqueValueData for by-value types. 
00113         This stores the data by value rather then as a pointer.
00114      */
00115     template<class Type>
00116     class OVDValueImpl : public OpaqueValueData
00117     {
00118     public:
00119         OVDValueImpl(Type src, void (*destructor)(Type))
00120             : refCnt(0), value(src), destroyOp(destructor) {}
00121 
00122         virtual ~OVDValueImpl() 
00123         {
00124             // should never happen, or else memory is stuffed
00125             assert(refCnt == 0);
00126         }
00127 
00128         virtual void *getValue() const {return (void*)&value;}
00129         virtual const std::type_info &type() const {return typeid(Type);}
00130 
00131         OpaqueValueData *clone() { return this; }
00132         void retain() {++refCnt;}
00133         bool release()
00134         {
00135             if(--refCnt == 0)
00136             {
00137                 if(destroyOp)
00138                     (*destroyOp)(value);
00139                 return true;
00140             } else
00141                 return false;
00142         }
00143 
00144         bool interpret(const std::type_info &resultType,
00145                 const OpaqueValue *args, OpaqueValue *output)
00146         { return smartPtrInterpret<Type>(&value, resultType, args, output); }
00147 
00148         int refCnt;
00149         // raw data pointer.  This is opaque to the map.
00150         Type value;
00151         // destructor helper
00152         void (*destroyOp)(Type);
00153     };
00154 
00155 } // namespace rel
00156 
00157 #endif

Generated at Sat Sep 22 02:20:00 2001 for librel by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001