Skip to content

Commit

Permalink
COMP: Rule of Zero, SFINAE ImageBufferRange, ImageRegionRange iterators
Browse files Browse the repository at this point in the history
Used SFINAE (`enable_if`) to implement non-const to const conversion for the
iterator types of `ImageBufferRange` and `ImageRegionRange`. Followed the Rule
of Zero for those types.

Prevents potential clang warnings, as reported before by Bradley Lowekamp:

> definition of implicit copy constructor for 'QualifiedIterator<true>'
> is deprecated because it has a user-declared copy assignment operator

Follow-up to pull request #4049
commit df6aa66 "COMP: QualifiedIterator follow
rule of zero", merged on 19 May, 2023
  • Loading branch information
N-Dekker authored and dzenanz committed May 30, 2023
1 parent a024dfa commit 19079c8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 27 deletions.
21 changes: 7 additions & 14 deletions Modules/Core/Common/include/itkImageBufferRange.h
Expand Up @@ -23,7 +23,7 @@
#include <cstddef> // For ptrdiff_t.
#include <iterator> // For random_access_iterator_tag.
#include <limits>
#include <type_traits> // For conditional, is_same, and is_const.
#include <type_traits> // For conditional, enable_if, is_same, and is_const.

#include "itkMacro.h" // For itkNotUsed.
#include "itkDefaultPixelAccessor.h"
Expand Down Expand Up @@ -300,17 +300,15 @@ class ImageBufferRange final
* the guarantee added to the C++14 Standard: "value-initialized iterators
* may be compared and shall compare equal to other value-initialized
* iterators of the same type."
* \note `QualifiedIterator<VIsConst>` follows the C++ "Rule of Zero" when
* VIsConst is true: The other five "special member functions" of the class
* are then implicitly defaulted. When VIsConst is false, its
* copy-constructor is provided explicitly, but it still behaves the same as
* a default implementation.
*
* \note The other five "special member functions" are defaulted implicitly,
* following the C++ "Rule of Zero".
*/
QualifiedIterator() = default;

/** Constructor that allows implicit conversion from non-const to const
* iterator. Also serves as copy-constructor of a non-const iterator. */
QualifiedIterator(const QualifiedIterator<false> & arg) noexcept
/** Constructor for implicit conversion from non-const to const iterator. */
template <bool VIsArgumentConst, typename = std::enable_if_t<VIsConst && !VIsArgumentConst>>
QualifiedIterator(const QualifiedIterator<VIsArgumentConst> & arg) noexcept
: // Note: Use parentheses instead of curly braces to initialize data members,
// to avoid AppleClang 6.0.0.6000056 compilation error, "no viable conversion..."
m_OptionalAccessorFunctor(arg.m_OptionalAccessorFunctor)
Expand Down Expand Up @@ -475,11 +473,6 @@ class ImageBufferRange final

/** Returns it[n] for iterator 'it' and integer value 'n'. */
reference operator[](const difference_type n) const noexcept { return *(*this + n); }


/** Explicitly-defaulted assignment operator. */
QualifiedIterator &
operator=(const QualifiedIterator &) noexcept = default;
};

static constexpr bool IsImageTypeConst = std::is_const_v<TImage>;
Expand Down
20 changes: 7 additions & 13 deletions Modules/Core/Common/include/itkImageRegionRange.h
Expand Up @@ -25,7 +25,7 @@
#include <iterator> // For bidirectional_iterator_tag.
#include <functional> // For multiplies.
#include <numeric> // For accumulate.
#include <type_traits> // For conditional and is_const.
#include <type_traits> // For conditional, enable_if, and is_const.

#include "itkImageHelper.h"
#include "itkImageRegion.h"
Expand Down Expand Up @@ -205,12 +205,15 @@ class ImageRegionRange final
* the guarantee added to the C++14 Standard: "value-initialized iterators
* may be compared and shall compare equal to other value-initialized
* iterators of the same type."
*
* \note The other five "special member functions" are defaulted implicitly,
* following the C++ "Rule of Zero".
*/
QualifiedIterator() = default;

/** Constructor that allows implicit conversion from non-const to const
* iterator. Also serves as copy-constructor of a non-const iterator. */
QualifiedIterator(const QualifiedIterator<false> & arg) noexcept
/** Constructor for implicit conversion from non-const to const iterator. */
template <bool VIsArgumentConst, typename = std::enable_if_t<VIsConst && !VIsArgumentConst>>
QualifiedIterator(const QualifiedIterator<VIsArgumentConst> & arg) noexcept
: m_BufferIterator(arg.m_BufferIterator)
,
// Note: Use parentheses instead of curly braces to initialize data members,
Expand Down Expand Up @@ -281,15 +284,6 @@ class ImageRegionRange final
// Implemented just like the corresponding std::rel_ops operator.
return !(lhs == rhs);
}


/** Explicitly-defaulted assignment operator. */
QualifiedIterator &
operator=(const QualifiedIterator &) noexcept = default;


/** Explicitly-defaulted destructor. */
~QualifiedIterator() = default;
};

// Inspired by, and originally copied from ImageBase::FastComputeOffset(ind)).
Expand Down

0 comments on commit 19079c8

Please sign in to comment.