Back to home page

EIC code displayed by LXR

 
 

    


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

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/empty.hpp"
0016 #include "detray/utils/ranges/ranges.hpp"
0017 
0018 // System include(s)
0019 #include <type_traits>
0020 
0021 namespace detray::ranges {
0022 
0023 namespace detail {
0024 /// @brief Implements a subrange by providing start and end iterators on
0025 /// another range.
0026 ///
0027 /// @see https://en.cppreference.com/w/cpp/ranges/subrange
0028 ///
0029 /// @tparam range_t the iterable which to constrain to a subrange.
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   /// Default constructor
0039   constexpr subrange_view() = default;
0040 
0041   /// Construct from an @param start and @param end iterator pair.
0042   DETRAY_HOST_DEVICE constexpr subrange_view(iterator_t start, iterator_t end)
0043       : m_begin{start}, m_end{end} {}
0044 
0045   /// @return start position of range.
0046   DETRAY_HOST_DEVICE
0047   constexpr auto begin() -> iterator_t { return m_begin; }
0048 
0049   /// @return sentinel of the range.
0050   DETRAY_HOST_DEVICE
0051   constexpr auto end() -> iterator_t { return m_end; }
0052 
0053   /// @return start position of the range - const
0054   DETRAY_HOST_DEVICE
0055   constexpr auto begin() const -> const_iterator_t { return m_begin; }
0056 
0057   /// @return sentinel of the range.
0058   DETRAY_HOST_DEVICE
0059   constexpr auto end() const -> const_iterator_t { return m_end; }
0060 
0061   /// Equality operator
0062   ///
0063   /// @param rhs the subrange to compare with
0064   ///
0065   /// @returns whether the two subranges are equal
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   /// Start and end position of the subrange
0073   iterator_t m_begin;
0074   iterator_t m_end;
0075 };
0076 
0077 }  // namespace detail
0078 
0079 /// @brief interface type to construct a @c subrange_view with CTAD
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   /// Default constructor
0088   constexpr subrange() = default;
0089 
0090   /// Construct from a @param range and an index range @param pos.
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   /// Construct from an @param start and @param end iterator pair.
0096   DETRAY_HOST_DEVICE constexpr subrange(iterator_t start, iterator_t end)
0097       : base_type{start, end} {}
0098 
0099   /// Construct from a @param range.
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   /// Construct from a @param range and starting position @param pos. Used
0106   /// as an overload when only a single position is needed.
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   /// Construct from a @param range and an index range @param pos.
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   /// Call operator for range composition
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   /// @returns an iterator over the @param range at a position taken from
0133   /// the I-th element of @param pos
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   /// Index range that defines the subrange
0144   index_range_t m_pos{};
0145 };
0146 
0147 // deduction guides
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 /// @see https://en.cppreference.com/w/cpp/ranges/borrowed_iterator_t
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 }  // namespace detray::ranges