aboutsummaryrefslogtreecommitdiffstats
path: root/src/sort.c
diff options
context:
space:
mode:
authorMattias EngdegÄrd2024-03-19 13:03:47 +0100
committerMattias EngdegÄrd2024-03-29 11:39:38 +0100
commitae5f2c02bd2fc269e2cc32c8039d95fbf4225e69 (patch)
treea4c4b2d9cb7288524b7946e0f3263dca4357fd9c /src/sort.c
parenta52f1121a3589af8f89828e04d66f1215c361bcf (diff)
downloademacs-ae5f2c02bd2fc269e2cc32c8039d95fbf4225e69.tar.gz
emacs-ae5f2c02bd2fc269e2cc32c8039d95fbf4225e69.zip
New `sort` keyword arguments (bug#69709)
Add the :key, :lessp, :reverse and :in-place keyword arguments. The old calling style remains available and is unchanged. * src/fns.c (sort_list, sort_vector, Fsort): * src/sort.c (tim_sort): Add keyword arguments with associated new features. All callers of Fsort adapted. * test/src/fns-tests.el (fns-tests--shuffle-vector, fns-tests-sort-kw): New test. * doc/lispref/sequences.texi (Sequence Functions): Update manual. * etc/NEWS: Announce.
Diffstat (limited to 'src/sort.c')
-rw-r--r--src/sort.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/sort.c b/src/sort.c
index d91993c8c65..a0f127c35b3 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1072,11 +1072,11 @@ resolve_fun (Lisp_Object fun)
1072} 1072}
1073 1073
1074/* Sort the array SEQ with LENGTH elements in the order determined by 1074/* Sort the array SEQ with LENGTH elements in the order determined by
1075 PREDICATE. */ 1075 PREDICATE (where Qnil means value<) and KEYFUNC (where Qnil means identity),
1076 1076 optionally reversed. */
1077void 1077void
1078tim_sort (Lisp_Object predicate, Lisp_Object keyfunc, 1078tim_sort (Lisp_Object predicate, Lisp_Object keyfunc,
1079 Lisp_Object *seq, const ptrdiff_t length) 1079 Lisp_Object *seq, const ptrdiff_t length, bool reverse)
1080{ 1080{
1081 /* FIXME: optimise for the predicate being value<; at the very 1081 /* FIXME: optimise for the predicate being value<; at the very
1082 least we'd go without the Lisp funcall overhead. */ 1082 least we'd go without the Lisp funcall overhead. */
@@ -1091,9 +1091,8 @@ tim_sort (Lisp_Object predicate, Lisp_Object keyfunc,
1091 if (EQ (keyfunc, Qidentity)) 1091 if (EQ (keyfunc, Qidentity))
1092 keyfunc = Qnil; 1092 keyfunc = Qnil;
1093 1093
1094 /* FIXME: consider a built-in reverse sorting flag: we would reverse 1094 if (reverse)
1095 the input in-place here and reverse it back just before 1095 reverse_slice (seq, seq + length); /* preserve stability */
1096 returning. */
1097 1096
1098 if (NILP (keyfunc)) 1097 if (NILP (keyfunc))
1099 { 1098 {
@@ -1159,6 +1158,9 @@ tim_sort (Lisp_Object predicate, Lisp_Object keyfunc,
1159 eassume (ms.pending[0].len == length); 1158 eassume (ms.pending[0].len == length);
1160 lo = ms.pending[0].base; 1159 lo = ms.pending[0].base;
1161 1160
1161 if (reverse)
1162 reverse_slice (seq, seq + length);
1163
1162 if (ms.a.keys != ms.temparray || allocated_keys != NULL) 1164 if (ms.a.keys != ms.temparray || allocated_keys != NULL)
1163 unbind_to (ms.count, Qnil); 1165 unbind_to (ms.count, Qnil);
1164} 1166}