7
7
8
8
#include < type_traits>
9
9
#include < cstddef>
10
+ #include < algorithm>
10
11
11
12
/* * A Span is an object that can refer to a contiguous sequence of objects.
12
13
*
@@ -21,9 +22,25 @@ class Span
21
22
public:
22
23
constexpr Span () noexcept : m_data(nullptr ), m_size(0 ) {}
23
24
constexpr Span (C* data, std::ptrdiff_t size) noexcept : m_data(data), m_size(size) {}
25
+ constexpr Span (C* data, C* end) noexcept : m_data(data), m_size(end - data) {}
24
26
25
27
constexpr C* data () const noexcept { return m_data; }
28
+ constexpr C* begin () const noexcept { return m_data; }
29
+ constexpr C* end () const noexcept { return m_data + m_size; }
26
30
constexpr std::ptrdiff_t size () const noexcept { return m_size; }
31
+ constexpr C& operator [](std::ptrdiff_t pos) const noexcept { return m_data[pos]; }
32
+
33
+ constexpr Span<C> subspan (std::ptrdiff_t offset) const noexcept { return Span<C>(m_data + offset, m_size - offset); }
34
+ constexpr Span<C> subspan (std::ptrdiff_t offset, std::ptrdiff_t count) const noexcept { return Span<C>(m_data + offset, count); }
35
+ constexpr Span<C> first (std::ptrdiff_t count) const noexcept { return Span<C>(m_data, count); }
36
+ constexpr Span<C> last (std::ptrdiff_t count) const noexcept { return Span<C>(m_data + m_size - count, count); }
37
+
38
+ friend constexpr bool operator ==(const Span& a, const Span& b) noexcept { return a.size () == b.size () && std::equal (a.begin (), a.end (), b.begin ()); }
39
+ friend constexpr bool operator !=(const Span& a, const Span& b) noexcept { return !(a == b); }
40
+ friend constexpr bool operator <(const Span& a, const Span& b) noexcept { return std::lexicographical_compare (a.begin (), a.end (), b.begin (), b.end ()); }
41
+ friend constexpr bool operator <=(const Span& a, const Span& b) noexcept { return !(b < a); }
42
+ friend constexpr bool operator >(const Span& a, const Span& b) noexcept { return (b < a); }
43
+ friend constexpr bool operator >=(const Span& a, const Span& b) noexcept { return !(a < b); }
27
44
};
28
45
29
46
/* * Create a span to a container exposing data() and size().
@@ -34,6 +51,9 @@ class Span
34
51
*
35
52
* std::span will have a constructor that implements this functionality directly.
36
53
*/
54
+ template <typename A, int N>
55
+ constexpr Span<A> MakeSpan (A (&a)[N]) { return Span<A>(a, N); }
56
+
37
57
template <typename V>
38
58
constexpr Span<typename std::remove_pointer<decltype (std::declval<V>().data())>::type> MakeSpan (V& v) { return Span<typename std::remove_pointer<decltype (std::declval<V>().data ())>::type>(v.data (), v.size ()); }
39
59
0 commit comments