Skip to content

Commit

Permalink
Span can be constructed from empty std::array safely (#686)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
dave-hill authored and Anna Gringauze committed Nov 5, 2018
1 parent 2bf9f13 commit c02ddae
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
28 changes: 19 additions & 9 deletions include/gsl/span
Original file line number Diff line number Diff line change
Expand Up @@ -394,17 +394,27 @@ public:
: storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>())
{}

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

template <std::size_t N>
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
constexpr span(std::array<std::remove_const_t<element_type>, 0>&) noexcept
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
{
}

template <std::size_t N, class = std::enable_if_t<(N > 0)>>
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
: storage_(arr.data(), details::extent_type<N>())
{}
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
{
}

constexpr span(const std::array<std::remove_const_t<element_type>, 0>&) noexcept
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
{
}

// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
// on Container to be a contiguous sequence container.
Expand Down
8 changes: 7 additions & 1 deletion tests/span_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,13 @@ TEST_CASE("from_std_array_constructor")
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
}

std::array<AddressOverloaded, 4> ao_arr{};
{
std::array<int, 0> empty_arr{};
span<int> s{empty_arr};
CHECK((s.size() == 0 && s.empty()));
}

std::array<AddressOverloaded, 4> ao_arr{};

{
span<AddressOverloaded, 4> fs{ao_arr};
Expand Down

0 comments on commit c02ddae

Please sign in to comment.