Line data Source code
1 : /*
2 : * Licensed to the Apache Software Foundation (ASF) under one or more
3 : * contributor license agreements. See the NOTICE file distributed with
4 : * this work for additional information regarding copyright ownership.
5 : * The ASF licenses this file to You under the Apache License, Version 2.0
6 : * (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #ifndef _LOG4CXX_HELPERS_OBJECT_PTR_H
19 : #define _LOG4CXX_HELPERS_OBJECT_PTR_H
20 :
21 : #include <log4cxx/log4cxx.h>
22 :
23 : //
24 : // Helgrind (race detection tool for Valgrind) will complain if pointer
25 : // is not initialized in an atomic operation. Static analysis tools
26 : // (gcc's -Weffc++, for example) will complain if pointer is not initialized
27 : // in member initialization list. The use of a macro allows quick
28 : // switching between the initialization styles.
29 : //
30 : #if LOG4CXX_HELGRIND
31 : #define _LOG4CXX_OBJECTPTR_INIT(x) { exchange(x);
32 : #else
33 : #define _LOG4CXX_OBJECTPTR_INIT(x) : p(x) {
34 : #endif
35 :
36 : namespace log4cxx
37 : {
38 : namespace helpers
39 : {
40 : class Class;
41 :
42 : class LOG4CXX_EXPORT ObjectPtrBase {
43 : public:
44 : ObjectPtrBase();
45 : virtual ~ObjectPtrBase();
46 : static void checkNull(const int& null);
47 : static void* exchange(void** destination, void* newValue);
48 : virtual void* cast(const Class& cls) const = 0;
49 : };
50 :
51 :
52 : /** smart pointer to a Object descendant */
53 : template<typename T> class ObjectPtrT : public ObjectPtrBase
54 : {
55 : public:
56 : ObjectPtrT(const int& null)
57 : _LOG4CXX_OBJECTPTR_INIT(0)
58 : ObjectPtrBase::checkNull(null);
59 : }
60 :
61 7 : ObjectPtrT()
62 7 : _LOG4CXX_OBJECTPTR_INIT(0)
63 7 : }
64 :
65 14 : ObjectPtrT(T * p1)
66 14 : _LOG4CXX_OBJECTPTR_INIT(p1)
67 14 : if (this->p != 0)
68 : {
69 14 : this->p->addRef();
70 : }
71 14 : }
72 :
73 :
74 7 : ObjectPtrT(const ObjectPtrT& p1)
75 7 : _LOG4CXX_OBJECTPTR_INIT(p1.p)
76 7 : if (this->p != 0)
77 : {
78 7 : this->p->addRef();
79 : }
80 7 : }
81 :
82 : ObjectPtrT(const ObjectPtrBase& p1)
83 : _LOG4CXX_OBJECTPTR_INIT(reinterpret_cast<T*>(p1.cast(T::getStaticClass())))
84 : if (this->p != 0) {
85 : this->p->addRef();
86 : }
87 : }
88 :
89 : ObjectPtrT(ObjectPtrBase& p1)
90 : _LOG4CXX_OBJECTPTR_INIT(reinterpret_cast<T*>(p1.cast(T::getStaticClass())))
91 : if (this->p != 0) {
92 : this->p->addRef();
93 : }
94 : }
95 :
96 :
97 60254 : ~ObjectPtrT()
98 : {
99 60254 : if (p != 0) {
100 120503 : p->releaseRef();
101 : }
102 120508 : }
103 :
104 : ObjectPtrT& operator=(const ObjectPtrT& p1) {
105 : T* newPtr = p1.p;
106 : if (newPtr != 0) {
107 : newPtr->addRef();
108 : }
109 : T* oldPtr = exchange(newPtr);
110 : if (oldPtr != 0) {
111 : oldPtr->releaseRef();
112 : }
113 : return *this;
114 : }
115 :
116 : ObjectPtrT& operator=(const int& null) //throw(IllegalArgumentException)
117 : {
118 : //
119 : // throws IllegalArgumentException if null != 0
120 : //
121 : ObjectPtrBase::checkNull(null);
122 : T* oldPtr = exchange(0);
123 : if (oldPtr != 0) {
124 : oldPtr->releaseRef();
125 : }
126 : return *this;
127 : }
128 :
129 : ObjectPtrT& operator=(T* p1) {
130 : if (p1 != 0) {
131 : p1->addRef();
132 : }
133 : T* oldPtr = exchange(p1);
134 : if (oldPtr != 0) {
135 : oldPtr->releaseRef();
136 : }
137 : return *this;
138 : }
139 :
140 :
141 : ObjectPtrT& operator=(ObjectPtrBase& p1) {
142 : T* newPtr = reinterpret_cast<T*>(p1.cast(T::getStaticClass()));
143 : return operator=(newPtr);
144 : }
145 :
146 : ObjectPtrT& operator=(const ObjectPtrBase& p1) {
147 : T* newPtr = reinterpret_cast<T*>(p1.cast(T::getStaticClass()));
148 : return operator=(newPtr);
149 : }
150 :
151 : bool operator==(const ObjectPtrT& p1) const { return (this->p == p1.p); }
152 : bool operator!=(const ObjectPtrT& p1) const { return (this->p != p1.p); }
153 : bool operator<(const ObjectPtrT& p1) const { return (this->p < p1.p); }
154 : bool operator==(const T* p1) const { return (this->p == p1); }
155 : bool operator!=(const T* p1) const { return (this->p != p1); }
156 : bool operator<(const T* p1) const { return (this->p < p1); }
157 60055 : T* operator->() const {return p; }
158 7 : T& operator*() const {return *p; }
159 : operator T*() const {return p; }
160 :
161 :
162 :
163 : private:
164 : T * p;
165 0 : virtual void* cast(const Class& cls) const {
166 0 : if (p != 0) {
167 0 : return const_cast<void*>(p->cast(cls));
168 : }
169 0 : return 0;
170 : }
171 : T* exchange(const T* newValue) {
172 : return static_cast<T*>(ObjectPtrBase::exchange(
173 : reinterpret_cast<void**>(&p),
174 : const_cast<T*>(newValue)));
175 : }
176 :
177 : };
178 :
179 :
180 : }
181 : }
182 :
183 : #endif //_LOG4CXX_HELPERS_OBJECT_PTR_H
|