itk::NeighborhoodRange: a new class for efficient modern C++ style iteration

Thanks very much for giving it a try, @phcerdan I hadn’t realized that std::accumulate is not constexpr. But even in the latest draft of the C++ Standard, it is not. :confused:

However, in the meantime I did manage to write a constexpr CalculateNumberOfOffsets() that does compile… at least on g++ 5.4.0, clang 3.8.0 and MSVC 2017:

#include <array>

// Minimal version of itk::Size<VDimension>
template <unsigned int VDimension = 2>
struct Size
{
  std::size_t m_InternalArray[VDimension];
};

// Minimal version of proposed shape class from http://review.source.kitware.com/#/c/23389/
template <unsigned VImageDimension>
struct HyperrectangularImageNeighborhoodShape
{
  const Size<VImageDimension> m_Radius;

  constexpr std::size_t CalculateNumberOfOffsets() const noexcept
  {
    std::size_t result = 1;

    for (const auto radiusValue : m_Radius.m_InternalArray)
    {
      result *= 2 * radiusValue + 1;
    }
    return result;
  }
};

int main()
{
  constexpr Size<> radius{ { 3, 4 } };
  constexpr HyperrectangularImageNeighborhoodShape<2> shape{ radius };
  constexpr std::size_t numberOfOffsets = shape.CalculateNumberOfOffsets();
  static_assert(numberOfOffsets == (2 * 3 + 1) * (2 * 4 + 1), "Yes!");

  // Yes: Can be used as the dimension parameter of std::array!  :-)
  struct OffsetType {};
  std::array<OffsetType, numberOfOffsets> offsets{ {} };
}

Or click here: constexpr CalculateNumberOfOffsets() for ITK, C++ (clang) - rextester

Of course, this cannot yet be used to implement CalculateNumberOfOffsets() for ITK 5.0, because C++11 does not support a for loop or a variable declaration inside a constexpr function. But any ITK user can actually write such code, when using a C++14 compiler. Isn’t that cool?

I’ll still look at your other posts here… hope you’re not impatient :slight_smile: