1 // Module:  Log4CPLUS
  2 // File:    pointer.h
  3 // Created: 6/2001
  4 // Author:  Tad E. Smith
  5 //
  6 //
  7 // Copyright (C) Tad E. Smith  All rights reserved.
  8 //
  9 // This software is published under the terms of the Apache Software
 10 // License version 1.1, a copy of which has been included with this
 11 // distribution in the LICENSE.APL file.
 12 //
 13 
 14 //
 15 // Note: Some of this code uses ideas from "More Effective C++" by Scott
 16 // Myers, Addison Wesley Longmain, Inc., (c) 1996, Chapter 29, pp. 183-213
 17 //
 18 
 19 /** @file */
 20 
 21 #ifndef _LOG4CPLUS_HELPERS_POINTERS_HEADER_
 22 #define _LOG4CPLUS_HELPERS_POINTERS_HEADER_
 23 
 24 #include <log4cplus/config.h>
 25 #include <memory>
 26 #include <stdexcept>
 27 #include <string>
 28 
 29 
 30 namespace log4cplus {
 31     namespace helpers {
 32 
 33 #if (_MSC_VER >= 1300)
 34         // Added to remove the following warning from MSVC++ 7:
 35         // warning C4275: non dll-interface class 'std::runtime_error' used as 
 36         //                base for dll-interface class 
 37         //                'log4cplus::helpers::NullPointerException'
 38         class LOG4CPLUS_EXPORT std::runtime_error;
 39 #endif
 40 
 41         class LOG4CPLUS_EXPORT NullPointerException : public std::runtime_error {
 42         public:
 43             NullPointerException(const std::string& what_arg) : std::runtime_error(what_arg) {}
 44         };
 45 
 46         void throwNullPointerException(const char* file, int line);
 47 
 48         template<class T>
 49         class LOG4CPLUS_EXPORT safe_auto_ptr {
 50         public:
 51           // Ctors
 52             explicit safe_auto_ptr(T* val = 0) : value(val){}
 53             safe_auto_ptr(const safe_auto_ptr& rhs) 
 54              : value(const_cast<safe_auto_ptr&>(rhs).value){}
 55 
 56             // Note: No Dtor needed since value is an auto_ptr
 57 
 58           // operators
 59             safe_auto_ptr& operator=(safe_auto_ptr& rhs) {value = rhs.value; return *this;}
 60             T& operator*() const { validate(); return *value; }
 61             T* operator->() const { validate(); return value.operator->(); }
 62 
 63           // methods
 64             T* get() const { return value.get(); }
 65             T* release() { return value.release(); }
 66             void reset(T* val = 0) { value.reset(val); }
 67             void validate(const char* file, int line) const { 
 68                 if(value.get() == 0) {
 69                     throwNullPointerException(file, line);
 70                 }
 71             }
 72 
 73         private:
 74             void validate() const { 
 75                 if(value.get() == 0) {
 76                     throw NullPointerException("safe_auto_ptr::validate()- NullPointer");
 77                 }
 78             }
 79             std::auto_ptr<T> value;
 80         };
 81 
 82 
 83 
 84         /******************************************************************************
 85          *                       Class SharedObject (from pp. 204-205)                *
 86          ******************************************************************************/
 87 
 88         class LOG4CPLUS_EXPORT SharedObject {
 89         public:
 90             void addReference();
 91             void removeReference();
 92 
 93         protected:
 94           // Ctor
 95             SharedObject() 
 96              : access_mutex(LOG4CPLUS_MUTEX_CREATE), count(0), destroyed(false) {}
 97             SharedObject(const SharedObject&) 
 98              : access_mutex(LOG4CPLUS_MUTEX_CREATE), count(0), destroyed(false) {}
 99 
100           // Dtor
101             virtual ~SharedObject();
102 
103           // Operators
104             SharedObject& operator=(const SharedObject&) { return *this; }
105 
106         public:
107             LOG4CPLUS_MUTEX_PTR_DECLARE access_mutex;
108 
109         private:
110             int count;
111             bool destroyed;
112         };
113 
114 
115         /******************************************************************************
116          *           Template Class SharedObjectPtr (from pp. 203, 206)               *
117          ******************************************************************************/
118         template<class T>
119         class LOG4CPLUS_EXPORT SharedObjectPtr {
120         public:
121           // Ctor
122             SharedObjectPtr(T* realPtr = 0) : pointee(realPtr) { init(); };
123             SharedObjectPtr(const SharedObjectPtr& rhs) : pointee(rhs.pointee) { init(); };
124 
125           // Dtor
126             ~SharedObjectPtr() {if (pointee != 0) ((SharedObject *)pointee)->removeReference(); }
127 
128           // Operators
129             bool operator==(const SharedObjectPtr& rhs) const { return (pointee == rhs.pointee); }
130             bool operator!=(const SharedObjectPtr& rhs) const { return (pointee != rhs.pointee); }
131             bool operator==(const T* rhs) const { return (pointee == rhs); }
132             bool operator!=(const T* rhs) const { return (pointee != rhs); }
133             T* operator->() const {validate(); return pointee; }
134             T& operator*() const {validate(); return *pointee; }
135             SharedObjectPtr& operator=(const SharedObjectPtr& rhs) {
136                 if (pointee != rhs.pointee) {
137                     T* oldPointee = pointee;
138                     pointee = rhs.pointee;
139                     init();
140                     if(oldPointee != 0) oldPointee->removeReference();
141                 }
142                 return *this;
143             }
144             SharedObjectPtr& operator=(T* rhs) {
145                 if (pointee != rhs) {
146                     T* oldPointee = pointee;
147                     pointee = rhs;
148                     init();
149                     if(oldPointee != 0) oldPointee->removeReference();
150                 }
151                 return *this;
152             }
153 
154           // Methods
155             T* get() const { return pointee; }
156 
157         private:
158           // Methods
159             void init() {
160                 if(pointee == 0) return;
161                 ((SharedObject*)pointee)->addReference();
162             }
163             void validate() const {
164                 if(pointee == 0) throw std::runtime_error("NullPointer");
165             }
166 
167           // Data
168             T* pointee;
169         };
170 
171     } // end namespace helpers
172 } // end namespace log4cplus
173 
174 using log4cplus::helpers::safe_auto_ptr;
175 
176 #endif // _LOG4CPLUS_HELPERS_POINTERS_HEADER_


syntax highlighted by Code2HTML, v. 0.9.1