Changeset View
Changeset View
Standalone View
Standalone View
src/span.h
// Copyright (c) 2018 The Bitcoin Core developers | // Copyright (c) 2018 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#ifndef BITCOIN_SPAN_H | #ifndef BITCOIN_SPAN_H | ||||
#define BITCOIN_SPAN_H | #define BITCOIN_SPAN_H | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cassert> | |||||
#include <cstddef> | #include <cstddef> | ||||
#include <type_traits> | #include <type_traits> | ||||
/** A Span is an object that can refer to a contiguous sequence of objects. | /** A Span is an object that can refer to a contiguous sequence of objects. | ||||
* | * | ||||
* It implements a subset of C++20's std::span. | * It implements a subset of C++20's std::span. | ||||
*/ | */ | ||||
template <typename C> class Span { | template <typename C> class Span { | ||||
C *m_data; | C *m_data; | ||||
std::ptrdiff_t m_size; | std::ptrdiff_t m_size; | ||||
public: | public: | ||||
constexpr Span() noexcept : m_data(nullptr), m_size(0) {} | constexpr Span() noexcept : m_data(nullptr), m_size(0) {} | ||||
constexpr Span(C *data, std::ptrdiff_t size) noexcept | constexpr Span(C *data, std::ptrdiff_t size) noexcept | ||||
: m_data(data), m_size(size) {} | : m_data(data), m_size(size) {} | ||||
constexpr Span(C *data, C *end) noexcept | constexpr Span(C *data, C *end) noexcept | ||||
: m_data(data), m_size(end - data) {} | : m_data(data), m_size(end - data) {} | ||||
constexpr C *data() const noexcept { return m_data; } | constexpr C *data() const noexcept { return m_data; } | ||||
constexpr C *begin() const noexcept { return m_data; } | constexpr C *begin() const noexcept { return m_data; } | ||||
constexpr C *end() const noexcept { return m_data + m_size; } | constexpr C *end() const noexcept { return m_data + m_size; } | ||||
constexpr C &front() const noexcept { return m_data[0]; } | |||||
constexpr C &back() const noexcept { return m_data[m_size - 1]; } | |||||
constexpr std::ptrdiff_t size() const noexcept { return m_size; } | constexpr std::ptrdiff_t size() const noexcept { return m_size; } | ||||
constexpr C &operator[](std::ptrdiff_t pos) const noexcept { | constexpr C &operator[](std::ptrdiff_t pos) const noexcept { | ||||
return m_data[pos]; | return m_data[pos]; | ||||
} | } | ||||
constexpr Span<C> subspan(std::ptrdiff_t offset) const noexcept { | constexpr Span<C> subspan(std::ptrdiff_t offset) const noexcept { | ||||
return Span<C>(m_data + offset, m_size - offset); | return Span<C>(m_data + offset, m_size - offset); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
constexpr Span< | constexpr Span< | ||||
typename std::remove_pointer<decltype(std::declval<V>().data())>::type> | typename std::remove_pointer<decltype(std::declval<V>().data())>::type> | ||||
MakeSpan(V &v) { | MakeSpan(V &v) { | ||||
return Span< | return Span< | ||||
typename std::remove_pointer<decltype(std::declval<V>().data())>::type>( | typename std::remove_pointer<decltype(std::declval<V>().data())>::type>( | ||||
v.data(), v.size()); | v.data(), v.size()); | ||||
} | } | ||||
/** Pop the last element off a span, and return a reference to that element. */ | |||||
template <typename T> T &SpanPopBack(Span<T> &span) { | |||||
size_t size = span.size(); | |||||
assert(size > 0); | |||||
T &back = span[size - 1]; | |||||
span = Span<T>(span.data(), size - 1); | |||||
return back; | |||||
} | |||||
#endif // BITCOIN_SPAN_H | #endif // BITCOIN_SPAN_H |