diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-01-30 16:40:10 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-01-30 16:40:10 +0100 |
commit | 9f2d020d396132ecbc0be6faa1de29c7078bb5ac (patch) | |
tree | e4ec6f0fcf0e409a9b7c1c24818107c0ef752210 | |
parent | 21109272f5b0d32c408dc292561c0b1f2f8ebc53 (diff) |
patch 8.2.0182: min() and max() materialize a range() listv8.2.0182
Problem: Min() and max() materialize a range() list.
Solution: Compute the result without materializing the list. (#5541)
-rw-r--r-- | src/evalfunc.c | 34 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 24 insertions, 12 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index 19f7294390..15b799088d 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -4881,21 +4881,31 @@ max_min(typval_T *argvars, typval_T *rettv, int domax) listitem_T *li; l = argvars[0].vval.v_list; - if (l != NULL) + if (l != NULL && l->lv_len > 0) { - range_list_materialize(l); - li = l->lv_first; - if (li != NULL) + if (l->lv_first == &range_list_item) + { + if ((l->lv_u.nonmat.lv_stride > 0) ^ domax) + n = l->lv_u.nonmat.lv_start; + else + n = l->lv_u.nonmat.lv_start + (l->lv_len - 1) + * l->lv_u.nonmat.lv_stride; + } + else { - n = tv_get_number_chk(&li->li_tv, &error); - for (;;) + li = l->lv_first; + if (li != NULL) { - li = li->li_next; - if (li == NULL) - break; - i = tv_get_number_chk(&li->li_tv, &error); - if (domax ? i > n : i < n) - n = i; + n = tv_get_number_chk(&li->li_tv, &error); + for (;;) + { + li = li->li_next; + if (li == NULL) + break; + i = tv_get_number_chk(&li->li_tv, &error); + if (domax ? i > n : i < n) + n = i; + } } } } diff --git a/src/version.c b/src/version.c index acbc4f2955..be4da51fc4 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 182, +/**/ 181, /**/ 180, |