File indexing completed on 2026-05-27 07:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/definitions/indexing.hpp"
0014 #include "detray/utils/concepts.hpp"
0015 #include "detray/utils/ranges/detail/iterator_functions.hpp"
0016 #include "detray/utils/ranges/ranges.hpp"
0017
0018
0019 #include <concepts>
0020 #include <iterator>
0021 #include <type_traits>
0022
0023 namespace detray::ranges {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 template <std::incrementable incr_t>
0035 class iota_view : public detray::ranges::view_interface<iota_view<incr_t>> {
0036 private:
0037
0038 struct iterator {
0039 using difference_type = std::ptrdiff_t;
0040 using value_type = incr_t;
0041 using pointer = incr_t *;
0042 using reference = incr_t;
0043 using iterator_category =
0044 std::conditional_t<concepts::random_access_incrementable<incr_t> &&
0045 std::totally_ordered<incr_t>,
0046 detray::ranges::random_access_iterator_tag,
0047 detray::ranges::bidirectional_iterator_tag>;
0048
0049 constexpr iterator()
0050 requires std::default_initializable<incr_t>
0051 = default;
0052
0053
0054 DETRAY_HOST_DEVICE constexpr explicit iterator(incr_t i) : m_i{i} {}
0055
0056
0057
0058 DETRAY_HOST_DEVICE
0059 constexpr auto operator++() -> iterator & {
0060 ++m_i;
0061 return *this;
0062 }
0063
0064 DETRAY_HOST_DEVICE constexpr auto operator++(int) -> iterator {
0065 auto tmp(*this);
0066 ++(*this);
0067 return tmp;
0068 }
0069 DETRAY_HOST_DEVICE
0070 constexpr auto operator--() -> iterator & {
0071 --m_i;
0072 return *this;
0073 }
0074
0075 DETRAY_HOST_DEVICE constexpr auto operator--(int) -> iterator {
0076 auto tmp(*this);
0077 --(*this);
0078 return tmp;
0079 }
0080
0081 DETRAY_HOST_DEVICE constexpr iterator &operator+=(const difference_type n)
0082 requires concepts::random_access_incrementable<incr_t>
0083 {
0084 difference_type nv = static_cast<difference_type>(m_i) + n;
0085
0086
0087 assert(static_cast<difference_type>(static_cast<incr_t>(nv)) == nv);
0088 m_i = static_cast<incr_t>(nv);
0089 return *this;
0090 }
0091
0092 DETRAY_HOST_DEVICE friend constexpr iterator operator+(
0093 const iterator &i, const difference_type n)
0094 requires concepts::random_access_incrementable<incr_t>
0095 {
0096 return iterator(i.m_i + n);
0097 }
0098
0099 DETRAY_HOST_DEVICE friend constexpr iterator operator+(
0100 const difference_type n, const iterator &i)
0101 requires concepts::random_access_incrementable<incr_t>
0102 {
0103 return iterator(i.m_i + n);
0104 }
0105
0106 DETRAY_HOST_DEVICE constexpr iterator &operator-=(const difference_type n)
0107 requires concepts::random_access_incrementable<incr_t>
0108 {
0109 m_i -= n;
0110 return *this;
0111 }
0112
0113 DETRAY_HOST_DEVICE friend constexpr iterator operator-(
0114 const iterator &i, const difference_type n)
0115 requires concepts::random_access_incrementable<incr_t>
0116 {
0117 return iterator(i.m_i - n);
0118 }
0119
0120 DETRAY_HOST_DEVICE friend constexpr difference_type operator-(
0121 const iterator &i, const iterator &j)
0122 requires concepts::random_access_incrementable<incr_t>
0123 {
0124 return i.m_i - j.m_i;
0125 }
0126
0127
0128
0129 DETRAY_HOST_DEVICE
0130 constexpr auto operator*() const
0131 noexcept(std::is_nothrow_copy_constructible_v<incr_t>) -> incr_t {
0132 return m_i;
0133 }
0134
0135 DETRAY_HOST_DEVICE
0136 constexpr incr_t operator[](const difference_type n) const
0137 requires concepts::random_access_incrementable<incr_t>
0138 {
0139 return static_cast<incr_t>(m_i + n);
0140 }
0141
0142 private:
0143 DETRAY_HOST_DEVICE
0144 friend constexpr auto operator<=>(const iterator &lhs, const iterator &rhs)
0145 requires std::totally_ordered<incr_t>
0146 = default;
0147
0148
0149 incr_t m_i{};
0150 };
0151
0152
0153 incr_t m_start;
0154 incr_t m_end;
0155
0156 public:
0157 using iterator_t = iterator;
0158
0159
0160
0161 constexpr iota_view()
0162 requires std::default_initializable<incr_t>
0163 = default;
0164
0165
0166 template <concepts::interval interval_t>
0167 requires(!std::same_as<interval_t, iota_view>)
0168 DETRAY_HOST_DEVICE constexpr explicit iota_view(interval_t &&interval)
0169 : m_start{detray::detail::get<0>(interval)},
0170 m_end{detray::detail::get<1>(interval)} {}
0171
0172
0173 DETRAY_HOST_DEVICE constexpr iota_view(incr_t start, incr_t end)
0174 : m_start{start}, m_end{end} {}
0175
0176
0177 DETRAY_HOST_DEVICE
0178 constexpr explicit iota_view(incr_t start)
0179 : m_start{start}, m_end{start + 1} {}
0180
0181
0182 DETRAY_HOST_DEVICE
0183 constexpr auto begin() const -> iterator_t { return iterator_t{m_start}; }
0184
0185
0186 DETRAY_HOST_DEVICE
0187 constexpr auto end() const -> iterator_t { return iterator_t{m_end}; }
0188
0189
0190 DETRAY_HOST_DEVICE
0191 constexpr auto size() const -> incr_t { return m_end - m_start; }
0192 };
0193
0194 namespace views {
0195
0196
0197 template <std::incrementable incr_t>
0198 struct iota : public detray::ranges::iota_view<incr_t> {
0199 using base_type = detray::ranges::iota_view<incr_t>;
0200
0201 constexpr iota()
0202 requires std::default_initializable<incr_t>
0203 = default;
0204
0205 template <concepts::interval interval_t>
0206 requires(!std::same_as<interval_t, iota>)
0207 DETRAY_HOST_DEVICE constexpr explicit iota(interval_t &&interval)
0208 : base_type(std::forward<interval_t>(interval)) {}
0209
0210 DETRAY_HOST_DEVICE constexpr iota(incr_t start, incr_t end)
0211 : base_type(start, end) {}
0212
0213 DETRAY_HOST_DEVICE constexpr explicit iota(incr_t start) : base_type(start) {}
0214 };
0215
0216
0217 template <concepts::interval interval_t>
0218 DETRAY_HOST_DEVICE iota(interval_t &&interval)
0219 -> iota<std::remove_cvref_t<decltype(detray::detail::get<0>(interval))>>;
0220
0221 template <concepts::index I>
0222 DETRAY_HOST_DEVICE iota(I start, I end) -> iota<I>;
0223
0224 template <concepts::index I>
0225 DETRAY_HOST_DEVICE iota(I start) -> iota<I>;
0226
0227 }
0228
0229 }