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