Skip to content

Commit

Permalink
Make pointer-based Span construction safer
Browse files Browse the repository at this point in the history
This prevents constructing a Span<A> given two pointers into an array
of B (where B is a subclass of A), at least without explicit cast to
pointers to A.
  • Loading branch information
sipa authored and furszy committed Jul 6, 2021
1 parent 33d5297 commit 38f105b
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,22 @@ class Span

public:
constexpr Span() noexcept : m_data(nullptr), m_size(0) {}
constexpr Span(C* data, std::size_t size) noexcept : m_data(data), m_size(size) {}

constexpr Span(C* data, C* end) noexcept : m_data(data), m_size(end - data) {}
/** Construct a span from a begin pointer and a size.
*
* This implements a subset of the iterator-based std::span constructor in C++20,
* which is hard to implement without std::address_of.
*/
template <typename T, typename std::enable_if<std::is_convertible<T (*)[], C (*)[]>::value, int>::type = 0>
constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}

/** Construct a span from a begin and end pointer.
*
* This implements a subset of the iterator-based std::span constructor in C++20,
* which is hard to implement without std::address_of.
*/
template <typename T, typename std::enable_if<std::is_convertible<T (*)[], C (*)[]>::value, int>::type = 0>
constexpr Span(T* begin, T* end) noexcept : m_data(begin), m_size(end - begin) {}

/** Implicit conversion of spans between compatible types.
*
Expand Down

0 comments on commit 38f105b

Please sign in to comment.