Orfeo Toolbox  4.0
itkLightObject.cxx
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
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 #include "itkFastMutexLock.h"
19 
20 
21 // Better name demanging for gcc
22 #if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 )
23 #define GCC_USEDEMANGLE
24 #endif
25 
26 #ifdef GCC_USEDEMANGLE
27 #include <cstdlib>
28 #include <cxxabi.h>
29 #endif
30 
31 #if defined( __APPLE__ )
32 // OSAtomic.h optimizations only used in 10.5 and later
33  #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
34  #include <libkern/OSAtomic.h>
35  #endif
36 
37 #elif defined( __GLIBCPP__ ) || defined( __GLIBCXX__ )
38  #if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 2 ) )
39  #include <ext/atomicity.h>
40  #else
41  #include <bits/atomicity.h>
42  #endif
43 
44 #endif
45 
46 namespace itk
47 {
48 #if defined( __GLIBCXX__ ) // g++ 3.4+
49 
50 using __gnu_cxx::__atomic_add;
51 using __gnu_cxx::__exchange_and_add;
52 
53 #endif
54 
57 {
58  Pointer smartPtr;
60 
61  if ( rawPtr == NULL )
62  {
63  rawPtr = new LightObject;
64  }
65  smartPtr = rawPtr;
66  rawPtr->UnRegister();
67  return smartPtr;
68 }
69 
72 {
73  return LightObject::New();
74 }
75 
78 {
79  // nothing to clone in the most basic class of the toolkit.
80  // just return a new instance
81  return CreateAnother();
82 }
83 
89 void
92 {
93  this->UnRegister();
94 }
95 
99 #ifdef _WIN32
100 void *
101 LightObject
102 ::operator new(size_t n)
103 {
104  return new char[n];
105 }
106 
107 void *
108 LightObject
109 ::operator new[](size_t n)
110 {
111  return new char[n];
112 }
113 
114 void
115 LightObject
116 ::operator delete(void *m)
117 {
118  delete[] (char *)m;
119 }
120 
121 void
122 LightObject
123 ::operator delete[](void *m, size_t)
124 {
125  delete[] (char *)m;
126 }
127 
128 #endif
129 
135 void
137 ::Print(std::ostream & os, Indent indent) const
138 {
139  this->PrintHeader(os, indent);
140  this->PrintSelf( os, indent.GetNextIndent() );
141  this->PrintTrailer(os, indent);
142 }
143 
148 void
151 {}
152 
156 void
158 ::Register() const
159 {
160  // Windows optimization
161 #if ( defined( WIN32 ) || defined( _WIN32 ) )
162  InterlockedIncrement(&m_ReferenceCount);
163 
164  // Mac optimization
165 #elif defined( __APPLE__ ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 )
166  #if defined ( __LP64__ ) && __LP64__
167  OSAtomicIncrement64Barrier(&m_ReferenceCount);
168  #else
169  OSAtomicIncrement32Barrier(&m_ReferenceCount);
170  #endif
171 
172  // gcc optimization
173 #elif defined( __GLIBCPP__ ) || defined( __GLIBCXX__ )
174  __atomic_add(&m_ReferenceCount, 1);
175 
176  // General case
177 #else
178  m_ReferenceCountLock.Lock();
179  m_ReferenceCount++;
180  m_ReferenceCountLock.Unlock();
181 #endif
182 }
183 
187 void
190 {
191  // As ReferenceCount gets unlocked, we may have a race condition
192  // to delete the object.
193 
194  // Windows optimization
195 #if ( defined( WIN32 ) || defined( _WIN32 ) )
196  if ( InterlockedDecrement(&m_ReferenceCount) <= 0 )
197  {
198  delete this;
199  }
200 
201 // Mac optimization
202 #elif defined( __APPLE__ ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 )
203  #if defined ( __LP64__ ) && __LP64__
204  if ( OSAtomicDecrement64Barrier(&m_ReferenceCount) <= 0 )
205  {
206  delete this;
207  }
208  #else
209  if ( OSAtomicDecrement32Barrier(&m_ReferenceCount) <= 0 )
210  {
211  delete this;
212  }
213  #endif
214 
215 // gcc optimization
216 #elif defined( __GLIBCPP__ ) || defined( __GLIBCXX__ )
217  if ( __exchange_and_add(&m_ReferenceCount, -1) <= 1 )
218  {
219  delete this;
220  }
221 
222 // General case
223 #else
224  m_ReferenceCountLock.Lock();
225  InternalReferenceCountType tmpReferenceCount = --m_ReferenceCount;
226  m_ReferenceCountLock.Unlock();
227 
228  if ( tmpReferenceCount <= 0 )
229  {
230  delete this;
231  }
232 #endif
233 }
234 
238 void
241 {
242  m_ReferenceCountLock.Lock();
243  m_ReferenceCount = static_cast< InternalReferenceCountType >( ref );
244  m_ReferenceCountLock.Unlock();
245 
246  if ( ref <= 0 )
247  {
248  delete this;
249  }
250 }
251 
254 {
265  if ( m_ReferenceCount > 0 && !std::uncaught_exception() )
266  {
267  // A general exception safety rule is that destructors should
268  // never throw. Something is wrong with a program that reaches
269  // this point anyway. Also this is the least-derived class so the
270  // whole object has been destroyed by this point anyway. Just
271  // issue a warning.
272  // itkExceptionMacro(<< "Trying to delete object with non-zero reference
273  // count.");
274  itkWarningMacro("Trying to delete object with non-zero reference count.");
275  }
276 }
277 
282 void
284 ::PrintSelf(std::ostream & os, Indent indent) const
285 {
286 #ifdef GCC_USEDEMANGLE
287  char const *mangledName = typeid( *this ).name();
288  int status;
289  char * unmangled = abi::__cxa_demangle(mangledName, 0, 0, &status);
290 
291  os << indent << "RTTI typeinfo: ";
292 
293  if ( status == 0 )
294  {
295  os << unmangled;
296  free(unmangled);
297  }
298  else
299  {
300  os << mangledName;
301  }
302 
303  os << std::endl;
304 #else
305  os << indent << "RTTI typeinfo: " << typeid( *this ).name() << std::endl;
306 #endif
307  os << indent << "Reference Count: " << m_ReferenceCount << std::endl;
308 }
309 
313 void
315 ::PrintHeader(std::ostream & os, Indent indent) const
316 {
317  os << indent << this->GetNameOfClass() << " (" << this << ")\n";
318 }
319 
323 void
325 ::PrintTrailer( std::ostream & itkNotUsed(os), Indent itkNotUsed(indent) ) const
326 {}
327 
334 std::ostream &
335 operator<<(std::ostream & os, const LightObject & o)
336 {
337  o.Print(os);
338  return os;
339 }
340 } // end namespace itk

Generated at Sat Mar 8 2014 15:09:17 for Orfeo Toolbox with doxygen 1.8.3.1