File indexing completed on 2025-01-18 09:54:46
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <cstddef>
0011 #include <type_traits>
0012
0013 #include "Array.hh"
0014
0015 #include "detail/SpanImpl.hh"
0016
0017 namespace celeritas
0018 {
0019
0020
0021 constexpr std::size_t dynamic_extent = detail::dynamic_extent;
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 template<class T, std::size_t Extent = dynamic_extent>
0049 class Span
0050 {
0051 using SpanTraitsT = detail::SpanTraits<T>;
0052
0053 public:
0054
0055
0056 using element_type = typename SpanTraitsT::element_type;
0057 using value_type = std::remove_cv_t<element_type>;
0058 using size_type = std::size_t;
0059 using pointer = typename SpanTraitsT::pointer;
0060 using const_pointer = typename SpanTraitsT::const_pointer;
0061 using reference = typename SpanTraitsT::reference;
0062 using const_reference = typename SpanTraitsT::const_reference;
0063 using iterator = typename SpanTraitsT::iterator;
0064 using const_iterator = typename SpanTraitsT::const_iterator;
0065
0066
0067
0068 static constexpr std::size_t extent = Extent;
0069
0070 public:
0071
0072
0073
0074 constexpr Span() = default;
0075
0076
0077 CELER_FORCEINLINE_FUNCTION Span(pointer d, size_type s) : s_(d, s) {}
0078
0079
0080 template<class Iter>
0081 CELER_FORCEINLINE_FUNCTION Span(Iter first, Iter last)
0082 : s_(&(*first), static_cast<size_type>(last - first))
0083 {
0084 }
0085
0086
0087 template<std::size_t N>
0088 CELER_CONSTEXPR_FUNCTION Span(element_type (&arr)[N]) : s_(arr, N)
0089 {
0090 }
0091
0092
0093 template<class U, std::size_t N>
0094 CELER_CONSTEXPR_FUNCTION Span(Span<U, N> const& other)
0095 : s_(other.data(), other.size())
0096 {
0097 }
0098
0099
0100 Span(Span const&) noexcept = default;
0101
0102
0103 Span& operator=(Span const&) noexcept = default;
0104
0105
0106
0107
0108
0109 CELER_CONSTEXPR_FUNCTION iterator begin() const { return s_.data; }
0110 CELER_CONSTEXPR_FUNCTION iterator end() const { return s_.data + s_.size; }
0111
0112
0113
0114
0115 CELER_CONSTEXPR_FUNCTION reference operator[](size_type i) const
0116 {
0117 return s_.data[i];
0118 }
0119 CELER_CONSTEXPR_FUNCTION reference front() const { return s_.data[0]; }
0120 CELER_CONSTEXPR_FUNCTION reference back() const
0121 {
0122 return s_.data[s_.size - 1];
0123 }
0124 CELER_CONSTEXPR_FUNCTION pointer data() const
0125 {
0126 return static_cast<pointer>(s_.data);
0127 }
0128
0129
0130
0131
0132 CELER_CONSTEXPR_FUNCTION bool empty() const { return s_.size == 0; }
0133 CELER_CONSTEXPR_FUNCTION size_type size() const { return s_.size; }
0134 CELER_CONSTEXPR_FUNCTION size_type size_bytes() const
0135 {
0136 return sizeof(element_type) * s_.size;
0137 }
0138
0139
0140
0141
0142 template<std::size_t Count>
0143 CELER_FUNCTION Span<T, Count> first() const
0144 {
0145 CELER_EXPECT(Count == 0 || Count <= this->size());
0146 return {this->data(), Count};
0147 }
0148 CELER_FUNCTION
0149 Span<T, dynamic_extent> first(std::size_t count) const
0150 {
0151 CELER_EXPECT(count <= this->size());
0152 return {this->data(), count};
0153 }
0154
0155 template<std::size_t Offset, std::size_t Count = dynamic_extent>
0156 CELER_FUNCTION Span<T, detail::subspan_extent(Extent, Offset, Count)>
0157 subspan() const
0158 {
0159 CELER_EXPECT((Count == dynamic_extent) || (Offset == 0 && Count == 0)
0160 || (Offset + Count <= this->size()));
0161 return {this->data() + Offset,
0162 detail::subspan_size(this->size(), Offset, Count)};
0163 }
0164 CELER_FUNCTION
0165 Span<T, dynamic_extent>
0166 subspan(std::size_t offset, std::size_t count = dynamic_extent) const
0167 {
0168 CELER_EXPECT(offset + count <= this->size());
0169 return {this->data() + offset,
0170 detail::subspan_size(this->size(), offset, count)};
0171 }
0172
0173 template<std::size_t Count>
0174 CELER_FUNCTION Span<T, Count> last() const
0175 {
0176 CELER_EXPECT(Count == 0 || Count <= this->size());
0177 return {this->data() + this->size() - Count, Count};
0178 }
0179 CELER_FUNCTION
0180 Span<T, dynamic_extent> last(std::size_t count) const
0181 {
0182 CELER_EXPECT(count <= this->size());
0183 return {this->data() + this->size() - count, count};
0184 }
0185
0186
0187 private:
0188
0189 detail::SpanImpl<T, Extent> s_;
0190 };
0191
0192 template<class T, std::size_t N>
0193 constexpr std::size_t Span<T, N>::extent;
0194
0195
0196
0197
0198
0199 template<class T, std::size_t N>
0200 CELER_CONSTEXPR_FUNCTION Span<T, N> make_span(Array<T, N>& x)
0201 {
0202 return {x.data(), N};
0203 }
0204
0205
0206
0207 template<class T, std::size_t N>
0208 CELER_CONSTEXPR_FUNCTION Span<T const, N> make_span(Array<T, N> const& x)
0209 {
0210 return {x.data(), N};
0211 }
0212
0213
0214
0215 template<class T, std::size_t N>
0216 CELER_CONSTEXPR_FUNCTION Span<T, N> make_span(T (&arr)[N])
0217 {
0218 return {arr};
0219 }
0220
0221
0222
0223 template<class T>
0224 CELER_FUNCTION Span<typename T::value_type> make_span(T& cont)
0225 {
0226 return {cont.data(), cont.size()};
0227 }
0228
0229
0230
0231 template<class T>
0232 CELER_FUNCTION Span<typename T::value_type const> make_span(T const& cont)
0233 {
0234 return {cont.data(), cont.size()};
0235 }
0236
0237
0238
0239 template<class T, std::size_t N>
0240 CELER_CONSTEXPR_FUNCTION auto make_array(Span<T, N> const& s)
0241 {
0242 Array<std::remove_cv_t<T>, N> result{};
0243 for (std::size_t i = 0; i < N; ++i)
0244 {
0245 result[i] = s[i];
0246 }
0247 return result;
0248 }
0249
0250
0251 }