Apache log4cxx  Version 0.11.0
objectptr.h
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) : ObjectPtrBase() { exchange(x);
32 #else
33  #define _LOG4CXX_OBJECTPTR_INIT(x) : ObjectPtrBase(), p(x) {
34 #endif
35 
36 namespace log4cxx
37 {
38 namespace helpers
39 {
40 class Class;
41 
42 class LOG4CXX_EXPORT ObjectPtrBase
43 {
44  public:
45  ObjectPtrBase();
46  virtual ~ObjectPtrBase();
47  static void checkNull(const int& null);
48  static void* exchange(void** destination, void* newValue);
49  virtual void* cast(const Class& cls) const = 0;
50 };
51 
52 
54 template<typename T> class ObjectPtrT : public ObjectPtrBase
55 {
56  public:
57  ObjectPtrT(const int& null)
58  _LOG4CXX_OBJECTPTR_INIT(0)
59  ObjectPtrBase::checkNull(null);
60 }
61 
62 ObjectPtrT()
63 _LOG4CXX_OBJECTPTR_INIT(0)
64 }
65 
66 ObjectPtrT(T* p1)
67 _LOG4CXX_OBJECTPTR_INIT(p1)
68 
69 if (this->p != 0)
70 {
71  this->p->addRef();
72 }
73 }
74 
75 
76 ObjectPtrT(const ObjectPtrT& p1)
77 _LOG4CXX_OBJECTPTR_INIT(p1.p)
78 
79 if (this->p != 0)
80 {
81  this->p->addRef();
82 }
83 }
84 
85 ObjectPtrT(const ObjectPtrBase& p1)
86 _LOG4CXX_OBJECTPTR_INIT(reinterpret_cast<T*>(p1.cast(T::getStaticClass())))
87 
88 if (this->p != 0)
89 {
90  this->p->addRef();
91 }
92 }
93 
95 _LOG4CXX_OBJECTPTR_INIT(reinterpret_cast<T*>(p1.cast(T::getStaticClass())))
96 
97 if (this->p != 0)
98 {
99  this->p->addRef();
100 }
101 }
102 
103 
104 ~ObjectPtrT()
105 {
106  if (p != 0)
107  {
108  p->releaseRef();
109  }
110 }
111 
112 ObjectPtrT& operator=(const ObjectPtrT& p1)
113 {
114  T* newPtr = p1.p;
115 
116  if (newPtr != 0)
117  {
118  newPtr->addRef();
119  }
120 
121  T* oldPtr = exchange(newPtr);
122 
123  if (oldPtr != 0)
124  {
125  oldPtr->releaseRef();
126  }
127 
128  return *this;
129 }
130 
131 ObjectPtrT& operator=(const int& null) //throw(IllegalArgumentException)
132 {
133  //
134  // throws IllegalArgumentException if null != 0
135  //
136  ObjectPtrBase::checkNull(null);
137  T* oldPtr = exchange(0);
138 
139  if (oldPtr != 0)
140  {
141  oldPtr->releaseRef();
142  }
143 
144  return *this;
145 }
146 
147 ObjectPtrT& operator=(T* p1)
148 {
149  if (p1 != 0)
150  {
151  p1->addRef();
152  }
153 
154  T* oldPtr = exchange(p1);
155 
156  if (oldPtr != 0)
157  {
158  oldPtr->releaseRef();
159  }
160 
161  return *this;
162 }
163 
164 
165 ObjectPtrT& operator=(ObjectPtrBase& p1)
166 {
167  T* newPtr = reinterpret_cast<T*>(p1.cast(T::getStaticClass()));
168  return operator=(newPtr);
169 }
170 
171 ObjectPtrT& operator=(const ObjectPtrBase& p1)
172 {
173  T* newPtr = reinterpret_cast<T*>(p1.cast(T::getStaticClass()));
174  return operator=(newPtr);
175 }
176 
177 bool operator==(const ObjectPtrT& p1) const
178 {
179  return (this->p == p1.p);
180 }
181 bool operator!=(const ObjectPtrT& p1) const
182 {
183  return (this->p != p1.p);
184 }
185 bool operator<(const ObjectPtrT& p1) const
186 {
187  return (this->p < p1.p);
188 }
189 bool operator==(const T* p1) const
190 {
191  return (this->p == p1);
192 }
193 bool operator!=(const T* p1) const
194 {
195  return (this->p != p1);
196 }
197 bool operator<(const T* p1) const
198 {
199  return (this->p < p1);
200 }
201 T* operator->() const
202 {
203  return p;
204 }
205 T& operator*() const
206 {
207  return *p;
208 }
209 operator T* () const
210 {
211  return p;
212 }
213 
214 
215 
216 private:
217 T* p;
218 virtual void* cast(const Class& cls) const
219 {
220  if (p != 0)
221  {
222  return const_cast<void*>(p->cast(cls));
223  }
224 
225  return 0;
226 }
227 T* exchange(const T* newValue)
228 {
229  // Avoid GCC strict aliasing warnings
230  union
231  {
232  T** in;
233  void** out;
234  } temp = { &p };
235  return static_cast<T*>(ObjectPtrBase::exchange(
236  temp.out,
237  const_cast<T*>(newValue)));
238 }
239 
240 };
241 
242 
243 }
244 }
245 
246 #endif //_LOG4CXX_HELPERS_OBJECT_PTR_H
Definition: class.h:39
Definition: appender.h:33
Definition: objectptr.h:42
smart pointer to a Object descendant
Definition: objectptr.h:54