Skip to content

Commit bb3d38f

Browse files
committed
Make pointer-based Span construction safer
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.
1 parent 1f790a1 commit bb3d38f

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

src/span.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,22 @@ class Span
2222

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

27-
constexpr Span(C* data, C* end) noexcept : m_data(data), m_size(end - data) {}
26+
/** Construct a span from a begin pointer and a size.
27+
*
28+
* This implements a subset of the iterator-based std::span constructor in C++20,
29+
* which is hard to implement without std::address_of.
30+
*/
31+
template <typename T, typename std::enable_if<std::is_convertible<T (*)[], C (*)[]>::value, int>::type = 0>
32+
constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
33+
34+
/** Construct a span from a begin and end pointer.
35+
*
36+
* This implements a subset of the iterator-based std::span constructor in C++20,
37+
* which is hard to implement without std::address_of.
38+
*/
39+
template <typename T, typename std::enable_if<std::is_convertible<T (*)[], C (*)[]>::value, int>::type = 0>
40+
constexpr Span(T* begin, T* end) noexcept : m_data(begin), m_size(end - begin) {}
2841

2942
/** Implicit conversion of spans between compatible types.
3043
*

0 commit comments

Comments
 (0)