00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00035
00036
00037
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
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
00057
00058
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
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
00086
00087
00088 class LOG4CPLUS_EXPORT SharedObject {
00089 public:
00090 void addReference();
00091 void removeReference();
00092
00093 protected:
00094
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
00101 virtual ~SharedObject();
00102
00103
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
00117
00118 template<class T>
00119 class LOG4CPLUS_EXPORT SharedObjectPtr {
00120 public:
00121
00122 SharedObjectPtr(T* realPtr = 0) : pointee(realPtr) { init(); };
00123 SharedObjectPtr(const SharedObjectPtr& rhs) : pointee(rhs.pointee) { init(); };
00124
00125
00126 ~SharedObjectPtr() {if (pointee != 0) ((SharedObject *)pointee)->removeReference(); }
00127
00128
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
00155 T* get() const { return pointee; }
00156
00157 private:
00158
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
00168 T* pointee;
00169 };
00170
00171 }
00172 }
00173
00174 using log4cplus::helpers::safe_auto_ptr;
00175
00176 #endif // _LOG4CPLUS_HELPERS_POINTERS_HEADER_
00177