diff --git a/Modules/Core/Common/include/itkExceptionObject.h b/Modules/Core/Common/include/itkExceptionObject.h index 934e236cad6..4a33ba47d7b 100644 --- a/Modules/Core/Common/include/itkExceptionObject.h +++ b/Modules/Core/Common/include/itkExceptionObject.h @@ -16,14 +16,15 @@ * *=========================================================================*/ #ifndef itkExceptionObject_h -# error "Do not include itkExceptionObject.h directly, include itkMacro.h instead." -#else // itkExceptionObject_h +#define itkExceptionObject_h -# include "itkMacro.h" +// NOTE: This itkExceptionObject.h file is included by itkMacro.h, and should never be included directly. +#ifndef allow_inclusion_of_itkExceptionObject_h +# error "Do not include itkExceptionObject.h directly, include itkMacro.h instead." +#endif -# include // For shared_ptr. -# include -# include +#include // For shared_ptr. +#include namespace itk { @@ -241,6 +242,28 @@ class ITKCommon_EXPORT ProcessAborted : public ExceptionObject /** \see LightObject::GetNameOfClass() */ itkOverrideGetNameOfClassMacro(ProcessAborted); }; -} // end namespace itk +// Forward declaration in Macro.h, implementation here to avoid circular dependency +template +TTarget +itkDynamicCastInDebugMode(TSource x) +{ +#ifndef NDEBUG + if (x == nullptr) + { + return nullptr; + } + TTarget rval = dynamic_cast(x); + if (rval == nullptr) + { + itkGenericExceptionMacro("Failed dynamic cast to " << typeid(TTarget).name() + << " object type = " << x->GetNameOfClass()); + } + return rval; +#else + return static_cast(x); +#endif +} + +} // end namespace itk #endif // itkExceptionObject_h diff --git a/Modules/Core/Common/include/itkMacro.h b/Modules/Core/Common/include/itkMacro.h index b0135dec0b6..d8dc4870aef 100644 --- a/Modules/Core/Common/include/itkMacro.h +++ b/Modules/Core/Common/include/itkMacro.h @@ -1340,39 +1340,6 @@ compilers. } \ ITK_MACROEND_NOOP_STATEMENT - -#define itkExceptionObject_h -#include "itkExceptionObject.h" -#undef itkExceptionObject_h - -/** itkDynamicCastInDebugMode - * Use static_cast in Release builds, and dynamic_cast in Debug - * - * Note: this must come after: - * - * #include "itkExceptionObject.h" - */ -template -TTarget -itkDynamicCastInDebugMode(TSource x) -{ -#ifndef NDEBUG - if (x == nullptr) - { - return nullptr; - } - TTarget rval = dynamic_cast(x); - if (rval == nullptr) - { - itkGenericExceptionMacro("Failed dynamic cast to " << typeid(TTarget).name() - << " object type = " << x->GetNameOfClass()); - } - return rval; -#else - return static_cast(x); -#endif -} - // ITK_FUTURE_DEPRECATED is only for internal use, within the implementation of ITK. It allows triggering "deprecated" // warnings when legacy support is removed, which warn that a specific feature may be removed in the future. #if defined(ITK_LEGACY_REMOVE) && !defined(ITK_LEGACY_SILENT) @@ -1471,4 +1438,9 @@ itkDynamicCastInDebugMode(TSource x) # define ITK_ITERATOR_FINAL /*purposefully empty for ITKv6, iterators are not virtual for performance reasons*/ #endif +#define allow_inclusion_of_itkExceptionObject_h +// Must include itkExceptionObject.h at the end of the file +// because it depends on the macros defined above +#include "itkExceptionObject.h" +#undef allow_inclusion_of_itkExceptionObject_h #endif // itkMacro_h