File indexing completed on 2025-10-30 08:37:55
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 }