diff --git a/libs/patch/PatchIterators.h b/libs/patch/PatchIterators.h index 0537f5fd0e..d39a8ae5a3 100644 --- a/libs/patch/PatchIterators.h +++ b/libs/patch/PatchIterators.h @@ -206,11 +206,12 @@ class ColumnWisePatchIteratorBase : ColumnWisePatchIteratorBase(IPatch& patch, std::size_t startColumn, std::size_t endColumn, int rowDelta) : PatchControlIterator(patch, rowDelta > 0 ? 0 : patch.getHeight() - 1, startColumn, - std::bind(ColumnWisePatchIteratorBase::moveNext, std::placeholders::_1, std::ref(patch), endColumn, rowDelta)) + std::bind(ColumnWisePatchIteratorBase::moveNext, std::placeholders::_1, std::ref(patch), + endColumn, startColumn <= endColumn ? +1 : -1, rowDelta)) {} private: - static void moveNext(PatchControlIterator& it, const IPatch& patch, std::size_t endColumn, int rowDelta) + static void moveNext(PatchControlIterator& it, const IPatch& patch, std::size_t endColumn, int columnDelta, int rowDelta) { auto nextRow = it.getRow() + rowDelta; auto nextColumn = it.getColumn(); @@ -220,7 +221,10 @@ class ColumnWisePatchIteratorBase : { // Advance to the next column // If that doesn't succeed, just leave the indices out of bounds - if (++nextColumn <= endColumn) + nextColumn += columnDelta; + + if (columnDelta > 0 && nextColumn <= endColumn || + columnDelta < 0 && nextColumn >= endColumn) { nextRow = rowDelta > 0 ? 0 : patch.getHeight() - 1; } @@ -273,11 +277,12 @@ class RowWisePatchIteratorBase : RowWisePatchIteratorBase(IPatch& patch, std::size_t startRow, std::size_t endRow, int columnDelta) : PatchControlIterator(patch, startRow, columnDelta > 0 ? 0 : patch.getWidth() - 1, - std::bind(RowWisePatchIteratorBase::moveNext, std::placeholders::_1, std::ref(patch), endRow, columnDelta)) + std::bind(RowWisePatchIteratorBase::moveNext, std::placeholders::_1, std::ref(patch), + endRow, startRow <= endRow ? +1 : -1, columnDelta)) {} private: - static void moveNext(PatchControlIterator& it, const IPatch& patch, std::size_t endRow, int columnDelta) + static void moveNext(PatchControlIterator& it, const IPatch& patch, std::size_t endRow, int rowDelta, int columnDelta) { auto nextColumn = it.getColumn() + columnDelta; auto nextRow = it.getRow(); @@ -287,7 +292,10 @@ class RowWisePatchIteratorBase : { // Advance to the next row // If that doesn't succeed, just leave the indices out of bounds - if (++nextRow <= endRow) + nextRow += rowDelta; + + if (rowDelta > 0 && nextRow <= endRow || + rowDelta < 0 && nextRow >= endRow) { nextColumn = columnDelta > 0 ? 0 : patch.getWidth() - 1; } diff --git a/test/PatchIterators.cpp b/test/PatchIterators.cpp index 6589cd274b..45723a6e17 100644 --- a/test/PatchIterators.cpp +++ b/test/PatchIterators.cpp @@ -147,12 +147,14 @@ TEST_F(PatchIteratorTest, IterateOverWholePatchRowWiseColumnBackwards) EXPECT_EQ(expected, expectedValues.end()); // assume no underflow } -void iterateOverPartialPatchColumnWise(IPatch& patch, std::size_t startCol, std::size_t endCol, bool rowBackwards) +void iterateOverPartialPatchColumnWise(IPatch& patch, int startCol, int endCol, bool rowBackwards) { std::vector expectedValues; // Fill the vector with the expected values - for (auto col = startCol; col <= endCol; ++col) + int step = startCol <= endCol ? +1 : -1; + + for (auto col = startCol; col != endCol + step; col += step) { if (rowBackwards) { @@ -197,6 +199,15 @@ TEST_F(PatchIteratorTest, IterateOverPartialPatchColumnWise) iterateOverPartialPatchColumnWise(patch->getPatch(), 1, 3, false); iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 4, false); iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 4, false); + + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 0, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 0, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 0, 0, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 0, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 3, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 1, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 4, false); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 3, false); } TEST_F(PatchIteratorTest, IterateOverPartialPatchColumnWiseRowBackwards) @@ -212,14 +223,25 @@ TEST_F(PatchIteratorTest, IterateOverPartialPatchColumnWiseRowBackwards) iterateOverPartialPatchColumnWise(patch->getPatch(), 1, 3, true); iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 4, true); iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 4, true); + + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 0, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 0, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 0, 0, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 0, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 3, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 1, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 4, true); + iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 3, true); } -void iterateOverPartialPatchRowWise(IPatch& patch, std::size_t startRow, std::size_t endRow, bool columnBackwards) +void iterateOverPartialPatchRowWise(IPatch& patch, int startRow, int endRow, bool columnBackwards) { std::vector expectedValues; // Fill the vector with the expected values - for (auto row = startRow; row <= endRow; ++row) + int step = startRow <= endRow ? +1 : -1; + + for (auto row = startRow; row != endRow + step; row += step) { if (columnBackwards) { @@ -264,6 +286,15 @@ TEST_F(PatchIteratorTest, IterateOverPartialPatchRowWise) iterateOverPartialPatchRowWise(patch->getPatch(), 1, 3, false); iterateOverPartialPatchRowWise(patch->getPatch(), 6, 6, false); iterateOverPartialPatchRowWise(patch->getPatch(), 3, 4, false); + + iterateOverPartialPatchRowWise(patch->getPatch(), 6, 0, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 3, 0, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 0, 0, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 4, 0, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 6, 3, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 3, 1, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 6, 6, false); + iterateOverPartialPatchRowWise(patch->getPatch(), 4, 3, false); } TEST_F(PatchIteratorTest, IterateOverPartialPatchRowWiseColumnBackwards) @@ -279,6 +310,15 @@ TEST_F(PatchIteratorTest, IterateOverPartialPatchRowWiseColumnBackwards) iterateOverPartialPatchRowWise(patch->getPatch(), 1, 3, true); iterateOverPartialPatchRowWise(patch->getPatch(), 6, 6, true); iterateOverPartialPatchRowWise(patch->getPatch(), 3, 4, true); + + iterateOverPartialPatchRowWise(patch->getPatch(), 6, 0, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 3, 0, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 0, 0, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 4, 0, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 6, 3, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 3, 1, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 6, 6, true); + iterateOverPartialPatchRowWise(patch->getPatch(), 4, 3, true); } void iterateOverSingleColum(IPatch& patch, std::size_t colToTest)