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