aboutsummaryrefslogtreecommitdiff
path: root/src/span.h
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2020-03-29 16:58:04 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2020-05-12 14:12:46 -0700
commitbb3d38fc061d8482e68cd335a45c9cd8bb66a475 (patch)
treee267d5d97f68f8b0a73035c4ff913a4cd30b709a /src/span.h
parent1f790a1147ad9a5fe06987d84b6cd71f91cbec4b (diff)
downloadbitcoin-bb3d38fc061d8482e68cd335a45c9cd8bb66a475.tar.xz
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.
Diffstat (limited to 'src/span.h')
-rw-r--r--src/span.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/span.h b/src/span.h
index 31e9fba12c..f83c1a5349 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 <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.
*