diff options
-rw-r--r-- | lib.c | 2 | ||||
-rw-r--r-- | share/txr/stdlib/doc-syms.tl | 3 | ||||
-rw-r--r-- | tests/010/tree.tl | 9 | ||||
-rw-r--r-- | tree.c | 22 | ||||
-rw-r--r-- | tree.h | 3 | ||||
-rw-r--r-- | txr.1 | 25 |
6 files changed, 62 insertions, 2 deletions
@@ -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) @@ -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)); @@ -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); @@ -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 |