Skip to content

COMP: Support non-EqualityComparable pixels Image template instantiation#2585

Merged
N-Dekker merged 1 commit intoInsightSoftwareConsortium:masterfrom
N-Dekker:Image-with-NonEqualityComparable-PixelType
Jun 15, 2021
Merged

COMP: Support non-EqualityComparable pixels Image template instantiation#2585
N-Dekker merged 1 commit intoInsightSoftwareConsortium:masterfrom
N-Dekker:Image-with-NonEqualityComparable-PixelType

Conversation

@N-Dekker
Copy link
Copy Markdown
Contributor

@N-Dekker N-Dekker commented Jun 7, 2021

The ability to instantiate itk::Image<TPixel, VImageDimension> for a
non-EqualityComparable pixel type was broken by:

"ENH: Add operator== and operator!= to itk::Image"
pull request #2188
commit 7f3337d

Reported by Bradley Lowekamp:
issue #2583
"Explicit instantiation of itk::Image fails with 5.2 when pixel type
does not support operator=="

This commit fixes the issue by defining the operator== and operator!=
friend functions of itk::Image as function templates, rather than as
non-templates.

@github-actions github-actions Bot added area:Core Issues affecting the Core module type:Compiler Compiler support or related warnings type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct labels Jun 7, 2021
@Leengit
Copy link
Copy Markdown
Contributor

Leengit commented Jun 7, 2021

Nice.

Do we want the template to include a NVImageDimension parameter too, and then check it for equality with VImageDimension ... so that image1==image2 will compile (and return false) if the two images have different image dimensions?

@N-Dekker
Copy link
Copy Markdown
Contributor Author

N-Dekker commented Jun 7, 2021

Do we want the template to include a NVImageDimension parameter too, and then check it for equality with VImageDimension ... so that image1==image2 will compile (and return false) if the two images have different image dimensions?

Nice suggestion @Leengit I think I would rather have a compilation error on image1==image2, when their dimensions differ. But please let us know if you have a useful use case to support image1==image2, when their dimensions differ.

Copy link
Copy Markdown
Member

@dzenanz dzenanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it compiles and works as intended, good.

@N-Dekker
Copy link
Copy Markdown
Contributor Author

N-Dekker commented Jun 7, 2021

If it compiles and works as intended, good.

I must say, that Linux-warning is non-ObVious 😸 to me: https://open.cdash.org/viewBuildError.php?type=1&buildid=7271820

Modules/Core/Common/include/itkImage.hxx:79:1: warning: 'void itk::Image<TPixel, VImageDimension>::FillBuffer(const TPixel&) [with TPixel = {anonymous}::NonEqualityComparableType; unsigned int VImageDimension = 2]' defined but not used [-Wunused-function]

Any suggestion?

@dzenanz
Copy link
Copy Markdown
Member

dzenanz commented Jun 7, 2021

Any suggestion?

Sadly, no. It is just as cryptic to me.

@N-Dekker N-Dekker force-pushed the Image-with-NonEqualityComparable-PixelType branch 3 times, most recently from b432b7a to 4549ea3 Compare June 14, 2021 10:03
@N-Dekker N-Dekker marked this pull request as ready for review June 14, 2021 12:51
@N-Dekker
Copy link
Copy Markdown
Contributor Author

@dzenanz Just fixed the Linux GCC warning, which said:

'FillBuffer(const TPixel&)' defined but not used [-Wunused-function]

The fix (as I just force-pushed) was to simply use the function, en another unit test! 😄

@dzenanz dzenanz requested review from Leengit and blowekamp June 14, 2021 13:07
Copy link
Copy Markdown
Contributor

@Leengit Leengit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In itkImage.h, is this line correct?:

const TPixel * const lhsBufferPointer = lhsBuffer.GetBufferPointer();

I worry that TPixel is the pixel type of the right-hand side, but not necessarily of the left-hand side.

@N-Dekker
Copy link
Copy Markdown
Contributor Author

In itkImage.h, is this line correct?:

const TPixel * const lhsBufferPointer = lhsBuffer.GetBufferPointer();

I worry that TPixel is the pixel type of the right-hand side, but not necessarily of the left-hand side.

Well observed @Leengit Would you like it better if it would use auto instead?

Please keep in mind that the aim of this pull request is just to allow itk::Image template instantiations for non-EqualityComparable pixel types. It isn't meant to further enhance operator==.

@Leengit
Copy link
Copy Markdown
Contributor

Leengit commented Jun 14, 2021

In itkImage.h, is this line correct?:

const TPixel * const lhsBufferPointer = lhsBuffer.GetBufferPointer();

I worry that TPixel is the pixel type of the right-hand side, but not necessarily of the left-hand side.

