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

SmartPtr.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 _OpaqueValue_incl_
00020 #define _OpaqueValue_incl_
00021 
00022 #include <unistd.h>
00023 
00024 #include <rel/SmartPtrImpl.h>
00025 
00026 
00027 namespace rel
00028 {
00029 
00056     class OpaqueValue
00057     {
00058     public:
00059         enum DestructorFlag
00060         {
00061             No_Destructor
00062         };
00063 
00064 
00065 
00066         OpaqueValue();
00067         OpaqueValue(const OpaqueValue &value);
00068         OpaqueValue(OpaqueValueData *value);
00069         ~OpaqueValue();
00070 
00071         const std::type_info &type() const;
00072         bool interpret(const std::type_info &attemptedResultType,
00073                 const OpaqueValue *args, OpaqueValue *output);
00074 
00075         OpaqueValue &operator=(const OpaqueValue &src);
00076 
00077         /*
00078             Get a pointer to the data being stored
00079          */
00080         inline void *get() const    { return data ? data->getValue() : NULL; }
00081 
00082         // check that the current type matches the destination type.  Returns
00083         // false if they do not match.
00084         bool checkType(const std::type_info &dst);
00085         // just like checkType, except that it throws a bad_cast error if the
00086         // types do not match.
00087         void assertType(const std::type_info &dst);
00088         // throw a bad_operation error if value is NULL
00089         void assertNotNull(const void *value) const;
00090 
00091         void reset(OpaqueValueData *value = NULL);
00092 
00093     private:
00094         OpaqueValueData *data;
00095     };
00096 
00097 
00098     template<typename Type>
00099     void defaultDestructorFunc(Type *data)
00100     {
00101         delete data;
00102     }
00103 
00104     // destructor which can be used for malloc allocated string
00105     void freeDestructor(char *data);
00106 
00107     template<class Type>
00108     class SmartPtr : public OpaqueValue
00109     {
00110     public:
00111         SmartPtr() {}
00112 
00113         ~SmartPtr() {}
00114 
00115         SmartPtr( const OpaqueValue &untyped ) 
00116             : OpaqueValue(untyped)
00117             { 
00118                 assertType(typeid(Type));
00119             }
00120 
00121         SmartPtr( const SmartPtr<Type> &src ) 
00122             : OpaqueValue(src)
00123             {}
00124 
00125         // don't want automatic conversion from Type*, since that conversion is
00126         // a change of ownership - it must be explicit!
00127         explicit SmartPtr(Type *value)
00128             : OpaqueValue(new OVDPtrImpl<Type>(value, 
00129                         &defaultDestructorFunc<Type>))
00130             {}
00131 
00132         // for specifying no destructor
00133         SmartPtr(Type *value, DestructorFlag)
00134             : OpaqueValue(new OVDPtrImpl<Type>(value, (void(*)(Type*))NULL))
00135             {}
00136         // for specifying no destructor for by-value information..
00137         SmartPtr(Type value, DestructorFlag)
00138             : OpaqueValue(new OVDValueImpl<Type>(value, (void(*)(Type))NULL))
00139             {}
00140 
00141         // for specifying destructor function directly.  This is useful if the
00142         // map should not own the value.
00143         SmartPtr(Type *value, void (*destructorFunc)(Type *))
00144             : OpaqueValue(new OVDPtrImpl<Type>(value, destructorFunc))
00145             {}
00146 
00147         // for pointer types.  Rather then having to store a pointer to a
00148         // pointer, conver the pointer to a void* directly..
00149         SmartPtr(Type value, void(*destructor)(Type))
00150             : OpaqueValue(new OVDValueImpl<Type>(value, destructor))
00151             {}
00152 
00153 #if 0
00154         SmartPtr &operator=(const SmartPtr<Type> &src)
00155         {
00156             OpaqueValue::operator=(src);
00157             return *this;
00158         }
00159 #endif
00160 
00161         Type *get() const          
00162         { 
00163             return (Type*)OpaqueValue::get();
00164         }
00165 
00166         Type &operator *() const   
00167         { 
00168             Type *value = get();
00169             assertNotNull((void*)value);
00170             return *value;
00171         }
00172         Type *operator ->() const  
00173         { 
00174             Type *value = get();
00175             assertNotNull((void*)value);
00176             return value;
00177         }
00178         operator Type*() const     { return   get(); }
00179 
00180         void reset(Type *value = NULL)
00181         {
00182             if(!value)
00183                 OpaqueValue::reset();
00184             else
00185             {
00186                 OpaqueValue::reset(new OVDPtrImpl<Type>(value,
00187                             &defaultDestructorFunc<Type>));
00188             }
00189         }
00190 
00191         void reset(Type &value, void(*destructor)(Type))
00192         {
00193             OpaqueValue::reset(new OVDValueImpl<Type>(value,destructor));
00194         }
00195     };
00196 
00197 
00198     // Should be moved out of OpaqueValue and somewhere more general..
00199     class bad_cast : public std::exception
00200     {
00201         SmartPtr<char*> _what;
00202     public:
00203         bad_cast(const char *fromType, const char *toType);
00204         const char *what() const;
00205     };
00206 
00207     class bad_operation : public std::exception
00208     {
00209         SmartPtr<char*> _what;
00210     public:
00211         bad_operation(const char *what);
00212         const char *what() const;
00213     };
00214 
00215 
00216 } // namespace rel
00217 
00218 #endif
00219 

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