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