diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-11-16 06:38:49 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-11-16 06:38:49 -0800 |
commit | 6570b4ba2056818462a01f2752f318cc00e0e8da (patch) | |
tree | e24d6778ea173afd3ef4a9af0ff530c9c2e27410 | |
parent | 89b51ce4482c0d10abe2947fb02876784119e091 (diff) | |
download | txr-6570b4ba2056818462a01f2752f318cc00e0e8da.tar.gz txr-6570b4ba2056818462a01f2752f318cc00e0e8da.tar.bz2 txr-6570b4ba2056818462a01f2752f318cc00e0e8da.zip |
pos-max: rewrite.
* lib.c (pos_max): Rewrite using seq_info.
-rw-r--r-- | lib.c | 66 |
1 files changed, 48 insertions, 18 deletions
@@ -8951,32 +8951,62 @@ val rpos_if(val pred, val seq, val key) val pos_max(val seq, val testfun, val keyfun) { - val pos = zero; - val maxkey; - val maxpos = zero; - - seq = nullify(seq); + seq_info_t si = seq_info(seq); + testfun = default_arg(testfun, greater_f); + keyfun = default_arg(keyfun, identity_f); - if (!seq) + switch (si.kind) { + case SEQ_NIL: return nil; + case SEQ_LISTLIKE: + { + val maxkey = funcall1(keyfun, car(si.obj)); + val maxpos = zero; + val pos; - gc_hint(seq); + gc_hint(seq); - testfun = default_arg(testfun, greater_f); - keyfun = default_arg(keyfun, identity_f); + for (pos = one, seq = cdr(z(si.obj)); + seq; + seq = cdr(seq), pos = succ(pos)) + { + val elt = car(seq); + val key = funcall1(keyfun, elt); + if (funcall2(testfun, key, maxkey)) { + maxkey = key; + maxpos = pos; + } + } - maxkey = funcall1(keyfun, car(seq)); + return maxpos; + } + case SEQ_VECLIKE: + { + val vec = si.obj; + val len = length(vec); - for (seq = cdr(seq); seq; seq = cdr(seq)) { - val key = funcall1(keyfun, car(seq)); - pos = plus(pos, one); - if (funcall2(testfun, key, maxkey)) { - maxkey = key; - maxpos = pos; + if (len != zero) { + val maxpos = zero; + val maxkey = funcall1(keyfun, ref(vec, zero)); + val i; + + for (i = one; lt(i, len); i = succ(i)) { + val elt = ref(vec, i); + val key = funcall1(keyfun, elt); + if (funcall2(testfun, key, maxkey)) { + maxkey = key; + maxpos = i; + } + } + return maxpos; + } + + return nil; } + case SEQ_NOTSEQ: + default: + uw_throwf(error_s, lit("pos-max: unsupported object ~s"), seq, nao); } - - return maxpos; } val pos_min(val seq, val testfun, val keyfun) |