Warning, file /include/corecel/cont/detail/RangeImpl.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <iterator>
0010 #include <type_traits>
0011
0012 #include "corecel/Assert.hh"
0013 #include "corecel/Macros.hh"
0014 #include "corecel/data/Ldg.hh"
0015
0016 namespace celeritas
0017 {
0018 template<class TagT, class IndexT>
0019 class OpaqueId;
0020 namespace detail
0021 {
0022
0023 template<class T, class Enable = void>
0024 struct RangeTypeTraits
0025 {
0026 static_assert(std::is_integral_v<T>,
0027 "Only integer types can be used in a range");
0028 using value_type = T;
0029 using counter_type = T;
0030 using difference_type = std::make_signed_t<counter_type>;
0031
0032 template<class U>
0033 using common_type = std::common_type_t<T, U>;
0034
0035 static CELER_CONSTEXPR_FUNCTION value_type zero() { return {}; }
0036 static CELER_CONSTEXPR_FUNCTION bool is_valid(value_type) { return true; }
0037 static CELER_CONSTEXPR_FUNCTION counter_type to_counter(value_type v)
0038 {
0039 return v;
0040 }
0041 static CELER_CONSTEXPR_FUNCTION value_type to_value(counter_type c)
0042 {
0043 return c;
0044 }
0045 static CELER_CONSTEXPR_FUNCTION value_type increment(value_type v,
0046 difference_type i)
0047 {
0048 v += i;
0049 return v;
0050 }
0051 static CELER_CONSTEXPR_FUNCTION value_type decrement(value_type v,
0052 difference_type i)
0053 {
0054 v -= i;
0055 return v;
0056 }
0057 };
0058
0059 template<class T, class Enable = void>
0060 struct EnumWithSize
0061 {
0062 static CELER_CONSTEXPR_FUNCTION bool is_valid(T) { return true; }
0063 };
0064
0065 template<class T>
0066 struct EnumWithSize<T, std::enable_if_t<(T::size_ >= 0)>>
0067 {
0068 static CELER_CONSTEXPR_FUNCTION bool is_valid(T value)
0069 {
0070 return value <= T::size_;
0071 }
0072 };
0073
0074
0075 template<class T>
0076 struct RangeTypeTraits<T, std::enable_if_t<std::is_enum<T>::value>>
0077 {
0078 using value_type = T;
0079 using counter_type = std::underlying_type_t<T>;
0080 using difference_type = std::make_signed_t<counter_type>;
0081 template<class U>
0082 using common_type = value_type;
0083
0084 static CELER_CONSTEXPR_FUNCTION value_type zero() { return {}; }
0085 static CELER_CONSTEXPR_FUNCTION bool is_valid(value_type v)
0086 {
0087 return EnumWithSize<T>::is_valid(v);
0088 }
0089 static CELER_CONSTEXPR_FUNCTION counter_type to_counter(value_type v)
0090 {
0091 return static_cast<counter_type>(v);
0092 }
0093 static CELER_CONSTEXPR_FUNCTION value_type to_value(counter_type c)
0094 {
0095 return static_cast<value_type>(c);
0096 }
0097 static CELER_CONSTEXPR_FUNCTION value_type increment(value_type v,
0098 difference_type i)
0099 {
0100 auto temp = to_counter(v);
0101 temp += i;
0102 return to_value(temp);
0103 }
0104 static CELER_CONSTEXPR_FUNCTION value_type decrement(value_type v,
0105 difference_type i)
0106 {
0107 auto temp = to_counter(v);
0108 temp -= i;
0109 return to_value(temp);
0110 }
0111 };
0112
0113
0114 template<class I, class T>
0115 struct RangeTypeTraits<OpaqueId<I, T>, void>
0116 {
0117 using value_type = OpaqueId<I, T>;
0118 using counter_type = T;
0119 using difference_type = std::make_signed_t<counter_type>;
0120 template<class U>
0121 using common_type = value_type;
0122
0123 static CELER_CONSTEXPR_FUNCTION value_type zero() { return value_type(0); }
0124 static CELER_CONSTEXPR_FUNCTION bool is_valid(value_type v)
0125 {
0126 return static_cast<bool>(v);
0127 }
0128 static CELER_CONSTEXPR_FUNCTION counter_type to_counter(value_type v)
0129 {
0130 return v.unchecked_get();
0131 }
0132 static CELER_CONSTEXPR_FUNCTION value_type to_value(difference_type c)
0133 {
0134 return static_cast<value_type>(c);
0135 }
0136 static CELER_CONSTEXPR_FUNCTION value_type increment(value_type v,
0137 difference_type i)
0138 {
0139 counter_type temp = to_counter(v);
0140 temp += i;
0141 return to_value(temp);
0142 }
0143 static CELER_CONSTEXPR_FUNCTION value_type decrement(value_type v,
0144 difference_type i)
0145 {
0146 counter_type temp = to_counter(v);
0147 temp -= i;
0148 return to_value(temp);
0149 }
0150 };
0151
0152
0153 template<class T>
0154 class range_iter
0155 {
0156 public:
0157
0158
0159 using TraitsT = RangeTypeTraits<T>;
0160 using value_type = T;
0161 using counter_type = typename TraitsT::counter_type;
0162 using iterator_category = std::input_iterator_tag;
0163 using difference_type = typename TraitsT::difference_type;
0164 using pointer = void;
0165 using reference = value_type;
0166
0167
0168 public:
0169
0170
0171 constexpr range_iter() = default;
0172
0173 explicit CELER_CONSTEXPR_FUNCTION range_iter(value_type value)
0174 : value_(value)
0175 {
0176 CELER_EXPECT(TraitsT::is_valid(value_));
0177 }
0178
0179
0180
0181 CELER_CONSTEXPR_FUNCTION value_type operator*() const { return value_; }
0182 CELER_CONSTEXPR_FUNCTION value_type const* operator->() const
0183 {
0184 return &value_;
0185 }
0186
0187 CELER_CONSTEXPR_FUNCTION value_type operator[](counter_type inc) const
0188 {
0189 return TraitsT::increment(value_, inc);
0190 }
0191
0192
0193
0194 CELER_CONSTEXPR_FUNCTION range_iter& operator++()
0195 {
0196 value_ = TraitsT::increment(value_, 1);
0197 return *this;
0198 }
0199
0200 CELER_CONSTEXPR_FUNCTION range_iter operator++(int)
0201 {
0202 auto copy = *this;
0203 value_ = TraitsT::increment(value_, 1);
0204 return copy;
0205 }
0206
0207 CELER_CONSTEXPR_FUNCTION range_iter operator+(difference_type inc) const
0208 {
0209 return range_iter{TraitsT::increment(value_, inc)};
0210 }
0211
0212 CELER_CONSTEXPR_FUNCTION range_iter& operator--()
0213 {
0214 value_ = TraitsT::decrement(value_, 1);
0215 return *this;
0216 }
0217
0218 CELER_CONSTEXPR_FUNCTION range_iter operator--(int)
0219 {
0220 auto copy = *this;
0221 value_ = TraitsT::decrement(value_, 1);
0222 return copy;
0223 }
0224
0225 CELER_CONSTEXPR_FUNCTION range_iter operator-(difference_type inc) const
0226 {
0227 return range_iter{TraitsT::decrement(value_, inc)};
0228 }
0229
0230 CELER_CONSTEXPR_FUNCTION bool operator==(range_iter const& other) const
0231 {
0232 return value_ == other.value_;
0233 }
0234
0235 CELER_CONSTEXPR_FUNCTION bool operator!=(range_iter const& other) const
0236 {
0237 return !(*this == other);
0238 }
0239
0240
0241 CELER_CONSTEXPR_FUNCTION friend auto operator-(range_iter a, range_iter b)
0242 {
0243 using TraitsT = RangeTypeTraits<T>;
0244 using DT = typename TraitsT::difference_type;
0245 return static_cast<DT>(TraitsT::to_counter(a.value()))
0246 - static_cast<DT>(TraitsT::to_counter(b.value()));
0247 }
0248
0249
0250 CELER_CEF value_type value() const& { return value_; }
0251
0252
0253 CELER_CONSTEXPR_FUNCTION friend range_iter ldg(
0254 range_iter const* ri) noexcept
0255 {
0256 using ::celeritas::ldg;
0257 return range_iter{ldg(&ri->value_)};
0258 }
0259
0260 protected:
0261
0262 value_type value_{TraitsT::zero()};
0263 };
0264
0265
0266 template<class T>
0267 class inf_range_iter : public range_iter<T>
0268 {
0269 using Base = range_iter<T>;
0270
0271 public:
0272 using TraitsT = typename Base::TraitsT;
0273
0274 explicit CELER_CONSTEXPR_FUNCTION inf_range_iter(T value) : Base(value) {}
0275 explicit CELER_CONSTEXPR_FUNCTION inf_range_iter()
0276 : inf_range_iter{TraitsT::zero()}
0277 {
0278 }
0279
0280 CELER_CONSTEXPR_FUNCTION bool operator==(inf_range_iter const&) const
0281 {
0282 return false;
0283 }
0284
0285 CELER_CONSTEXPR_FUNCTION bool operator!=(inf_range_iter const&) const
0286 {
0287 return true;
0288 }
0289 };
0290
0291
0292 template<class T>
0293 class step_range_iter : public range_iter<T>
0294 {
0295 using Base = range_iter<T>;
0296
0297 public:
0298 using TraitsT = typename Base::TraitsT;
0299 using counter_type = typename TraitsT::counter_type;
0300 using difference_type = typename TraitsT::difference_type;
0301
0302 CELER_CONSTEXPR_FUNCTION step_range_iter(T value, counter_type step)
0303 : Base(value), step_(step)
0304 {
0305 }
0306
0307 CELER_CONSTEXPR_FUNCTION step_range_iter& operator++()
0308 {
0309 value_ = TraitsT::increment(value_, step_);
0310 return *this;
0311 }
0312
0313 CELER_CONSTEXPR_FUNCTION step_range_iter operator++(int)
0314 {
0315 auto copy = *this;
0316 ++*this;
0317 return copy;
0318 }
0319
0320 CELER_CONSTEXPR_FUNCTION step_range_iter operator+(difference_type inc)
0321 {
0322 return {TraitsT::increment(value_, inc * step_)};
0323 }
0324
0325 CELER_FUNCTION bool operator==(step_range_iter const& other) const
0326 {
0327 if constexpr (std::is_signed_v<counter_type>)
0328 {
0329 return step_ >= 0 ? !(value_ < other.value_)
0330 : value_ < other.value_;
0331 }
0332 else
0333 {
0334 return !(value_ < other.value_);
0335 }
0336 }
0337
0338 CELER_FUNCTION bool operator!=(step_range_iter const& other) const
0339 {
0340 return !(*this == other);
0341 }
0342
0343
0344 CELER_FORCEINLINE_FUNCTION counter_type step() const { return step_; }
0345
0346 private:
0347 using Base::value_;
0348 counter_type step_;
0349 };
0350
0351
0352 template<class T>
0353 class inf_step_range_iter : public step_range_iter<T>
0354 {
0355 using Base = step_range_iter<T>;
0356
0357 public:
0358 using TraitsT = typename Base::TraitsT;
0359 using counter_type = typename TraitsT::counter_type;
0360
0361 CELER_FUNCTION inf_step_range_iter(T current = TraitsT::zero(),
0362 counter_type step = {})
0363 : Base(current, step)
0364 {
0365 }
0366
0367 CELER_FUNCTION bool operator==(inf_step_range_iter const&) const
0368 {
0369 return false;
0370 }
0371
0372 CELER_FUNCTION bool operator!=(inf_step_range_iter const&) const
0373 {
0374 return true;
0375 }
0376 };
0377
0378
0379
0380
0381
0382 template<class T>
0383 class StepRange
0384 {
0385 public:
0386 using IterT = step_range_iter<T>;
0387 using counter_type = typename RangeTypeTraits<T>::counter_type;
0388
0389 CELER_FUNCTION StepRange(T begin, T end, counter_type step)
0390 : begin_(begin, step), end_(end, step)
0391 {
0392 }
0393
0394 CELER_CONSTEXPR_FUNCTION IterT begin() const { return begin_; }
0395 CELER_CONSTEXPR_FUNCTION IterT end() const { return end_; }
0396
0397 private:
0398 IterT begin_;
0399 IterT end_;
0400 };
0401
0402
0403
0404
0405
0406 template<class T>
0407 class InfStepRange
0408 {
0409 public:
0410 using IterT = inf_step_range_iter<T>;
0411 using counter_type = typename RangeTypeTraits<T>::counter_type;
0412
0413
0414 CELER_FUNCTION InfStepRange(T begin, counter_type step)
0415 : begin_(begin, step)
0416 {
0417 }
0418
0419 CELER_CONSTEXPR_FUNCTION IterT begin() const { return begin_; }
0420 CELER_CONSTEXPR_FUNCTION IterT end() const { return IterT(); }
0421
0422 private:
0423 IterT begin_;
0424 };
0425
0426 }
0427 }