-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspan.hh
127 lines (106 loc) · 3.18 KB
/
span.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#pragma once
#include <array>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>
#include <vector>
/// A workalike for std::span from C++20 (only dynamic-extent, without ranges
/// support).
template<class T>
struct span {
using element_type = T;
using value_type = std::remove_cv_t<T>;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T *;
using const_pointer = const T *;
using reference = T &;
using const_reference = const T &;
using iterator = pointer; // implementation-defined
using reverse_iterator = std::reverse_iterator<iterator>;
constexpr span() noexcept : span(nullptr, nullptr) {}
constexpr span(pointer p, size_type sz) : span(p, p + sz) {}
constexpr span(pointer p, pointer q) : p(p), q(q) {}
template<std::size_t N>
constexpr span(element_type (&a)[N]) : span(a, N) {}
/// \warning Destroying \a C leaves this object dangling if it owns its
/// elements. This implementation does not check for "borrowing".
template<class C,
class = std::enable_if_t<std::is_convertible_v<
std::remove_pointer_t<decltype(void(std::size(std::declval<C &&>())),
std::data(std::declval<C &&>()))> (*)[],
T (*)[]>>>
constexpr span(C && c) : span(std::data(c), std::size(c)) {}
KOKKOS_INLINE_FUNCTION
constexpr iterator begin() const noexcept {
return p;
}
KOKKOS_INLINE_FUNCTION
constexpr iterator end() const noexcept {
return q;
}
KOKKOS_INLINE_FUNCTION
constexpr reverse_iterator rbegin() const noexcept {
return reverse_iterator(end());
}
KOKKOS_INLINE_FUNCTION
constexpr reverse_iterator rend() const noexcept {
return reverse_iterator(begin());
}
KOKKOS_INLINE_FUNCTION
constexpr reference front() const {
return *begin();
}
KOKKOS_INLINE_FUNCTION
constexpr reference back() const {
return end()[-1];
}
KOKKOS_INLINE_FUNCTION
constexpr reference operator[](size_type i) const {
return begin()[i];
}
KOKKOS_INLINE_FUNCTION
constexpr pointer data() const noexcept {
return begin();
}
// FIXME: Spurious overflow for extremely large ranges
KOKKOS_INLINE_FUNCTION
constexpr size_type size() const noexcept {
return end() - begin();
}
KOKKOS_INLINE_FUNCTION
constexpr size_type size_bytes() const noexcept {
return sizeof(element_type) * size();
}
KOKKOS_INLINE_FUNCTION
constexpr bool empty() const noexcept {
return begin() == end();
}
KOKKOS_INLINE_FUNCTION
constexpr span first(size_type n) const {
return {begin(), n};
}
KOKKOS_INLINE_FUNCTION
constexpr span last(size_type n) const {
return {end() - n, n};
}
KOKKOS_INLINE_FUNCTION
constexpr span subspan(size_type i, size_type n = -1) const {
return {begin() + i, n == size_type(-1) ? size() - i : n};
}
private:
pointer p, q;
};
template<class C>
span(C &) -> span<typename C::value_type>;
template<class C>
span(const C &) -> span<const typename C::value_type>;
/// Copy a span into a std::vector.
template<class T>
auto
to_vector(span<T> s) {
// Work around GCC<8 having no deduction guide for vector:
return std::vector<typename span<T>::value_type>(s.begin(), s.end());
}