File indexing completed on 2025-01-18 09:54:47
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 constexpr LdgIterator(LdgIterator const&) noexcept = default;
0055 CELER_CONSTEXPR_FUNCTION LdgIterator(std::nullptr_t) noexcept {}
0056 CELER_CONSTEXPR_FUNCTION explicit LdgIterator(pointer ptr) noexcept
0057 : ptr_{ptr}
0058 {
0059 }
0060
0061
0062
0063
0064 CELER_CONSTEXPR_FUNCTION reference operator*() const noexcept
0065 {
0066 return LoadPolicyT::read(ptr_);
0067 }
0068 CELER_CONSTEXPR_FUNCTION LdgIterator& operator++() noexcept
0069 {
0070 ++ptr_;
0071 return *this;
0072 }
0073 CELER_CONSTEXPR_FUNCTION void swap(LdgIterator& it) noexcept
0074 {
0075 ::celeritas::trivial_swap(ptr_, it.ptr_);
0076 }
0077 CELER_CONSTEXPR_FUNCTION LdgIterator operator++(int) noexcept
0078 {
0079 LdgIterator tmp{ptr_};
0080 ++ptr_;
0081 return tmp;
0082 }
0083 CELER_CONSTEXPR_FUNCTION pointer operator->() const noexcept
0084 {
0085 return ptr_;
0086 }
0087 CELER_CONSTEXPR_FUNCTION LdgIterator& operator--() noexcept
0088 {
0089 --ptr_;
0090 return *this;
0091 }
0092 CELER_CONSTEXPR_FUNCTION LdgIterator operator--(int) noexcept
0093 {
0094 LdgIterator tmp{ptr_};
0095 --ptr_;
0096 return tmp;
0097 }
0098 CELER_CONSTEXPR_FUNCTION LdgIterator& operator+=(difference_type n) noexcept
0099 {
0100 ptr_ += n;
0101 return *this;
0102 }
0103 CELER_CONSTEXPR_FUNCTION LdgIterator& operator-=(difference_type n) noexcept
0104 {
0105 ptr_ -= n;
0106 return *this;
0107 }
0108 CELER_CONSTEXPR_FUNCTION reference operator[](difference_type n) const noexcept
0109 {
0110 return LoadPolicyT::read(ptr_ + n);
0111 }
0112 LdgIterator& operator=(LdgIterator const&) = default;
0113
0114
0115
0116
0117 CELER_CONSTEXPR_FUNCTION explicit operator pointer() const noexcept
0118 {
0119 return ptr_;
0120 }
0121 CELER_CONSTEXPR_FUNCTION explicit operator bool() const noexcept
0122 {
0123 return ptr_ != nullptr;
0124 }
0125
0126
0127 private:
0128 pointer ptr_{nullptr};
0129 };
0130
0131
0132
0133
0134 template<class T>
0135 LdgIterator(T*) -> LdgIterator<std::add_const_t<T>>;
0136
0137
0138
0139
0140
0141
0142
0143 template<class T>
0144 CELER_CONSTEXPR_FUNCTION bool
0145 operator==(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0146 {
0147 using pointer = typename LdgIterator<T>::pointer;
0148 return static_cast<pointer>(lhs) == static_cast<pointer>(rhs);
0149 }
0150 template<class T>
0151 CELER_CONSTEXPR_FUNCTION bool
0152 operator!=(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0153 {
0154 return !(lhs == rhs);
0155 }
0156 template<class T>
0157 CELER_CONSTEXPR_FUNCTION bool
0158 operator==(LdgIterator<T> const& it, std::nullptr_t) noexcept
0159 {
0160 return !static_cast<bool>(it);
0161 }
0162 template<class T>
0163 CELER_CONSTEXPR_FUNCTION bool
0164 operator!=(LdgIterator<T> const& it, std::nullptr_t) noexcept
0165 {
0166 return static_cast<bool>(it);
0167 }
0168 template<class T>
0169 CELER_CONSTEXPR_FUNCTION bool
0170 operator==(std::nullptr_t, LdgIterator<T> const& it) noexcept
0171 {
0172 return !static_cast<bool>(it);
0173 }
0174 template<class T>
0175 CELER_CONSTEXPR_FUNCTION bool
0176 operator!=(std::nullptr_t, LdgIterator<T> const& it) noexcept
0177 {
0178 return static_cast<bool>(it);
0179 }
0180 template<class T>
0181 CELER_CONSTEXPR_FUNCTION bool
0182 operator<(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0183 {
0184 using pointer = typename LdgIterator<T>::pointer;
0185 return static_cast<pointer>(lhs) < static_cast<pointer>(rhs);
0186 }
0187 template<class T>
0188 CELER_CONSTEXPR_FUNCTION bool
0189 operator>(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0190 {
0191 return rhs < lhs;
0192 }
0193 template<class T>
0194 CELER_CONSTEXPR_FUNCTION bool
0195 operator<=(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0196 {
0197 return !(lhs > rhs);
0198 }
0199 template<class T>
0200 CELER_CONSTEXPR_FUNCTION bool
0201 operator>=(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept
0202 {
0203 return !(lhs < rhs);
0204 }
0205 template<class T>
0206 CELER_CONSTEXPR_FUNCTION LdgIterator<T>
0207 operator+(LdgIterator<T> const& it,
0208 typename LdgIterator<T>::difference_type const n) noexcept
0209 {
0210 LdgIterator tmp{it};
0211 return tmp += n;
0212 }
0213 template<class T>
0214 CELER_CONSTEXPR_FUNCTION LdgIterator<T>
0215 operator+(typename LdgIterator<T>::difference_type const n,
0216 LdgIterator<T> const& it) noexcept
0217 {
0218 return it + n;
0219 }
0220 template<class T>
0221 CELER_CONSTEXPR_FUNCTION LdgIterator<T>
0222 operator-(LdgIterator<T> const& it,
0223 typename LdgIterator<T>::difference_type const n) noexcept
0224 {
0225 LdgIterator<T> tmp{it};
0226 return tmp -= n;
0227 }
0228 template<class T>
0229 CELER_CONSTEXPR_FUNCTION auto
0230 operator-(LdgIterator<T> const& lhs, LdgIterator<T> const& rhs) noexcept ->
0231 typename LdgIterator<T>::difference_type
0232 {
0233 using pointer = typename LdgIterator<T>::pointer;
0234 return static_cast<pointer>(lhs) - static_cast<pointer>(rhs);
0235 }
0236 template<class T>
0237 CELER_CONSTEXPR_FUNCTION void
0238 swap(LdgIterator<T>& lhs, LdgIterator<T>& rhs) noexcept
0239 {
0240 return lhs.swap(rhs);
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 template<class T>
0253 struct LdgValue
0254 {
0255 using value_type = T;
0256 static_assert(detail::is_ldg_supported_v<T>,
0257 "const arithmetic, OpaqueId or enum type "
0258 "required");
0259 };
0260
0261
0262
0263 template<class T, std::size_t Extent = dynamic_extent>
0264 using LdgSpan = Span<LdgValue<T>, Extent>;
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 template<class T, std::size_t N>
0277 CELER_CONSTEXPR_FUNCTION auto make_array(LdgSpan<T, N> const& s)
0278 {
0279 Array<std::remove_cv_t<T>, N> result{};
0280 for (std::size_t i = 0; i < N; ++i)
0281 {
0282 result[i] = s[i];
0283 }
0284 return result;
0285 }
0286
0287
0288 }