guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

218/376: Make forceValueDeep work on values with cycles


From: Ludovic Courtès
Subject: 218/376: Make forceValueDeep work on values with cycles
Date: Wed, 28 Jan 2015 22:05:10 +0000

civodul pushed a commit to tag 1.8
in repository guix.

commit 831fc8ea21fc730388e9359fcafed279c8ec413d
Author: Eelco Dolstra <address@hidden>
Date:   Mon Sep 22 15:16:09 2014 +0200

    Make forceValueDeep work on values with cycles
---
 src/libexpr/eval.cc |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index f1212cd..43d8f13 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1183,17 +1183,28 @@ void ExprPos::eval(EvalState & state, Env & env, Value 
& v)
 
 void EvalState::forceValueDeep(Value & v)
 {
-    forceValue(v);
+    std::set<const Value *> seen;
 
-    if (v.type == tAttrs) {
-        foreach (Bindings::iterator, i, *v.attrs)
-            forceValueDeep(*i->value);
-    }
+    std::function<void(Value & v)> recurse;
 
-    else if (v.type == tList) {
-        for (unsigned int n = 0; n < v.list.length; ++n)
-            forceValueDeep(*v.list.elems[n]);
-    }
+    recurse = [&](Value & v) {
+        if (seen.find(&v) != seen.end()) return;
+        seen.insert(&v);
+
+        forceValue(v);
+
+        if (v.type == tAttrs) {
+            foreach (Bindings::iterator, i, *v.attrs)
+                recurse(*i->value);
+        }
+
+        else if (v.type == tList) {
+            for (unsigned int n = 0; n < v.list.length; ++n)
+                recurse(*v.list.elems[n]);
+        }
+    };
+
+    recurse(v);
 }
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]