changeset 19247:c077438ceb93 v8.2.0182

patch 8.2.0182: min() and max() materialize a range() list Commit: https://github.com/vim/vim/commit/9f2d020d396132ecbc0be6faa1de29c7078bb5ac Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jan 30 16:40:10 2020 +0100 patch 8.2.0182: min() and max() materialize a range() list Problem: Min() and max() materialize a range() list. Solution: Compute the result without materializing the list. (https://github.com/vim/vim/issues/5541)
author Bram Moolenaar <Bram@vim.org>
date Thu, 30 Jan 2020 16:45:04 +0100
parents fb4df26177a5
children 5e803caf5e9c
files src/evalfunc.c src/version.c
diffstat 2 files changed, 24 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -4881,21 +4881,31 @@ max_min(typval_T *argvars, typval_T *ret
 	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;
+		    }
 		}
 	    }
 	}
--- 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,