File indexing completed on 2025-09-18 09:09:38
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <cstddef>
0011 #include <iterator>
0012 #include <type_traits>
0013
0014 #include "corecel/Macros.hh"
0015 #include "corecel/Types.hh"
0016 #include "corecel/cont/Span.hh"
0017 #include "corecel/math/Algorithms.hh"
0018
0019 #include "detail/LdgIteratorImpl.hh"
0020
0021 namespace celeritas
0022 {
0023
0024
0025
0026
0027
0028
0029
0030 template<class T>
0031 class LdgIterator
0032 {
0033 static_assert(detail::is_ldg_supported_v<T>,
0034 "LdgIterator requires const arithmetic, OpaqueId or "
0035 "enum type");
0036
0037 private:
0038 using LoadPolicyT = detail::LdgLoader<T>;
0039
0040 public:
0041
0042
0043 using difference_type = std::ptrdiff_t;
0044 using value_type = typename LoadPolicyT::value_type;
0045 using pointer = typename LoadPolicyT::pointer;
0046 using reference = typename LoadPolicyT::reference;
0047 using iterator_category = std::random_access_iterator_tag;
0048
0049
0050 public:
0051
0052
0053 constexpr LdgIterator() noexcept = default;
0054 CELER_CONSTEXPR_FUNCTION LdgIterator(std::nullptr_t) noexcept {}
0055 CELER_CONSTEXPR_FUNCTION explicit LdgIterator(pointer ptr) noexcept
0056 : ptr_{ptr}
0057 {
0058 }
0059
0060
0061
0062
0063 CELER_CONSTEXPR_FUNCTION reference operator*() const noexcept
0064 {
0065 return LoadPolicyT::read(ptr_);
0066 }
0067 CELER_CONSTEXPR_FUNCTION LdgIterator& operator++() noexcept
0068 {
0069 ++ptr_;
0070 return *this;
0071 }
0072 CELER_CONSTEXPR_FUNCTION void swap(LdgIterator& it) noexcept
0073 {
0074 ::celeritas::trivial_swap(ptr_, it.ptr_);
0075 }
0076 CELER_CONSTEXPR_FUNCTION LdgIterator operator++(int) noexcept
0077 {
0078 LdgIterator tmp{ptr_};
0079 ++ptr_;
0080 return tmp;
0081 }
0082 CELER_CONSTEXPR_FUNCTION pointer operator->() const noexcept
0083 {
0084 return ptr_;
0085 }
0086 CELER_CONSTEXPR_FUNCTION LdgIterator& operator--() noexcept
0087 {
0088 --ptr_;
0089 return *this;
0090 }
0091 CELER_CONSTEXPR_FUNCTION LdgIterator operator--(int) noexcept
0092 {
0093 LdgIterator tmp{ptr_};
0094 --ptr_;
0095 return tmp;
0096 }
0097 CELER_CONSTEXPR_FUNCTION LdgIterator& operator+=(difference_type n) noexcept
0098 {
0099 ptr_ += n;
0100 return *this;
0101 }
0102 CELER_CONSTEXPR_FUNCTION LdgIterator& operator-=(difference_type n) noexcept
0103 {
0104 ptr_ -= n;
0105 return *this;
0106 }
0107 CELER_CONSTEXPR_FUNCTION reference operator[](difference_type n) const noexcept
0108 {
0109 return LoadPolicyT::read(ptr_ + n);
0110 }
0111
0112
0113
0114
0115 CELER_CONSTEXPR_FUNCTION explicit operator pointer() const noexcept
0116 {
0117 return ptr_;
0118 }
0119 CELER_CONSTEXPR_FUNCTION explicit operator bool() const noexcept
0120 {
0121 return ptr_ != nullptr;
0122 }
0123
0124
0125 private:
0126 pointer ptr_{nullptr};
0127 };
0128
0129
0130
0131
0132 template<class T>
0133 LdgIterator(T*) -> LdgIterator<std::add_const_t<T>>;
0134
0135
0136
0137
0138
0139
0140
0141 template<class T>
0142 CELER_CONSTEXPR_FUNCTION bool
0143 operator==(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0144 {
0145 using pointer = typename LdgIterator<T>::pointer;
0146 return static_cast<pointer>(lhs) == static_cast<pointer>(rhs);
0147 }
0148 template<class T>
0149 CELER_CONSTEXPR_FUNCTION bool
0150 operator!=(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0151 {
0152 return !(lhs == rhs);
0153 }
0154 template<class T>
0155 CELER_CONSTEXPR_FUNCTION bool
0156 operator==(LdgIterator<T> const& it, std::nullptr_t) noexcept
0157 {
0158 return !static_cast<bool>(it);
0159 }
0160 template<class T>
0161 CELER_CONSTEXPR_FUNCTION bool
0162 operator!=(LdgIterator<T> const& it, std::nullptr_t) noexcept
0163 {
0164 return static_cast<bool>(it);
0165 }
0166 template<class T>
0167 CELER_CONSTEXPR_FUNCTION bool
0168 operator==(std::nullptr_t, LdgIterator<T> const& it) noexcept
0169 {
0170 return !static_cast<bool>(it);
0171 }
0172 template<class T>
0173 CELER_CONSTEXPR_FUNCTION bool
0174 operator!=(std::nullptr_t, LdgIterator<T> const& it) noexcept
0175 {
0176 return static_cast<bool>(it);
0177 }
0178 template<class T>
0179 CELER_CONSTEXPR_FUNCTION bool
0180 operator<(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0181 {
0182 using pointer = typename LdgIterator<T>::pointer;
0183 return static_cast<pointer>(lhs) < static_cast<pointer>(rhs);
0184 }
0185 template<class T>
0186 CELER_CONSTEXPR_FUNCTION bool
0187 operator>(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0188 {
0189 return rhs < lhs;
0190 }
0191 template<class T>
0192 CELER_CONSTEXPR_FUNCTION bool
0193 operator<=(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0194 {
0195 return !(lhs > rhs);
0196 }
0197 template<class T>
0198 CELER_CONSTEXPR_FUNCTION bool
0199 operator>=(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0200 {
0201 return !(lhs < rhs);
0202 }
0203 template<class T>
0204 CELER_CONSTEXPR_FUNCTION LdgIterator<T>
0205 operator+(LdgIterator<T> const& it,
0206 typename LdgIterator<T>::difference_type const n) noexcept
0207 {
0208 LdgIterator tmp{it};
0209 return tmp += n;
0210 }
0211 template<class T>
0212 CELER_CONSTEXPR_FUNCTION LdgIterator<T>
0213 operator+(typename LdgIterator<T>::difference_type const n,
0214 LdgIterator<T> const& it) noexcept
0215 {
0216 return it + n;
0217 }
0218 template<class T>
0219 CELER_CONSTEXPR_FUNCTION LdgIterator<T>
0220 operator-(LdgIterator<T> const& it,
0221 typename LdgIterator<T>::difference_type const n) noexcept
0222 {
0223 LdgIterator<T> tmp{it};
0224 return tmp -= n;
0225 }
0226 template<class T>
0227 CELER_CONSTEXPR_FUNCTION auto
0228 operator-(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept ->
0229 typename LdgIterator<T>::difference_type
0230 {
0231 using pointer = typename LdgIterator<T>::pointer;
0232 return static_cast<pointer>(lhs) - static_cast<pointer>(rhs);
0233 }
0234 template<class T>
0235 CELER_CONSTEXPR_FUNCTION void
0236 swap(LdgIterator<T>& lhs, LdgIterator<T>& rhs) noexcept
0237 {
0238 return lhs.swap(rhs);
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 template<class T>
0251 struct LdgValue
0252 {
0253 using value_type = T;
0254 static_assert(detail::is_ldg_supported_v<T>,
0255 "const arithmetic, OpaqueId or enum type "
0256 "required");
0257 };
0258
0259
0260
0261 template<class T, std::size_t Extent = dynamic_extent>
0262 using LdgSpan = Span<LdgValue<T>, Extent>;
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 template<class T, std::size_t N>
0275 CELER_CONSTEXPR_FUNCTION auto make_array(LdgSpan<T, N> const& s)
0276 {
0277 Array<std::remove_cv_t<T>, N> result{};
0278 for (std::size_t i = 0; i < N; ++i)
0279 {
0280 result[i] = s[i];
0281 }
0282 return result;
0283 }
0284
0285
0286 }