Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:54:04

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file corecel/cont/Span.hh
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 //! Sentinel value for span of dynamic type
0022 constexpr std::size_t dynamic_extent = detail::dynamic_extent;
0023 
0024 //---------------------------------------------------------------------------//
0025 /*!
0026  * Non-owning reference to a contiguous span of data.
0027  * \tparam T value type
0028  * \tparam Extent fixed size; defaults to dynamic.
0029  *
0030  * This Span class is a modified backport of the C++20 \c std::span . In
0031  * Celeritas, it is often used as a return value from accessing elements in a
0032  * \c Collection.
0033  *
0034  * Like the \ref celeritas::Array , this class is not 100% compatible
0035  * with the \c std::span class. The hope is that it will be complete and
0036  * correct for the use cases needed by Celeritas (and, as a bonus, it will be
0037  * device-compatible).
0038  *
0039  * \c Span can be instantiated with the special marker type \c LdgValue<T> to
0040  * optimize constant data access in global device memory.
0041  * In that case, data returned
0042  * by \c front, \c back, \c operator[] and \c begin / \c end iterators use
0043  * value semantics instead of reference. The \c data accessor still returns a
0044  * pointer to the underlying memory and can be used to bypass using \c
0045  * LdgIterator .
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     //! \name Type aliases
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     //! Size (may be dynamic)
0067     static constexpr std::size_t extent = Extent;
0068 
0069   public:
0070     //// CONSTRUCTION ////
0071 
0072     //! Construct with default null pointer and size zero
0073     constexpr Span() = default;
0074 
0075     //! Construct from data and size
0076     CELER_CONSTEXPR_FUNCTION Span(pointer d, size_type s) : s_(d, s) {}
0077 
0078     //! Construct from two contiguous random-access iterators
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     //! Construct from a C array
0086     template<std::size_t N>
0087     CELER_CONSTEXPR_FUNCTION Span(element_type (&arr)[N]) : s_(arr, N)
0088     {
0089     }
0090 
0091     //! Construct from another span
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     //// ACCESS ////
0101 
0102     //!@{
0103     //! \name Iterators
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     //! \name Element access
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     //! \name Observers
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     //! \name Subviews
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     //! Storage
0185     detail::SpanImpl<T, Extent> s_;
0186 };
0187 
0188 //---------------------------------------------------------------------------//
0189 // DEDUCTION GUIDES
0190 //---------------------------------------------------------------------------//
0191 
0192 // Deduction guide for pointer and size
0193 template<class T>
0194 Span(T*, std::size_t) -> Span<T>;
0195 
0196 // Deduction guide for two iterators
0197 template<class Iter>
0198 Span(Iter, Iter) -> Span<typename std::iterator_traits<Iter>::value_type>;
0199 
0200 // Deduction guide for C array
0201 template<class T, std::size_t N>
0202 Span(T (&)[N]) -> Span<T, N>;
0203 
0204 //---------------------------------------------------------------------------//
0205 // FREE FUNCTIONS
0206 //---------------------------------------------------------------------------//
0207 //! Get a mutable fixed-size view to an array
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 //! Get a constant fixed-size view to an array
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 //! Get a mutable fixed-size view to a C array
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 //! Get a mutable view to a generic container
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 //! Get a const view to a generic container
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 //! Construct an array from a fixed-size span
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 }  // namespace celeritas