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