Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

pointer.h

Go to the documentation of this file.
00001 // Module:  Log4CPLUS
00002 // File:    pointer.h
00003 // Created: 6/2001
00004 // Author:  Tad E. Smith
00005 //
00006 //
00007 // Copyright (C) Tad E. Smith  All rights reserved.
00008 //
00009 // This software is published under the terms of the Apache Software
00010 // License version 1.1, a copy of which has been included with this
00011 // distribution in the LICENSE.APL file.
00012 //
00013 
00014 //
00015 // Note: Some of this code uses ideas from "More Effective C++" by Scott
00016 // Myers, Addison Wesley Longmain, Inc., (c) 1996, Chapter 29, pp. 183-213
00017 //
00018 
00021 #ifndef _LOG4CPLUS_HELPERS_POINTERS_HEADER_
00022 #define _LOG4CPLUS_HELPERS_POINTERS_HEADER_
00023 
00024 #include <log4cplus/config.h>
00025 #include <memory>
00026 #include <stdexcept>
00027 #include <string>
00028 
00029 
00030 namespace log4cplus {
00031     namespace helpers {
00032 
00033 #if (_MSC_VER >= 1300)
00034         // Added to remove the following warning from MSVC++ 7:
00035         // warning C4275: non dll-interface class 'std::runtime_error' used as 
00036         //                base for dll-interface class 
00037         //                'log4cplus::helpers::NullPointerException'
00038         class LOG4CPLUS_EXPORT std::runtime_error;
00039 #endif
00040 
00041         class LOG4CPLUS_EXPORT NullPointerException : public std::runtime_error {
00042         public:
00043             NullPointerException(const std::string& what_arg) : std::runtime_error(what_arg) {}
00044         };
00045 
00046         void throwNullPointerException(const char* file, int line);
00047 
00048         template<class T>
00049         class LOG4CPLUS_EXPORT safe_auto_ptr {
00050         public:
00051           // Ctors
00052             explicit safe_auto_ptr(T* val = 0) : value(val){}
00053             safe_auto_ptr(const safe_auto_ptr& rhs) 
00054              : value(const_cast<safe_auto_ptr&>(rhs).value){}
00055 
00056             // Note: No Dtor needed since value is an auto_ptr
00057 
00058           // operators
00059             safe_auto_ptr& operator=(safe_auto_ptr& rhs) {value = rhs.value; return *this;}
00060             T& operator*() const { validate(); return *value; }
00061             T* operator->() const { validate(); return value.operator->(); }
00062 
00063           // methods
00064             T* get() const { return value.get(); }
00065             T* release() { return value.release(); }
00066             void reset(T* val = 0) { value.reset(val); }
00067             void validate(const char* file, int line) const { 
00068                 if(value.get() == 0) {
00069                     throwNullPointerException(file, line);
00070                 }
00071             }
00072 
00073         private:
00074             void validate() const { 
00075                 if(value.get() == 0) {
00076                     throw NullPointerException("safe_auto_ptr::validate()- NullPointer");
00077                 }
00078             }
00079             std::auto_ptr<T> value;
00080         };
00081 
00082 
00083 
00084         /******************************************************************************
00085          *                       Class SharedObject (from pp. 204-205)                *
00086          ******************************************************************************/
00087 
00088         class LOG4CPLUS_EXPORT SharedObject {
00089         public:
00090             void addReference();
00091             void removeReference();
00092 
00093         protected:
00094           // Ctor
00095             SharedObject() 
00096              : access_mutex(LOG4CPLUS_MUTEX_CREATE), count(0), destroyed(false) {}
00097             SharedObject(const SharedObject&) 
00098              : access_mutex(LOG4CPLUS_MUTEX_CREATE), count(0), destroyed(false) {}
00099 
00100           // Dtor
00101             virtual ~SharedObject();
00102 
00103           // Operators
00104             SharedObject& operator=(const SharedObject&) { return *this; }
00105 
00106         public:
00107             LOG4CPLUS_MUTEX_PTR_DECLARE access_mutex;
00108 
00109         private:
00110             int count;
00111             bool destroyed;
00112         };
00113 
00114 
00115         /******************************************************************************
00116          *           Template Class SharedObjectPtr (from pp. 203, 206)               *
00117          ******************************************************************************/
00118         template<class T>
00119         class LOG4CPLUS_EXPORT SharedObjectPtr {
00120         public:
00121           // Ctor
00122             SharedObjectPtr(T* realPtr = 0) : pointee(realPtr) { init(); };
00123             SharedObjectPtr(const SharedObjectPtr& rhs) : pointee(rhs.pointee) { init(); };
00124 
00125           // Dtor
00126             ~SharedObjectPtr() {if (pointee != 0) ((SharedObject *)pointee)->removeReference(); }
00127 
00128           // Operators
00129             bool operator==(const SharedObjectPtr& rhs) const { return (pointee == rhs.pointee); }
00130             bool operator!=(const SharedObjectPtr& rhs) const { return (pointee != rhs.pointee); }
00131             bool operator==(const T* rhs) const { return (pointee == rhs); }
00132             bool operator!=(const T* rhs) const { return (pointee != rhs); }
00133             T* operator->() const {validate(); return pointee; }
00134             T& operator*() const {validate(); return *pointee; }
00135             SharedObjectPtr& operator=(const SharedObjectPtr& rhs) {
00136                 if (pointee != rhs.pointee) {
00137                     T* oldPointee = pointee;
00138                     pointee = rhs.pointee;
00139                     init();
00140                     if(oldPointee != 0) oldPointee->removeReference();
00141                 }
00142                 return *this;
00143             }
00144             SharedObjectPtr& operator=(T* rhs) {
00145                 if (pointee != rhs) {
00146                     T* oldPointee = pointee;
00147                     pointee = rhs;
00148                     init();
00149                     if(oldPointee != 0) oldPointee->removeReference();
00150                 }
00151                 return *this;
00152             }
00153 
00154           // Methods
00155             T* get() const { return pointee; }
00156 
00157         private:
00158           // Methods
00159             void init() {
00160                 if(pointee == 0) return;
00161                 ((SharedObject*)pointee)->addReference();
00162             }
00163             void validate() const {
00164                 if(pointee == 0) throw std::runtime_error("NullPointer");
00165             }
00166 
00167           // Data
00168             T* pointee;
00169         };
00170 
00171     } // end namespace helpers
00172 } // end namespace log4cplus
00173 
00174 using log4cplus::helpers::safe_auto_ptr;
00175 
00176 #endif // _LOG4CPLUS_HELPERS_POINTERS_HEADER_
00177 

Generated on Mon Feb 9 09:10:30 2004 for log4cplus by doxygen 1.3.2