From e4aabc7feb86099135baa013b8992d989c9b74f6 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Tue, 21 Jun 2022 18:11:36 +0200 Subject: [PATCH] adjacency_matrix: single edge iterator --- TODO | 2 - src/entt/graph/adjacency_matrix.hpp | 106 ++++++---------------------- 2 files changed, 23 insertions(+), 85 deletions(-) diff --git a/TODO b/TODO index ef65c91ce..6b22fed7c 100644 --- a/TODO +++ b/TODO @@ -13,8 +13,6 @@ DOC: * update entity doc when the storage based model is in place WIP: -* refine graph iterators a little -* add directed/undirected support to dot * dense_map/set and registry: move ctor/op should be noexcept (op is conditionally noexcept though) * "replace" organizer with flow * add storage getter for filters to views and groups diff --git a/src/entt/graph/adjacency_matrix.hpp b/src/entt/graph/adjacency_matrix.hpp index 02666910d..457a1bca2 100644 --- a/src/entt/graph/adjacency_matrix.hpp +++ b/src/entt/graph/adjacency_matrix.hpp @@ -21,7 +21,7 @@ namespace entt { namespace internal { template -class row_edge_iterator { +class edge_iterator { using size_type = std::size_t; public: @@ -31,27 +31,29 @@ public: using difference_type = std::ptrdiff_t; using iterator_category = std::input_iterator_tag; - constexpr row_edge_iterator() noexcept + constexpr edge_iterator() noexcept : it{}, vert{}, pos{}, - last{} {} + last{}, + offset{} {} - constexpr row_edge_iterator(It base, const size_type vertices, const size_type from, const size_type to) noexcept + constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept : it{std::move(base)}, vert{vertices}, pos{from}, - last{to} { - for(; pos != last && !it[pos]; ++pos) {} + last{to}, + offset{step} { + for(; pos != last && !it[pos]; pos += offset) {} } - constexpr row_edge_iterator &operator++() noexcept { - for(++pos; pos != last && !it[pos]; ++pos) {} + constexpr edge_iterator &operator++() noexcept { + for(pos += offset; pos != last && !it[pos]; pos += offset) {} return *this; } - constexpr row_edge_iterator operator++(int) noexcept { - row_edge_iterator orig = *this; + constexpr edge_iterator operator++(int) noexcept { + edge_iterator orig = *this; return ++(*this), orig; } @@ -64,85 +66,23 @@ public: } template - friend constexpr bool operator==(const row_edge_iterator &, const row_edge_iterator &) noexcept; + friend constexpr bool operator==(const edge_iterator &, const edge_iterator &) noexcept; private: It it; size_type vert; size_type pos; size_type last; + size_type offset{}; }; template -[[nodiscard]] inline constexpr bool operator==(const row_edge_iterator &lhs, const row_edge_iterator &rhs) noexcept { +[[nodiscard]] inline constexpr bool operator==(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { return lhs.pos == rhs.pos; } template -[[nodiscard]] inline constexpr bool operator!=(const row_edge_iterator &lhs, const row_edge_iterator &rhs) noexcept { - return !(lhs == rhs); -} - -template -class col_edge_iterator { - using size_type = std::size_t; - -public: - using value_type = std::pair; - using pointer = input_iterator_pointer; - using reference = value_type; - using difference_type = std::ptrdiff_t; - using iterator_category = std::input_iterator_tag; - - constexpr col_edge_iterator() noexcept - : it{}, - vert{}, - pos{}, - last{} {} - - constexpr col_edge_iterator(It base, const size_type vertices, const size_type from, const size_type to) noexcept - : it{std::move(base)}, - vert{vertices}, - pos{from}, - last{to} { - for(; pos != last && !it[pos]; pos += vert) {} - } - - constexpr col_edge_iterator &operator++() noexcept { - for(pos += vert; pos != last && !it[pos]; pos += vert) {} - return *this; - } - - constexpr col_edge_iterator operator++(int) noexcept { - col_edge_iterator orig = *this; - return ++(*this), orig; - } - - [[nodiscard]] constexpr reference operator*() const noexcept { - return *operator->(); - } - - [[nodiscard]] constexpr pointer operator->() const noexcept { - return std::make_pair(pos / vert, pos % vert); - } - - template - friend constexpr bool operator==(const col_edge_iterator &, const col_edge_iterator &) noexcept; - -private: - It it; - size_type vert; - size_type pos; - size_type last; -}; - -template -[[nodiscard]] inline constexpr bool operator==(const col_edge_iterator &lhs, const col_edge_iterator &rhs) noexcept { - return lhs.pos == rhs.pos; -} - -template -[[nodiscard]] inline constexpr bool operator!=(const col_edge_iterator &lhs, const col_edge_iterator &rhs) noexcept { +[[nodiscard]] inline constexpr bool operator!=(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { return !(lhs == rhs); } @@ -177,11 +117,11 @@ public: /*! @brief Vertex iterator type. */ using vertex_iterator = iota_iterator; /*! @brief Edge iterator type. */ - using edge_iterator = internal::row_edge_iterator; + using edge_iterator = internal::edge_iterator; /*! @brief Out edge iterator type. */ - using out_edge_iterator = internal::row_edge_iterator; + using out_edge_iterator = edge_iterator; /*! @brief In edge iterator type. */ - using in_edge_iterator = internal::col_edge_iterator; + using in_edge_iterator = edge_iterator; /*! @brieg Graph category tag. */ using graph_category = Category; @@ -307,7 +247,7 @@ public: [[nodiscard]] iterable_adaptor edges() const noexcept { const auto it = matrix.cbegin(); const auto sz = matrix.size(); - return {{it, vert, 0u, sz}, {it, vert, sz, sz}}; + return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}}; } /** @@ -319,7 +259,7 @@ public: const auto it = matrix.cbegin(); const auto from = vertex * vert; const auto to = vertex * vert + vert; - return {{it, vert, from, to}, {it, vert, to, to}}; + return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}}; } /** @@ -331,7 +271,7 @@ public: const auto it = matrix.cbegin(); const auto from = vertex; const auto to = vert * (vert - 1u) + vertex; - return {{it, vert, from, to}, {it, vert, to, to}}; + return {{it, vert, from, to, vert}, {it, vert, to, to, vert}}; } /** @@ -366,7 +306,7 @@ public: } const auto inserted = !std::exchange(matrix[pos], 1u); - return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size()}, inserted}; + return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted}; } /**