diff --git a/include/podio/detail/LinkCollectionIterator.h b/include/podio/detail/LinkCollectionIterator.h index 35fcba8d0..b51c2fb40 100644 --- a/include/podio/detail/LinkCollectionIterator.h +++ b/include/podio/detail/LinkCollectionIterator.h @@ -3,6 +3,7 @@ #include "podio/detail/LinkFwd.h" #include "podio/utilities/MaybeSharedPtr.h" +#include namespace podio { template @@ -11,20 +12,33 @@ class LinkCollectionIteratorT { using LinkObjT = LinkObj; public: + using value_type = LinkType; + using difference_type = ptrdiff_t; + using reference = LinkType; + using pointer = LinkType*; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::input_iterator_tag; + LinkCollectionIteratorT(size_t index, const LinkObjPointerContainer* coll) : m_index(index), m_object(podio::utils::MaybeSharedPtr{nullptr}), m_collection(coll) { } - - LinkCollectionIteratorT(const LinkCollectionIteratorT&) = delete; - LinkCollectionIteratorT& operator=(const LinkCollectionIteratorT&) = delete; + LinkCollectionIteratorT() = default; + LinkCollectionIteratorT(const LinkCollectionIteratorT&) = default; + LinkCollectionIteratorT& operator=(const LinkCollectionIteratorT&) = default; + LinkCollectionIteratorT(LinkCollectionIteratorT&&) = default; + LinkCollectionIteratorT& operator=(LinkCollectionIteratorT&&) = default; + ~LinkCollectionIteratorT() = default; bool operator!=(const LinkCollectionIteratorT& other) const { - return m_index != other.m_index; // TODO: may not be complete + return m_index != other.m_index; } - LinkType operator*() { - m_object.m_obj = podio::utils::MaybeSharedPtr((*m_collection)[m_index]); - return m_object; + bool operator==(const LinkCollectionIteratorT& other) const { + return m_index == other.m_index; + } + + LinkType operator*() const { + return LinkType{podio::utils::MaybeSharedPtr((*m_collection)[m_index])}; } LinkType* operator->() { @@ -37,10 +51,16 @@ class LinkCollectionIteratorT { return *this; } + LinkCollectionIteratorT operator++(int) { + auto copy = *this; + ++m_index; + return copy; + } + private: - size_t m_index; - LinkType m_object; - const LinkObjPointerContainer* m_collection; + size_t m_index{0}; + LinkType m_object{podio::utils::MaybeSharedPtr{nullptr}}; + const LinkObjPointerContainer* m_collection{nullptr}; }; } // namespace podio diff --git a/tests/unittests/std_interoperability.cpp b/tests/unittests/std_interoperability.cpp index 8f34376bf..e840d951e 100644 --- a/tests/unittests/std_interoperability.cpp +++ b/tests/unittests/std_interoperability.cpp @@ -1,6 +1,7 @@ #include "datamodel/ExampleHit.h" #include "datamodel/ExampleHitCollection.h" #include "datamodel/MutableExampleHit.h" +#include "podio/LinkCollection.h" #include @@ -1184,5 +1185,22 @@ TEST_CASE("Collection and unsupported std ranges algorithms", "[collection][rang DOCUMENTED_STATIC_FAILURE(is_range_fillable); } +TEST_CASE("LinkCollectionIterator and iterator concepts", "[links][iterator][std]") { + using link_iterator = podio::LinkCollectionIteratorT; + using link_const_iterator = podio::LinkCollectionIteratorT; + + STATIC_REQUIRE(std::input_iterator); + STATIC_REQUIRE(std::input_iterator); +} + +TEST_CASE("LinkCollection and range concepts", "[links][iterator][std]") { + using link_collection = podio::LinkCollection; + + STATIC_REQUIRE(std::ranges::input_range); + STATIC_REQUIRE(std::ranges::sized_range); + STATIC_REQUIRE(std::ranges::common_range); + STATIC_REQUIRE(std::ranges::viewable_range); +} + #undef DOCUMENTED_STATIC_FAILURE #undef DOCUMENTED_FAILURE