Bitcoin ABC  0.22.13
P2P Digital Currency
span.h
Go to the documentation of this file.
1 // Copyright (c) 2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_SPAN_H
6 #define BITCOIN_SPAN_H
7 
8 #include <algorithm>
9 #include <cassert>
10 #include <cstddef>
11 #include <type_traits>
12 
17 template <typename C> class Span {
18  C *m_data;
19  std::ptrdiff_t m_size;
20 
21 public:
22  constexpr Span() noexcept : m_data(nullptr), m_size(0) {}
23  constexpr Span(C *data, std::ptrdiff_t size) noexcept
24  : m_data(data), m_size(size) {}
25  constexpr Span(C *data, C *end) noexcept
26  : m_data(data), m_size(end - data) {}
27 
38  template <typename O,
39  typename std::enable_if<
40  std::is_convertible<O (*)[], C (*)[]>::value, int>::type = 0>
41  constexpr Span(const Span<O> &other) noexcept
42  : m_data(other.m_data), m_size(other.m_size) {}
43 
45  constexpr Span(const Span &) noexcept = default;
46 
48  Span &operator=(const Span &other) noexcept = default;
49 
50  constexpr C *data() const noexcept { return m_data; }
51  constexpr C *begin() const noexcept { return m_data; }
52  constexpr C *end() const noexcept { return m_data + m_size; }
53  constexpr C &front() const noexcept { return m_data[0]; }
54  constexpr C &back() const noexcept { return m_data[m_size - 1]; }
55  constexpr std::ptrdiff_t size() const noexcept { return m_size; }
56  constexpr C &operator[](std::ptrdiff_t pos) const noexcept {
57  return m_data[pos];
58  }
59 
60  constexpr Span<C> subspan(std::ptrdiff_t offset) const noexcept {
61  return Span<C>(m_data + offset, m_size - offset);
62  }
63  constexpr Span<C> subspan(std::ptrdiff_t offset, std::ptrdiff_t count) const
64  noexcept {
65  return Span<C>(m_data + offset, count);
66  }
67  constexpr Span<C> first(std::ptrdiff_t count) const noexcept {
68  return Span<C>(m_data, count);
69  }
70  constexpr Span<C> last(std::ptrdiff_t count) const noexcept {
71  return Span<C>(m_data + m_size - count, count);
72  }
73 
74  friend constexpr bool operator==(const Span &a, const Span &b) noexcept {
75  return a.size() == b.size() &&
76  std::equal(a.begin(), a.end(), b.begin());
77  }
78  friend constexpr bool operator!=(const Span &a, const Span &b) noexcept {
79  return !(a == b);
80  }
81  friend constexpr bool operator<(const Span &a, const Span &b) noexcept {
82  return std::lexicographical_compare(a.begin(), a.end(), b.begin(),
83  b.end());
84  }
85  friend constexpr bool operator<=(const Span &a, const Span &b) noexcept {
86  return !(b < a);
87  }
88  friend constexpr bool operator>(const Span &a, const Span &b) noexcept {
89  return (b < a);
90  }
91  friend constexpr bool operator>=(const Span &a, const Span &b) noexcept {
92  return !(a < b);
93  }
94 
95  template <typename O> friend class Span;
96 };
97 
108 template <typename A, int N> constexpr Span<A> MakeSpan(A (&a)[N]) {
109  return Span<A>(a, N);
110 }
111 
112 template <typename V>
113 constexpr Span<
114  typename std::remove_pointer<decltype(std::declval<V>().data())>::type>
115 MakeSpan(V &v) {
116  return Span<
117  typename std::remove_pointer<decltype(std::declval<V>().data())>::type>(
118  v.data(), v.size());
119 }
120 
122 template <typename T> T &SpanPopBack(Span<T> &span) {
123  size_t size = span.size();
124  assert(size > 0);
125  T &back = span[size - 1];
126  span = Span<T>(span.data(), size - 1);
127  return back;
128 }
129 
130 #endif // BITCOIN_SPAN_H
constexpr std::ptrdiff_t size() const noexcept
Definition: span.h:55
friend constexpr bool operator<(const Span &a, const Span &b) noexcept
Definition: span.h:81
constexpr C * end() const noexcept
Definition: span.h:52
constexpr Span(C *data, std::ptrdiff_t size) noexcept
Definition: span.h:23
friend constexpr bool operator<=(const Span &a, const Span &b) noexcept
Definition: span.h:85
constexpr Span(const Span< O > &other) noexcept
Implicit conversion of spans between compatible types.
Definition: span.h:41
friend constexpr bool operator>=(const Span &a, const Span &b) noexcept
Definition: span.h:91
constexpr Span< A > MakeSpan(A(&a)[N])
Create a span to a container exposing data() and size().
Definition: span.h:108
friend constexpr bool operator!=(const Span &a, const Span &b) noexcept
Definition: span.h:78
friend constexpr bool operator==(const Span &a, const Span &b) noexcept
Definition: span.h:74
friend constexpr bool operator>(const Span &a, const Span &b) noexcept
Definition: span.h:88
constexpr Span< C > last(std::ptrdiff_t count) const noexcept
Definition: span.h:70
constexpr Span(C *data, C *end) noexcept
Definition: span.h:25
constexpr Span< C > subspan(std::ptrdiff_t offset) const noexcept
Definition: span.h:60
constexpr Span() noexcept
Definition: span.h:22
constexpr Span< C > first(std::ptrdiff_t count) const noexcept
Definition: span.h:67
std::ptrdiff_t m_size
Definition: span.h:19
constexpr C * begin() const noexcept
Definition: span.h:51
constexpr C * data() const noexcept
Definition: span.h:50
Span & operator=(const Span &other) noexcept=default
Default assignment operator.
T & SpanPopBack(Span< T > &span)
Pop the last element off a span, and return a reference to that element.
Definition: span.h:122
static int count
Definition: tests.c:35
constexpr C & front() const noexcept
Definition: span.h:53
constexpr Span< C > subspan(std::ptrdiff_t offset, std::ptrdiff_t count) const noexcept
Definition: span.h:63
constexpr C & back() const noexcept
Definition: span.h:54
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:17
C * m_data
Definition: span.h:18
constexpr C & operator[](std::ptrdiff_t pos) const noexcept
Definition: span.h:56