API Documentation
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