From 68a21c5a5952913d6192be747efd245887bc36cc Mon Sep 17 00:00:00 2001 From: Alexis Placet <2400067+Alex-PLACET@users.noreply.github.com> Date: Thu, 30 Apr 2026 13:24:54 +0200 Subject: [PATCH 1/5] Fix substring calculation in CSV cell parsing and add lexical_cast for signed and unsigned char --- include/xtensor/io/xcsv.hpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/xtensor/io/xcsv.hpp b/include/xtensor/io/xcsv.hpp index 080ccaf54..2fd347745 100644 --- a/include/xtensor/io/xcsv.hpp +++ b/include/xtensor/io/xcsv.hpp @@ -66,7 +66,7 @@ namespace xt } size_t last = cell.find_last_not_of(' '); - return cell.substr(first, last == std::string::npos ? cell.size() : last + 1); + return cell.substr(first, last == std::string::npos ? cell.size() : last - first + 1); } template <> @@ -93,6 +93,18 @@ namespace xt return std::stoi(cell); } + template <> + inline signed char lexical_cast(const std::string& cell) + { + return static_cast(std::stoi(cell)); + } + + template <> + inline unsigned char lexical_cast(const std::string& cell) + { + return static_cast(std::stoul(cell)); + } + template <> inline long lexical_cast(const std::string& cell) { From c04d440f7f55a403b244a0fb8b54aba6945a9aa9 Mon Sep 17 00:00:00 2001 From: Alexis Placet <2400067+Alex-PLACET@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:04:18 +0200 Subject: [PATCH 2/5] Add vstack functionality for fixed shape tensors in xbuilder --- include/xtensor/generators/xbuilder.hpp | 25 +++++++++++++++++++++++++ test/test_xbuilder.cpp | 15 +++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/xtensor/generators/xbuilder.hpp b/include/xtensor/generators/xbuilder.hpp index 7474357b6..ab2660f34 100644 --- a/include/xtensor/generators/xbuilder.hpp +++ b/include/xtensor/generators/xbuilder.hpp @@ -910,6 +910,24 @@ namespace xt namespace detail { + template + struct vstack_fixed_shape; + + template + struct vstack_fixed_shape> + { + using type = fixed_shape<1, N>; + }; + + template + struct vstack_fixed_shape> + { + using type = fixed_shape; + }; + + template + using vstack_fixed_shape_t = concat_fixed_shape_t<0, typename vstack_fixed_shape::shape_type>::type...>; + template inline auto vstack_shape(std::tuple& t, const S& shape) { @@ -948,6 +966,13 @@ namespace xt return detail::make_xgenerator(detail::vstack_impl(std::move(t), size_t(0)), new_shape); } + template + inline auto vstack(std::tuple&& t) + { + using shape_type = detail::vstack_fixed_shape_t; + return detail::make_xgenerator(detail::vstack_impl(std::move(t), size_t(0)), shape_type{}); + } + namespace detail { diff --git a/test/test_xbuilder.cpp b/test/test_xbuilder.cpp index 73d952b6f..d35847a8e 100644 --- a/test/test_xbuilder.cpp +++ b/test/test_xbuilder.cpp @@ -424,6 +424,21 @@ namespace xt ASSERT_TRUE(arange(8) == w1); ASSERT_TRUE(w1 == w2); } + + TEST(xbuilder, vstack_fixed) + { + xtensor_fixed> a = {{1.f, 2.f}}; + xtensor_fixed> b = {{3.f, 4.f}, {5.f, 6.f}}; + + auto c = vstack(xtuple(a, b)); + + using expected_shape_t = fixed_shape<3, 2>; + ASSERT_EQ(expected_shape_t{}, c.shape()); + EXPECT_EQ(1.f, c(0, 0)); + EXPECT_EQ(2.f, c(0, 1)); + EXPECT_EQ(3.f, c(1, 0)); + EXPECT_EQ(6.f, c(2, 1)); + } #endif TEST(xbuilder, access) From 8ff008e14cbaf91d825f99785335b744a93c68dd Mon Sep 17 00:00:00 2001 From: Alexis Placet <2400067+Alex-PLACET@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:16:41 +0200 Subject: [PATCH 3/5] Add documentation Co-authored-by: Copilot --- include/xtensor/generators/xbuilder.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/xtensor/generators/xbuilder.hpp b/include/xtensor/generators/xbuilder.hpp index ab2660f34..9fcc8183b 100644 --- a/include/xtensor/generators/xbuilder.hpp +++ b/include/xtensor/generators/xbuilder.hpp @@ -966,6 +966,14 @@ namespace xt return detail::make_xgenerator(detail::vstack_impl(std::move(t), size_t(0)), new_shape); } + /** + * @brief Stack fixed-shape xexpressions in sequence vertically (row wise). + * This overload preserves the result shape at compile time by treating + * 1-D fixed shapes as ``(1, N)`` row vectors before concatenation. + * + * @param t \ref xtuple of fixed-shape xexpressions to stack + * @return xgenerator evaluating to stacked elements with a fixed compile-time shape + */ template inline auto vstack(std::tuple&& t) { From 6caea2662b9c81df8f3e601a7068141109ecdd5d Mon Sep 17 00:00:00 2001 From: Alexis Placet <2400067+Alex-PLACET@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:17:22 +0200 Subject: [PATCH 4/5] formatting --- include/xtensor/generators/xbuilder.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/xtensor/generators/xbuilder.hpp b/include/xtensor/generators/xbuilder.hpp index 9fcc8183b..6b0e8a5ab 100644 --- a/include/xtensor/generators/xbuilder.hpp +++ b/include/xtensor/generators/xbuilder.hpp @@ -926,7 +926,9 @@ namespace xt }; template - using vstack_fixed_shape_t = concat_fixed_shape_t<0, typename vstack_fixed_shape::shape_type>::type...>; + using vstack_fixed_shape_t = concat_fixed_shape_t< + 0, + typename vstack_fixed_shape::shape_type>::type...>; template inline auto vstack_shape(std::tuple& t, const S& shape) From 9dba62e3f4d32fcbc138237523b61f6939f4a725 Mon Sep 17 00:00:00 2001 From: Alexis Placet <2400067+Alex-PLACET@users.noreply.github.com> Date: Tue, 12 May 2026 11:40:47 +0200 Subject: [PATCH 5/5] fix --- include/xtensor/generators/xbuilder.hpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/xtensor/generators/xbuilder.hpp b/include/xtensor/generators/xbuilder.hpp index 6b0e8a5ab..7f82bd345 100644 --- a/include/xtensor/generators/xbuilder.hpp +++ b/include/xtensor/generators/xbuilder.hpp @@ -911,24 +911,28 @@ namespace xt namespace detail { template - struct vstack_fixed_shape; + struct vstack_fixed_shape_impl; template - struct vstack_fixed_shape> + struct vstack_fixed_shape_impl> { using type = fixed_shape<1, N>; }; template - struct vstack_fixed_shape> + struct vstack_fixed_shape_impl> { using type = fixed_shape; }; template - using vstack_fixed_shape_t = concat_fixed_shape_t< - 0, - typename vstack_fixed_shape::shape_type>::type...>; + struct vstack_fixed_shape + { + using type = concat_fixed_shape_t<0, typename vstack_fixed_shape_impl::shape_type>::type...>; + }; + + template + using vstack_fixed_shape_t = typename vstack_fixed_shape::type; template inline auto vstack_shape(std::tuple& t, const S& shape)