# 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