diff --git a/Core/include/Acts/EventData/SpacePointContainer.hpp b/Core/include/Acts/EventData/SpacePointContainer.hpp index ef2c183e8a29..f34dda19487f 100644 --- a/Core/include/Acts/EventData/SpacePointContainer.hpp +++ b/Core/include/Acts/EventData/SpacePointContainer.hpp @@ -12,9 +12,9 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/EventData/SpacePointData.hpp" #include "Acts/EventData/SpacePointProxy.hpp" -#include "Acts/EventData/SpacePointProxyIterator.hpp" #include "Acts/EventData/Utils.hpp" #include "Acts/Utilities/HashedString.hpp" +#include "Acts/Utilities/Iterator.hpp" #include #include @@ -67,19 +67,22 @@ class SpacePointContainer { public: friend class Acts::SpacePointProxy< Acts::SpacePointContainer>; - friend class Acts::SpacePointProxyIterator< - Acts::SpacePointContainer>; public: - using iterator = Acts::SpacePointProxyIterator< - Acts::SpacePointContainer>; - using const_iterator = iterator; - using SpacePointProxyType = Acts::SpacePointProxy>; + + using iterator = + ContainerIndexIterator, + SpacePointProxyType&, false>; + using const_iterator = + ContainerIndexIterator, + const SpacePointProxyType&, true>; + using ValueType = typename container_t::ValueType; using ProxyType = SpacePointProxyType; using value_type = ProxyType; + using size_type = std::size_t; public: // Constructors @@ -118,9 +121,15 @@ class SpacePointContainer { std::size_t size() const; - iterator begin() const; - iterator end() const; + iterator begin(); + iterator end(); + const_iterator cbegin() const; + const_iterator cend() const; + const_iterator begin() const; + const_iterator end() const; + ProxyType& at(const std::size_t n); + const ProxyType& at(const std::size_t n) const; const ValueType& sp(const std::size_t n) const; private: diff --git a/Core/include/Acts/EventData/SpacePointContainer.ipp b/Core/include/Acts/EventData/SpacePointContainer.ipp index 484aed7a3d0a..9a200f019fa1 100644 --- a/Core/include/Acts/EventData/SpacePointContainer.ipp +++ b/Core/include/Acts/EventData/SpacePointContainer.ipp @@ -104,13 +104,13 @@ std::size_t SpacePointContainer::size() const { } template class holder_t> -typename SpacePointContainer::iterator +typename SpacePointContainer::const_iterator SpacePointContainer::begin() const { return {*this, 0}; } template class holder_t> -typename SpacePointContainer::iterator +typename SpacePointContainer::const_iterator SpacePointContainer::end() const { return {*this, size()}; } diff --git a/Core/include/Acts/EventData/SpacePointProxyIterator.hpp b/Core/include/Acts/EventData/SpacePointProxyIterator.hpp deleted file mode 100644 index 93794195d04a..000000000000 --- a/Core/include/Acts/EventData/SpacePointProxyIterator.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2024 CERN for the benefit of the Acts project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#pragma once - -#include "Acts/EventData/SpacePointProxy.hpp" -#include "Acts/Utilities/Holders.hpp" - -namespace Acts { - -template -class SpacePointProxyIterator { - public: - using ContainerType = container_t; - using ProxyType = typename container_t::SpacePointProxyType; - - using iterator_category = std::random_access_iterator_tag; - using value_type = ProxyType; - using difference_type = std::ptrdiff_t; - using pointer = value_type*; - using reference = value_type&; - - public: - // Constructors - SpacePointProxyIterator(container_t&& container, std::size_t index) = delete; - SpacePointProxyIterator(const container_t& container, std::size_t index); - - SpacePointProxyIterator& operator++(); - SpacePointProxyIterator& operator--(); - SpacePointProxyIterator operator++(int); - SpacePointProxyIterator operator--(int); - - bool operator==(const SpacePointProxyIterator& other) const; - auto operator<=>(const SpacePointProxyIterator& other) const; - - SpacePointProxyIterator& operator+=(const std::size_t offset); - SpacePointProxyIterator& operator-=(const std::size_t offset); - - SpacePointProxyIterator operator+(const std::size_t offset) const; - SpacePointProxyIterator operator-(const std::size_t offset) const; - - difference_type operator-(const SpacePointProxyIterator& other) const; - - const value_type& operator*() const; - - private: - const container_t* m_container{nullptr}; - std::size_t m_index{0ul}; -}; - -} // namespace Acts - -#include "Acts/EventData/SpacePointProxyIterator.ipp" diff --git a/Core/include/Acts/EventData/SpacePointProxyIterator.ipp b/Core/include/Acts/EventData/SpacePointProxyIterator.ipp deleted file mode 100644 index 5318c3b6f285..000000000000 --- a/Core/include/Acts/EventData/SpacePointProxyIterator.ipp +++ /dev/null @@ -1,100 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2024 CERN for the benefit of the Acts project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -namespace Acts { - -// Implementation -template -SpacePointProxyIterator::SpacePointProxyIterator( - const container_t& container, std::size_t index) - : m_container(&container), m_index(index) {} - -template -SpacePointProxyIterator& -SpacePointProxyIterator::operator++() { - ++m_index; - return *this; -} - -template -SpacePointProxyIterator& -SpacePointProxyIterator::operator--() { - --m_index; - return *this; -} - -template -SpacePointProxyIterator -SpacePointProxyIterator::operator++(int) { - SpacePointProxyIterator other(*this); - ++m_index; - return other; -} - -template -SpacePointProxyIterator -SpacePointProxyIterator::operator--(int) { - SpacePointProxyIterator other(*this); - --m_index; - return other; -} - -template -bool SpacePointProxyIterator::operator==( - const SpacePointProxyIterator& other) const { - return m_container == other.m_container && m_index == other.m_index; -} - -template -auto SpacePointProxyIterator::operator<=>( - const SpacePointProxyIterator& other) const { - return m_index <=> other.m_index; -} - -template -SpacePointProxyIterator& -SpacePointProxyIterator::operator+=(const std::size_t offset) { - m_index += offset; - return *this; -} - -template -SpacePointProxyIterator& -SpacePointProxyIterator::operator-=(const std::size_t offset) { - m_index -= offset; - return *this; -} - -template -SpacePointProxyIterator -SpacePointProxyIterator::operator+( - const std::size_t offset) const { - return SpacePointProxyIterator(*m_container, m_index + offset); -} - -template -SpacePointProxyIterator -SpacePointProxyIterator::operator-( - const std::size_t offset) const { - return SpacePointProxyIterator(*m_container, m_index - offset); -} - -template -typename SpacePointProxyIterator::difference_type -SpacePointProxyIterator::operator-( - const SpacePointProxyIterator& other) const { - return m_index - other.m_index; -} - -template -const typename SpacePointProxyIterator::value_type& -SpacePointProxyIterator::operator*() const { - return m_container->proxy(m_index); -} - -} // namespace Acts diff --git a/Core/include/Acts/EventData/TrackContainer.hpp b/Core/include/Acts/EventData/TrackContainer.hpp index 24702870bdb0..0b898e296b86 100644 --- a/Core/include/Acts/EventData/TrackContainer.hpp +++ b/Core/include/Acts/EventData/TrackContainer.hpp @@ -19,6 +19,8 @@ #include "Acts/EventData/Utils.hpp" #include "Acts/Utilities/HashedString.hpp" #include "Acts/Utilities/Holders.hpp" +#include "Acts/Utilities/Iterator.hpp" +#include "Acts/Utilities/TypeTraits.hpp" #include "Acts/Utilities/UnitVectors.hpp" #include @@ -78,6 +80,12 @@ class TrackContainer { using ConstTrackStateProxy = typename MultiTrajectory::ConstTrackStateProxy; + using size_type = IndexType; + using iterator = + Acts::ContainerIndexIterator; + using const_iterator = + Acts::ContainerIndexIterator; + #ifndef DOXYGEN friend TrackProxy; friend ConstTrackProxy; @@ -148,6 +156,21 @@ class TrackContainer { return {*this, itrack}; } + /// Get a const track proxy for a track index + /// @param itrack the track index in the container + /// @return A const track proxy for the index + ConstTrackProxy at(IndexType itrack) const { return getTrack(itrack); } + + /// Get a mutable track proxy for a track index + /// @note Only available if the track container is not read-only + /// @param itrack the track index in the container + /// @return A mutable track proxy for the index + TrackProxy at(IndexType itrack) + requires(!ReadOnly) + { + return {*this, itrack}; + } + /// Add a track to the container. Note this only creates the logical track and /// allocates memory. You can combine this with @c getTrack to obtain a track proxy /// @note Only available if the track container is not read-only @@ -184,36 +207,28 @@ class TrackContainer { /// Get a mutable iterator to the first track in the container /// @note Only available if the track container is not read-only /// @return a mutable iterator to the first track - auto begin() + iterator begin() requires(!ReadOnly) { - return detail_tc::TrackProxyIterator, - TrackProxy, false>{*this, 0}; + return iterator{*this, 0}; } /// Get a past-the-end iterator for this container /// @note Only available if the track container is not read-only /// @return a past-the-end iterator - auto end() + iterator end() requires(!ReadOnly) { - return detail_tc::TrackProxyIterator, - TrackProxy, false>{*this, size()}; + return iterator{*this, size()}; } /// Get an const iterator to the first track in the container /// @return a const iterator to the first track - auto begin() const { - return detail_tc::TrackProxyIterator, - ConstTrackProxy, true>{*this, 0}; - } + const_iterator begin() const { return const_iterator{*this, 0}; } /// Get a past-the-end iterator for this container /// @return a past-the-end iterator - auto end() const { - return detail_tc::TrackProxyIterator, - ConstTrackProxy, true>{*this, size()}; - } + const_iterator end() const { return const_iterator{*this, size()}; } /// @} @@ -411,8 +426,8 @@ class TrackContainer { } } - detail_tc::ConstIf, ReadOnly> m_container; - detail_tc::ConstIf, ReadOnly> m_traj; + const_if_t> m_container; + const_if_t> m_traj; }; template diff --git a/Core/include/Acts/EventData/TrackProxy.hpp b/Core/include/Acts/EventData/TrackProxy.hpp index 8323878dd3cd..2ef517abe192 100644 --- a/Core/include/Acts/EventData/TrackProxy.hpp +++ b/Core/include/Acts/EventData/TrackProxy.hpp @@ -17,6 +17,7 @@ #include "Acts/EventData/TrackProxyConcept.hpp" #include "Acts/EventData/TrackStatePropMask.hpp" #include "Acts/Utilities/HashedString.hpp" +#include "Acts/Utilities/TypeTraits.hpp" #include "Acts/Utilities/UnitVectors.hpp" #include @@ -29,108 +30,6 @@ template class holder_t> class TrackContainer; -namespace detail_tc { -template -using ConstIf = std::conditional_t; - -/// Helper iterator to allow iteration over tracks via track proxies. -template -class TrackProxyIterator { - using ProxyType = proxy_t; - using IndexType = typename ProxyType::IndexType; - using ContainerType = container_t; - - public: - using iterator_category = std::random_access_iterator_tag; - using value_type = ProxyType; - using difference_type = std::ptrdiff_t; - using pointer = void; - using reference = void; - - TrackProxyIterator(container_t& container, IndexType itrack) - requires(!ReadOnly) - : m_container(&container), m_itrack(itrack) {} - - TrackProxyIterator(const container_t& container, IndexType itrack) - requires ReadOnly - : m_container(&container), m_itrack(itrack) {} - - TrackProxyIterator& operator++() { - m_itrack++; - return *this; - } - TrackProxyIterator& operator--() { - m_itrack--; - return *this; - } - - bool operator==(const TrackProxyIterator& other) const { - return m_container == other.m_container && m_itrack == other.m_itrack; - } - - auto operator<=>(const TrackProxyIterator& other) const { - return m_itrack <=> other.m_itrack; - } - - ProxyType operator*() const { return m_container->getTrack(m_itrack); } - - ProxyType operator*() - requires(!ReadOnly) - { - return m_container->getTrack(m_itrack); - } - - TrackProxyIterator operator[](difference_type n) const { - TrackProxyIterator copy = *this; - copy += n; - return copy; - }; - - TrackProxyIterator& operator+=(difference_type n) { - m_itrack += n; - return *this; - } - - TrackProxyIterator operator-=(difference_type n) { - m_itrack -= n; - return *this; - } - - friend difference_type operator-(const TrackProxyIterator& lhs, - const TrackProxyIterator& rhs) { - return lhs.m_itrack - rhs.m_itrack; - } - - friend TrackProxyIterator operator+(const TrackProxyIterator& lhs, - difference_type rhs) { - TrackProxyIterator copy = lhs; - copy += rhs; - return copy; - } - - friend TrackProxyIterator operator+(difference_type lhs, - const TrackProxyIterator& rhs) { - return rhs + lhs; - } - - friend TrackProxyIterator operator-(const TrackProxyIterator& lhs, - difference_type rhs) { - return lhs + (-rhs); - } - - friend TrackProxyIterator operator-(difference_type lhs, - const TrackProxyIterator& rhs) { - return rhs + (-lhs); - } - - private: - detail_lt::TransitiveConstPointer> - m_container; - IndexType m_itrack; -}; - -} // namespace detail_tc - /// Proxy class representing a single track. /// This class provides a **view** into an associated @ref TrackContainer, and /// has **reference semantics**. You can think of it as a pointer to a vector @@ -876,13 +775,14 @@ class TrackProxy { const auto& container() const { return *m_container; } private: - TrackProxy(detail_tc::ConstIf, - ReadOnly>& container, - IndexType itrack) + TrackProxy( + const_if_t>& + container, + IndexType itrack) : m_container{&container}, m_index{itrack} {} - detail_lt::TransitiveConstPointer, ReadOnly>> + detail_lt::TransitiveConstPointer< + const_if_t>> m_container; IndexType m_index; }; diff --git a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp index ab3ae4af1b9e..2749c0f14279 100644 --- a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp +++ b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp @@ -141,15 +141,6 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( Acts::CylindricalSpacePointGrid& grid, external_spacepoint_iterator_t spBegin, external_spacepoint_iterator_t spEnd, Acts::Extent& rRangeSPExtent) { - using iterated_value_t = - typename std::iterator_traits::value_type; - using iterated_t = typename std::remove_const< - typename std::remove_pointer::type>::type; - static_assert(!std::is_pointer::value, - "Iterator must contain pointers to space points"); - static_assert(std::is_same::value, - "Iterator does not contain type this class was templated with"); - if (!config.isInInternalUnits) { throw std::runtime_error( "SeedFinderConfig not in ACTS internal units in BinnedSPGroup"); diff --git a/Core/include/Acts/Utilities/Iterator.hpp b/Core/include/Acts/Utilities/Iterator.hpp new file mode 100644 index 000000000000..5a383f4be973 --- /dev/null +++ b/Core/include/Acts/Utilities/Iterator.hpp @@ -0,0 +1,130 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include +#include +#include +#include + +namespace Acts { +template +class ContainerIndexIterator { + public: + using value_type = Value; + using iterator_category = std::random_access_iterator_tag; + using container_type = + std::conditional_t; + using difference_type = std::ptrdiff_t; + + ContainerIndexIterator() : m_container(nullptr), m_index(0) {} + + ContainerIndexIterator(container_type& container, std::size_t index) + : m_container(&container), m_index(index) {} + + template + explicit ContainerIndexIterator( + const ContainerIndexIterator<_Container, OtherValue, OtherConst>& o) + requires(!OtherConst || Const) + : m_container(o.m_container), m_index(o.m_index) {} + + value_type operator*() const { + assert(m_container != nullptr); + return m_container->at(m_index); + } + + template + ContainerIndexIterator& operator=( + const ContainerIndexIterator<_Container, OtherValue, OtherConst>& o) + requires(!OtherConst || Const) + { + m_container = o.m_container; + m_index = o.m_index; + return *this; + } + + ContainerIndexIterator& operator++() { + ++m_index; + return *this; + } + + ContainerIndexIterator operator++(int) { + auto copy = *this; + ++*this; + return copy; + } + + ContainerIndexIterator& operator+=(const difference_type& i) { + m_index += i; + return *this; + } + + friend ContainerIndexIterator operator+(const ContainerIndexIterator& t, + const difference_type& i) { + return IteratorImpl(t.m_container, t.m_index + i); + } + + friend ContainerIndexIterator operator+(const difference_type& i, + const ContainerIndexIterator& t) { + return t + i; + } + + ContainerIndexIterator& operator--() { + --m_index; + return *this; + } + + ContainerIndexIterator operator--(int) { + auto copy = *this; + --*this; + return copy; + } + + ContainerIndexIterator& operator-=(const difference_type& i) { + m_index -= i; + return *this; + } + + friend ContainerIndexIterator operator-(const ContainerIndexIterator& t, + const difference_type& i) { + return IteratorImpl(t.m_container, t.m_index - i); + } + + template + friend difference_type operator-( + const ContainerIndexIterator& t, + const ContainerIndexIterator<_Container, OtherValue, OtherConst>& o) { + assert(t.m_container == o.m_container); + return t.m_index - o.m_index; + } + + value_type operator[](const difference_type& i) const { return *(*this + i); } + + template + std::strong_ordering operator<=>( + const ContainerIndexIterator<_Container, OtherValue, OtherConst>& o) + const { + if (m_container == o.m_container) { + return m_index <=> o.m_index; + } else { + return m_container <=> o.m_container; + } + } + + template + bool operator==(const ContainerIndexIterator<_Container, OtherValue, + OtherConst>& other) const { + return m_container == other.m_container && m_index == other.m_index; + } + + private: + container_type* m_container; + container_type::size_type m_index; +}; +} // namespace Acts diff --git a/Core/include/Acts/Utilities/TypeTraits.hpp b/Core/include/Acts/Utilities/TypeTraits.hpp new file mode 100644 index 000000000000..58f592f72d97 --- /dev/null +++ b/Core/include/Acts/Utilities/TypeTraits.hpp @@ -0,0 +1,16 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include + +namespace Acts { +template +using const_if_t = std::conditional_t; +} // namespace Acts diff --git a/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp b/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp index fc3aacc84e73..71e22646382d 100644 --- a/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp @@ -17,12 +17,15 @@ #include "Acts/EventData/detail/CalculateResiduals.hpp" #include "Acts/EventData/detail/ParameterTraits.hpp" #include "Acts/EventData/detail/PrintParameters.hpp" +#include "Acts/Utilities/Iterator.hpp" #include "ActsExamples/EventData/MeasurementConcept.hpp" #include +#include #include #include #include +#include #include #include #include @@ -58,7 +61,8 @@ using ConstVariableBoundMeasurementProxy = /// provide access to the individual measurements. class MeasurementContainer { public: - using Index = std::size_t; + using size_type = std::size_t; + using Index = size_type; template using FixedProxy = FixedMeasurementProxy; template @@ -81,6 +85,15 @@ class MeasurementContainer { /// @return The index of the added measurement Index addMeasurement(std::uint8_t size); + /// @brief Get a variable-size measurement proxy + /// @param index The index of the measurement + /// @return The variable-size measurement proxy + VariableProxy at(Index index); + /// @brief Get a const variable-size measurement proxy + /// @param index The index of the measurement + /// @return The const variable-size measurement proxy + ConstVariableProxy at(Index index) const; + /// @brief Get a variable-size measurement proxy /// @param index The index of the measurement /// @return The variable-size measurement proxy @@ -125,48 +138,11 @@ class MeasurementContainer { template FixedProxy emplaceMeasurement(Args&&... args); - template - class IteratorImpl { - public: - using value_type = - std::conditional_t; - using reference = value_type; - using pointer = value_type*; - using difference_type = std::ptrdiff_t; - using iterator_category = std::forward_iterator_tag; - - using Container = std::conditional_t; - - IteratorImpl(Container& container, std::size_t index) - : m_container(container), m_index(index) {} - - reference operator*() const { return m_container.getMeasurement(m_index); } - - pointer operator->() const { return &operator*(); } - - IteratorImpl& operator++() { - ++m_index; - return *this; - } - - IteratorImpl operator++(int) { - auto copy = *this; - ++*this; - return copy; - } - - bool operator==(const IteratorImpl& other) const { - return m_index == other.m_index; - } - - private: - Container& m_container; - Index m_index; - }; - - using iterator = IteratorImpl; - using const_iterator = IteratorImpl; + using iterator = + Acts::ContainerIndexIterator; + using const_iterator = + Acts::ContainerIndexIterator; iterator begin(); iterator end(); @@ -535,4 +511,7 @@ MeasurementContainer::FixedProxy MeasurementContainer::emplaceMeasurement( return meas; } +static_assert( + std::random_access_iterator && + std::random_access_iterator); } // namespace ActsExamples diff --git a/Examples/Framework/src/EventData/Measurement.cpp b/Examples/Framework/src/EventData/Measurement.cpp index d9ae3520d867..2ea9efa8e6e5 100644 --- a/Examples/Framework/src/EventData/Measurement.cpp +++ b/Examples/Framework/src/EventData/Measurement.cpp @@ -33,6 +33,16 @@ std::size_t MeasurementContainer::addMeasurement(std::uint8_t size) { return m_entries.size() - 1; } +MeasurementContainer::VariableProxy MeasurementContainer::at( + std::size_t index) { + return VariableProxy{*this, index}; +} + +MeasurementContainer::ConstVariableProxy MeasurementContainer::at( + std::size_t index) const { + return ConstVariableProxy{*this, index}; +} + MeasurementContainer::VariableProxy MeasurementContainer::getMeasurement( std::size_t index) { return VariableProxy{*this, index};