summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-01-30 16:40:10 +0100
committerBram Moolenaar <Bram@vim.org>2020-01-30 16:40:10 +0100
commit9f2d020d396132ecbc0be6faa1de29c7078bb5ac (patch)
treee4ec6f0fcf0e409a9b7c1c24818107c0ef752210
parent21109272f5b0d32c408dc292561c0b1f2f8ebc53 (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.c34
-rw-r--r--src/version.c2
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,