Orfeo Toolbox  4.0
itkExceptionObject.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 "itkLightObject.h"
19 
20 
21 namespace itk
22 {
30 {
31 protected:
32  // Constructor. Might throw an exception.
34  const std::string & file, unsigned int line,
35  const std::string & description,
36  const std::string & location):
37  m_Location(location),
38  m_Description(description),
39  m_File(file),
40  m_Line(line)
41  {
42  std::ostringstream loc;
43 
44  loc << ":" << m_Line << ":\n";
45  m_What = m_File;
46  m_What += loc.str();
48  m_WhatPointer = m_What.c_str();
49  }
50 
51 private:
52  void operator=(const ExceptionData &); //purposely not implemented
53 
54  friend class ExceptionObject;
55 
56  // The data members should never change after construction of the
57  // ExceptionData object,
58  // to ensure the consistency of the exception data.
59  const std::string m_Location;
60  const std::string m_Description;
61  const std::string m_File;
62  const unsigned int m_Line;
63  std::string m_What;
64  const char * m_WhatPointer;
65 };
66 
78 {
79 public:
83  const std::string & file, unsigned int line,
84  const std::string & description,
85  const std::string & location)
86  {
87  ConstPointer smartPtr;
88  const Self *const rawPtr = new Self(file, line, description, location);
89 
90  smartPtr = rawPtr;
91  rawPtr->LightObject::UnRegister();
92  return smartPtr;
93  }
94 
97  virtual void Register() const
98  {
99  this->LightObject::Register();
100  }
101 
104  virtual void UnRegister() const
105  {
106  this->LightObject::UnRegister();
107  }
108 
109 private:
110  // Constructor. Might throw an exception.
112  const std::string & file, unsigned int line,
113  const std::string & description,
114  const std::string & location):
115  ExceptionData(file, line, description, location),
116  LightObject()
117  {}
118 
119  // Destructor. Only invoked via LightObject::UnRegister(), when its reference
120  // count drops to zero.
122  {}
123 
124  ReferenceCountedExceptionData(const Self &); //purposely not implemented
125  void operator=(const Self &); //purposely not implemented
126 };
127 
129 {
130  // The default construction never throws an exception.
131 }
132 
134  const char *file,
135  unsigned int lineNumber,
136  const char *desc,
137  const char *loc):
138  m_ExceptionData( ReferenceCountedExceptionData::ConstNew(file == 0 ? "":file, lineNumber, desc == 0 ? "":desc, loc ==
139  0 ? "":loc) )
140 {}
141 
143  const std::string & file,
144  unsigned int lineNumber,
145  const std::string & desc,
146  const std::string & loc):
147  m_ExceptionData( ReferenceCountedExceptionData::ConstNew(file, lineNumber, desc, loc) )
148 {}
149 
151  Superclass(orig),
152  m_ExceptionData(orig.m_ExceptionData)
153 {
154  // This copy construction never throws, because it just copies the smart
155  // pointer.
156 }
157 
159 throw( )
160 {
161  // During destruction, the reference count of the
162  // ReferenceCountedExceptionData will be decreased
163  // automatically, by the destructor of the smart pointer.
164 }
165 
168 {
169  // Note: dynamic_cast does a runtime check if the m_ExceptionData pointer is
170  // indeed
171  // pointing to an ExceptionData object. In this case, a static_cast could have
172  // been
173  // used instead, which only does compile time checking. But we expect the
174  // runtime overhead of this particular dynamic_cast to be insignificant.
175  const ExceptionData *thisData =
176  dynamic_cast< const ExceptionData * >( this->m_ExceptionData.GetPointer() );
177 
178  return thisData;
179 }
180 
183 {
184  // Note: there is no superclass assignment here, because
185  // std::exception::operator=
186  // appears have a bug on some platforms, including MSVC 2003. The MSVC 2003
187  // bug is
188  // described at the Usenet newsgroup microsoft.public.vc.language, June 2,
189  // 2008,
190  // subject "VC7.1 std::exception assignment operator bug (crash) a known
191  // issue?"
192  //
193  //
194  //
195  // http://groups.google.com/group/microsoft.public.vc.language/msg/15b927c8c1130e88
196 
197  // Assigns its smart pointer:
199  return *this;
200 }
201 
202 bool
204 {
205  // operator== is reimplemented, but it still behaves like the previous
206  // version, from ITK 3.6.0.
207  const ExceptionData *const thisData = this->GetExceptionData();
208  const ExceptionData *const origData = orig.GetExceptionData();
209 
210  if ( thisData == origData )
211  {
212  return true;
213  }
214  else
215  {
216  return ( thisData != 0 ) && ( origData != 0 )
217  && thisData->m_Location == origData->m_Location
218  && thisData->m_Description == origData->m_Description
219  && thisData->m_File == origData->m_File
220  && thisData->m_Line == origData->m_Line;
221  }
222 }
223 
224 void
225 ExceptionObject::SetLocation(const std::string & s)
226 {
227  const bool IsNull = m_ExceptionData.IsNull();
228 
230  IsNull ? "" : this->GetExceptionData()->m_File.c_str(),
231  IsNull ? 0 : this->GetExceptionData()->m_Line,
232  IsNull ? "" : this->GetExceptionData()->m_Description.c_str(),
233  s);
234 }
235 
236 void
237 ExceptionObject::SetDescription(const std::string & s)
238 {
239  const bool IsNull = m_ExceptionData.IsNull();
240 
242  IsNull ? "" : this->GetExceptionData()->m_File.c_str(),
243  IsNull ? 0 : this->GetExceptionData()->m_Line,
244  s,
245  IsNull ? "" : this->GetExceptionData()->m_Location.c_str() );
246 }
247 
248 void
250 {
251  std::string location;
252 
253  if ( s )
254  {
255  location = s;
256  }
258 }
259 
260 void
262 {
263  std::string description;
264 
265  if ( s )
266  {
267  description = s;
268  }
269  ExceptionObject::SetDescription(description);
270 }
271 
272 const char *
274 {
275  // Note: std::string::c_str() might throw an exception.
276  return m_ExceptionData.IsNull() ? "" : this->GetExceptionData()->m_Location.c_str();
277 }
278 
279 const char *
281 {
282  // Note: std::string::c_str() might throw an exception.
283  return m_ExceptionData.IsNull() ? "" : this->GetExceptionData()->m_Description.c_str();
284 }
285 
286 const char *
288 {
289  // Note: std::string::c_str() might throw an exception.
290  return m_ExceptionData.IsNull() ? "" : this->GetExceptionData()->m_File.c_str();
291 }
292 
293 unsigned int
295 {
296  return m_ExceptionData.IsNull() ? 0 : this->GetExceptionData()->m_Line;
297 }
298 
299 const char *
301 throw( )
302 {
303  const ExceptionData *const thisData = this->GetExceptionData();
304 
305  // Note: m_What.c_str() wouldn't be safe, because c_str() might throw an
306  // exception.
307  return thisData ? thisData->m_WhatPointer : "ExceptionObject";
308 }
309 
310 void
312 ::Print(std::ostream & os) const
313 {
314  Indent indent;
315 
316  // Print header
317  os << std::endl;
318  os << indent << "itk::" << this->GetNameOfClass() << " (" << this << ")\n";
319 
320  // Print self
321  indent.GetNextIndent();
322 
323  if ( m_ExceptionData.IsNotNull() )
324  {
325  const ExceptionData & data = *( this->GetExceptionData() );
326 
327  if ( !data.m_Location.empty() )
328  {
329  os << indent << "Location: \"" << data.m_Location << "\" " << std::endl;
330  }
331 
332  if ( !data.m_File.empty() )
333  {
334  os << indent << "File: " << data.m_File << std::endl;
335  os << indent << "Line: " << data.m_Line << std::endl;
336  }
337 
338  if ( !data.m_Description.empty() )
339  {
340  os << indent << "Description: " << data.m_Description << std::endl;
341  }
342  }
343  // Print trailer
344  os << indent << std::endl;
345 }
346 } // end namespace itk

Generated at Sat Mar 8 2014 14:35:02 for Orfeo Toolbox with doxygen 1.8.3.1