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