ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkMacro.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
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 * https://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/*=========================================================================
19 *
20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21 *
22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23 *
24 * For complete copyright, license and disclaimer of warranty information
25 * please refer to the NOTICE file at the top of the ITK source tree.
26 *
27 *=========================================================================*/
37
38#ifndef itkMacro_h
39#define itkMacro_h
40
41#include "itkWin32Header.h"
42#include "itkConfigure.h"
43#include "ITKCommonExport.h"
44
45#include <typeinfo>
46
47#include <string>
48#include <cstdlib>
49#ifndef NDEBUG
50# include <cassert>
51# include "itkPrintHelper.h" // for ostream operator<<std::vector<T>
52#endif
53
54#include <sstream>
55#include <type_traits> // For is_same, remove_const, and remove_reference.
56
61namespace itk
62{
63// end namespace itk - this is here for documentation purposes
64}
65
68#define itkNotUsed(x)
69
70// clang-format off
81#define ITK_NOOP_STATEMENT static_assert(true, "")
82
83/* NOTE: The ITK_MACROEND_NOOP_STATEMENT is used at the end
84 * of ITK supported macros to ensure that when the macro
85 * is used in the code base that the line must have ';' after
86 * the macro is used. This makes formatting visually similar
87 * to functions, and greatly improves the clang-format
88 * behaviors for indentation. This also assists
89 * modern IDE's and removes 1000's of warnings about
90 * unused statements or unnecessary ';' when macros are
91 * used. */
92#define ITK_MACROEND_NOOP_STATEMENT ITK_NOOP_STATEMENT
93// clang-format on
94
95// Define ITK_PRAGMA macro.
96//
97// It sets "#pragma" preprocessor directives without expecting the arguments
98// to be quoted.
99#define ITK_PRAGMA(x) _Pragma(#x)
100
101// The GCC/Clang compilers have many useful non-default compiler warnings
102// that tend to have a high false positive rate or are otherwise not always appropriate.
103// The following set of defines allows us to suppress instances of said warnings.
104
105// For GCC and Clang (Clang also identifies itself as GCC, and supports these pragmas):
106#if defined(__GNUC__)
107# define ITK_GCC_PRAGMA_PUSH ITK_PRAGMA(GCC diagnostic push)
108# define ITK_GCC_PRAGMA_POP ITK_PRAGMA(GCC diagnostic pop)
109# define ITK_GCC_SUPPRESS_Wfloat_equal ITK_PRAGMA(GCC diagnostic ignored "-Wfloat-equal")
110# define ITK_GCC_SUPPRESS_Wformat_nonliteral ITK_PRAGMA(GCC diagnostic ignored "-Wformat-nonliteral")
111# define ITK_GCC_SUPPRESS_Warray_bounds ITK_PRAGMA(GCC diagnostic ignored "-Warray-bounds")
112#else
113# define ITK_GCC_PRAGMA_PUSH
114# define ITK_GCC_PRAGMA_POP
115# define ITK_GCC_SUPPRESS_Wfloat_equal
116# define ITK_GCC_SUPPRESS_Wformat_nonliteral
117# define ITK_GCC_SUPPRESS_Warray_bounds
118#endif
119
120// For Clang only (and not GCC):
121#if defined(__clang__) && defined(__has_warning)
122# define ITK_CLANG_PRAGMA_PUSH ITK_PRAGMA(clang diagnostic push)
123# define ITK_CLANG_PRAGMA_POP ITK_PRAGMA(clang diagnostic pop)
124# if __has_warning("-Wzero-as-null-pointer-constant")
125# define ITK_CLANG_SUPPRESS_Wzero_as_null_pointer_constant \
126 ITK_PRAGMA(clang diagnostic ignored "-Wzero-as-null-pointer-constant")
127# else
128# define ITK_CLANG_SUPPRESS_Wzero_as_null_pointer_constant
129# endif
130# if __has_warning("-Wduplicate-enum")
131# define ITK_CLANG_SUPPRESS_Wduplicate_enum ITK_PRAGMA(clang diagnostic ignored "-Wduplicate-enum")
132# else
133# define ITK_CLANG_SUPPRESS_Wduplicate_enum
134# endif
135#else
136# define ITK_CLANG_PRAGMA_PUSH
137# define ITK_CLANG_PRAGMA_POP
138# define ITK_CLANG_SUPPRESS_Wzero_as_null_pointer_constant
139# define ITK_CLANG_SUPPRESS_Wduplicate_enum
140#endif
141
142// These were not intended as public API, but some code was nevertheless using them.
143// Support the pre ITK 5.4 spelling for compatibility.
144#define CLANG_PRAGMA_PUSH ITK_CLANG_PRAGMA_PUSH
145#define CLANG_PRAGMA_POP ITK_CLANG_PRAGMA_POP
146#define CLANG_SUPPRESS_Wfloat_equal ITK_GCC_SUPPRESS_Wfloat_equal
147
148// For GCC/Clang, to decorate printf-like functions allowing for compiler checks of format strings.
149#if defined(__GNUC__)
150# define ITK_FORMAT_PRINTF(a, b) __attribute__((format(printf, a, b)))
151#else
152# define ITK_FORMAT_PRINTF(a, b)
153#endif
154
155#if !defined(ITK_LEGACY_REMOVE)
156// Issue warning if deprecated preprocessor flag is used.
157# define CLANG_SUPPRESS_Wcpp14_extensions \
158 [[deprecated("Remove deprecated CLANG_SUPPRESS_Wcpp14_extensions c++14 warning suppression")]] void * \
159 CLANG_SUPPRESS_Wcpp14_extensions = nullptr;
160#endif
161
162// Intel compiler convenience macros
163#if defined(__INTEL_COMPILER)
164# define INTEL_PRAGMA_WARN_PUSH ITK_PRAGMA(warning push)
165# define INTEL_PRAGMA_WARN_POP ITK_PRAGMA(warning pop)
166# define INTEL_SUPPRESS_warning_1292 ITK_PRAGMA(warning disable 1292)
167#else
168# define INTEL_PRAGMA_WARN_PUSH
169# define INTEL_PRAGMA_WARN_POP
170# define INTEL_SUPPRESS_warning_1292
171#endif
172
173// Define ITK_GCC_PRAGMA_DIAG(param1 [param2 [...]]) macro.
174//
175// This macro sets a pragma diagnostic
176//
177// Define ITK_GCC_PRAGMA_DIAG_(PUSH|POP) macros.
178//
179// These macros respectively push and pop the diagnostic context
180//
181#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
182# define ITK_GCC_PRAGMA_DIAG(x) ITK_PRAGMA(GCC diagnostic x)
183# define ITK_GCC_PRAGMA_DIAG_PUSH() ITK_GCC_PRAGMA_DIAG(push)
184# define ITK_GCC_PRAGMA_DIAG_POP() ITK_GCC_PRAGMA_DIAG(pop)
185#else
186# define ITK_GCC_PRAGMA_DIAG(x)
187# define ITK_GCC_PRAGMA_DIAG_PUSH()
188# define ITK_GCC_PRAGMA_DIAG_POP()
189#endif
190
191/*
192 * ITK only supports MSVC++ 14.2 and greater
193 * MSVC++ 14.2 _MSC_VER == 1920 (Visual Studio 2019 Version 16.0)
194 */
195#if defined(_MSC_VER) && (_MSC_VER < 1920)
196# error "MSVC versions before Visual Studio 2019 are not supported"
197#endif
198#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
199# error "SUNPro C++ < 5.14.0 is not supported"
200#endif
201#if defined(__CYGWIN__)
202# error "The Cygwin compiler is not supported"
203#endif
204#if defined(__BORLANDC__)
205# error "The Borland C compiler is not supported"
206#endif
207#if defined(__MWERKS__)
208# error "The MetroWerks compiler is not supported"
209#endif
210#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && (__GNUC__ < 7)
211# error "GCC < 7 is not supported"
212#endif
213#if defined(__sgi)
214// This is true for IRIX 6.5.18m with MIPSPro 7.3.1.3m.
215// TODO: At some future point, it may be necessary to
216// define a minimum __sgi version that will work.
217# error "The SGI compiler is not supported"
218#endif
219#if defined(__apple_build_version__) && (__apple_build_version__ < 12000032)
220# error "AppleClang < Xcode 12.4 is not supported"
221#elif defined(__clang__) && (__clang_major__ < 5)
222# error "Clang < 5 is not supported"
223#endif
224#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER < 1910)
225# error "Intel C++ < 19.1 is not supported4"
226#endif
227
228// Setup symbol exports
229#if defined(_WIN32) || defined(WIN32)
230# define ITK_ABI_IMPORT __declspec(dllimport)
231# define ITK_ABI_EXPORT __declspec(dllexport)
232# define ITK_ABI_HIDDEN
233#else
234# ifdef __GNUC__
235# define ITK_ABI_IMPORT __attribute__((visibility("default")))
236# define ITK_ABI_EXPORT __attribute__((visibility("default")))
237# define ITK_ABI_HIDDEN __attribute__((visibility("hidden")))
238# else
239# define ITK_ABI_IMPORT
240# define ITK_ABI_EXPORT
241# define ITK_ABI_HIDDEN
242# endif
243#endif
244
245// Setup symbol exports
246#ifndef ITK_TEMPLATE_EXPORT
247# ifdef ITK_TEMPLATE_VISIBILITY_DEFAULT
248# define ITK_TEMPLATE_EXPORT __attribute__((visibility("default")))
249# else
250# define ITK_TEMPLATE_EXPORT
251# endif
252#endif
253
254// Setup symbol exports
255#ifdef ITK_TEMPLATE_VISIBILITY_DEFAULT
256# define ITK_FORCE_EXPORT_MACRO(moduleName) __attribute__((visibility("default")))
257#else
258# define ITK_FORCE_EXPORT_MACRO(moduleName) moduleName##_EXPORT
259#endif
260
261#ifndef ITK_FORWARD_EXPORT
262// If build with shared libraries, on MacOS, if USE_COMPILER_HIDDEN_VISIBILITY is ON
263# if defined(__APPLE__) && defined(ITK_TEMPLATE_VISIBILITY_DEFAULT) && defined(ITK_BUILD_SHARED_LIBS) && \
264 defined(USE_COMPILER_HIDDEN_VISIBILITY)
265# define ITK_FORWARD_EXPORT __attribute__((visibility("default")))
266# else
267# define ITK_FORWARD_EXPORT
268# endif
269#endif
270
271
293#define itkNewMacro(x) \
294 itkSimpleNewMacro(x); \
295 itkCreateAnotherMacro(x); \
296 itkCloneMacro(x); \
297 ITK_MACROEND_NOOP_STATEMENT
299#define itkSimpleNewMacro(x) \
300 static Pointer New() \
301 { \
302 Pointer smartPtr = ::itk::ObjectFactory<x>::Create(); \
303 if (smartPtr == nullptr) \
304 { \
305 smartPtr = new x(); \
306 } \
307 smartPtr->UnRegister(); \
308 return smartPtr; \
309 } \
310 ITK_MACROEND_NOOP_STATEMENT
311
312#define itkCreateAnotherMacro(x) \
313 ::itk::LightObject::Pointer CreateAnother() const override { return x::New().GetPointer(); } \
314 ITK_MACROEND_NOOP_STATEMENT
315
316#define itkCloneMacro(x) \
317 Pointer Clone() const \
318 { \
319 Pointer rval = dynamic_cast<x *>(this->InternalClone().GetPointer()); \
320 return rval; \
321 } \
322 ITK_MACROEND_NOOP_STATEMENT
323
328#define itkFactoryOnlyNewMacro(x) \
329 itkSimpleFactoryOnlyNewMacro(x); \
330 itkCreateAnotherMacro(x); \
331 itkCloneMacro(x); \
332 ITK_MACROEND_NOOP_STATEMENT
334#define itkSimpleFactoryOnlyNewMacro(x) \
335 static auto New() -> Pointer \
336 { \
337 Pointer smartPtr = ::itk::ObjectFactory<x>::Create(); \
338 if (smartPtr == nullptr) \
339 { \
340 itkSpecializedMessageExceptionMacro(ExceptionObject, \
341 "Object factory failed to instantiate " << typeid(x).name()); \
342 } \
343 smartPtr->UnRegister(); \
344 return smartPtr; \
345 } \
346 ITK_MACROEND_NOOP_STATEMENT
347
361#define itkFactorylessNewMacro(x) \
362 static Pointer New() \
363 { \
364 auto * rawPtr = new x(); \
365 Pointer smartPtr = rawPtr; \
366 rawPtr->UnRegister(); \
367 return smartPtr; \
368 } \
369 itkCreateAnotherMacro(x); \
370 ITK_MACROEND_NOOP_STATEMENT
372//
373// A macro to disallow the copy constructor, copy assignment,
374// move constructor, and move assignment functions.
375// This should be used in the public: declarations for a class
376//
377// ITK's paradigm for smart pointer and pipeline consistency
378// prohibits the use of copy/move construction and copy/move assignment
379// functions.
380//
381#define ITK_DISALLOW_COPY_AND_MOVE(TypeName) \
382 TypeName(const TypeName &) = delete; \
383 TypeName & operator=(const TypeName &) = delete; \
384 TypeName(TypeName &&) = delete; \
385 TypeName & operator=(TypeName &&) = delete
386
387#if !defined(ITK_LEGACY_REMOVE)
388# define ITK_DISALLOW_COPY_AND_ASSIGN(TypeName) ITK_DISALLOW_COPY_AND_MOVE(TypeName)
389#else
390# define ITK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
391 static_assert(false, "Replace deprecated ITK_DISALLOW_COPY_AND_ASSIGN with modern ITK_DISALLOW_COPY_AND_MOVE")
392#endif
393
394
403#define ITK_DEFAULT_COPY_AND_MOVE(TypeName) \
404 TypeName(const TypeName &) = default; \
405 TypeName & operator=(const TypeName &) = default; \
406 TypeName(TypeName &&) = default; \
407 TypeName & operator=(TypeName &&) = default
409
410// When ITK_EXPERIMENTAL_CXX20_REWRITTEN_UNEQUAL_OPERATOR is defined, ITK uses
411// the ability for operator!= to be rewritten automatically in terms of
412// operator==, as introduced with C++20. This macro is experimental. It may be
413// modified, renamed, or removed without backward compatibility support.
414#if __cplusplus >= 202002L
415# define ITK_EXPERIMENTAL_CXX20_REWRITTEN_UNEQUAL_OPERATOR
416#endif
417
418// Note: The following macro, ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(TypeName),
419// is only for internal use within the implementation of ITK. It may be
420// modified, renamed, or removed without backward compatibility support.
421#ifdef ITK_EXPERIMENTAL_CXX20_REWRITTEN_UNEQUAL_OPERATOR
422// With C++20, operator!= is automatically rewritten in terms of the
423// corresponding operator==.
424# define ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(TypeName) ITK_MACROEND_NOOP_STATEMENT
425#else
426// For C++14 and C++17, this macro defines an operator!= member function that
427// just calls the corresponding operator== member function.
428# define ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(TypeName) \
429 bool operator!=(const TypeName & other) const { return !(this->operator==(other)); } \
430 ITK_MACROEND_NOOP_STATEMENT
431#endif
432
433
434// Internal macro (not part of the public ITK API), used to implement `GetNameOfClass()` member functions.
435#define itkInternalGetNameOfClassImplementationMacro(thisClass) \
436 { \
437 static_assert(std::is_same_v<thisClass, std::remove_const_t<std::remove_reference_t<decltype(*this)>>>, \
438 "The macro argument `" #thisClass \
439 "` appears incorrect! It should correspond with the name of this class!"); \
440 return #thisClass; \
441 } \
442 ITK_MACROEND_NOOP_STATEMENT
443
444
448#define itkVirtualGetNameOfClassMacro(thisClass) \
449 virtual const char * GetNameOfClass() const itkInternalGetNameOfClassImplementationMacro(thisClass)
450
451#define itkOverrideGetNameOfClassMacro(thisClass) \
452 const char * GetNameOfClass() const override itkInternalGetNameOfClassImplementationMacro(thisClass)
453
454#ifdef ITK_FUTURE_LEGACY_REMOVE
455# define itkTypeMacro(thisClass, superclass) \
456 static_assert(false, \
457 "In a future revision of ITK, the macro `itkTypeMacro(thisClass, superclass)` will be removed. " \
458 "Please call `itkOverrideGetNameOfClassMacro(thisClass)` instead!")
459# define itkTypeMacroNoParent(thisClass) \
460 static_assert(false, \
461 "In a future revision of ITK, the macro `itkTypeMacroNoParent(thisClass)` will be removed. " \
462 "Please call `itkVirtualGetNameOfClassMacro(thisClass)` instead!")
463#else
468# define itkTypeMacro(thisClass, superclass) itkOverrideGetNameOfClassMacro(thisClass)
469# define itkTypeMacroNoParent(thisClass) itkVirtualGetNameOfClassMacro(thisClass)
470#endif
471
472
473namespace itk
474{
482extern ITKCommon_EXPORT void
483OutputWindowDisplayText(const char *);
484
485extern ITKCommon_EXPORT void
486OutputWindowDisplayErrorText(const char *);
487
488extern ITKCommon_EXPORT void
489OutputWindowDisplayWarningText(const char *);
490
491extern ITKCommon_EXPORT void
492OutputWindowDisplayGenericOutputText(const char *);
493
494extern ITKCommon_EXPORT void
495OutputWindowDisplayDebugText(const char *);
497
498} // end namespace itk
499
500// The itkDebugStatement is to be used to protect code that is only used in the itkDebugMacro
506#if defined(NDEBUG)
507# define itkDebugMacro(x) ITK_NOOP_STATEMENT
508# define itkDebugStatement(x) ITK_NOOP_STATEMENT
509#else
510# define itkDebugMacro(x) \
511 { \
512 using namespace ::itk::print_helper; /* for ostream << std::vector<T> */ \
513 if (this->GetDebug() && ::itk::Object::GetGlobalWarningDisplay()) \
514 { \
515 std::ostringstream itkmsg; \
516 itkmsg << "Debug: In " __FILE__ ", line " << __LINE__ << '\n' \
517 << this->GetNameOfClass() << " (" << this << "): " x << "\n\n"; \
518 ::itk::OutputWindowDisplayDebugText(itkmsg.str().c_str()); \
519 } \
520 } \
521 ITK_MACROEND_NOOP_STATEMENT
522// The itkDebugStatement is to be used to protect code that is only
523// used in the itkDebugMacro
524# define itkDebugStatement(x) x
525#endif
530#define itkWarningMacro(x) \
531 { \
532 if (::itk::Object::GetGlobalWarningDisplay()) \
533 { \
534 std::ostringstream itkmsg; \
535 itkmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << '\n' \
536 << this->GetNameOfClass() << " (" << this << "): " x << "\n\n"; \
537 ::itk::OutputWindowDisplayWarningText(itkmsg.str().c_str()); \
538 } \
539 } \
540 ITK_MACROEND_NOOP_STATEMENT
541
542
543#define itkWarningStatement(x) x
544
545#if defined(ITK_CPP_FUNCTION)
546# if defined(_WIN32) && !defined(__MINGW32__) && !defined(ITK_WRAPPING_PARSER)
547# define ITK_LOCATION __FUNCSIG__
548# elif defined(__GNUC__)
549# define ITK_LOCATION __PRETTY_FUNCTION__
550# else
551# define ITK_LOCATION __FUNCTION__
552# endif
553#else
554# define ITK_LOCATION "unknown"
555#endif
556
557#define itkDeclareExceptionMacro(newexcp, parentexcp, whatmessage) \
558 namespace itk \
559 { \
560 class newexcp : public parentexcp \
561 { \
562 public: \
563 /* default message provides backward compatibility for a given exception type */ \
564 static constexpr const char * const default_exception_message = whatmessage; \
565 /* Inherit the constructors from its base class. */ \
566 using parentexcp::parentexcp; \
567 itkOverrideGetNameOfClassMacro(newexcp); \
568 }; \
569 } \
570 ITK_MACROEND_NOOP_STATEMENT
571
572
573#define itkSpecializedMessageExceptionMacro(ExceptionType, x) \
574 { \
575 std::ostringstream exceptionDescriptionOutputStringStream; \
576 exceptionDescriptionOutputStringStream << "ITK ERROR: " x; \
577 throw ::itk::ExceptionType( \
578 std::string{ __FILE__ }, __LINE__, exceptionDescriptionOutputStringStream.str(), std::string{ ITK_LOCATION }); \
579 } \
580 ITK_MACROEND_NOOP_STATEMENT
581
582#define itkSpecializedExceptionMacro(ExceptionType) \
583 itkSpecializedMessageExceptionMacro(ExceptionType, << ::itk::ExceptionType::default_exception_message)
584
588#define itkExceptionMacro(x) \
589 itkSpecializedMessageExceptionMacro(ExceptionObject, << this->GetNameOfClass() << '(' << this << "): " x)
590
591#define itkGenericExceptionMacro(x) itkSpecializedMessageExceptionMacro(ExceptionObject, x)
592
593#define itkGenericOutputMacro(x) \
594 { \
595 if (::itk::Object::GetGlobalWarningDisplay()) \
596 { \
597 std::ostringstream itkmsg; \
598 itkmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << "\n" x << "\n\n"; \
599 ::itk::OutputWindowDisplayGenericOutputText(itkmsg.str().c_str()); \
600 } \
601 } \
602 ITK_MACROEND_NOOP_STATEMENT
603
604//----------------------------------------------------------------------------
605// Macros for simplifying the use of logging
606//
607#define itkLogMacro(x, y) \
608 { \
609 if (this->GetLogger()) \
610 { \
611 this->GetLogger()->Write(::itk::LoggerBase::x, y); \
612 } \
613 } \
614 ITK_MACROEND_NOOP_STATEMENT
615
616#define itkLogMacroStatic(obj, x, y) \
617 { \
618 if (obj->GetLogger()) \
619 { \
620 obj->GetLogger()->Write(::itk::LoggerBase::x, y); \
621 } \
622 } \
623 ITK_MACROEND_NOOP_STATEMENT
624
625//----------------------------------------------------------------------------
626// Setup legacy code policy.
627//
628// CMake options:
629// - When ITK_LEGACY_REMOVE:BOOL=ON, legacy code is hidden, thus causing compiler errors for code that depends on it
630// - When ITK_LEGACY_REMOVE:BOOL=OFF, and ITK_LEGACY_SILENT:BOOL=ON, use
631// of legacy code will not produce compiler warnings.
632// - When ITK_LEGACY_REMOVE:BOOL=OFF, and ITK_LEGACY_SILENT:BOOL=OFF, use
633// of legacy code will produce compiler warnings
634//
635// ITK_LEGACY_SILENT silently use legacy code. The default is to warn about legacy code use.
636//
637// Source files that test the legacy code may define ITK_LEGACY_TEST
638// like this:
639//
640// #define ITK_LEGACY_TEST
641// #include "itkClassWithDeprecatedMethod.h"
642//
643// in order to silence the warnings for calling deprecated methods.
644// No other source files in ITK should call the methods since they are
645// provided only for compatibility with older user code.
646
647// Define itkLegacyMacro to mark legacy methods where they are
648// declared in their class. Example usage:
649//
650// // \deprecated Replaced by MyOtherMethod() as of ITK 2.0.
651// itkLegacyMacro(void MyMethod();)
652//
653// See below for what to do for the method definition.
654#if defined(ITK_LEGACY_REMOVE)
655# define itkLegacyMacro(method) /* no ';' */
656#else
657# if defined(ITK_LEGACY_SILENT) || defined(ITK_LEGACY_TEST)
658// Provide legacy methods with no warnings.
659# define itkLegacyMacro(method) method /* no ';' */
660# else
661// Request compile-time warnings for uses of deprecated methods.
662# define itkLegacyMacro(method) [[deprecated]] method /* no ';' */
663# endif
664#endif
665
666// Macros to create runtime deprecation warning messages in function
667// bodies. Example usage:
668//
669// #if !defined( ITK_LEGACY_REMOVE )
670// void itkMyClass::MyOldMethod()
671// {
672// itkLegacyBodyMacro(itkMyClass::MyOldMethod, 2.0);
673// }
674//
675// void itkMyClass::MyMethod()
676// {
677// itkLegacyReplaceBodyMacro(itkMyClass::MyMethod, 2.0,
678// itkMyClass::MyOtherMethod);
679// }
680// #endif
681//
682// NOTE: These 4 macros itkLegacyBodyMacro, itkLegacyReplaceBodyMacro,
683// itkGenericLegacyBodyMacro, and itkGenericLegacyReplaceBodyMacro
684// are purposefully not defined when ITK_LEGACY_REMOVE is on,
685// because these macros are only relevant inside code segments
686// that are conditionally compiled only when ITK_LEGACY_REMOVE
687// is off.
688#if defined(ITK_LEGACY_SILENT)
689# define itkLegacyBodyMacro(method, version) ITK_NOOP_STATEMENT
690# define itkLegacyReplaceBodyMacro(method, version, replace) ITK_NOOP_STATEMENT
691# define itkGenericLegacyBodyMacro(method, version) ITK_NOOP_STATEMENT
692# define itkGenericLegacyReplaceBodyMacro(method, version, replace) ITK_NOOP_STATEMENT
693#else
694# define itkLegacyBodyMacro(method, version) \
695 itkWarningMacro(#method " was deprecated for ITK " #version " and will be removed in a future version.")
696# define itkLegacyReplaceBodyMacro(method, version, replace) \
697 itkWarningMacro(#method " was deprecated for ITK " #version \
698 " and will be removed in a future version. Use " #replace " instead.")
699# define itkGenericLegacyBodyMacro(method, version) \
700 itkGenericOutputMacro(#method " was deprecated for ITK " #version " and will be removed in a future version.")
701# define itkGenericLegacyReplaceBodyMacro(method, version, replace) \
702 itkGenericOutputMacro(#method " was deprecated for ITK " #version \
703 " and will be removed in a future version. Use " #replace " instead.")
704#endif
705
706// Most modern x86 CPUs have 64 byte aligned blocks which are used for
707// the cache lines. By aligning multi-threaded structures with the
708// cache lines, false shared can be reduced, and performance
709// increased.
710constexpr size_t ITK_CACHE_LINE_ALIGNMENT = 64;
711
712//
713// itkPadStruct will add padding to a structure to ensure a minimum size
714// for ensuring that adjacent structures do not share CACHE lines.
715// Each struct will take up some multiple of cacheline sizes.
716// This is particularly useful for arrays of thread private variables.
717//
718#define itkPadStruct(mincachesize, oldtype, newtype) \
719 struct newtype : public oldtype \
720 { \
721 char _StructPadding[mincachesize - (sizeof(oldtype) % mincachesize)]; \
722 }
723
724//
725// itkAlignedTypedef is a macro which creates a new type to make a
726// data structure aligned.
727//
728#if defined(ITK_HAS_GNU_ATTRIBUTE_ALIGNED)
729# define itkAlignedTypedef(alignment, oldtype, newtype) using newtype = oldtype __attribute__((aligned(alignment)))
730#elif defined(_MSC_VER)
731# define itkAlignedTypedef(alignment, oldtype, newtype) using newtype = __declspec(align(alignment)) oldtype
732#else
733# define itkAlignedTypedef(alignment, oldtype, newtype) using newtype = oldtype
734#endif
735
736#if defined(ITK_FUTURE_LEGACY_REMOVE)
737//=============================================================================
738/*
739NOTE: DEPRECATED - This macro is not longer needed to support modern
740compilers.
741
742 Define a common way of declaring a templated function as a friend inside a class.
743 - ITK_FRIEND_TEMPLATE_FUNCTION_ARGUMENTS(T)
744
745 The following templated function
746
747 template <T>
748 T add(const T & a, const T & b);
749
750 is declared as friend with
751
752 class A
753 {
754 public:
755 friend Self add<>( const Self & a, const Self & b );
756 }
757
758*/
759# define ITK_FRIEND_TEMPLATE_FUNCTION_ARGUMENT(T) < >
760#else // LEGACY_REMOVE
761# define ITK_FRIEND_TEMPLATE_FUNCTION_ARGUMENT(T) "Macro remove use C++11 compliant declaration of "
762#endif
763
764//--------------------------------------------------------------------------------
765// Helper macros for Template Meta-Programming techniques of for-loops
766// unrolling
767//--------------------------------------------------------------------------------
768
769//--------------------------------------------------------------------------------
770// Macro that generates an unrolled for loop for assigning elements of one array
771// to elements of another array The array are assumed to be of same length
772// (dimension), and this is also assumed to be the value of NumberOfIterations.
773// No verification of size is performed. Casting is performed as part of the
774// assignment, by using the DestinationElementType as the casting type.
775// Source and destination array types must have defined operator[] in their
776// API.
777#define itkForLoopAssignmentMacro( \
778 DestinationType, SourceType, DestinationElementType, DestinationArray, SourceArray, NumberOfIterations) \
779 for (unsigned int i = 0; i < NumberOfIterations; ++i) \
780 { \
781 DestinationArray[i] = static_cast<DestinationElementType>(SourceArray[i]); \
782 } \
783 ITK_MACROEND_NOOP_STATEMENT
784
785//--------------------------------------------------------------------------------
786// Macro that generates an unrolled for loop for rounding and assigning
787// elements of one array to elements of another array The array are assumed to
788// be of same length (dimension), and this is also assumed to be the value of
789// NumberOfIterations. No verification of size is performed. Casting is
790// performed as part of the assignment, by using the DestinationElementType as
791// the casting type.
792// Source and destination array types must have defined operator[] in their
793// API.
794#define itkForLoopRoundingAndAssignmentMacro( \
795 DestinationType, Sourcrnd_halfintup, DestinationElementType, DestinationArray, SourceArray, NumberOfIterations) \
796 for (unsigned int i = 0; i < NumberOfIterations; ++i) \
797 { \
798 DestinationArray[i] = ::itk::Math::Round<DestinationElementType>(SourceArray[i]); \
799 } \
800 ITK_MACROEND_NOOP_STATEMENT
801
802// end of Template Meta Programming helper macros
803
804#if !defined(NDEBUG) && !defined(ITK_WRAPPING)
805
806# ifdef __GLIBC__
807# define itkAssertInDebugOrThrowInReleaseMacro(msg) __assert_fail(msg, __FILE__, __LINE__, __ASSERT_FUNCTION);
808# else
809# define itkAssertInDebugOrThrowInReleaseMacro(msg) itkGenericExceptionMacro(<< msg);
810# endif
811
812#else
813# define itkAssertInDebugOrThrowInReleaseMacro(msg) itkGenericExceptionMacro(<< msg);
814#endif
815
816#define itkAssertOrThrowMacro(test, message) \
817 if (!(test)) \
818 { \
819 std::ostringstream msgstr; \
820 msgstr << message; \
821 itkAssertInDebugOrThrowInReleaseMacro(msgstr.str().c_str()); \
822 } \
823 ITK_MACROEND_NOOP_STATEMENT
824
825#if !defined(NDEBUG) && !defined(ITK_WRAPPING)
826# define itkAssertInDebugAndIgnoreInReleaseMacro(X) assert(X)
827#else
828# define itkAssertInDebugAndIgnoreInReleaseMacro(X) ITK_NOOP_STATEMENT
829#endif
830
831
832// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
833// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
834// !! The ITK Get/Set Macros for various types !!
835// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
836// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
837
838#ifdef ITK_FUTURE_LEGACY_REMOVE
839# define itkStaticConstMacro(name, type, value) \
840 "Replace itkStaticConstMacro(name, type, value) with `static constexpr type name = value`"
841# define itkGetStaticConstMacro(name) "Replace itkGetStaticConstMacro(name) with `Self::name`"
842#else
857# define itkStaticConstMacro(name, type, value) static constexpr type name = value
858
859# define itkGetStaticConstMacro(name) (Self::name)
860#endif
861
864#define itkSetInputMacro(name, type) \
865 virtual void Set##name(const type * _arg) \
866 { \
867 itkDebugMacro("setting input " #name " to " << _arg); \
868 if (_arg != itkDynamicCastInDebugMode<type *>(this->ProcessObject::GetInput(#name))) \
869 { \
870 this->ProcessObject::SetInput(#name, const_cast<type *>(_arg)); \
871 this->Modified(); \
872 } \
873 } \
874 ITK_MACROEND_NOOP_STATEMENT
878#define itkGetInputMacro(name, type) \
879 virtual const type * Get##name() const \
880 { \
881 itkDebugMacro("returning input " << #name " of " << this->ProcessObject::GetInput(#name)); \
882 return itkDynamicCastInDebugMode<const type *>(this->ProcessObject::GetInput(#name)); \
883 } \
884 ITK_MACROEND_NOOP_STATEMENT
886// clang-format off
889#define itkSetDecoratedInputMacro(name, type) \
890 virtual void Set## name## Input(const SimpleDataObjectDecorator<type> * _arg) \
891 { \
892 itkDebugMacro("setting input " #name " to " << _arg); \
893 if (_arg != itkDynamicCastInDebugMode<SimpleDataObjectDecorator<type> *>(this->ProcessObject::GetInput(#name))) \
894 { \
895 this->ProcessObject::SetInput(#name, const_cast<SimpleDataObjectDecorator<type> *>(_arg)); \
896 this->Modified(); \
897 } \
898 } \
899 virtual void Set## name(const SimpleDataObjectDecorator<type> * _arg) { this->Set## name## Input(_arg); } \
900 virtual void Set## name(const type & _arg) \
901 { \
902 using DecoratorType = SimpleDataObjectDecorator<type>; \
903 itkDebugMacro("setting input " #name " to " << _arg); \
904 const DecoratorType * oldInput = \
905 itkDynamicCastInDebugMode<const DecoratorType *>(this->ProcessObject::GetInput(#name)); \
906 ITK_GCC_PRAGMA_PUSH \
907 ITK_GCC_SUPPRESS_Wfloat_equal \
908 if (oldInput && oldInput->Get() == _arg) \
909 { \
910 return; \
911 } \
912 ITK_GCC_PRAGMA_POP \
913 auto newInput = DecoratorType::New(); \
914 newInput->Set(_arg); \
915 this->Set## name## Input(newInput); \
916 } \
917 ITK_MACROEND_NOOP_STATEMENT
918// clang-format on
922#define itkGetDecoratedInputMacro(name, type) \
923 virtual const SimpleDataObjectDecorator<type> * Get##name##Input() const \
924 { \
925 itkDebugMacro("returning input " << #name " of " << this->ProcessObject::GetInput(#name)); \
926 return itkDynamicCastInDebugMode<const SimpleDataObjectDecorator<type> *>(this->ProcessObject::GetInput(#name)); \
927 } \
928 virtual const type & Get##name() const \
929 { \
930 itkDebugMacro("Getting input " #name); \
931 using DecoratorType = SimpleDataObjectDecorator<type>; \
932 const DecoratorType * input = \
933 itkDynamicCastInDebugMode<const DecoratorType *>(this->ProcessObject::GetInput(#name)); \
934 if (input == nullptr) \
935 { \
936 itkExceptionMacro("input" #name " is not set"); \
937 } \
938 return input->Get(); \
939 } \
940 ITK_MACROEND_NOOP_STATEMENT
944#define itkSetGetDecoratedInputMacro(name, type) \
945 itkSetDecoratedInputMacro(name, type); \
946 itkGetDecoratedInputMacro(name, type)
947
953#define itkSetDecoratedObjectInputMacro(name, type) \
954 virtual void Set##name##Input(const DataObjectDecorator<type> * _arg) \
955 { \
956 itkDebugMacro("setting input " #name " to " << _arg); \
957 if (_arg != itkDynamicCastInDebugMode<DataObjectDecorator<type> *>(this->ProcessObject::GetInput(#name))) \
958 { \
959 this->ProcessObject::SetInput(#name, const_cast<DataObjectDecorator<type> *>(_arg)); \
960 this->Modified(); \
961 } \
962 } \
963 virtual void Set##name(const type * _arg) \
964 { \
965 using DecoratorType = DataObjectDecorator<type>; \
966 itkDebugMacro("setting input " #name " to " << _arg); \
967 const DecoratorType * oldInput = \
968 itkDynamicCastInDebugMode<const DecoratorType *>(this->ProcessObject::GetInput(#name)); \
969 if (oldInput && oldInput->Get() == _arg) \
970 { \
971 return; \
972 } \
973 auto newInput = DecoratorType::New(); \
974 newInput->Set(_arg); \
975 this->Set##name##Input(newInput); \
976 } \
977 ITK_MACROEND_NOOP_STATEMENT
984#define itkGetDecoratedObjectInputMacro(name, type) \
985 virtual const DataObjectDecorator<type> * Get##name##Input() const \
986 { \
987 itkDebugMacro("returning input " << #name " of " << this->ProcessObject::GetInput(#name)); \
988 return itkDynamicCastInDebugMode<const DataObjectDecorator<type> *>(this->ProcessObject::GetInput(#name)); \
989 } \
990 virtual const type * Get##name() const \
991 { \
992 itkDebugMacro("Getting input " #name); \
993 using DecoratorType = DataObjectDecorator<type>; \
994 const DecoratorType * input = \
995 itkDynamicCastInDebugMode<const DecoratorType *>(this->ProcessObject::GetInput(#name)); \
996 if (input == nullptr) \
997 { \
998 return nullptr; \
999 } \
1000 return input->Get(); \
1001 } \
1002 ITK_MACROEND_NOOP_STATEMENT
1006#define itkSetGetDecoratedObjectInputMacro(name, type) \
1007 itkSetDecoratedObjectInputMacro(name, type); \
1008 itkGetDecoratedObjectInputMacro(name, type)
1009
1011// clang-format off
1012#define itkSetMacro(name, type) \
1013 virtual void Set## name(type _arg) \
1014 { \
1015 itkDebugMacro("setting " #name " to " << _arg); \
1016 ITK_GCC_PRAGMA_PUSH \
1017 ITK_GCC_SUPPRESS_Wfloat_equal \
1018 if (this->m_## name != _arg) \
1019 { \
1020 this->m_## name = std::move(_arg); \
1021 this->Modified(); \
1022 } \
1023 ITK_GCC_PRAGMA_POP \
1024 } \
1025 ITK_MACROEND_NOOP_STATEMENT
1026// clang-format on
1027
1030#define itkGetMacro(name, type) \
1031 virtual type Get##name() { return this->m_##name; } \
1032 ITK_MACROEND_NOOP_STATEMENT
1038#define itkGetConstMacro(name, type) \
1039 virtual type Get##name() const { return this->m_##name; } \
1040 ITK_MACROEND_NOOP_STATEMENT
1047#define itkGetConstReferenceMacro(name, type) \
1048 virtual const type & Get##name() const { return this->m_##name; } \
1049 ITK_MACROEND_NOOP_STATEMENT
1056#define itkSetEnumMacro(name, type) \
1057 virtual void Set##name(const type _arg) \
1058 { \
1059 itkDebugMacro("setting " #name " to " << static_cast<long>(_arg)); \
1060 if (this->m_##name != _arg) \
1061 { \
1062 this->m_##name = _arg; \
1063 this->Modified(); \
1064 } \
1065 } \
1066 ITK_MACROEND_NOOP_STATEMENT
1073#define itkGetEnumMacro(name, type) \
1074 virtual type Get##name() const { return this->m_##name; } \
1075 ITK_MACROEND_NOOP_STATEMENT
1081#define itkSetStringMacro(name) \
1082 virtual void Set##name(const char * _arg) \
1083 { \
1084 if (_arg && (_arg == this->m_##name)) \
1085 { \
1086 return; \
1087 } \
1088 if (_arg) \
1089 { \
1090 this->m_##name = _arg; \
1091 } \
1092 else \
1093 { \
1094 this->m_##name = ""; \
1095 } \
1096 this->Modified(); \
1097 } \
1098 virtual void Set##name(const std::string & _arg) { this->Set##name(_arg.c_str()); } \
1099 ITK_MACROEND_NOOP_STATEMENT
1101
1105#define itkGetStringMacro(name) \
1106 virtual const char * Get##name() const { return this->m_##name.c_str(); } \
1107 ITK_MACROEND_NOOP_STATEMENT
1108
1109// clang-format off
1114#define itkSetClampMacro(name, type, min, max) \
1115 virtual void Set## name(type _arg) \
1116 { \
1117 const type temp_extrema = (_arg <= min ? min : (_arg >= max ? max : _arg)); \
1118 itkDebugMacro("setting " << #name " to " << _arg); \
1119 ITK_GCC_PRAGMA_PUSH \
1120 ITK_GCC_SUPPRESS_Wfloat_equal \
1121 if (this->m_## name != temp_extrema) \
1122 { \
1123 this->m_## name = temp_extrema; \
1124 this->Modified(); \
1125 } \
1126 ITK_GCC_PRAGMA_POP \
1127 } \
1128 ITK_MACROEND_NOOP_STATEMENT
1129// clang-format on
1131// clang-format off
1136#define itkSetObjectMacro(name, type) \
1137 virtual void Set## name(type * _arg) \
1138 { \
1139 itkDebugMacro("setting " << #name " to " << _arg); \
1140 if (this->m_## name != _arg) \
1141 { \
1142 this->m_## name = _arg; \
1143 this->Modified(); \
1144 } \
1145 } \
1146 ITK_MACROEND_NOOP_STATEMENT
1147// clang-format on
1157// NOTE: A class can use either itkGetModifiableObjectMacro
1158// or itkGetObjectMacro, but not both.
1159// A class can use either itkGetModifiableObjectMacro
1160// or itkGetConstObjectMacro, but not both.
1161// If the desired behavior is to only provide const
1162// access to the itkObject ivar, then use itkGetConstObjectMacro,
1163// else use itkGetModifiableObjectMacro for read/write access to
1164// the ivar.
1165// It is permissible to use both itkGetObjectMacro and itkGetConstObjectMacro
1166// for backwards compatibility.
1167// If the ITK_LEGACY_REMOVE=FALSE, then it is
1168// permissible to use itkGetObjectMacro which
1169// defines both signatures itk::GetXXX() and
1170// itk::GetModifiableXXX()
1171
1174#define itkGetConstObjectMacro(name, type) \
1175 virtual const type * Get##name() const { return this->m_##name.GetPointer(); } \
1176 ITK_MACROEND_NOOP_STATEMENT
1177
1178
1179#if defined(ITK_FUTURE_LEGACY_REMOVE)
1180// In the future, the itkGetObjectMacro will be deprecated with the ITK_LEGACY_REMOVE
1181// flag. For now, this very advanced feature is only available
1182// through manual setting of a compiler define -DITK_FUTURE_LEGACY_REMOVE
1183// ("/DITK_FUTURE_LEGACY_REMOVE /EHsc" with Visual Studio)
1184// to ease the transition from the historical GetObjectMacro to the GetModifiableObjectMacro
1185# define itkGetObjectMacro(name, type) \
1186 virtual type * Get##name() \
1187 { \
1188 purposeful_error("itkGetObjectMacro should be replaced with itkGetModifiableObjectMacro."); \
1189 } \
1190 ITK_MACROEND_NOOP_STATEMENT
1191
1192# define itkGetModifiableObjectMacro(name, type) \
1193 virtual type * GetModifiable##name() { return this->m_##name.GetPointer(); } \
1194 itkGetConstObjectMacro(name, type)
1195
1196#else // defined ( ITK_FUTURE_LEGACY_REMOVE )
1200# define itkGetObjectMacro(name, type) \
1201 virtual type * Get##name() { return this->m_##name.GetPointer(); } \
1202 ITK_MACROEND_NOOP_STATEMENT
1203# define itkGetModifiableObjectMacro(name, type) \
1204 virtual type * GetModifiable##name() { return this->m_##name.GetPointer(); } \
1205 itkGetConstObjectMacro(name, type); \
1206 itkGetObjectMacro(name, type)
1208#endif // defined ( ITK_FUTURE_LEGACY_REMOVE )
1209
1210// For backwards compatibility define ITK_EXPORT to nothing
1211#define ITK_EXPORT
1212
1213
1216#define itkGetConstReferenceObjectMacro(name, type) \
1217 virtual const typename type::Pointer & Get##name() const { return this->m_##name; } \
1218 ITK_MACROEND_NOOP_STATEMENT
1219
1224#define itkSetConstObjectMacro(name, type) \
1225 virtual void Set##name(const type * _arg) \
1226 { \
1227 itkDebugMacro("setting " << #name " to " << _arg); \
1228 if (this->m_##name != _arg) \
1229 { \
1230 this->m_##name = _arg; \
1231 this->Modified(); \
1232 } \
1233 } \
1234 ITK_MACROEND_NOOP_STATEMENT
1239#define itkBooleanMacro(name) \
1240 virtual void name##On() { this->Set##name(true); } \
1241 virtual void name##Off() { this->Set##name(false); } \
1242 ITK_MACROEND_NOOP_STATEMENT
1244
1253template <typename MemberContainerType, typename CopyFromValueType, typename LoopEndType>
1254bool
1255ContainerFillWithCheck(MemberContainerType & m, const CopyFromValueType & c, const LoopEndType N)
1256{
1257 bool value_updated = false;
1258 for (unsigned int i = 0; i < N; ++i)
1259 {
1260 ITK_GCC_PRAGMA_PUSH
1261 ITK_GCC_SUPPRESS_Wfloat_equal
1262 if (m[i] != c)
1263 {
1264 m[i] = c;
1265 value_updated = true;
1266 }
1267 ITK_GCC_PRAGMA_POP
1268 }
1269 return value_updated;
1270}
1271
1280template <typename MemberContainerType, typename CopyFromContainerType, typename LoopEndType>
1281bool
1282ContainerCopyWithCheck(MemberContainerType & m, const CopyFromContainerType & c, const LoopEndType N)
1283{
1284 bool value_updated = false;
1285 for (LoopEndType i = 0; i < N; ++i)
1286 {
1287 ITK_GCC_PRAGMA_PUSH
1288 ITK_GCC_SUPPRESS_Wfloat_equal
1289 if (m[i] != c[i])
1290 {
1291 m[i] = c[i];
1292 value_updated = true;
1293 }
1294 ITK_GCC_PRAGMA_POP
1295 }
1296 return value_updated;
1297}
1298
1299// clang-format off
1304#define itkSetVectorMacro(name, type, count) \
1305 virtual void Set## name(type data[]) \
1306 { \
1307 if (ContainerCopyWithCheck( this->m_## name, data, count)) \
1308 { \
1309 this->Modified(); \
1310 } \
1311 } \
1312 ITK_MACROEND_NOOP_STATEMENT
1313// clang-format on
1317#define itkGetVectorMacro(name, type, count) \
1318 virtual type * Get##name() const { return this->m_##name; } \
1319 ITK_MACROEND_NOOP_STATEMENT
1320
1325#define itkGPUKernelClassMacro(kernel) class itkGPUKernelMacro(kernel)
1326
1333#define itkGPUKernelMacro(kernel) \
1334 kernel \
1335 { \
1336 public: \
1337 ITK_DISALLOW_COPY_AND_MOVE(kernel); \
1338 kernel() = delete; \
1339 ~kernel() = delete; \
1340 static const char * GetOpenCLSource(); \
1341 }
1343#define itkGetOpenCLSourceFromKernelMacro(kernel) \
1344 static const char * GetOpenCLSource() { return kernel::GetOpenCLSource(); } \
1345 ITK_MACROEND_NOOP_STATEMENT
1346
1347// A useful macro in the PrintSelf method for printing member variables
1348// which are pointers to object based on the LightObject class.
1349#define itkPrintSelfObjectMacro(name) \
1350 if (static_cast<const LightObject *>(this->m_##name) == nullptr) \
1351 { \
1352 os << indent << #name << ": (null)" << std::endl; \
1353 } \
1354 else \
1355 { \
1356 os << indent << #name << ": " << std::endl; \
1357 this->m_##name->Print(os, indent.GetNextIndent()); \
1358 } \
1359 ITK_MACROEND_NOOP_STATEMENT
1360
1361
1362// A useful macro in the PrintSelf method for printing boolean member
1363// variables.
1364#define itkPrintSelfBooleanMacro(name) \
1365 os << indent << #name << ": " << (this->m_##name ? "On" : "Off") << std::endl; \
1366 ITK_MACROEND_NOOP_STATEMENT
1367
1368
1371#define itkSetDecoratedOutputMacro(name, type) \
1372 virtual void Set##name##Output(const SimpleDataObjectDecorator<type> * _arg) \
1373 { \
1374 itkDebugMacro("setting output " #name " to " << _arg); \
1375 if (_arg != itkDynamicCastInDebugMode<SimpleDataObjectDecorator<type> *>(this->ProcessObject::GetOutput(#name))) \
1376 { \
1377 this->ProcessObject::SetOutput(#name, const_cast<SimpleDataObjectDecorator<type> *>(_arg)); \
1378 this->Modified(); \
1379 } \
1380 } \
1381 virtual void Set##name(const type & _arg) \
1382 { \
1383 using DecoratorType = SimpleDataObjectDecorator<type>; \
1384 itkDebugMacro("setting output " #name " to " << _arg); \
1385 DecoratorType * output = itkDynamicCastInDebugMode<DecoratorType *>(this->ProcessObject::GetOutput(#name)); \
1386 if (output) \
1387 { \
1388 if (output->Get() == _arg) \
1389 { \
1390 return; \
1391 } \
1392 else \
1393 { \
1394 output->Set(_arg); \
1395 } \
1396 } \
1397 else \
1398 { \
1399 auto newOutput = DecoratorType::New(); \
1400 newOutput->Set(_arg); \
1401 this->Set##name##Output(newOutput); \
1402 } \
1403 } \
1404 ITK_MACROEND_NOOP_STATEMENT
1408#define itkGetDecoratedOutputMacro(name, type) \
1409 virtual const SimpleDataObjectDecorator<type> * Get##name##Output() const \
1410 { \
1411 itkDebugMacro("returning output " << #name " of " << this->ProcessObject::GetOutput(#name)); \
1412 return itkDynamicCastInDebugMode<const SimpleDataObjectDecorator<type> *>(this->ProcessObject::GetOutput(#name)); \
1413 } \
1414 virtual const type & Get##name() const \
1415 { \
1416 itkDebugMacro("Getting output " #name); \
1417 using DecoratorType = SimpleDataObjectDecorator<type>; \
1418 const DecoratorType * output = \
1419 itkDynamicCastInDebugMode<const DecoratorType *>(this->ProcessObject::GetOutput(#name)); \
1420 if (output == nullptr) \
1421 { \
1422 itkExceptionMacro("output" #name " is not set"); \
1423 } \
1424 return output->Get(); \
1425 } \
1426 ITK_MACROEND_NOOP_STATEMENT
1428// ITK_FUTURE_DEPRECATED is only for internal use, within the implementation of ITK. It allows triggering "deprecated"
1429// warnings when legacy support is removed, which warn that a specific feature may be removed in the future.
1430#if defined(ITK_LEGACY_REMOVE) && !defined(ITK_LEGACY_SILENT)
1431# define ITK_FUTURE_DEPRECATED(message) [[deprecated(message)]]
1432#else
1433# define ITK_FUTURE_DEPRECATED(message)
1434#endif
1435
1436#if __cplusplus >= 202002L
1437# define ITK_NODISCARD(message) [[nodiscard(message)]]
1438#else
1439# define ITK_NODISCARD(message) [[nodiscard]]
1440#endif
1441
1442//-*-*-*
1443
1444#if defined(ITK_LEGACY_REMOVE)
1445# define itkExposeEnumValue(name) \
1446 static_assert(false, "ERROR: Replace static_cast<int>(name) with with proper enumeration instead of integer")
1447
1448# define ITK_NOEXCEPT_OR_THROW static_assert(false, "Replace ITK_NOEXCEPT_OR_THROW with ITK_NOEXCEPT")
1449
1450# define ITK_DELETE_FUNCTION static_assert(false, "ERROR: ITK_DELETE_FUNCTION must be replaced with `= delete`"
1451# define ITK_CONSTEXPR_FUNC static_assert(false, "ERROR: ITK_CONSTEXPR_FUNC must be replaced with 'constexpr'")
1452# define ITK_CONSTEXPR_VAR static_assert(false, "ERROR: ITK_CONSTEXPR_VAR must be replaced with 'constexpr'")
1453
1454# define ITK_FALLTHROUGH static_assert(false, "ERROR: ITK_FALLTHROUGH must be replaced with '[[fallthrough]]'")
1455
1456// Defines which used to be in itk_compiler_detection.h
1457# define ITK_ALIGNAS static_assert(false, "ERROR: ITK_ALIGNAS must be replaced with 'alignas'")
1458# define ITK_ALIGNOF static_assert(false, "ERROR: ITK_ALIGNOF must be replaced with 'alignof'")
1459# define ITK_DEPRECATED static_assert(false, "ERROR: ITK_DEPRECATED must be replaced with '[[deprecated]]'")
1460# define ITK_DEPRECATED_MSG \
1461 static_assert(false, "ERROR: ITK_DEPRECATED_MSG must be replaced with '[[deprecated(MSG)]]'")
1462# define ITK_CONSTEXPR static_assert(false, "ERROR: ITK_CONSTEXPR must be replaced with 'constexpr'")
1463# define ITK_DELETED_FUNCTION static_assert(false, "ERROR: ITK_DELETED_FUNCTION must be replaced with '= delete'")
1464# define ITK_EXTERN_TEMPLATE static_assert(false, "ERROR: ITK_EXTERN_TEMPLATE must be replaced with 'extern'")
1465# define ITK_FINAL static_assert(false, "ERROR: ITK_FINAL must be replaced with 'final'")
1466# define ITK_NOEXCEPT static_assert(false, "ERROR: ITK_NOEXCEPT must be replaced with 'noexcept'")
1467# define ITK_NOEXCEPT_EXPR static_assert(false, "ERROR: ITK_NOEXCEPT_EXPR must be replaced with 'noexcept'")
1468# define ITK_NULLPTR static_assert(false, "ERROR: ITK_NULLPTR must be replaced with 'nullptr'")
1469# define ITK_OVERRIDE static_assert(false, "ERROR: ITK_OVERRIDE must be replaced with 'override'")
1470# define ITK_STATIC_ASSERT static_assert(false, "ERROR: ITK_STATIC_ASSERT must be replaced with 'static_assert'")
1471# define ITK_STATIC_ASSERT_MSG \
1472 static_assert(false, "ERROR: ITK_STATIC_ASSERT_MSG must be replaced with 'static_assert'")
1473# define ITK_THREAD_LOCAL static_assert(false, "ERROR: ITK_THREAD_LOCAL must be replaced with 'thread_local'")
1474
1475// A macro for methods which are const in ITKv5 and ITKv6 require const for functions
1476# define ITKv5_CONST static_assert(false, "ERROR: ITKv5_CONST must be replaced with 'const'")
1477
1478# define ITK_ITERATOR_VIRTUAL static_assert(false, "ERROR: ITK_ITERATOR_VIRTUAL must be removed'")
1479# define ITK_ITERATOR_OVERRIDE static_assert(false, "ERROR: ITK_ITERATOR_OVERRIDE must be removed")
1480# define ITK_ITERATOR_FINAL static_assert(false, "ERROR: ITK_ITERATOR_FINAL must be removed")
1481
1482#else
1483// DEPRECATED: These macros are left here for compatibility with remote modules.
1484// Once they have been removed from all known remote modules, this code should
1485// be removed.
1486
1487// Future remove `#define itkExposeEnumValue(name)`
1488// "Replace type of `name` with proper enumeration instead of integer.
1489# define itkExposeEnumValue(name) static_cast<int>(name)
1490
1491
1492# define ITK_NOEXCEPT_OR_THROW ITK_NOEXCEPT
1493
1494# define ITK_FALLTHROUGH [[fallthrough]]
1495
1496# define ITK_DELETE_FUNCTION = delete
1497
1498# define ITK_CONSTEXPR_FUNC constexpr
1499# define ITK_CONSTEXPR_VAR constexpr
1500
1501// Defines which used to be in itk_compiler_detection.h
1502# define ITK_ALIGNAS(X) alignas(X)
1503# define ITK_ALIGNOF(X) alignof(X)
1504# define ITK_DEPRECATED [[deprecated]]
1505# define ITK_DEPRECATED_MSG(MSG) [[deprecated(MSG)]]
1506# define ITK_CONSTEXPR constexpr
1507# define ITK_DELETED_FUNCTION = delete
1508# define ITK_EXTERN_TEMPLATE extern
1509# define ITK_FINAL final
1510# define ITK_NOEXCEPT noexcept
1511# define ITK_NOEXCEPT_EXPR(X) noexcept(X)
1512# define ITK_NULLPTR nullptr
1513# define ITK_OVERRIDE override
1514# define ITK_STATIC_ASSERT(X) static_assert(X, #X)
1515# define ITK_STATIC_ASSERT_MSG(X, MSG) static_assert(X, MSG)
1516# define ITK_THREAD_LOCAL thread_local
1517
1518// A macro for methods which are const in after ITKv4
1519# define ITKv5_CONST const
1520
1521# define ITK_ITERATOR_VIRTUAL /*purposefully empty for ITKv6, iterators are not virtual for performance reasons*/
1522# define ITK_ITERATOR_OVERRIDE /*purposefully empty for ITKv6, iterators are not virtual for performance reasons*/
1523# define ITK_ITERATOR_FINAL /*purposefully empty for ITKv6, iterators are not virtual for performance reasons*/
1524#endif
1525
1526#define allow_inclusion_of_itkExceptionObject_h
1527// Must include itkExceptionObject.h at the end of the file
1528// because it depends on the macros defined above
1529#include "itkExceptionObject.h"
1530
1531
1532#undef allow_inclusion_of_itkExceptionObject_h
1533#endif // itkMacro_h
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....