ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
pick.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
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"
16
17// System include(s)
18#include <cassert>
19#include <memory>
20#include <type_traits>
21#include <utility>
22
23namespace detray::ranges {
24
35template <std::input_iterator range_itr_t, std::input_iterator sequence_itr_t>
37 pick_view<range_itr_t, sequence_itr_t>> {
38 private:
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>;
42
50 struct iterator {
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;
54
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;
61
62 static_assert(std::is_convertible_v<index_t, difference_type>,
63 "Given sequence cannot be "
64 "used to index elements of range.");
65
67 constexpr iterator() = default;
68
70 DETRAY_HOST_DEVICE
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},
75 m_seq_iter{sq_itr},
76 m_seq_end{sq_end} {}
77
80 DETRAY_HOST_DEVICE constexpr auto operator++() -> iterator & {
81 ++m_seq_iter;
82 if (m_seq_iter != m_seq_end) {
83 m_range_iter =
84 m_range_begin + static_cast<difference_type>(*m_seq_iter);
85 }
86 return *this;
87 }
88
89 DETRAY_HOST_DEVICE constexpr auto operator++(int) -> iterator {
90 auto tmp(*this);
91 ++(*this);
92 return tmp;
93 }
95
98 DETRAY_HOST_DEVICE constexpr auto operator--() -> iterator &
99 requires std::bidirectional_iterator<range_itr_t>
100 {
101 m_range_iter =
102 m_range_begin + static_cast<difference_type>(*(--m_seq_iter));
103 return *this;
104 }
105
106 DETRAY_HOST_DEVICE constexpr auto operator--(int) -> iterator
107 requires std::bidirectional_iterator<range_itr_t>
108 {
109 auto tmp(*this);
110 --(*this);
111 return tmp;
112 }
113
115 DETRAY_HOST_DEVICE auto operator*() const {
116 return value_type(*m_seq_iter, *m_range_iter);
117 }
118
121 DETRAY_HOST_DEVICE constexpr auto operator+=(const difference_type j)
122 -> iterator &
123 requires std::random_access_iterator<range_itr_t>
124 {
125 detray::ranges::advance(m_seq_iter, j);
126 m_range_begin += static_cast<difference_type>(*m_seq_iter);
127 return *this;
128 }
129
132 DETRAY_HOST_DEVICE constexpr auto operator-=(const difference_type j)
133 -> iterator &
134 requires std::random_access_iterator<range_itr_t> &&
135 std::random_access_iterator<sequence_itr_t>
136 {
137 return *this += -j;
138 }
139
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>
144 {
145 const auto index{m_seq_iter[i]};
146 return value_type(index, m_range_begin[index]);
147 }
148
149 private:
151 DETRAY_HOST_DEVICE
152 friend constexpr auto operator==(const iterator &lhs, const iterator &rhs)
153 -> bool {
154 return (lhs.m_seq_iter == rhs.m_seq_iter);
155 }
156
158 DETRAY_HOST_DEVICE
159 friend constexpr auto operator<=>(const iterator &lhs, const iterator &rhs)
160 requires detray::ranges::random_access_iterator<sequence_itr_t>
161 {
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;
167 }
168 if (l > r || (l == r && l > r)) {
169 return std::strong_ordering::greater;
170 }
171 return std::strong_ordering::equivalent;
172#else
173 return (lhs.m_seq_iter <=> rhs.m_seq_iter);
174#endif
175 }
176
181 DETRAY_HOST_DEVICE friend constexpr auto operator+(const iterator &itr,
182 const difference_type j)
183 -> iterator
184 requires std::random_access_iterator<range_itr_t>
185 {
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};
189 }
190
195 DETRAY_HOST_DEVICE friend constexpr auto operator+(const difference_type j,
196 const iterator &itr)
197 -> iterator
198 requires std::random_access_iterator<range_itr_t>
199 {
200 return itr + j;
201 }
202
207 DETRAY_HOST_DEVICE friend constexpr auto operator-(const iterator &itr,
208 const difference_type j)
209 -> iterator
210 requires std::random_access_iterator<range_itr_t>
211 {
212 return itr + (-j);
213 }
214
216 DETRAY_HOST_DEVICE friend constexpr auto operator-(const iterator &lhs,
217 const iterator &rhs)
218 -> difference_type
219 requires std::random_access_iterator<range_itr_t> &&
220 std::random_access_iterator<sequence_itr_t>
221 {
222 return lhs.m_seq_iter - rhs.m_seq_iter;
223 }
224
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{};
229 };
230
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{};
235
236 public:
238 using iterator_t = iterator;
239
241 constexpr pick_view() = default;
242
246 template <detray::ranges::range range_t, detray::ranges::range sequence_t>
247 DETRAY_HOST_DEVICE constexpr pick_view(range_t &&range, sequence_t &&seq)
248 : m_range_begin{detray::ranges::begin(std::forward<range_t>(range))},
249 m_range_end{detray::ranges::end(std::forward<range_t>(range))},
250 m_seq_begin{detray::ranges::cbegin(std::forward<sequence_t>(seq))},
251 m_seq_end{detray::ranges::cend(std::forward<sequence_t>(seq))} {}
252
254 DETRAY_HOST_DEVICE
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};
258 }
259
261 DETRAY_HOST_DEVICE
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};
265 }
266
268 DETRAY_HOST_DEVICE
269 constexpr auto end() -> iterator {
270 return {m_range_begin, m_range_begin, m_seq_end, m_seq_end};
271 }
272
275 DETRAY_HOST_DEVICE
276 constexpr auto data() const -> const typename iterator_t::value_type * {
277 return std::addressof(
278 *(m_range_begin + static_cast<difference_t>(*m_seq_begin)));
279 }
280
283 DETRAY_HOST_DEVICE
284 constexpr auto data() -> typename iterator_t::value_type * {
285 return std::addressof(
286 *(m_range_begin + static_cast<difference_t>(*m_seq_begin)));
287 }
288
291 DETRAY_HOST_DEVICE
292 constexpr auto size() const noexcept {
293 return detray::ranges::distance(m_seq_begin, m_seq_end);
294 }
295
298 DETRAY_HOST_DEVICE
299 constexpr auto front() noexcept {
300 return std::pair<index_t, value_t &>(
301 *m_seq_begin,
302 *detray::ranges::next(m_range_begin,
303 static_cast<difference_t>(*m_seq_begin)));
304 }
305
308 DETRAY_HOST_DEVICE
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)));
315 }
316
320 DETRAY_HOST_DEVICE
321 constexpr auto operator[](const dindex i) const {
322 index_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)));
327 }
328};
329
330namespace views {
331
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>>;
342
343 constexpr pick() = default;
344
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)) {}
350
354 template <detray::ranges::range range_t,
355 detray::ranges::input_range deduced_sequence_t>
356 DETRAY_HOST_DEVICE constexpr pick(range_t &&range, deduced_sequence_t &&seq)
357 : base_type(std::forward<range_t>(range), seq),
358 m_seq{std::forward<deduced_sequence_t>(seq)} {}
359
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));
370 }
371
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);
382 }
383
387 DETRAY_HOST_DEVICE
388 pick &operator=(const pick &other) {
389 base_type::operator=(other);
390 m_seq = other.m_seq;
391 return *this;
392 }
393
394 private:
395 sequence_t m_seq{};
396};
397
398// deduction guides>
399DETRAY_HOST_DEVICE_DEDUCTION_GUIDE pick()
400 -> pick<detray::ranges::iterator_t<detray::ranges::views::empty<int>>,
402
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>>,
406 sequence_t>;
407
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>>,
411 sequence_t>;
412
413} // namespace views
414
415} // namespace detray::ranges
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 category concepts.
Definition ranges.hpp:107
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