From 926c36e57cebf5936f732b9d5693c399c9eb665f Mon Sep 17 00:00:00 2001 From: Maya Ogita Date: Fri, 10 Jul 2026 18:42:41 +0900 Subject: [PATCH] Fix size calculation of `xstepped_range` --- include/xtensor/views/xslice.hpp | 7 ++++++- test/test_xview.cpp | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/xtensor/views/xslice.hpp b/include/xtensor/views/xslice.hpp index d2142fb82..cdae97c9f 100644 --- a/include/xtensor/views/xslice.hpp +++ b/include/xtensor/views/xslice.hpp @@ -1058,8 +1058,13 @@ namespace xt , m_size(size_type(0)) , m_step(step) { + if ((step > 0 && start_val >= stop_val) || (step < 0 && start_val <= stop_val)) + { + m_size = 0; + return; + } size_type n = stop_val - start_val; - m_size = n / step + (((n < 0) ^ (step > 0)) && (n % step)); + m_size = n / step + static_cast(n % step); } template diff --git a/test/test_xview.cpp b/test/test_xview.cpp index 18449b742..6547b9df1 100644 --- a/test/test_xview.cpp +++ b/test/test_xview.cpp @@ -226,6 +226,41 @@ namespace xt EXPECT_EQ(view0, view1); } + TEST(xview, negative_step) + { + view_shape_type shape = {3, 4}; + xarray a(shape); + std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + std::copy(data.cbegin(), data.cend(), a.template begin()); + + auto view0 = view(a, 1, range(3, 0, -1)); + EXPECT_EQ(size_t(1), view0.dimension()); + EXPECT_EQ(size_t(3), view0.shape(0)); + EXPECT_EQ(a(1, 3), view0(0)); + EXPECT_EQ(a(1, 2), view0(1)); + EXPECT_EQ(a(1, 1), view0(2)); + } + + TEST(xview, size_zero) + { + view_shape_type shape = {3, 4}; + xarray a(shape); + std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + std::copy(data.cbegin(), data.cend(), a.template begin()); + + auto view0 = view(a, 1, range(0, 0)); + EXPECT_EQ(size_t(1), view0.dimension()); + EXPECT_EQ(size_t(0), view0.shape(0)); + + auto view1 = view(a, 1, range(3, 0, 1)); + EXPECT_EQ(size_t(1), view1.dimension()); + EXPECT_EQ(size_t(0), view1.shape(0)); + + auto view2 = view(a, 1, range(0, 3, -1)); + EXPECT_EQ(size_t(1), view2.dimension()); + EXPECT_EQ(size_t(0), view2.shape(0)); + } + TEST(xview, stored_range) { view_shape_type shape = {3, 4};