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 | 6c94850e2cf44009648fd3d2ce3ef010aea8a7a0 (patch) | |
tree | aa025f6f7c1013775b98000a8944f029373a8765 | |
parent | 27e54c2db0cbb08b8cd4163c828e964dedd0e08f (diff) | |
download | txr-6c94850e2cf44009648fd3d2ce3ef010aea8a7a0.tar.gz txr-6c94850e2cf44009648fd3d2ce3ef010aea8a7a0.tar.bz2 txr-6c94850e2cf44009648fd3d2ce3ef010aea8a7a0.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; } |