From bb3d38fc061d8482e68cd335a45c9cd8bb66a475 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 29 Mar 2020 16:58:04 -0700 Subject: [PATCH] Make pointer-based Span construction safer This prevents constructing a Span given two pointers into an array of B (where B is a subclass of A), at least without explicit cast to pointers to A. --- src/span.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/span.h b/src/span.h index 31e9fba12ce..f83c1a53492 100644 --- a/src/span.h +++ b/src/span.h @@ -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 ::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 ::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. *