Skip to content

Commit

Permalink
Merge bitcoin#19387: (almost) match std::span's constructor behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Mar 23, 2021
1 parent 602d18c commit 574cfa0
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ class Span
C* m_data;
std::size_t m_size;

template <class T>
struct is_Span_int : public std::false_type {};
template <class T>
struct is_Span_int<Span<T>> : public std::true_type {};
template <class T>
struct is_Span : public is_Span_int<typename std::remove_cv<T>::type>{};


public:
constexpr Span() noexcept : m_data(nullptr), m_size(0) {}

Expand Down Expand Up @@ -78,8 +86,19 @@ class Span
* To prevent surprises, only Spans for constant value types are supported when passing in temporaries.
* Note that this restriction does not exist when converting arrays or other Spans (see above).
*/
template <typename V, typename std::enable_if<(std::is_const<C>::value || std::is_lvalue_reference<V>::value) && std::is_convertible<typename std::remove_pointer<decltype(std::declval<V&>().data())>::type (*)[], C (*)[]>::value && std::is_convertible<decltype(std::declval<V&>().size()), std::size_t>::value, int>::type = 0>
constexpr Span(V&& v) noexcept : m_data(v.data()), m_size(v.size()) {}
template <typename V>
constexpr Span(V& other,
typename std::enable_if<!is_Span<V>::value &&
std::is_convertible<typename std::remove_pointer<decltype(std::declval<V&>().data())>::type (*)[], C (*)[]>::value &&
std::is_convertible<decltype(std::declval<V&>().size()), std::size_t>::value, std::nullptr_t>::type = nullptr)
: m_data(other.data()), m_size(other.size()){}

template <typename V>
constexpr Span(const V& other,
typename std::enable_if<!is_Span<V>::value &&
std::is_convertible<typename std::remove_pointer<decltype(std::declval<const V&>().data())>::type (*)[], C (*)[]>::value &&
std::is_convertible<decltype(std::declval<const V&>().size()), std::size_t>::value, std::nullptr_t>::type = nullptr)
: m_data(other.data()), m_size(other.size()){}

constexpr C* data() const noexcept { return m_data; }
constexpr C* begin() const noexcept { return m_data; }
Expand Down

0 comments on commit 574cfa0

Please sign in to comment.