Skip to content

Commit

Permalink
ENH: Add class template argument deduction (CTAD) support to ImageRegion
Browse files Browse the repository at this point in the history
Simplified the definition of `IndexType` and `SizeType` in order to add CTAD
support to `ImageRegion`. Added a deduction guide, to avoid compiler warnings.

Supports declaring a region, without explicitly specifying its dimension, e.g.:

    itk::ImageRegion region(index, size);
  • Loading branch information
N-Dekker authored and hjmjohnson committed Jan 2, 2024
1 parent c1af2b7 commit 8de195f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
16 changes: 12 additions & 4 deletions Modules/Core/Common/include/itkImageRegion.h
Expand Up @@ -113,15 +113,15 @@ class ITK_TEMPLATE_EXPORT ImageRegion final
}

/** Index type alias support An index is used to access pixel values. */
using IndexType = Index<Self::ImageDimension>;
using IndexType = Index<VImageDimension>;
using IndexValueType = typename IndexType::IndexValueType;
using OffsetType = typename IndexType::OffsetType;
using OffsetValueType = typename OffsetType::OffsetValueType;
using IndexValueArrayType = IndexValueType[ImageDimension];
using OffsetTableType = OffsetValueType[ImageDimension + 1];

/** Size type alias support A size is used to define region bounds. */
using SizeType = Size<Self::ImageDimension>;
using SizeType = Size<VImageDimension>;
using SizeValueType = typename SizeType::SizeValueType;

/** Slice region type alias. SliceRegion is one dimension less than Self. */
Expand Down Expand Up @@ -152,7 +152,8 @@ class ITK_TEMPLATE_EXPORT ImageRegion final
ImageRegion(const Self &) noexcept = default;

/** Constructor that takes an index and size. ImageRegion is a lightweight
* object that is not reference counted, so this constructor is public. */
* object that is not reference counted, so this constructor is public.
* \note This constructor supports class template argument deduction (CTAD). */
ImageRegion(const IndexType & index, const SizeType & size) noexcept
: // Note: Use parentheses instead of curly braces to initialize data members,
// to avoid AppleClang 6.0.0.6000056 compile errors, "no viable conversion..."
Expand All @@ -162,7 +163,8 @@ class ITK_TEMPLATE_EXPORT ImageRegion final

/** Constructor that takes a size and assumes an index of zeros. ImageRegion
* is lightweight object that is not reference counted so this constructor
* is public. */
* is public.
* \note This constructor supports class template argument deduction (CTAD). */
ImageRegion(const SizeType & size) noexcept
: m_Size(size)
{
Expand Down Expand Up @@ -408,6 +410,12 @@ class ITK_TEMPLATE_EXPORT ImageRegion final
friend class ImageBase<VImageDimension>;
};


// Deduction guide to avoid compiler warnings (-wctad-maybe-unsupported) when using class template argument deduction.
template <unsigned int VImageDimension>
ImageRegion(const Index<VImageDimension> &, const Size<VImageDimension> &)->ImageRegion<VImageDimension>;


template <unsigned int VImageDimension>
std::ostream &
operator<<(std::ostream & os, const ImageRegion<VImageDimension> & region);
Expand Down
19 changes: 19 additions & 0 deletions Modules/Core/Common/test/itkImageRegionGTest.cxx
Expand Up @@ -40,11 +40,30 @@ CheckTrivialCopyabilityOfImageRegion()
return !isImageRegionTriviallyCopyable;
#endif
}


// Checks that `ImageRegion` supports class template argument deduction (CTAD).
template <unsigned int VDimension>
constexpr bool
CheckClassTemplateArgumentDeduction()
{
using ExpectedType = itk::ImageRegion<VDimension>;

static_assert(
std::is_same_v<decltype(itk::ImageRegion(itk::Index<VDimension>{}, itk::Size<VDimension>{})), ExpectedType>,
"The `ImageRegion(Index, Size)` constructor should support CTAD!");
static_assert(std::is_same_v<decltype(itk::ImageRegion(itk::Size<VDimension>{})), ExpectedType>,
"The `ImageRegion(Size)` constructor should support CTAD!");
return true;
}


} // namespace

static_assert(CheckTrivialCopyabilityOfImageRegion<2>() && CheckTrivialCopyabilityOfImageRegion<3>(),
"ImageRegion<VDimension> should be trivially copyable when legacy support is removed.");

static_assert(CheckClassTemplateArgumentDeduction<2>() && CheckClassTemplateArgumentDeduction<3>());

// Tests that a zero-sized region is not considered to be inside of another region.
TEST(ImageRegion, ZeroSizedRegionIsNotInside)
Expand Down

0 comments on commit 8de195f

Please sign in to comment.