summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib.c2
-rw-r--r--share/txr/stdlib/doc-syms.tl3
-rw-r--r--tests/010/tree.tl9
-rw-r--r--tree.c22
-rw-r--r--tree.h3
-rw-r--r--txr.125
6 files changed, 62 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index 5419494e..721e6e48 100644
--- a/lib.c
+++ b/lib.c
@@ -11340,6 +11340,8 @@ val copy(val seq)
return copy_carray(seq);
if (seq->co.cls == tree_s)
return copy_search_tree(seq);
+ if (seq->co.cls == tree_iter_s)
+ return copy_tree_iter(seq);
if (obj_struct_p(seq))
return copy_struct(seq);
/* fallthrough */
diff --git a/share/txr/stdlib/doc-syms.tl b/share/txr/stdlib/doc-syms.tl
index 2355066e..64fbcf6c 100644
--- a/share/txr/stdlib/doc-syms.tl
+++ b/share/txr/stdlib/doc-syms.tl
@@ -901,9 +901,9 @@
("tanh" "D-0037")
("improper-plist-to-alist" "N-006E31B5")
("seek" "N-0136D6A2")
+ ("*stdout*" "N-006566FB")
("include" "N-01A2ECA0")
("interpose" "N-0030734D")
- ("*stdout*" "N-006566FB")
("*n" "N-02E7AE5A")
("buf-put-uchar" "N-03BCF627")
("gen" "N-0323BEBD")
@@ -1420,6 +1420,7 @@
("seek-set" "N-01D6E4D8")
("vectorp" "N-03B9C3E5")
("r-mod" "N-02F8C918")
+ ("copy-tree-iter" "N-025C3140")
("rlcp-tree" "N-024EB211")
("parenb" "N-01B1B5DF")
("inaddr-any" "N-026A2C3B")
diff --git a/tests/010/tree.tl b/tests/010/tree.tl
index c2fe5382..e3b2ce0c 100644
--- a/tests/010/tree.tl
+++ b/tests/010/tree.tl
@@ -94,6 +94,15 @@
(add (key n))))
(range 8 19))
+(test (let* ((t0 (tree-begin tr))
+ (t1 (progn (tree-next t0) (copy-tree-iter t0))))
+ (tree-next t0)
+ (tree-next t0)
+ (list (key (tree-next t1))
+ (key (tree-next t1))
+ (key (tree-next t1))))
+ (1 2 3))
+
(test (tree-next (tree-begin-at tr 20)) nil)
(test (tree-next (tree-begin-at #T(()) 0)) nil)
diff --git a/tree.c b/tree.c
index 1f9bd9ff..e8b42523 100644
--- a/tree.c
+++ b/tree.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include <limits.h>
#include <signal.h>
#include "config.h"
@@ -811,6 +812,26 @@ val tree_begin_at(val tree, val lowkey)
return iter;
}
+val copy_tree_iter(val iter)
+{
+ val self = lit("copy-tree-iter");
+ struct tree_diter *tdis = coerce(struct tree_diter *,
+ cobj_handle(self, iter, tree_iter_s));
+ struct tree_diter *tdid = coerce(struct tree_diter *,
+ chk_calloc(1, sizeof *tdid));
+ val iter_copy = cobj(coerce(mem_t *, tdid), tree_iter_s, &tree_iter_ops);
+ int depth = tdis->ti.depth;
+
+ tdid->ti.self = iter_copy;
+ tdid->ti.depth = depth;
+ tdid->ti.state = tdis->ti.state;
+ tdid->lastnode = tdis->lastnode;
+
+ memcpy(tdid->ti.path, tdis->ti.path, sizeof tdid->ti.path[0] * depth);
+
+ return iter_copy;
+}
+
val tree_reset(val iter, val tree)
{
val self = lit("tree-reset");
@@ -908,6 +929,7 @@ void tree_init(void)
reg_fun(intern(lit("tree-root"), user_package), func_n1(tree_root));
reg_fun(intern(lit("tree-begin"), user_package), func_n1(tree_begin));
reg_fun(intern(lit("tree-begin-at"), user_package), func_n2(tree_begin_at));
+ reg_fun(intern(lit("copy-tree-iter"), user_package), func_n1(copy_tree_iter));
reg_fun(intern(lit("tree-reset"), user_package), func_n2(tree_reset));
reg_fun(intern(lit("tree-reset-at"), user_package), func_n3(tree_reset_at));
reg_fun(intern(lit("tree-next"), user_package), func_n1(tree_next));
diff --git a/tree.h b/tree.h
index 690cd91b..72ee43db 100644
--- a/tree.h
+++ b/tree.h
@@ -25,7 +25,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-extern val tree_s, tree_fun_whitelist_s;
+extern val tree_s, tree_iter_s, tree_fun_whitelist_s;
#define tree_fun_whitelist (deref(lookup_var_l(nil, tree_fun_whitelist_s)))
@@ -50,6 +50,7 @@ val tree_delete_node(val tree, val key);
val tree_delete(val tree, val key);
val tree_begin(val tree);
val tree_begin_at(val tree, val lowkey);
+val copy_tree_iter(val iter);
val tree_reset(val iter, val tree);
val tree_reset_at(val iter, val tree, val lowkey);
val tree_next(val iter);
diff --git a/txr.1 b/txr.1
index 4c462a32..42c73080 100644
--- a/txr.1
+++ b/txr.1
@@ -19582,6 +19582,10 @@ the type of the argument, as follows:
.mono
.meti (copy-search-tree << object )
.onom
+.coIP tree-iter
+.mono
+.meti (copy-tree-iter << object )
+.onom
.RE
.IP
@@ -51921,6 +51925,27 @@ is invoked more than once on the same iterator without any intervening calls to
it returns the same node; it does not appear to change the state of
the iterator and therefore does not advance through successive nodes.
+.coNP Function @ copy-tree-iter
+.synb
+.mets (copy-tree-iter < iter )
+.syne
+.desc
+The
+.code copy-tree-iter
+function creates and returns a duplicate of the
+.meta iter
+object, which must be a tree iterator returned by
+.code tree-begin
+or
+.codn tree-begin-at .
+
+The returned object has the same state as the original; it references the same
+traversal position in the same tree. However, it is independent of the original.
+Calls to
+.code tree-next
+on the original have no effect on the duplicate and
+.IR vice-versa .
+
.coNP Special variable @ *tree-fun-whitelist*
.desc
The