Skip to content

Commit cbb22b1

Browse files
committed
Improve Span functionality
1 parent ecdb7a2 commit cbb22b1

File tree

2 files changed

+456
-94
lines changed

2 files changed

+456
-94
lines changed

Span.h

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cstddef>
55
#include <cstdint>
66

7+
#include <array>
78
#include <type_traits>
89
#include <vector>
910

@@ -38,12 +39,21 @@ template <typename T> class Span {
3839
Span(T *p_data, const uint32_t size) : p_data_(p_data), size_(size) {}
3940
#endif
4041
Span(T *p_begin, T *p_end) : p_data_(p_begin), size_(p_end - p_begin) {}
42+
43+
template <size_t N>
44+
Span(const std::array<typename remove_all_const<T>::type, N> &arr) : Span(arr.data(), arr.size()) {}
45+
template <size_t N>
46+
Span(const std::array<const typename remove_all_const<T>::type, N> &arr) : Span(arr.data(), arr.size()) {}
47+
template <size_t N> Span(std::array<typename std::remove_cv<T>::type, N> &arr) : Span(arr.data(), arr.size()) {}
48+
49+
template <typename Alloc>
50+
Span(const std::vector<typename remove_all_const<T>::type, Alloc> &v) : Span(v.data(), v.size()) {}
4151
template <typename Alloc>
42-
Span(const std::vector<typename remove_all_const<T>::type, Alloc> &v) : Span(v.data(), size_t(v.size())) {}
52+
Span(const std::vector<const typename remove_all_const<T>::type, Alloc> &v) : Span(v.data(), v.size()) {}
4353
template <typename Alloc>
44-
Span(std::vector<typename remove_all_const<T>::type, Alloc> &v) : Span(v.data(), size_t(v.size())) {}
54+
Span(std::vector<typename std::remove_cv<T>::type, Alloc> &v) : Span(v.data(), v.size()) {}
4555

46-
template <size_t N> Span(T (&arr)[N]) : p_data_(arr), size_(N) {}
56+
template <size_t N> Span(T (&arr)[N]) : Span(arr, N) {}
4757

4858
template <typename U = typename remove_all_const<T>::type,
4959
typename = typename std::enable_if<!std::is_same<T, U>::value>::type>
@@ -54,8 +64,12 @@ template <typename T> class Span {
5464

5565
force_inline T *data() const { return p_data_; }
5666
force_inline ptrdiff_t size() const { return size_; }
67+
force_inline ptrdiff_t size_bytes() const { return size_ * sizeof(T); }
5768
force_inline bool empty() const { return size_ == 0; }
5869

70+
force_inline T &front() const { return p_data_[0]; }
71+
force_inline T &back() const { return p_data_[size_ - 1]; }
72+
5973
force_inline T &operator[](const ptrdiff_t i) const {
6074
assert(i >= 0 && i < size_);
6175
return p_data_[i];
@@ -72,7 +86,99 @@ template <typename T> class Span {
7286
force_inline iterator end() const { return p_data_ + size_; }
7387
force_inline const_iterator cbegin() const { return p_data_; }
7488
force_inline const_iterator cend() const { return p_data_ + size_; }
89+
90+
template <typename IterType> class reverse_iterator_t {
91+
IterType iter_;
92+
93+
public:
94+
explicit reverse_iterator_t(IterType iter) : iter_(iter) {}
95+
96+
template <typename U> reverse_iterator_t(reverse_iterator_t<U> &rhs) : iter_(rhs.base()) {}
97+
98+
template <typename U> operator reverse_iterator_t<U>() { return reverse_iterator_t<U>(iter_); }
99+
100+
IterType base() const { return iter_; }
101+
102+
const T &operator*() const { return *(iter_ - 1); }
103+
const T *operator->() const { return &*(iter_ - 1); }
104+
105+
reverse_iterator_t &operator++() {
106+
--iter_;
107+
return *this;
108+
}
109+
110+
reverse_iterator_t operator++(int) {
111+
reverse_iterator_t ret(*this);
112+
--iter_;
113+
return ret;
114+
}
115+
116+
reverse_iterator_t &operator--() {
117+
++iter_;
118+
return *this;
119+
}
120+
121+
reverse_iterator_t operator--(int) {
122+
reverse_iterator_t ret(*this);
123+
++iter_;
124+
return ret;
125+
}
126+
127+
reverse_iterator_t operator+(ptrdiff_t n) const { return reverse_iterator_t(iter_ - n); }
128+
reverse_iterator_t &operator+=(ptrdiff_t n) const {
129+
iter_ -= n;
130+
return *this;
131+
}
132+
133+
reverse_iterator_t operator-(ptrdiff_t n) const { return reverse_iterator_t(iter_ + n); }
134+
reverse_iterator_t &operator-=(ptrdiff_t n) const {
135+
iter_ += n;
136+
return *this;
137+
}
138+
139+
T &operator[](ptrdiff_t n) const { return iter_[-n - 1]; }
140+
};
141+
142+
using reverse_iterator = reverse_iterator_t<T *>;
143+
using const_reverse_iterator = reverse_iterator_t<const T *>;
144+
145+
force_inline reverse_iterator rbegin() const { return reverse_iterator(p_data_ + size_); }
146+
force_inline reverse_iterator rend() const { return reverse_iterator(p_data_); }
147+
force_inline const_reverse_iterator crbegin() const { return const_reverse_iterator(p_data_ + size_); }
148+
force_inline const_reverse_iterator crend() const { return const_reverse_iterator(p_data_); }
149+
150+
Span<T> first(const size_t n) const { return Span<T>{p_data_, n}; }
151+
Span<T> last(const size_t n) const { return Span<T>{p_data_ + size_ - n, n}; }
152+
Span<T> subspan(const size_t offset, const size_t count = SIZE_MAX) const {
153+
return Span<T>{p_data_ + offset, count != SIZE_MAX ? count : (size_ - offset)};
154+
}
75155
};
156+
157+
template <typename Iter1, typename Iter2>
158+
bool lexicographical_compare(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) {
159+
for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
160+
if (*first1 < *first2) {
161+
return true;
162+
}
163+
if (*first2 < *first1) {
164+
return false;
165+
}
166+
}
167+
return first1 == last1 && first2 != last2;
168+
}
169+
170+
template <typename T, typename U> bool operator==(Span<T> lhs, Span<U> rhs) {
171+
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
172+
}
173+
template <typename T, typename U> bool operator!=(Span<T> lhs, Span<U> rhs) {
174+
return lhs.size() != rhs.size() || !std::equal(lhs.begin(), lhs.end(), rhs.begin());
175+
}
176+
template <typename T, typename U> bool operator<(Span<T> lhs, Span<U> rhs) {
177+
return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
178+
}
179+
template <typename T, typename U> bool operator<=(Span<T> lhs, Span<U> rhs) { return !operator<(rhs, lhs); }
180+
template <typename T, typename U> bool operator>(Span<T> lhs, Span<U> rhs) { return operator<(rhs, lhs); }
181+
template <typename T, typename U> bool operator>=(Span<T> lhs, Span<U> rhs) { return !operator<(lhs, rhs); }
76182
} // namespace Ray
77183

78184
#undef force_inline

0 commit comments

Comments
 (0)