Orfeo Toolbox  3.16
itkLightObject.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkLightObject.cxx,v $
5  Language: C++
6  Date: $Date: 2009-02-05 19:05:00 $
7  Version: $Revision: 1.41 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #include "itkLightObject.h"
18 #include "itkObjectFactory.h"
19 #include "itkFastMutexLock.h"
20 
21 #include <list>
22 #include <memory>
23 #include <exception>
24 
25 // Better name demanging for gcc
26 #if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 )
27 #define GCC_USEDEMANGLE
28 #endif
29 
30 #ifdef GCC_USEDEMANGLE
31 #include <cstdlib>
32 #include <cxxabi.h>
33 #endif
34 
35 #if defined(__APPLE__)
36  // OSAtomic.h optimizations only used in 10.5 and later
37  #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
38  #include <libkern/OSAtomic.h>
39  #endif
40 
41 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
42  #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
43  # include <ext/atomicity.h>
44  #else
45  # include <bits/atomicity.h>
46  #endif
47 
48 #endif
49 
50 
51 namespace itk
52 {
53 
54 #if defined(__GLIBCXX__) // g++ 3.4+
55 
56 using __gnu_cxx::__atomic_add;
57 using __gnu_cxx::__exchange_and_add;
58 
59 #endif
60 
63 {
64  Pointer smartPtr;
66  if(rawPtr == NULL)
67  {
68  rawPtr = new LightObject;
69  }
70  smartPtr = rawPtr;
71  rawPtr->UnRegister();
72  return smartPtr;
73 }
74 
77 {
78  return LightObject::New();
79 }
80 
86 void
89 {
90  this->UnRegister();
91 }
92 
93 
97 #ifdef _WIN32
98 void*
99 LightObject
100 ::operator new(size_t n)
101 {
102  return new char[n];
103 }
104 
105 void*
106 LightObject
107 ::operator new[](size_t n)
108 {
109  return new char[n];
110 }
111 
112 void
113 LightObject
114 ::operator delete(void* m)
115 {
116  delete [] (char*)m;
117 }
118 
119 void
120 LightObject
121 ::operator delete[](void* m, size_t)
122 {
123  delete [] (char*)m;
124 }
125 #endif
126 
127 
133 void
135 ::Print(std::ostream& os, Indent indent) const
136 {
137  this->PrintHeader(os, indent);
138  this->PrintSelf(os, indent.GetNextIndent());
139  this->PrintTrailer(os, indent);
140 }
141 
142 
147 void
150 {
151  ;
152 }
153 
154 
158 void
160 ::Register() const
161 {
162  // Windows optimization
163 #if (defined(WIN32) || defined(_WIN32))
164  InterlockedIncrement(&m_ReferenceCount);
165 
166  // Mac optimization
167 #elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
168  #if defined (__LP64__) && __LP64__
169  OSAtomicIncrement64Barrier(&m_ReferenceCount);
170  #else
171  OSAtomicIncrement32Barrier(&m_ReferenceCount);
172  #endif
173 
174  // gcc optimization
175 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
176  __atomic_add(&m_ReferenceCount, 1);
177 
178  // General case
179 #else
180  m_ReferenceCountLock.Lock();
181  m_ReferenceCount++;
182  m_ReferenceCountLock.Unlock();
183 #endif
184 }
185 
186 
190 void
193 {
194  // As ReferenceCount gets unlocked, we may have a race condition
195  // to delete the object.
196 
197  // Windows optimization
198 #if (defined(WIN32) || defined(_WIN32))
199  if ( InterlockedDecrement(&m_ReferenceCount) <= 0 )
200  {
201  delete this;
202  }
203 
204 // Mac optimization
205 #elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
206  #if defined (__LP64__) && __LP64__
207  if ( OSAtomicDecrement64Barrier(&m_ReferenceCount) <= 0 )
208  {
209  delete this;
210  }
211  #else
212  if ( OSAtomicDecrement32Barrier(&m_ReferenceCount) <= 0 )
213  {
214  delete this;
215  }
216  #endif
217 
218 // gcc optimization
219 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
220  if ( __exchange_and_add(&m_ReferenceCount, -1) <= 1 )
221  {
222  delete this;
223  }
224 
225 // General case
226 #else
227  m_ReferenceCountLock.Lock();
228  InternalReferenceCountType tmpReferenceCount = --m_ReferenceCount;
229  m_ReferenceCountLock.Unlock();
230 
231  if ( tmpReferenceCount <= 0)
232  {
233  delete this;
234  }
235 #endif
236 }
237 
238 
242 void
245 {
246  m_ReferenceCountLock.Lock();
247  m_ReferenceCount = static_cast<InternalReferenceCountType>(ref);
248  m_ReferenceCountLock.Unlock();
249 
250  if ( ref <= 0)
251  {
252  delete this;
253  }
254 }
255 
258 {
269  if(m_ReferenceCount > 0 && !std::uncaught_exception())
270  {
271  // A general exception safety rule is that destructors should
272  // never throw. Something is wrong with a program that reaches
273  // this point anyway. Also this is the least-derived class so the
274  // whole object has been destroyed by this point anyway. Just
275  // issue a warning.
276  // itkExceptionMacro(<< "Trying to delete object with non-zero reference count.");
277  itkWarningMacro("Trying to delete object with non-zero reference count.");
278  }
279 }
280 
281 
286 void
288 ::PrintSelf(std::ostream& os, Indent indent) const
289 {
290 #ifdef GCC_USEDEMANGLE
291  char const * mangledName = typeid(*this).name();
292  int status;
293  char* unmangled = abi::__cxa_demangle(mangledName, 0, 0, &status);
294 
295  os << indent << "RTTI typeinfo: ";
296 
297  if(status == 0)
298  {
299  os << unmangled;
300  free(unmangled);
301  }
302  else
303  {
304  os << mangledName;
305  }
306 
307  os << std::endl;
308 #else
309  os << indent << "RTTI typeinfo: " << typeid( *this ).name() << std::endl;
310 #endif
311  os << indent << "Reference Count: " << m_ReferenceCount << std::endl;
312 }
313 
314 
318 void
320 ::PrintHeader(std::ostream& os, Indent indent) const
321 {
322  os << indent << this->GetNameOfClass() << " (" << this << ")\n";
323 }
324 
325 
329 void
331 ::PrintTrailer(std::ostream& itkNotUsed(os), Indent itkNotUsed(indent)) const
332 {
333 }
334 
335 
342 std::ostream&
343 operator<<(std::ostream& os, const LightObject& o)
344 {
345  o.Print(os);
346  return os;
347 }
348 
349 
350 } // end namespace itk

Generated at Sat Jun 15 2013 23:51:56 for Orfeo Toolbox with doxygen 1.8.3.1