ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
iota.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/concepts.hpp"
15#include "detray/utils/ranges/detail/iterator_functions.hpp"
16#include "detray/utils/ranges/ranges.hpp"
17
18// System include(s)
19#include <concepts>
20#include <iterator>
21#include <type_traits>
22
23namespace detray::ranges {
24
34template <std::incrementable incr_t>
35class iota_view : public detray::ranges::view_interface<iota_view<incr_t>> {
36 private:
38 struct iterator {
39 using difference_type = std::ptrdiff_t;
40 using value_type = incr_t;
41 using pointer = incr_t *;
42 using reference = incr_t;
43 using iterator_category =
44 std::conditional_t<concepts::random_access_incrementable<incr_t> &&
45 std::totally_ordered<incr_t>,
46 detray::ranges::random_access_iterator_tag,
47 detray::ranges::bidirectional_iterator_tag>;
48
49 constexpr iterator()
50 requires std::default_initializable<incr_t>
51 = default;
52
54 DETRAY_HOST_DEVICE constexpr explicit iterator(incr_t i) : m_i{i} {}
55
58 DETRAY_HOST_DEVICE
59 constexpr auto operator++() -> iterator & {
60 ++m_i;
61 return *this;
62 }
63
64 DETRAY_HOST_DEVICE constexpr auto operator++(int) -> iterator {
65 auto tmp(*this);
66 ++(*this);
67 return tmp;
68 }
69 DETRAY_HOST_DEVICE
70 constexpr auto operator--() -> iterator & {
71 --m_i;
72 return *this;
73 }
74
75 DETRAY_HOST_DEVICE constexpr auto operator--(int) -> iterator {
76 auto tmp(*this);
77 --(*this);
78 return tmp;
79 }
80
81 DETRAY_HOST_DEVICE constexpr iterator &operator+=(const difference_type n)
83 {
84 difference_type nv = static_cast<difference_type>(m_i) + n;
85 // Check if the round trip between difference type and incrementor
86 // type is valid.
87 assert(static_cast<difference_type>(static_cast<incr_t>(nv)) == nv);
88 m_i = static_cast<incr_t>(nv);
89 return *this;
90 }
91
92 DETRAY_HOST_DEVICE friend constexpr iterator operator+(
93 const iterator &i, const difference_type n)
95 {
96 return iterator(i.m_i + n);
97 }
98
99 DETRAY_HOST_DEVICE friend constexpr iterator operator+(
100 const difference_type n, const iterator &i)
102 {
103 return iterator(i.m_i + n);
104 }
105
106 DETRAY_HOST_DEVICE constexpr iterator &operator-=(const difference_type n)
108 {
109 m_i -= n;
110 return *this;
111 }
112
113 DETRAY_HOST_DEVICE friend constexpr iterator operator-(
114 const iterator &i, const difference_type n)
116 {
117 return iterator(i.m_i - n);
118 }
119
120 DETRAY_HOST_DEVICE friend constexpr difference_type operator-(
121 const iterator &i, const iterator &j)
123 {
124 return i.m_i - j.m_i;
125 }
127
129 DETRAY_HOST_DEVICE
130 constexpr auto operator*() const
131 noexcept(std::is_nothrow_copy_constructible_v<incr_t>) -> incr_t {
132 return m_i;
133 }
134
135 DETRAY_HOST_DEVICE
136 constexpr incr_t operator[](const difference_type n) const
138 {
139 return static_cast<incr_t>(m_i + n);
140 }
141
142 private:
143 DETRAY_HOST_DEVICE
144 friend constexpr auto operator<=>(const iterator &lhs, const iterator &rhs)
145 requires std::totally_ordered<incr_t>
146 = default;
147
149 incr_t m_i{};
150 };
151
153 incr_t m_start;
154 incr_t m_end;
155
156 public:
158 using iterator_t = iterator;
159
162 constexpr iota_view()
163 requires std::default_initializable<incr_t>
164 = default;
165
168 template <concepts::interval interval_t>
169 requires(!std::same_as<interval_t, iota_view>)
170 DETRAY_HOST_DEVICE constexpr explicit iota_view(interval_t &&interval)
171 : m_start{detray::detail::get<0>(interval)},
172 m_end{detray::detail::get<1>(interval)} {
173 assert(m_start <= m_end);
174 }
175
179 DETRAY_HOST_DEVICE constexpr iota_view(incr_t start, incr_t end)
180 : m_start{start}, m_end{end} {
181 assert(m_start <= m_end);
182 }
183
186 DETRAY_HOST_DEVICE
187 constexpr explicit iota_view(incr_t start)
188 : m_start{start}, m_end{start + 1} {
189 assert(m_start <= m_end);
190 }
191
193 DETRAY_HOST_DEVICE
194 constexpr auto begin() const -> iterator_t { return iterator_t{m_start}; }
195
197 DETRAY_HOST_DEVICE
198 constexpr auto end() const -> iterator_t { return iterator_t{m_end}; }
199
201 DETRAY_HOST_DEVICE
202 constexpr auto size() const -> incr_t { return m_end - m_start; }
203};
204
205namespace views {
206
210template <std::incrementable incr_t>
211struct iota : public detray::ranges::iota_view<incr_t> {
214
215 constexpr iota()
216 requires std::default_initializable<incr_t>
217 = default;
218
221 template <concepts::interval interval_t>
222 requires(!std::same_as<interval_t, iota>)
223 DETRAY_HOST_DEVICE constexpr explicit iota(interval_t &&interval)
224 : base_type(std::forward<interval_t>(interval)) {}
225
229 DETRAY_HOST_DEVICE constexpr iota(incr_t start, incr_t end)
230 : base_type(start, end) {}
231
234 DETRAY_HOST_DEVICE constexpr explicit iota(incr_t start) : base_type(start) {}
235};
236
237// deduction guides
238template <concepts::interval interval_t>
239DETRAY_HOST_DEVICE_DEDUCTION_GUIDE iota(interval_t &&interval)
240 -> iota<std::remove_cvref_t<decltype(detray::detail::get<0>(interval))>>;
241
242template <concepts::index I>
243DETRAY_HOST_DEVICE_DEDUCTION_GUIDE iota(I start, I end) -> iota<I>;
244
245template <concepts::index I>
246DETRAY_HOST_DEVICE_DEDUCTION_GUIDE iota(I start) -> iota<I>;
247
248} // namespace views
249
250} // namespace detray::ranges
Range factory that produces a sequence of values.
Definition iota.hpp:35
constexpr iota_view()=default
Default constructor (only works if imrementable_t is default constructible).
constexpr auto end() const -> iterator_t
Definition iota.hpp:198
constexpr auto begin() const -> iterator_t
Definition iota.hpp:194
constexpr iota_view(incr_t start)
Construct from just a start value to represent a single value seq.
Definition iota.hpp:187
constexpr iota_view(incr_t start, incr_t end)
Construct from a start start and end value.
Definition iota.hpp:179
constexpr auto size() const -> incr_t
Definition iota.hpp:202
iterator iterator_t
Iterator over generated values in the requested sequence.
Definition iota.hpp:158
Defines a detray 'view'.
Definition ranges.hpp:190
constexpr decltype(auto) operator[](const dindex i) const
Definition ranges.hpp:292
Concept that checks whether a type can be incremented with arbitrary integer values.
Definition concepts.hpp:52
Type list concepts.
Definition concepts.hpp:17
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 iota(incr_t start)
Construct the adaptor for a one-value sequence.
Definition iota.hpp:234
constexpr iota(incr_t start, incr_t end)
Construct the adaptor from a start and one-past-the-end value.
Definition iota.hpp:229
detray::ranges::iota_view< incr_t > base_type
Base sequence view implementation.
Definition iota.hpp:213