Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:11:59

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/detail/SpanImpl.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cstddef>
0010 #include <type_traits>
0011 
0012 #include "corecel/Assert.hh"
0013 #include "corecel/Macros.hh"
0014 
0015 namespace celeritas
0016 {
0017 //---------------------------------------------------------------------------//
0018 template<class T>
0019 struct LdgValue;
0020 template<class T>
0021 class LdgIterator;
0022 
0023 //---------------------------------------------------------------------------//
0024 namespace detail
0025 {
0026 //---------------------------------------------------------------------------//
0027 /*!
0028  * Default type aliases for Span.
0029  */
0030 template<class T>
0031 struct SpanTraits
0032 {
0033     using element_type = T;
0034     using pointer = std::add_pointer_t<element_type>;
0035     using const_pointer = std::add_pointer_t<element_type const>;
0036     using iterator = pointer;
0037     using const_iterator = const_pointer;
0038     using reference = std::add_lvalue_reference_t<element_type>;
0039     using const_reference = std::add_lvalue_reference_t<element_type const>;
0040 };
0041 
0042 //---------------------------------------------------------------------------//
0043 /*!
0044  * Type aliases when data is read using __ldg.
0045  *
0046  * \c LdgValue checks that T is a
0047  * valid type (const arithmetic or OpaqueId). Since \c LdgIterator returns a
0048  * copy of the data read, we can't return a reference to the original data, we
0049  * need to return a copy as well.
0050  */
0051 template<class T>
0052 struct SpanTraits<LdgValue<T>>
0053 {
0054     using element_type = typename LdgValue<T>::value_type;  // Always const!
0055     using pointer = std::add_pointer_t<element_type const>;
0056     using const_pointer = pointer;
0057     using iterator = LdgIterator<element_type const>;
0058     using const_iterator = iterator;
0059     using reference = std::remove_const_t<element_type>;
0060     using const_reference = std::remove_const_t<element_type>;
0061 };
0062 
0063 //---------------------------------------------------------------------------//
0064 //! Sentinel value for span of dynamic type
0065 inline constexpr std::size_t dynamic_extent = std::size_t(-1);
0066 
0067 //---------------------------------------------------------------------------//
0068 //! Calculate the return type for a subspan
0069 CELER_CONSTEXPR_FUNCTION std::size_t
0070 subspan_extent(std::size_t extent, std::size_t offset, std::size_t count)
0071 {
0072     return count != dynamic_extent
0073                ? count
0074                : (extent != dynamic_extent ? extent - offset : dynamic_extent);
0075 }
0076 
0077 //---------------------------------------------------------------------------//
0078 //! Calculate the size of a subspan
0079 CELER_CONSTEXPR_FUNCTION std::size_t
0080 subspan_size(std::size_t size, std::size_t offset, std::size_t count)
0081 {
0082     return count != dynamic_extent ? count : size - offset;
0083 }
0084 
0085 //---------------------------------------------------------------------------//
0086 /*!
0087  * Storage for a Span.
0088  */
0089 template<class T, std::size_t Extent>
0090 struct SpanImpl
0091 {
0092     //// TYPES ////
0093 
0094     using iterator = typename SpanTraits<T>::iterator;
0095     using pointer = typename SpanTraits<T>::pointer;
0096 
0097     //// DATA ////
0098 
0099     iterator data = nullptr;
0100     static constexpr std::size_t size = Extent;
0101 
0102     //// METHODS ////
0103 
0104     //! No default constructor for fixed-size type
0105     SpanImpl() = delete;
0106 
0107     //! Construct from a dynamic span
0108     CELER_FORCEINLINE_FUNCTION
0109     SpanImpl(SpanImpl<T, dynamic_extent> const& other) : data(other.data)
0110     {
0111         CELER_EXPECT(other.size == Extent);
0112     }
0113 
0114     //! Construct from data and size
0115     CELER_FORCEINLINE_FUNCTION
0116     SpanImpl(pointer d, std::size_t s) : data(d)
0117     {
0118         CELER_EXPECT(d != nullptr);
0119         CELER_EXPECT(s == Extent);
0120     }
0121 };
0122 
0123 //---------------------------------------------------------------------------//
0124 /*!
0125  * Specialization for size-zero span.
0126  */
0127 template<class T>
0128 struct SpanImpl<T, 0>
0129 {
0130     //// TYPES ////
0131 
0132     using iterator = typename SpanTraits<T>::iterator;
0133     using pointer = typename SpanTraits<T>::pointer;
0134 
0135     //// DATA ////
0136 
0137     iterator data = nullptr;
0138     static constexpr std::size_t size = 0;
0139 
0140     //// CONSTRUCTORS ////
0141 
0142     //! Default constructor is empty and size zero
0143     constexpr SpanImpl() = default;
0144 
0145     //! Construct from data (any) and size (must be zero)
0146     CELER_FORCEINLINE_FUNCTION
0147     SpanImpl(pointer d, std::size_t s) : data(d) { CELER_EXPECT(s == 0); }
0148 };
0149 
0150 //---------------------------------------------------------------------------//
0151 /*!
0152  * Specialization for dynamic span.
0153  */
0154 template<class T>
0155 struct SpanImpl<T, dynamic_extent>
0156 {
0157     //// TYPES ////
0158 
0159     using iterator = typename SpanTraits<T>::iterator;
0160     using pointer = typename SpanTraits<T>::pointer;
0161 
0162     //// DATA ////
0163 
0164     iterator data = nullptr;
0165     std::size_t size = 0;
0166 
0167     //// METHODS ////
0168 
0169     //! Default constructor is empty and size zero
0170     constexpr SpanImpl() = default;
0171 
0172     //! Construct from data and size
0173     CELER_FORCEINLINE_FUNCTION
0174     SpanImpl(pointer d, std::size_t s) : data(d), size(s)
0175     {
0176         CELER_EXPECT(d != nullptr || size == 0);
0177     }
0178 };
0179 
0180 //---------------------------------------------------------------------------//
0181 }  // namespace detail
0182 }  // namespace celeritas