Skip to content

Commit c02ddae

Browse files
dave-hillAnna Gringauze
authored and
Anna Gringauze
committed
Span can be constructed from empty std::array safely (#686)
* Span std::array c'tor uses arr.data() instead of &arr[0] - Fixes runtime issues when constructing from an empty std::array * Construct span with std::data if C++17 detected * Specialize span c'tor for std::array of length 0, set storage to nullptr
1 parent 2bf9f13 commit c02ddae

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

include/gsl/span

+19-9
Original file line numberDiff line numberDiff line change
@@ -394,17 +394,27 @@ public:
394394
: storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>())
395395
{}
396396

397-
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
398-
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
399-
constexpr span(std::array<ArrayElementType, N>& arr) noexcept
400-
: storage_(arr.data(), details::extent_type<N>())
401-
{}
397+
template <std::size_t N, class = std::enable_if_t<(N > 0)>>
398+
constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) noexcept
399+
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
400+
{
401+
}
402402

403-
template <std::size_t N>
404-
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
403+
constexpr span(std::array<std::remove_const_t<element_type>, 0>&) noexcept
404+
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
405+
{
406+
}
407+
408+
template <std::size_t N, class = std::enable_if_t<(N > 0)>>
405409
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
406-
: storage_(arr.data(), details::extent_type<N>())
407-
{}
410+
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
411+
{
412+
}
413+
414+
constexpr span(const std::array<std::remove_const_t<element_type>, 0>&) noexcept
415+
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
416+
{
417+
}
408418

409419
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
410420
// on Container to be a contiguous sequence container.

tests/span_tests.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,13 @@ TEST_CASE("from_std_array_constructor")
452452
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
453453
}
454454

455-
std::array<AddressOverloaded, 4> ao_arr{};
455+
{
456+
std::array<int, 0> empty_arr{};
457+
span<int> s{empty_arr};
458+
CHECK((s.size() == 0 && s.empty()));
459+
}
460+
461+
std::array<AddressOverloaded, 4> ao_arr{};
456462

457463
{
458464
span<AddressOverloaded, 4> fs{ao_arr};

0 commit comments

Comments
 (0)