Well observed @Leengit Would you like it better if it would use auto instead?

Please keep in mind that the aim of this pull request is just to allow itk::Image template instantiations for non-EqualityComparable pixel types. It isn't meant to further enhance operator==.

So that the compiler catches type errors for me, I usually use the actual type if I can determine it and if it isn't completely obvious -- e.g., because we just cast to it on the right-hand side. In this case, I believe that that would be TEqualityComparable, but auto would work too.

@N-Dekker
Copy link
Copy Markdown
Contributor Author

So that the compiler catches type errors for me, I usually use the actual type if I can determine it and if it isn't completely obvious -- e.g., because we just cast to it on the right-hand side. In this case, I believe that that would be TEqualityComparable, but auto would work too.

OK @Leengit If I amend the commit to use TEqualityComparable, will you approve the pull request for me? 😸

@Leengit
Copy link
Copy Markdown
Contributor

Leengit commented Jun 14, 2021

So that the compiler catches type errors for me, I usually use the actual type if I can determine it and if it isn't completely obvious -- e.g., because we just cast to it on the right-hand side. In this case, I believe that that would be TEqualityComparable, but auto would work too.

OK @Leengit If I amend the commit to use TEqualityComparable, will you approve the pull request for me? smile_cat

It's a deal.

@N-Dekker N-Dekker force-pushed the Image-with-NonEqualityComparable-PixelType branch from 4549ea3 to b02c9cf Compare June 14, 2021 19:09
@N-Dekker
Copy link
Copy Markdown
Contributor Author

OK @Leengit If I amend the commit to use TEqualityComparable, will you approve the pull request for me? smile_cat

It's a deal.

@Leengit Thanks! Please check the amend + force-push: https://github.com/InsightSoftwareConsortium/ITK/compare/4549ea34b6f124cce48c6dcf7ba33aea9476e4b9..b02c9cfdb9788cbd02388f3579e26903a1654f52 Hope you appreciate the static_assert that I added with the amend. 😃

@Leengit
Copy link
Copy Markdown
Contributor

Leengit commented Jun 14, 2021

@Leengit Thanks! Please check the amend + force-push: https://github.com/InsightSoftwareConsortium/ITK/compare/4549ea34b6f124cce48c6dcf7ba33aea9476e4b9..b02c9cfdb9788cbd02388f3579e26903a1654f52 Hope you appreciate the static_assert that I added with the amend. smiley

The TEqualityComparable for lhsBufferPointer is good, thank you.

Is the thinking that the static_assert will make sure that operator== is only ever used the way it was before this pull request? That seems reasonable until we have a need for and an implementation of a more general use of operator== for images.

@N-Dekker
Copy link
Copy Markdown
Contributor Author

Is the thinking that the static_assert will make sure that operator== is only ever used the way it was before this pull request?

Indeed 😃

That seems reasonable until we have a need for and an implementation of a more general use of operator== for images.

Yes, exactly. The static_assert may be removed once (if ever) we need operator== to compare two images of different types. And then of course some extra unit tests must be added. But for now, at least the template instantiation issue should be fixed.

@N-Dekker
Copy link
Copy Markdown
Contributor Author

N-Dekker commented Jun 15, 2021

Update: force-pushed, now using C++ SFINAE (std::enable_if) (instead of a static_assert) to ensure that the images passed to operator== and operator!= have the correct pixel type TPixel.

@N-Dekker N-Dekker marked this pull request as draft June 15, 2021 08:15
The ability to instantiate `itk::Image<TPixel, VImageDimension>` for a
non-EqualityComparable pixel type was broken by:

"ENH: Add operator== and operator!= to itk::Image"
pull request InsightSoftwareConsortium#2188
commit 7f3337d

Reported by Bradley Lowekamp:
issue InsightSoftwareConsortium#2583
"Explicit instantiation of itk::Image fails with 5.2 when pixel type
does not support operator=="

This commit fixes the issue by defining the `operator==` and `operator!=`
friend functions of `itk::Image` as function _templates_, rather than as
non-templates.
@N-Dekker N-Dekker force-pushed the Image-with-NonEqualityComparable-PixelType branch from b02c9cf to 2e9f9ad Compare June 15, 2021 09:10
@N-Dekker N-Dekker marked this pull request as ready for review June 15, 2021 12:27
Copy link
Copy Markdown
Member

@blowekamp blowekamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the reported issue 👍

@N-Dekker N-Dekker merged commit a293c03 into InsightSoftwareConsortium:master Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Core Issues affecting the Core module type:Compiler Compiler support or related warnings type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explicit instantiation of itk::Image fails with 5.2 when pixel type does not support operator==

4 participants