diff options
author | Dmitry Antipov <dmantipov@yandex.ru> | 2014-05-15 18:59:02 +0400 |
---|---|---|
committer | Dmitry Antipov <dmantipov@yandex.ru> | 2014-05-15 18:59:02 +0400 |
commit | ddc30c996a3d14e0163df6946ba96c9bcf73bd2f (patch) | |
tree | 6c0a2fafa8a124e0c6e12174321dc012226bb7a9 /src/fns.c | |
parent | 92491099f710794ee2be60721fae50d68c5ca162 (diff) | |
download | emacs-ddc30c996a3d14e0163df6946ba96c9bcf73bd2f.tar.gz |
* src/fns.c (Fnreverse): Allow vectors and bool vectors.
* doc/lispref/lists.texi (Building Cons Cells and Lists): Remove
description of `nreverse' and generalize it...
* doc/lispref/sequences.texi (Sequences): ...for sequences here.
* tests/automated/fns-tests.el (fns-tests-nreverse)
(fns-tests-nreverse-bool-vector): New tests.
Diffstat (limited to 'src/fns.c')
-rw-r--r-- | src/fns.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/src/fns.c b/src/fns.c index 8f9734cd7cc..1694f1c798d 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1697,25 +1697,55 @@ changing the value of a sequence `foo'. */) } DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0, - doc: /* Reverse LIST by modifying cdr pointers. -Return the reversed list. Expects a properly nil-terminated list. */) - (Lisp_Object list) + doc: /* Reverse order of items in a list or vector SEQ. +If SEQ is a list, it should be nil-terminated, and reversed +by modifying cdr pointers. Return the reversed SEQ. + +Note that unlike `reverse', this function doesn't work with strings. +It is strongly encouraged to treat them as immutable. */) + (Lisp_Object seq) { - register Lisp_Object prev, tail, next; + if (NILP (seq)) + return seq; + else if (CONSP (seq)) + { + Lisp_Object prev, tail, next; - if (NILP (list)) return list; - prev = Qnil; - tail = list; - while (!NILP (tail)) + for (prev = Qnil, tail = seq; !NILP (tail); tail = next) + { + QUIT; + CHECK_LIST_CONS (tail, tail); + next = XCDR (tail); + Fsetcdr (tail, prev); + prev = tail; + } + seq = prev; + } + else if (VECTORP (seq)) { - QUIT; - CHECK_LIST_CONS (tail, tail); - next = XCDR (tail); - Fsetcdr (tail, prev); - prev = tail; - tail = next; + ptrdiff_t i, size = ASIZE (seq); + + for (i = 0; i < size / 2; i++) + { + Lisp_Object tem = AREF (seq, i); + ASET (seq, i, AREF (seq, size - i - 1)); + ASET (seq, size - i - 1, tem); + } } - return prev; + else if (BOOL_VECTOR_P (seq)) + { + ptrdiff_t i, size = bool_vector_size (seq); + + for (i = 0; i < size / 2; i++) + { + bool tem = bool_vector_bitref (seq, i); + bool_vector_set (seq, i, bool_vector_bitref (seq, size - i - 1)); + bool_vector_set (seq, size - i - 1, tem); + } + } + else + wrong_type_argument (Qarrayp, seq); + return seq; } DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0, |