diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-11-30 06:49:14 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-11-30 06:49:14 -0800 |
commit | a71adb359832e1c119166c651010f4aa4323031f (patch) | |
tree | aa025f6f7c1013775b98000a8944f029373a8765 | |
parent | ad277e8ac9f02ce6ad9cbd99fbd0a64244f379d6 (diff) | |
download | txr-a71adb359832e1c119166c651010f4aa4323031f.tar.gz txr-a71adb359832e1c119166c651010f4aa4323031f.tar.bz2 txr-a71adb359832e1c119166c651010f4aa4323031f.zip |
Rewrite internal mapping function.
* lib.c (mapcar_listout): Rework using seq_info for
efficient processing of vector-like sequences and
objects that implement sequences.
-rw-r--r-- | lib.c | 25 |
1 files changed, 21 insertions, 4 deletions
@@ -7866,14 +7866,31 @@ val copy_alist(val list) return mapcar(func_n1(copy_cons), list); } -val mapcar_listout(val fun, val list) +val mapcar_listout(val fun, val seq) { + val self = lit("mapcar"); + seq_info_t si = seq_info(seq); list_collect_decl (out, iter); - list = nullify(list); + switch (si.kind) { + case SEQ_NIL: + return nil; + case SEQ_VECLIKE: + { + val v = si.obj; + cnum i, len = c_fixnum(length(v), self); - for (; list; list = cdr(list)) - iter = list_collect(iter, funcall1(fun, car(list))); + for (i = 0; i < len; i++) + iter = list_collect(iter, funcall1(fun, ref(v, num_fast(i)))); + } + break; + case SEQ_LISTLIKE: + for (seq = z(si.obj); seq; seq = cdr(seq)) + iter = list_collect(iter, funcall1(fun, car(seq))); + break; + default: + unsup_obj(self, seq); + } return out; } |