diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-07-26 06:54:36 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-07-26 06:54:36 -0700 |
commit | f8ad6f5b4a33d85efab7de86e14ada750e3a23ce (patch) | |
tree | 723b3f677e03406290a5027d7cb8906e08be9d0d /lib.c | |
parent | f6fba584dbd928d9af82f97f71b2bddfbc05b2df (diff) | |
download | txr-f8ad6f5b4a33d85efab7de86e14ada750e3a23ce.tar.gz txr-f8ad6f5b4a33d85efab7de86e14ada750e3a23ce.tar.bz2 txr-f8ad6f5b4a33d85efab7de86e14ada750e3a23ce.zip |
lib: deprecate set-diff; extend set operations.
* eval.c (eval_init): Register set-diff under two
names: set-diff and diff. Register new isec and uni
intrinsics.
* lib.c (isec, uni): New functions.
* lib.h (isec, uni): Declared.
* txr.1: Documented new uni and isec functions, new diff
function name, and the deprecation of set-diff and its order
guarantee w.r.t the left sequence.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -9285,6 +9285,65 @@ val set_diff(val list1, val list2, val testfun, val keyfun) return make_like(out, list_orig); } +val isec(val list1, val list2, val testfun, val keyfun) +{ + list_collect_decl (out, ptail); + val list_orig = list1; + + list1 = nullify(list1); + list2 = nullify(list2); + + testfun = default_arg(testfun, equal_f); + keyfun = default_arg(keyfun, identity_f); + + for (; list1; list1 = cdr(list1)) { + /* optimization: list2 is a tail of list1, and so we + are done, unless the application has a weird test function. */ + if (list1 == list2) { + ptail = list_collect_append(ptail, list1); + break; + } else { + val item = car(list1); + val list1_key = funcall1(keyfun, item); + + if (member(list1_key, list2, testfun, keyfun)) + ptail = list_collect(ptail, item); + } + } + + return make_like(out, list_orig); +} + +val uni(val list1, val list2, val testfun, val keyfun) +{ + list_collect_decl (out, ptail); + val list_orig = list1; + + list1 = nullify(list1); + list2 = nullify(list2); + + testfun = default_arg(testfun, equal_f); + keyfun = default_arg(keyfun, identity_f); + + ptail = list_collect_append(ptail, list1); + + for (; list2; list2 = cdr(list2)) { + /* optimization: list2 is a tail of list1, and so we + are done, unless the application has a weird test function. */ + if (list1 == list2) { + break; + } else { + val item = car(list2); + val list2_key = funcall1(keyfun, item); + + if (!member(list2_key, list1, testfun, keyfun)) + ptail = list_collect(ptail, item); + } + } + + return make_like(out, list_orig); +} + val copy(val seq) { switch (type(seq)) { |