mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-17 13:07:54 +02:00
Merge 5c0aebfcd4 into merged_master (Bitcoin PR #19387)
This commit is contained in:
commit
0673bc107b
2 changed files with 43 additions and 4 deletions
|
|
@ -19,4 +19,14 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# if __has_attribute(lifetimebound)
|
||||
# define LIFETIMEBOUND [[clang::lifetimebound]]
|
||||
# else
|
||||
# define LIFETIMEBOUND
|
||||
# endif
|
||||
#else
|
||||
# define LIFETIMEBOUND
|
||||
#endif
|
||||
|
||||
#endif // BITCOIN_ATTRIBUTES_H
|
||||
|
|
|
|||
37
src/span.h
37
src/span.h
|
|
@ -18,6 +18,16 @@
|
|||
#define ASSERT_IF_DEBUG(x)
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_attribute(lifetimebound)
|
||||
#define SPAN_ATTR_LIFETIMEBOUND [[clang::lifetimebound]]
|
||||
#else
|
||||
#define SPAN_ATTR_LIFETIMEBOUND
|
||||
#endif
|
||||
#else
|
||||
#define SPAN_ATTR_LIFETIMEBOUND
|
||||
#endif
|
||||
|
||||
/** A Span is an object that can refer to a contiguous sequence of objects.
|
||||
*
|
||||
* It implements a subset of C++20's std::span.
|
||||
|
|
@ -84,6 +94,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) {}
|
||||
|
||||
|
|
@ -134,8 +152,19 @@ public:
|
|||
* 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 SPAN_ATTR_LIFETIMEBOUND,
|
||||
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 SPAN_ATTR_LIFETIMEBOUND,
|
||||
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; }
|
||||
|
|
@ -192,9 +221,9 @@ public:
|
|||
/** MakeSpan for arrays: */
|
||||
template <typename A, int N> Span<A> constexpr MakeSpan(A (&a)[N]) { return Span<A>(a, N); }
|
||||
/** MakeSpan for temporaries / rvalue references, only supporting const output. */
|
||||
template <typename V> constexpr auto MakeSpan(V&& v) -> typename std::enable_if<!std::is_lvalue_reference<V>::value, Span<const typename std::remove_pointer<decltype(v.data())>::type>>::type { return std::forward<V>(v); }
|
||||
template <typename V> constexpr auto MakeSpan(V&& v SPAN_ATTR_LIFETIMEBOUND) -> typename std::enable_if<!std::is_lvalue_reference<V>::value, Span<const typename std::remove_pointer<decltype(v.data())>::type>>::type { return std::forward<V>(v); }
|
||||
/** MakeSpan for (lvalue) references, supporting mutable output. */
|
||||
template <typename V> constexpr auto MakeSpan(V& v) -> Span<typename std::remove_pointer<decltype(v.data())>::type> { return v; }
|
||||
template <typename V> constexpr auto MakeSpan(V& v SPAN_ATTR_LIFETIMEBOUND) -> Span<typename std::remove_pointer<decltype(v.data())>::type> { return v; }
|
||||
|
||||
/** Pop the last element off a span, and return a reference to that element. */
|
||||
template <typename T>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue