12#include "detray/definitions/detail/qualifiers.hpp"
13#include "detray/definitions/indexing.hpp"
14#include "detray/utils/ranges/empty.hpp"
15#include "detray/utils/ranges/ranges.hpp"
23namespace detray::ranges {
35template <std::input_iterator range_itr_t, std::input_iterator sequence_itr_t>
37 pick_view<range_itr_t, sequence_itr_t>> {
39 using index_t = std::iter_value_t<sequence_itr_t>;
40 using value_t = std::iter_value_t<range_itr_t>;
41 using difference_t = std::iter_difference_t<range_itr_t>;
51 using itr_value_t = std::iter_value_t<range_itr_t>;
52 using itr_ref_t = std::iter_reference_t<range_itr_t>;
53 using itr_ptr_t =
typename std::iterator_traits<range_itr_t>::pointer;
55 using difference_type = std::iter_difference_t<range_itr_t>;
56 using value_type = std::pair<std::iter_value_t<sequence_itr_t>, itr_ref_t>;
57 using pointer = value_type *;
58 using reference = value_type;
59 using iterator_category =
60 typename std::iterator_traits<sequence_itr_t>::iterator_category;
62 static_assert(std::is_convertible_v<index_t, difference_type>,
63 "Given sequence cannot be "
64 "used to index elements of range.");
67 constexpr iterator() =
default;
71 constexpr iterator(range_itr_t rng_itr, range_itr_t rng_begin,
72 sequence_itr_t sq_itr, sequence_itr_t sq_end)
73 : m_range_iter{rng_itr},
74 m_range_begin{rng_begin},
80 DETRAY_HOST_DEVICE
constexpr auto operator++() -> iterator & {
82 if (m_seq_iter != m_seq_end) {
84 m_range_begin +
static_cast<difference_type
>(*m_seq_iter);
89 DETRAY_HOST_DEVICE
constexpr auto operator++(
int) -> iterator {
98 DETRAY_HOST_DEVICE
constexpr auto operator--() -> iterator &
99 requires std::bidirectional_iterator<range_itr_t>
102 m_range_begin +
static_cast<difference_type
>(*(--m_seq_iter));
106 DETRAY_HOST_DEVICE
constexpr auto operator--(
int) -> iterator
107 requires std::bidirectional_iterator<range_itr_t>
115 DETRAY_HOST_DEVICE
auto operator*()
const {
116 return value_type(*m_seq_iter, *m_range_iter);
121 DETRAY_HOST_DEVICE
constexpr auto operator+=(
const difference_type j)
123 requires std::random_access_iterator<range_itr_t>
125 detray::ranges::advance(m_seq_iter, j);
126 m_range_begin +=
static_cast<difference_type
>(*m_seq_iter);
132 DETRAY_HOST_DEVICE
constexpr auto operator-=(
const difference_type j)
134 requires std::random_access_iterator<range_itr_t> &&
135 std::random_access_iterator<sequence_itr_t>
141 DETRAY_HOST_DEVICE
constexpr auto operator[](
const difference_type i)
const
142 requires std::random_access_iterator<range_itr_t> &&
143 std::random_access_iterator<sequence_itr_t>
145 const auto index{m_seq_iter[i]};
146 return value_type(index, m_range_begin[index]);
152 friend constexpr auto operator==(
const iterator &lhs,
const iterator &rhs)
154 return (lhs.m_seq_iter == rhs.m_seq_iter);
159 friend constexpr auto operator<=>(
const iterator &lhs,
const iterator &rhs)
160 requires detray::ranges::random_access_iterator<sequence_itr_t>
162#if defined(__apple_build_version__)
163 const auto l{lhs.m_seq_iter};
164 const auto r{rhs.m_seq_iter};
165 if (l < r || (l == r && l < r)) {
166 return std::strong_ordering::less;
168 if (l > r || (l == r && l > r)) {
169 return std::strong_ordering::greater;
171 return std::strong_ordering::equivalent;
173 return (lhs.m_seq_iter <=> rhs.m_seq_iter);
181 DETRAY_HOST_DEVICE
friend constexpr auto operator+(
const iterator &itr,
182 const difference_type j)
184 requires std::random_access_iterator<range_itr_t>
186 auto seq_iter = detray::ranges::next(itr.m_seq_iter, j);
187 return {itr.m_range_begin +
static_cast<difference_type
>(*seq_iter),
188 itr.m_range_begin, seq_iter, itr.m_seq_end};
195 DETRAY_HOST_DEVICE
friend constexpr auto operator+(
const difference_type j,
198 requires std::random_access_iterator<range_itr_t>
207 DETRAY_HOST_DEVICE
friend constexpr auto operator-(
const iterator &itr,
208 const difference_type j)
210 requires std::random_access_iterator<range_itr_t>
216 DETRAY_HOST_DEVICE
friend constexpr auto operator-(
const iterator &lhs,
219 requires std::random_access_iterator<range_itr_t> &&
220 std::random_access_iterator<sequence_itr_t>
222 return lhs.m_seq_iter - rhs.m_seq_iter;
225 range_itr_t m_range_iter{};
226 range_itr_t m_range_begin{};
227 sequence_itr_t m_seq_iter{};
228 sequence_itr_t m_seq_end{};
231 range_itr_t m_range_begin{};
232 range_itr_t m_range_end{};
233 sequence_itr_t m_seq_begin{};
234 sequence_itr_t m_seq_end{};
246 template <detray::ranges::range range_t, detray::ranges::range sequence_t>
250 m_seq_begin{
detray::ranges::cbegin(std::forward<sequence_t>(seq))},
251 m_seq_end{
detray::ranges::cend(std::forward<sequence_t>(seq))} {}
255 constexpr auto begin() -> iterator {
256 return {m_range_begin +
static_cast<difference_t
>(*m_seq_begin),
257 m_range_begin, m_seq_begin, m_seq_end};
262 constexpr auto begin() const -> iterator {
263 return {m_range_begin +
static_cast<difference_t
>(*m_seq_begin),
264 m_range_begin, m_seq_begin, m_seq_end};
269 constexpr auto end() -> iterator {
270 return {m_range_begin, m_range_begin, m_seq_end, m_seq_end};
277 return std::addressof(
278 *(m_range_begin +
static_cast<difference_t
>(*m_seq_begin)));
284 constexpr auto data() ->
typename iterator_t::value_type * {
285 return std::addressof(
286 *(m_range_begin +
static_cast<difference_t
>(*m_seq_begin)));
292 constexpr auto size() const noexcept {
293 return detray::ranges::distance(m_seq_begin, m_seq_end);
300 return std::pair<index_t, value_t &>(
302 *detray::ranges::next(m_range_begin,
303 static_cast<difference_t
>(*m_seq_begin)));
309 constexpr auto back() noexcept {
310 index_t last_idx{*detray::ranges::next(
311 m_seq_begin,
static_cast<difference_t
>((
size() - 1u)))};
312 return std::pair<index_t, value_t &>(
313 last_idx, *detray::ranges::next(m_range_begin,
314 static_cast<difference_t
>(last_idx)));
323 *detray::ranges::next(m_seq_begin,
static_cast<difference_t
>(i))};
324 return std::pair<index_t, value_t &>(
325 last_idx, *detray::ranges::next(m_range_begin,
326 static_cast<difference_t
>(last_idx)));
333template <std::input_iterator range_itr_t,
335struct pick :
public pick_view<range_itr_t, detray::ranges::const_iterator_t<
336 std::decay_t<sequence_t>>> {
339 detray::ranges::const_iterator_t<std::decay_t<sequence_t>>;
343 constexpr pick() =
default;
347 template <detray::ranges::input_range deduced_sequence_t>
348 DETRAY_HOST_DEVICE
constexpr explicit pick(deduced_sequence_t &&seq)
349 : m_seq(std::forward<deduced_sequence_t>(seq)) {}
356 DETRAY_HOST_DEVICE
constexpr pick(range_t &&
range, deduced_sequence_t &&seq)
358 m_seq{std::forward<deduced_sequence_t>(seq)} {}
363 template <detray::ranges::range range_t>
364 requires(std::same_as<sequence_t, std::remove_cvref_t<sequence_t>> &&
365 !std::is_pointer_v<sequence_t>)
366 DETRAY_HOST_DEVICE
constexpr auto operator()(range_t &&rng) && {
367 using itr_t = detray::ranges::iterator_t<std::remove_reference_t<range_t>>;
369 std::forward<range_t>(rng), std::move(m_seq));
375 template <detray::ranges::range range_t>
376 requires(!std::same_as<sequence_t, std::remove_cvref_t<sequence_t>> ||
377 std::is_pointer_v<sequence_t>)
378 DETRAY_HOST_DEVICE
constexpr auto operator()(range_t &&rng) {
379 using itr_t = detray::ranges::iterator_t<std::remove_reference_t<range_t>>;
381 std::forward<range_t>(rng), m_seq);
389 base_type::operator=(other);
399DETRAY_HOST_DEVICE_DEDUCTION_GUIDE pick()
400 -> pick<detray::ranges::iterator_t<detray::ranges::views::empty<int>>,
403template <detray::ranges::range sequence_t>
404DETRAY_HOST_DEVICE_DEDUCTION_GUIDE pick(sequence_t &&seq)
405 -> pick<detray::ranges::iterator_t<detray::ranges::views::empty<int>>,
408template <detray::ranges::range range_t, detray::ranges::range sequence_t>
409DETRAY_HOST_DEVICE_DEDUCTION_GUIDE pick(range_t &&range, sequence_t &&seq)
410 -> pick<detray::ranges::iterator_t<std::remove_reference_t<range_t>>,
Range adaptor that indexes the elements of a range using another index range.
Definition pick.hpp:37
constexpr auto begin() -> iterator
Definition pick.hpp:255
constexpr auto back() noexcept
Definition pick.hpp:309
constexpr auto end() -> iterator
Definition pick.hpp:269
constexpr pick_view()=default
Default constructor.
constexpr pick_view(range_t &&range, sequence_t &&seq)
Select elements of range using the indices in seq.
Definition pick.hpp:247
constexpr auto data() const -> const typename iterator_t::value_type *
Definition pick.hpp:276
iterator iterator_t
Iterator yielding each selected index and its corresponding element.
Definition pick.hpp:238
constexpr auto operator[](const dindex i) const
Return the selected index and element at position i.
Definition pick.hpp:321
constexpr auto front() noexcept
Definition pick.hpp:299
constexpr auto data() -> typename iterator_t::value_type *
Definition pick.hpp:284
constexpr auto begin() const -> iterator
Definition pick.hpp:262
constexpr auto size() const noexcept
Definition pick.hpp:292
Defines a detray 'view'.
Definition ranges.hpp:190
Range concept.
Definition ranges.hpp:97
Detray include(s).
Definition array_operators.hpp:18
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
unsigned int dindex
Default index type.
Definition indexing.hpp:18
constexpr array_t< scalar1_t, 2 > operator*(const array_t< scalar1_t, 2 > &a, scalar2_t s)
Multiply an array-backed vector by a scalar.
Definition array_operators.hpp:26
constexpr array_t< scalar_t, 2 > operator+(const array_t< scalar_t, 2 > &a, const array_t< scalar_t, 2 > &b)
Add array-backed vectors component-wise.
Definition array_operators.hpp:47
constexpr array_t< scalar_t, 2 > operator-(const array_t< scalar_t, 2 > &a, const array_t< scalar_t, 2 > &b)
Subtract array-backed vectors component-wise.
Definition array_operators.hpp:40
constexpr bool operator==(const Fastor::Tensor< S, N > &lhs, const Fastor::Tensor< S, N > &rhs)
Compare two Fastor vectors component-wise for exact equality.
Definition fastor.hpp:35
pick & operator=(const pick &other)
Copy assignment operator.
Definition pick.hpp:388
constexpr pick(deduced_sequence_t &&seq)
Build an adaptor that will select the supplied indices from a later range.
Definition pick.hpp:348
constexpr pick(range_t &&range, deduced_sequence_t &&seq)
Construct the selection view immediately from both inputs.
Definition pick.hpp:356
pick_view< range_itr_t, sequence_itr_t > base_type
Base view implementation combining range and sequence iterators.
Definition pick.hpp:341
detray::ranges::const_iterator_t< std::decay_t< sequence_t > > sequence_itr_t
Iterator type used to read the selection sequence.
Definition pick.hpp:338
constexpr auto operator()(range_t &&rng) &&
Call operator for range composition - move semantics.
Definition pick.hpp:366