From 9be4e7cd25c958726e6ab76fa7fefcc8f5cc2000 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Tue, 3 Jun 2025 16:58:08 -0600 Subject: [PATCH] :bug: Fix dynamic span construct from array Problem: - When a dynamic span is constructed from an array, the size is not populated. Solution: - Initialize the base (size) properly. --- include/stdx/span.hpp | 7 ++++--- test/span.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/include/stdx/span.hpp b/include/stdx/span.hpp index 8c91bb2..49d5cfd 100644 --- a/include/stdx/span.hpp +++ b/include/stdx/span.hpp @@ -98,7 +98,7 @@ class span : public detail::span_base { template // NOLINTNEXTLINE(google-explicit-constructor) constexpr span(std::array &arr LIFETIMEBOUND) noexcept - : ptr{std::data(arr)} { + : base_t{std::data(arr), N}, ptr{std::data(arr)} { static_assert(Extent == dynamic_extent or Extent <= N, "Span extends beyond available storage"); } @@ -106,7 +106,7 @@ class span : public detail::span_base { template // NOLINTNEXTLINE(google-explicit-constructor) constexpr span(std::array const &arr LIFETIMEBOUND) noexcept - : ptr{std::data(arr)} { + : base_t{std::data(arr), N}, ptr{std::data(arr)} { static_assert(Extent == dynamic_extent or Extent <= N, "Span extends beyond available storage"); } @@ -116,7 +116,8 @@ class span : public detail::span_base { template // NOLINTNEXTLINE(google-explicit-constructor) - constexpr span(arr_t arr LIFETIMEBOUND) noexcept : ptr{std::data(arr)} { + constexpr span(arr_t arr LIFETIMEBOUND) noexcept + : base_t{std::data(arr), N}, ptr{std::data(arr)} { static_assert(Extent == dynamic_extent or Extent <= N, "Span extends beyond available storage"); } diff --git a/test/span.cpp b/test/span.cpp index 3b376f4..c3e8a93 100644 --- a/test/span.cpp +++ b/test/span.cpp @@ -141,6 +141,22 @@ TEST_CASE("span is constructible from std::array (non const data)", "[span]") { STATIC_REQUIRE(std::size(s) == 4); } +TEST_CASE("dynamic span is constructible from std::array (const data)", + "[span]") { + constexpr static auto a = std::array{1, 2, 3, 4}; + auto s = [](stdx::span x) { return x; }(a); + CHECK(std::data(s) == std::data(a)); + CHECK(std::size(s) == std::size(a)); +} + +TEST_CASE("dynamic span is constructible from std::array (non const data)", + "[span]") { + auto a = std::array{1, 2, 3, 4}; + auto s = [](stdx::span x) { return x; }(a); + CHECK(std::data(s) == std::data(a)); + CHECK(std::size(s) == std::size(a)); +} + TEST_CASE("span is constructible from C-style array (const data)", "[span]") { constexpr static int a[] = {1, 2, 3, 4}; constexpr auto s = stdx::span{a}; @@ -159,6 +175,22 @@ TEST_CASE("span is constructible from C-style array (non const data)", CHECK(std::size(s) == std::size(a)); } +TEST_CASE("dynamic span is constructible from C-style array (const data)", + "[span]") { + constexpr static int a[] = {1, 2, 3, 4}; + auto s = [](stdx::span x) { return x; }(a); + CHECK(std::data(s) == std::data(a)); + CHECK(std::size(s) == std::size(a)); +} + +TEST_CASE("dynamic span is constructible from C-style array (non const data)", + "[span]") { + int a[] = {1, 2, 3, 4}; + auto s = [](stdx::span x) { return x; }(a); + CHECK(std::data(s) == std::data(a)); + CHECK(std::size(s) == std::size(a)); +} + TEST_CASE("dynamic span is implicitly constructible from range (const data)", "[span]") { std::vector const v{1, 2, 3, 4};