Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:46

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