Mercurial > hg > xemacs-beta
diff lisp/cl-macs.el @ 4707:5bb0735f56e0
Handle non-list sequences better, delete-duplicates compiler macro.
2009-10-03 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (delete-duplicates):
Make this compiler macro aware that CL-SEQ is a sequence, which
may not necessarily be a list.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 03 Oct 2009 14:22:08 +0100 |
parents | eb1a409c317b |
children | 84f870bbd17b |
line wrap: on
line diff
--- a/lisp/cl-macs.el Thu Oct 01 18:00:11 2009 +0200 +++ b/lisp/cl-macs.el Sat Oct 03 14:22:08 2009 +0100 @@ -3218,26 +3218,46 @@ ;; #'equal or #'eq and no other keywords, we want the speed in ;; font-lock.el. (define-compiler-macro delete-duplicates (&whole form cl-seq &rest cl-keys) - (cond ((and (= 4 (length form)) - (eq :test (third form)) - (or (equal '(quote eq) (fourth form)) - (equal '(function eq) (fourth form)))) - `(let* ((begin ,cl-seq) - (cl-seq begin)) - (while cl-seq - (setq cl-seq (setcdr cl-seq (delq (car cl-seq) (cdr cl-seq))))) - begin)) - ((and (= 4 (length form)) - (eq :test (third form)) - (or (equal '(quote equal) (fourth form)) - (equal '(function equal) (fourth form)))) - `(let* ((begin ,cl-seq) - (cl-seq begin)) - (while cl-seq - (setq cl-seq (setcdr cl-seq (delete (car cl-seq) (cdr cl-seq))))) - begin)) - (t - form))) + (let ((listp-check + (if (memq (car-safe cl-seq) + ;; No need to check for a list at runtime with these. We + ;; could expand the list, but these are all the functions + ;; in the relevant context at the moment. + '(nreverse append nconc mapcan mapcar)) + t + '(listp begin)))) + (cond ((and (= 4 (length form)) + (eq :test (third form)) + (or (equal '(quote eq) (fourth form)) + (equal '(function eq) (fourth form)))) + `(let* ((begin ,cl-seq) + (cl-seq begin)) + (if ,listp-check + (progn + (while cl-seq + (setq cl-seq (setcdr cl-seq (delq (car cl-seq) + (cdr cl-seq))))) + begin) + ;; Call cl-delete-duplicates explicitly, to avoid the form + ;; getting compiler-macroexpanded again: + (cl-delete-duplicates begin ,(third form) ,(fourth form) nil)))) + ((and (= 4 (length form)) + (eq :test (third form)) + (or (equal '(quote equal) (fourth form)) + (equal '(function equal) (fourth form)))) + `(let* ((begin ,cl-seq) + (cl-seq begin)) + (if ,listp-check + (progn + (while cl-seq + (setq cl-seq (setcdr cl-seq (delete (car cl-seq) + (cdr cl-seq))))) + begin) + ;; Call cl-delete-duplicates explicitly, to avoid the form + ;; getting compiler-macroexpanded again: + (cl-delete-duplicates begin ,(third form) ,(fourth form) nil)))) + (t + form)))) (mapc #'(lambda (y)