File indexing completed on 2026-05-27 07:24:05
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/empty.hpp"
0016 #include "detray/utils/ranges/ranges.hpp"
0017
0018
0019 #include <type_traits>
0020
0021 namespace detray::ranges {
0022
0023 namespace detail {
0024
0025
0026
0027
0028
0029
0030 template <detray::ranges::range range_t>
0031 class subrange_view
0032 : public detray::ranges::view_interface<subrange_view<range_t>> {
0033 public:
0034 using iterator_t = typename detray::ranges::iterator_t<range_t>;
0035 using const_iterator_t = typename detray::ranges::const_iterator_t<range_t>;
0036 using difference_t = typename detray::ranges::range_difference_t<range_t>;
0037
0038
0039 constexpr subrange_view() = default;
0040
0041
0042 DETRAY_HOST_DEVICE constexpr subrange_view(iterator_t start, iterator_t end)
0043 : m_begin{start}, m_end{end} {}
0044
0045
0046 DETRAY_HOST_DEVICE
0047 constexpr auto begin() -> iterator_t { return m_begin; }
0048
0049
0050 DETRAY_HOST_DEVICE
0051 constexpr auto end() -> iterator_t { return m_end; }
0052
0053
0054 DETRAY_HOST_DEVICE
0055 constexpr auto begin() const -> const_iterator_t { return m_begin; }
0056
0057
0058 DETRAY_HOST_DEVICE
0059 constexpr auto end() const -> const_iterator_t { return m_end; }
0060
0061
0062
0063
0064
0065
0066 DETRAY_HOST_DEVICE
0067 constexpr auto operator==(const subrange_view &rhs) const -> bool {
0068 return m_begin == rhs.m_begin && m_end == rhs.m_end;
0069 }
0070
0071 private:
0072
0073 iterator_t m_begin;
0074 iterator_t m_end;
0075 };
0076
0077 }
0078
0079
0080 template <detray::ranges::range range_t, typename index_range_t = dindex_range>
0081 struct subrange : public detail::subrange_view<range_t> {
0082 using base_type = detray::ranges::detail::subrange_view<range_t>;
0083
0084 using iterator_t = typename detray::ranges::iterator_t<range_t>;
0085 using difference_t = typename detray::ranges::range_difference_t<range_t>;
0086
0087
0088 constexpr subrange() = default;
0089
0090
0091 template <concepts::index index_t>
0092 DETRAY_HOST_DEVICE constexpr subrange(index_t start, index_t end)
0093 : m_pos{start, end} {}
0094
0095
0096 DETRAY_HOST_DEVICE constexpr subrange(iterator_t start, iterator_t end)
0097 : base_type{start, end} {}
0098
0099
0100 template <detray::ranges::range deduced_range_t>
0101 requires(!std::same_as<subrange, deduced_range_t>)
0102 DETRAY_HOST_DEVICE constexpr explicit subrange(deduced_range_t &&range)
0103 : base_type{detray::ranges::begin(range), detray::ranges::end(range)} {}
0104
0105
0106
0107 template <detray::ranges::range deduced_range_t, concepts::index index_t>
0108 requires std::is_convertible_v<
0109 index_t, detray::ranges::range_difference_t<deduced_range_t>>
0110 DETRAY_HOST_DEVICE constexpr subrange(deduced_range_t &&range, index_t pos)
0111 : base_type{detray::ranges::next(detray::ranges::begin(range),
0112 static_cast<difference_t>(pos)),
0113 detray::ranges::next(
0114 detray::ranges::begin(range),
0115 static_cast<difference_t>(pos) + difference_t{1})} {}
0116
0117
0118 template <detray::ranges::range deduced_range_t,
0119 concepts::interval deduced_index_range_t>
0120 DETRAY_HOST_DEVICE constexpr subrange(deduced_range_t &&range,
0121 const deduced_index_range_t &pos)
0122 : base_type{get_itr<0>(range, pos), get_itr<1>(range, pos)} {}
0123
0124
0125 template <detray::ranges::range deduced_range_t>
0126 DETRAY_HOST_DEVICE constexpr auto operator()(deduced_range_t &&range) {
0127 return detail::subrange_view<deduced_range_t>{get_itr<0>(range, m_pos),
0128 get_itr<1>(range, m_pos)};
0129 }
0130
0131 private:
0132
0133
0134 template <std::size_t I, detray::ranges::range deduced_range_t,
0135 concepts::interval deduced_index_range_t>
0136 DETRAY_HOST_DEVICE constexpr auto get_itr(deduced_range_t &&range,
0137 const deduced_index_range_t &pos) {
0138 return detray::ranges::next(
0139 detray::ranges::begin(std::forward<deduced_range_t>(range)),
0140 static_cast<difference_t>(detray::detail::get<I>(pos)));
0141 }
0142
0143
0144 index_range_t m_pos{};
0145 };
0146
0147
0148 DETRAY_HOST_DEVICE subrange()
0149 -> subrange<detray::ranges::views::empty<int>, dindex_range>;
0150
0151 template <concepts::index index_t>
0152 DETRAY_HOST_DEVICE subrange(index_t start, index_t end)
0153 -> subrange<detray::ranges::views::empty<int>, darray<index_t, 2>>;
0154
0155 template <detray::ranges::range deduced_range_t>
0156 DETRAY_HOST_DEVICE subrange(deduced_range_t &&range)
0157 -> subrange<std::remove_reference_t<deduced_range_t>, bool>;
0158
0159 template <detray::ranges::range deduced_range_t, concepts::index index_t>
0160 requires std::convertible_to<
0161 index_t, detray::ranges::range_difference_t<deduced_range_t>>
0162 DETRAY_HOST_DEVICE subrange(deduced_range_t &&range, index_t pos)
0163 -> subrange<std::remove_reference_t<deduced_range_t>, index_t>;
0164
0165 template <detray::ranges::range deduced_range_t,
0166 concepts::interval index_range_t>
0167 DETRAY_HOST_DEVICE subrange(deduced_range_t &&range, index_range_t &&pos)
0168 -> subrange<std::remove_reference_t<deduced_range_t>,
0169 std::remove_cvref_t<index_range_t>>;
0170
0171
0172 template <detray::ranges::range R, concepts::interval I>
0173 using borrowed_subrange_t =
0174 std::conditional_t<borrowed_range<R>, detray::ranges::subrange<R, I>,
0175 dangling>;
0176
0177 }