From: Owen Avery <powerboat9.ga...@gmail.com> gcc/rust/ChangeLog:
* resolve/rust-forever-stack.h (ForeverStack::to_canonical_path): Make const. (ForeverStack::to_rib): Add const overload. (ForeverStack::reverse_iter): Add const overloads. (ForeverStack::ConstDfsResult): Add. (ForeverStack::dfs): Add const overload. (ForeverStack::dfs_rib): Likewise. * resolve/rust-forever-stack.hxx (ForeverStack::reverse_iter): Add const overloads. (ForeverStack::dfs): Add const overload. (ForeverStack::to_canonical_path): Make const. (ForeverStack::dfs_rib): Likewise. (ForeverStack::to_rib): Add const overload. Signed-off-by: Owen Avery <powerboat9.ga...@gmail.com> --- gcc/rust/resolve/rust-forever-stack.h | 15 +++- gcc/rust/resolve/rust-forever-stack.hxx | 91 ++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index c24289d0c7e..8c5e207a70d 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -513,10 +513,11 @@ public: tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments); // FIXME: Documentation - tl::optional<Resolver::CanonicalPath> to_canonical_path (NodeId id); + tl::optional<Resolver::CanonicalPath> to_canonical_path (NodeId id) const; // FIXME: Documentation tl::optional<Rib &> to_rib (NodeId rib_id); + tl::optional<const Rib &> to_rib (NodeId rib_id) const; std::string as_debug_string (); @@ -579,9 +580,12 @@ private: /* Reverse iterate on `Node`s from the cursor, in an outwards fashion */ void reverse_iter (std::function<KeepGoing (Node &)> lambda); + void reverse_iter (std::function<KeepGoing (const Node &)> lambda) const; /* Reverse iterate on `Node`s from a specified one, in an outwards fashion */ void reverse_iter (Node &start, std::function<KeepGoing (Node &)> lambda); + void reverse_iter (const Node &start, + std::function<KeepGoing (const Node &)> lambda) const; Node &cursor (); const Node &cursor () const; @@ -617,11 +621,20 @@ private: Node &first; std::string second; }; + struct ConstDfsResult + { + const Node &first; + std::string second; + }; // FIXME: Documentation tl::optional<DfsResult> dfs (Node &starting_point, NodeId to_find); + tl::optional<ConstDfsResult> dfs (const Node &starting_point, + NodeId to_find) const; // FIXME: Documentation tl::optional<Rib &> dfs_rib (Node &starting_point, NodeId to_find); + tl::optional<const Rib &> dfs_rib (const Node &starting_point, + NodeId to_find) const; }; } // namespace Resolver2_0 diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 4a8b6b59d17..5a5a7c73f32 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -192,6 +192,14 @@ ForeverStack<N>::reverse_iter (std::function<KeepGoing (Node &)> lambda) return reverse_iter (cursor (), lambda); } +template <Namespace N> +void +ForeverStack<N>::reverse_iter ( + std::function<KeepGoing (const Node &)> lambda) const +{ + return reverse_iter (cursor (), lambda); +} + template <Namespace N> void ForeverStack<N>::reverse_iter (Node &start, @@ -212,6 +220,26 @@ ForeverStack<N>::reverse_iter (Node &start, } } +template <Namespace N> +void +ForeverStack<N>::reverse_iter ( + const Node &start, std::function<KeepGoing (const Node &)> lambda) const +{ + auto *tmp = &start; + + while (true) + { + auto keep_going = lambda (*tmp); + if (keep_going == KeepGoing::No) + return; + + if (tmp->is_root ()) + return; + + tmp = &tmp->parent.value (); + } +} + template <Namespace N> typename ForeverStack<N>::Node & ForeverStack<N>::cursor () @@ -507,22 +535,53 @@ ForeverStack<N>::dfs (ForeverStack<N>::Node &starting_point, NodeId to_find) return tl::nullopt; } +template <Namespace N> +tl::optional<typename ForeverStack<N>::ConstDfsResult> +ForeverStack<N>::dfs (const ForeverStack<N>::Node &starting_point, + NodeId to_find) const +{ + auto values = starting_point.rib.get_values (); + + for (auto &kv : values) + { + for (auto id : kv.second.ids_shadowable) + if (id == to_find) + return {{starting_point, kv.first}}; + for (auto id : kv.second.ids_non_shadowable) + if (id == to_find) + return {{starting_point, kv.first}}; + for (auto id : kv.second.ids_globbed) + if (id == to_find) + return {{starting_point, kv.first}}; + } + + for (auto &child : starting_point.children) + { + auto candidate = dfs (child.second, to_find); + + if (candidate.has_value ()) + return candidate; + } + + return tl::nullopt; +} + template <Namespace N> tl::optional<Resolver::CanonicalPath> -ForeverStack<N>::to_canonical_path (NodeId id) +ForeverStack<N>::to_canonical_path (NodeId id) const { // find the id in the current forever stack, starting from the root, // performing either a BFS or DFS once the Node containing the ID is found, go // back up to the root (parent().parent().parent()...) accumulate link // segments reverse them that's your canonical path - return dfs (root, id).map ([this, id] (DfsResult tuple) { + return dfs (root, id).map ([this, id] (ConstDfsResult tuple) { auto containing_node = tuple.first; auto name = tuple.second; auto segments = std::vector<Resolver::CanonicalPath> (); - reverse_iter (containing_node, [&segments] (Node ¤t) { + reverse_iter (containing_node, [&segments] (const Node ¤t) { if (current.is_root ()) return KeepGoing::No; @@ -581,6 +640,25 @@ ForeverStack<N>::dfs_rib (ForeverStack<N>::Node &starting_point, NodeId to_find) return tl::nullopt; } +template <Namespace N> +tl::optional<const Rib &> +ForeverStack<N>::dfs_rib (const ForeverStack<N>::Node &starting_point, + NodeId to_find) const +{ + if (starting_point.id == to_find) + return starting_point.rib; + + for (auto &child : starting_point.children) + { + auto candidate = dfs_rib (child.second, to_find); + + if (candidate.has_value ()) + return candidate; + } + + return tl::nullopt; +} + template <Namespace N> tl::optional<Rib &> ForeverStack<N>::to_rib (NodeId rib_id) @@ -588,6 +666,13 @@ ForeverStack<N>::to_rib (NodeId rib_id) return dfs_rib (root, rib_id); } +template <Namespace N> +tl::optional<const Rib &> +ForeverStack<N>::to_rib (NodeId rib_id) const +{ + return dfs_rib (root, rib_id); +} + template <Namespace N> void ForeverStack<N>::stream_rib (std::stringstream &stream, const Rib &rib, -- 2.45.2