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 &current) {
+    reverse_iter (containing_node, [&segments] (const Node &current) {
       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

Reply via email to