Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:04

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 // Project include(s)
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 // System include(s)
0019 #include <concepts>
0020 #include <iterator>
0021 #include <type_traits>
0022 
0023 namespace detray::ranges {
0024 
0025 /// @brief Range factory that produces a sequence of values.
0026 ///
0027 /// @see https://en.cppreference.com/w/cpp/ranges/iota_view
0028 ///
0029 /// @tparam incr_t the incrementable type that makes up the sequence
0030 ///
0031 /// @note If given single value, does not do infinite iteration, but only jumps
0032 ///       to next value.
0033 /// @note Is not fit for lazy evaluation.
0034 template <std::incrementable incr_t>
0035 class iota_view : public detray::ranges::view_interface<iota_view<incr_t>> {
0036  private:
0037   /// @brief Nested iterator to generate a range of values on demand.
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     /// Parametrized Constructor
0054     DETRAY_HOST_DEVICE constexpr explicit iterator(incr_t i) : m_i{i} {}
0055 
0056     /// Increment the index
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       // Check if the round trip between difference type and incrementor
0086       // type is valid.
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     /// @returns the current value in the sequence - copy
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     /// Current value of sequence
0149     incr_t m_i{};
0150   };
0151 
0152   /// Start and end values of the sequence
0153   incr_t m_start;
0154   incr_t m_end;
0155 
0156  public:
0157   using iterator_t = iterator;
0158 
0159   /// Default constructor (only works if @c imrementable_t is default
0160   /// constructible)
0161   constexpr iota_view()
0162     requires std::default_initializable<incr_t>
0163   = default;
0164 
0165   /// Construct from an @param interval that defines start and end values.
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   /// Construct from a @param start start and @param end value.
0173   DETRAY_HOST_DEVICE constexpr iota_view(incr_t start, incr_t end)
0174       : m_start{start}, m_end{end} {}
0175 
0176   /// Construct from just a @param start value to represent a single value seq
0177   DETRAY_HOST_DEVICE
0178   constexpr explicit iota_view(incr_t start)
0179       : m_start{start}, m_end{start + 1} {}
0180 
0181   /// @return start position of range on container.
0182   DETRAY_HOST_DEVICE
0183   constexpr auto begin() const -> iterator_t { return iterator_t{m_start}; }
0184 
0185   /// @return sentinel of a sequence.
0186   DETRAY_HOST_DEVICE
0187   constexpr auto end() const -> iterator_t { return iterator_t{m_end}; }
0188 
0189   /// @returns the span of the sequence
0190   DETRAY_HOST_DEVICE
0191   constexpr auto size() const -> incr_t { return m_end - m_start; }
0192 };
0193 
0194 namespace views {
0195 
0196 /// @brief interface type to construct a @c iota_view with CTAD
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 // deduction guides
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 }  // namespace views
0228 
0229 }  // namespace detray::ranges